From f1bde1f8e5a84037d740afd09a83e7879b497b6a Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 01:36:27 +0500 Subject: [PATCH 01/11] Task 13.4: ship an Expo config plugin that prebuild reapplies. The plugin copies the bare app's source-map hook and Archive post-action, and writes bugsee.properties without turning NDK upload on for a placeholder token. Co-authored-by: Cursor --- .gitignore | 6 +- .../plans/2026-09-16-implementation-plan.md | 2 +- examples/expo/.gitignore | 3 + examples/expo/App.js | 8 + examples/expo/app.json | 17 + examples/expo/babel.config.js | 6 + examples/expo/index.js | 4 + examples/expo/metro.config.js | 3 + examples/expo/package.json | 19 + packages/react-native/app.plugin.js | 4 + packages/react-native/package.json | 6 +- .../plugin/build/bundle-phase.d.ts | 23 + .../react-native/plugin/build/bundle-phase.js | 77 + .../plugin/build/bundle-phase.js.map | 1 + .../plugin/build/dsym-script.d.ts | 1 + .../react-native/plugin/build/dsym-script.js | 7 + .../plugin/build/dsym-script.js.map | 1 + .../react-native/plugin/build/gradle.d.ts | 13 + packages/react-native/plugin/build/gradle.js | 129 + .../react-native/plugin/build/gradle.js.map | 1 + packages/react-native/plugin/build/index.d.ts | 23 + packages/react-native/plugin/build/index.js | 100 + .../react-native/plugin/build/index.js.map | 1 + .../react-native/plugin/build/manifest.d.ts | 11 + .../react-native/plugin/build/manifest.js | 20 + .../react-native/plugin/build/manifest.js.map | 1 + .../plugin/build/native-versions.d.ts | 10 + .../plugin/build/native-versions.js | 32 + .../plugin/build/native-versions.js.map | 1 + .../react-native/plugin/build/pbx-string.d.ts | 8 + .../react-native/plugin/build/pbx-string.js | 53 + .../plugin/build/pbx-string.js.map | 1 + .../react-native/plugin/build/properties.d.ts | 15 + .../react-native/plugin/build/properties.js | 37 + .../plugin/build/properties.js.map | 1 + .../react-native/plugin/build/scheme.d.ts | 9 + packages/react-native/plugin/build/scheme.js | 56 + .../react-native/plugin/build/scheme.js.map | 1 + .../plugin/src/__tests__/plugin.test.ts | 258 ++ .../react-native/plugin/src/bundle-phase.ts | 94 + .../react-native/plugin/src/dsym-script.ts | 3 + packages/react-native/plugin/src/gradle.ts | 129 + packages/react-native/plugin/src/index.ts | 150 + packages/react-native/plugin/src/manifest.ts | 23 + .../plugin/src/native-versions.ts | 41 + .../react-native/plugin/src/pbx-string.ts | 48 + .../react-native/plugin/src/properties.ts | 40 + packages/react-native/plugin/src/scheme.ts | 54 + packages/react-native/plugin/tsconfig.json | 19 + yarn.lock | 2644 +++++++++++++++-- 50 files changed, 3997 insertions(+), 217 deletions(-) create mode 100644 examples/expo/.gitignore create mode 100644 examples/expo/App.js create mode 100644 examples/expo/app.json create mode 100644 examples/expo/babel.config.js create mode 100644 examples/expo/index.js create mode 100644 examples/expo/metro.config.js create mode 100644 examples/expo/package.json create mode 100644 packages/react-native/app.plugin.js create mode 100644 packages/react-native/plugin/build/bundle-phase.d.ts create mode 100644 packages/react-native/plugin/build/bundle-phase.js create mode 100644 packages/react-native/plugin/build/bundle-phase.js.map create mode 100644 packages/react-native/plugin/build/dsym-script.d.ts create mode 100644 packages/react-native/plugin/build/dsym-script.js create mode 100644 packages/react-native/plugin/build/dsym-script.js.map create mode 100644 packages/react-native/plugin/build/gradle.d.ts create mode 100644 packages/react-native/plugin/build/gradle.js create mode 100644 packages/react-native/plugin/build/gradle.js.map create mode 100644 packages/react-native/plugin/build/index.d.ts create mode 100644 packages/react-native/plugin/build/index.js create mode 100644 packages/react-native/plugin/build/index.js.map create mode 100644 packages/react-native/plugin/build/manifest.d.ts create mode 100644 packages/react-native/plugin/build/manifest.js create mode 100644 packages/react-native/plugin/build/manifest.js.map create mode 100644 packages/react-native/plugin/build/native-versions.d.ts create mode 100644 packages/react-native/plugin/build/native-versions.js create mode 100644 packages/react-native/plugin/build/native-versions.js.map create mode 100644 packages/react-native/plugin/build/pbx-string.d.ts create mode 100644 packages/react-native/plugin/build/pbx-string.js create mode 100644 packages/react-native/plugin/build/pbx-string.js.map create mode 100644 packages/react-native/plugin/build/properties.d.ts create mode 100644 packages/react-native/plugin/build/properties.js create mode 100644 packages/react-native/plugin/build/properties.js.map create mode 100644 packages/react-native/plugin/build/scheme.d.ts create mode 100644 packages/react-native/plugin/build/scheme.js create mode 100644 packages/react-native/plugin/build/scheme.js.map create mode 100644 packages/react-native/plugin/src/__tests__/plugin.test.ts create mode 100644 packages/react-native/plugin/src/bundle-phase.ts create mode 100644 packages/react-native/plugin/src/dsym-script.ts create mode 100644 packages/react-native/plugin/src/gradle.ts create mode 100644 packages/react-native/plugin/src/index.ts create mode 100644 packages/react-native/plugin/src/manifest.ts create mode 100644 packages/react-native/plugin/src/native-versions.ts create mode 100644 packages/react-native/plugin/src/pbx-string.ts create mode 100644 packages/react-native/plugin/src/properties.ts create mode 100644 packages/react-native/plugin/src/scheme.ts create mode 100644 packages/react-native/plugin/tsconfig.json diff --git a/.gitignore b/.gitignore index 49c5f49..25b37ba 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,8 @@ coverage/ *.log .DS_Store -# Native build output +# Native build output. `build/` would also hide the compiled Expo config +# plugin, which ships in the package, so that directory is un-ignored below. android/build/ android/.gradle/ ios/build/ @@ -22,7 +23,8 @@ bugsee.properties .env .gradle/ local.properties -build/ +**/build/** +!packages/react-native/plugin/build/** .build/ .swiftpm/ *.xcodeproj/ diff --git a/docs/design/plans/2026-09-16-implementation-plan.md b/docs/design/plans/2026-09-16-implementation-plan.md index 9865f06..d9ab53e 100644 --- a/docs/design/plans/2026-09-16-implementation-plan.md +++ b/docs/design/plans/2026-09-16-implementation-plan.md @@ -4066,7 +4066,7 @@ The phase with the most native↔JS round-tripping, hence the most device testin - [x] **13.1** Source maps: `bugsee-cli sourcemaps inject` then `debug-files upload --type sourcemaps`. Injection must happen on the **composed** Hermes map, after `compose-source-maps.js`, or the debug ID lands on a map nothing consults. - [x] **13.2** dSYM upload as an Xcode **scheme post-action** running `bugsee-cli xcode post-action`. A build phase also works but needs `BUGSEE_BUILD_INFO_ALL_ACTIONS=1`, and Xcode 15+ defaults `ENABLE_USER_SCRIPT_SANDBOXING` to `YES`, which blocks it. - [ ] **13.3** Android mapping and NDK symbols — the Gradle plugin's job once applied. Write `android/bugsee.properties` with the **unprefixed** `app_token=` key (not `plugin.appToken`) at the *root* project, and default `plugin.ndk.enabled=true` for RN, since every RN app ships Hermes and `libreactnative.so` it did not write. -- [ ] **13.4** Expo config plugin, with a `prebuild --clean` test — the `.xcscheme` edit is the most fragile part and Expo has no helper for it. +- [x] **13.4** Expo config plugin, with a `prebuild --clean` test — the `.xcscheme` edit is the most fragile part and Expo has no helper for it. `CI=1 yarn expo prebuild --clean` in `examples/expo` exited 0 (CocoaPods installed) and left `bugsee-xcode.sh` on *Bundle React Native code and images* plus the Archive `Upload dSYMs` post-action. - [ ] **13.5** End-to-end: a release build whose JS stack symbolicates in the dashboard. This is the only test that proves the whole chain. - [ ] Review gate. diff --git a/examples/expo/.gitignore b/examples/expo/.gitignore new file mode 100644 index 0000000..f0b2974 --- /dev/null +++ b/examples/expo/.gitignore @@ -0,0 +1,3 @@ +ios/ +android/ +.expo/ diff --git a/examples/expo/App.js b/examples/expo/App.js new file mode 100644 index 0000000..861885f --- /dev/null +++ b/examples/expo/App.js @@ -0,0 +1,8 @@ +const React = require('react'); +const { Text, View } = require('react-native'); + +function App() { + return React.createElement(View, null, React.createElement(Text, null, 'Bugsee Expo')); +} + +module.exports = App; diff --git a/examples/expo/app.json b/examples/expo/app.json new file mode 100644 index 0000000..a2f8507 --- /dev/null +++ b/examples/expo/app.json @@ -0,0 +1,17 @@ +{ + "expo": { + "name": "BugseeExpo", + "slug": "bugsee-expo", + "version": "1.0.0", + "orientation": "portrait", + "ios": { + "bundleIdentifier": "com.bugsee.expoexample" + }, + "android": { + "package": "com.bugsee.expoexample" + }, + "plugins": [ + "@bugsee/react-native" + ] + } +} diff --git a/examples/expo/babel.config.js b/examples/expo/babel.config.js new file mode 100644 index 0000000..9d89e13 --- /dev/null +++ b/examples/expo/babel.config.js @@ -0,0 +1,6 @@ +module.exports = function (api) { + api.cache(true); + return { + presets: ['babel-preset-expo'], + }; +}; diff --git a/examples/expo/index.js b/examples/expo/index.js new file mode 100644 index 0000000..632871d --- /dev/null +++ b/examples/expo/index.js @@ -0,0 +1,4 @@ +const { registerRootComponent } = require('expo'); +const App = require('./App'); + +registerRootComponent(App); diff --git a/examples/expo/metro.config.js b/examples/expo/metro.config.js new file mode 100644 index 0000000..944ec02 --- /dev/null +++ b/examples/expo/metro.config.js @@ -0,0 +1,3 @@ +const { getDefaultConfig } = require('expo/metro-config'); + +module.exports = getDefaultConfig(__dirname); diff --git a/examples/expo/package.json b/examples/expo/package.json new file mode 100644 index 0000000..61218bb --- /dev/null +++ b/examples/expo/package.json @@ -0,0 +1,19 @@ +{ + "name": "bugsee-example-expo", + "version": "0.0.1", + "private": true, + "main": "index.js", + "scripts": { + "start": "expo start", + "prebuild": "expo prebuild --clean" + }, + "dependencies": { + "@bugsee/react-native": "workspace:*", + "expo": "~57.0.26", + "react": "19.2.3", + "react-native": "0.86.3" + }, + "devDependencies": { + "@babel/core": "^7.25.2" + } +} diff --git a/packages/react-native/app.plugin.js b/packages/react-native/app.plugin.js new file mode 100644 index 0000000..1e972f7 --- /dev/null +++ b/packages/react-native/app.plugin.js @@ -0,0 +1,4 @@ +// Expo loads a package plugin from this file with Node's require(). +const plugin = require('./plugin/build/index.js'); + +module.exports = plugin.default ?? plugin; diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 61f2590..a13a5bd 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -9,6 +9,8 @@ "src", "android", "ios", + "app.plugin.js", + "plugin/build", "scripts/hermes-sourcemaps.js", "scripts/compose-then-inject.js", "scripts/bugsee-xcode.sh", @@ -17,7 +19,8 @@ "*.podspec" ], "dependencies": { - "@bugsee/cli": "0.7.11" + "@bugsee/cli": "0.7.11", + "@expo/config-plugins": "~57.0.9" }, "peerDependencies": { "react": "*", @@ -27,6 +30,7 @@ "react-native": "0.87.1" }, "scripts": { + "build:plugin": "node ../../node_modules/typescript/lib/tsc.js -p plugin/tsconfig.json", "prepack": "node ../../scripts/cli-check-releasable-pins.ts" }, "codegenConfig": { diff --git a/packages/react-native/plugin/build/bundle-phase.d.ts b/packages/react-native/plugin/build/bundle-phase.d.ts new file mode 100644 index 0000000..e06ce99 --- /dev/null +++ b/packages/react-native/plugin/build/bundle-phase.d.ts @@ -0,0 +1,23 @@ +/** + * The "Bundle React Native code and images" shell script from the bare + * example's pbxproj. It runs `bugsee-xcode.sh`, which makes + * `REACT_NATIVE_PATH` absolute with `cd`/`pwd` and injects after compose. + * The upload function in that script is not executed. + */ +export declare const BARE_BUNDLE_SCRIPT: string; +export declare function rewriteBundlePhase(script: string): string; +export interface ShellPhase { + isa?: string; + name?: string; + shellScript?: string; +} +export interface XcodeProjectLike { + hash?: { + project?: { + objects?: { + PBXShellScriptBuildPhase?: Record; + }; + }; + }; +} +export declare function rewriteProjectBundlePhase(project: XcodeProjectLike): void; diff --git a/packages/react-native/plugin/build/bundle-phase.js b/packages/react-native/plugin/build/bundle-phase.js new file mode 100644 index 0000000..908621b --- /dev/null +++ b/packages/react-native/plugin/build/bundle-phase.js @@ -0,0 +1,77 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BARE_BUNDLE_SCRIPT = void 0; +exports.rewriteBundlePhase = rewriteBundlePhase; +exports.rewriteProjectBundlePhase = rewriteProjectBundlePhase; +const pbx_string_1 = require("./pbx-string"); +/** + * The "Bundle React Native code and images" shell script from the bare + * example's pbxproj. It runs `bugsee-xcode.sh`, which makes + * `REACT_NATIVE_PATH` absolute with `cd`/`pwd` and injects after compose. + * The upload function in that script is not executed. + */ +exports.BARE_BUNDLE_SCRIPT = [ + 'set -e', + '', + 'WITH_ENVIRONMENT="$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh"', + 'BUGSEE_XCODE="${SRCROOT}/../node_modules/@bugsee/react-native/scripts/bugsee-xcode.sh"', + '', + '/bin/sh -c "\\"$WITH_ENVIRONMENT\\" \\"$BUGSEE_XCODE\\""', + '', +].join('\n'); +const BUGSEE_XCODE = '"${SRCROOT}/../node_modules/@bugsee/react-native/scripts/bugsee-xcode.sh"'; +/** + * Expo's bundle phase sets ENTRY_FILE, CLI_PATH and BUNDLE_COMMAND, then + * runs react-native-xcode.sh. Replacing the whole phase would drop those + * and the Expo bundle would not be the one bugsee-xcode.sh injects into. + * Swap only that invocation for the existing hook. + */ +const EXPO_XCODE_INVOCATION = /`"\$NODE_BINARY" --print "require\('path'\)\.dirname\(require\.resolve\('react-native\/package\.json'\)\) \+ '\/scripts\/react-native-xcode\.sh'"`/; +const EXPO_REPLACEMENT = [ + 'export REACT_NATIVE_PATH="$("$NODE_BINARY" --print "require(\'path\').dirname(require.resolve(\'react-native/package.json\'))")"', + `/bin/bash ${BUGSEE_XCODE}`, +].join('\n'); +function rewriteBundlePhase(script) { + if (script.includes('bugsee-xcode.sh')) { + return script; + } + if (EXPO_XCODE_INVOCATION.test(script)) { + return script.replace(EXPO_XCODE_INVOCATION, EXPO_REPLACEMENT); + } + if (script.includes('with-environment.sh') && script.includes('react-native-xcode.sh')) { + return exports.BARE_BUNDLE_SCRIPT; + } + if (script.includes('react-native-xcode.sh')) { + return `${script.replace(/react-native-xcode\.sh/g, 'bugsee-xcode.sh')}\n${EXPO_REPLACEMENT}\n`; + } + return `${script.replace(/\s*$/, '')}\n${EXPO_REPLACEMENT}\n`; +} +function rewriteProjectBundlePhase(project) { + const section = project.hash?.project?.objects?.PBXShellScriptBuildPhase; + if (!section) { + throw new Error('PBXShellScriptBuildPhase is missing from the Xcode project'); + } + let found = false; + for (const [key, phase] of Object.entries(section)) { + if (key.endsWith('_comment') || !phase || typeof phase === 'string') { + continue; + } + const name = phase.name ? phase.name.replace(/^"|"$/g, '') : ''; + if (name !== 'Bundle React Native code and images') { + continue; + } + if (typeof phase.shellScript !== 'string') { + throw new Error('Bundle React Native code and images has no shellScript'); + } + const current = phase.shellScript.startsWith('"') + ? (0, pbx_string_1.decodePbxString)(phase.shellScript) + : phase.shellScript; + const next = rewriteBundlePhase(current); + phase.shellScript = phase.shellScript.startsWith('"') ? (0, pbx_string_1.encodePbxString)(next) : next; + found = true; + } + if (!found) { + throw new Error('Bundle React Native code and images build phase not found'); + } +} +//# sourceMappingURL=bundle-phase.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/bundle-phase.js.map b/packages/react-native/plugin/build/bundle-phase.js.map new file mode 100644 index 0000000..ee07bc9 --- /dev/null +++ b/packages/react-native/plugin/build/bundle-phase.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bundle-phase.js","sourceRoot":"","sources":["../src/bundle-phase.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/dsym-script.d.ts b/packages/react-native/plugin/build/dsym-script.d.ts new file mode 100644 index 0000000..3739ce4 --- /dev/null +++ b/packages/react-native/plugin/build/dsym-script.d.ts @@ -0,0 +1 @@ +export declare const DSYM_POST_ACTION_SCRIPT = "CREDS=\"${PROJECT_DIR}/../credentials.json\"\nTOKEN=\"$BUGSEE_APP_TOKEN\"\nif [ -z \"$TOKEN\" ]; then\n TOKEN=\"$BUGSEE_TOKEN_IOS\"\nfi\nif [ -z \"$TOKEN\" ] && [ -f \"$CREDS\" ]; then\n TOKEN=$(/usr/bin/plutil -extract ios raw -o - \"$CREDS\" 2>/dev/null || true)\nfi\nif [ -n \"$TOKEN\" ]; then\n export BUGSEE_APP_TOKEN=\"$TOKEN\"\nfi\nif [ -z \"$BUGSEE_ENDPOINT\" ] && [ -f \"$CREDS\" ]; then\n ENDPOINT=$(/usr/bin/plutil -extract endpoint raw -o - \"$CREDS\" 2>/dev/null || true)\n if [ -n \"$ENDPOINT\" ]; then\n export BUGSEE_ENDPOINT=\"$ENDPOINT\"\n fi\nfi\n\ntry_bin() {\n if [ -x \"$1\" ]; then\n \"$1\" xcode post-action\n exit $?\n fi\n}\n\nfor dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\ndo\n if [ \"$(uname -m)\" = \"x86_64\" ]; then\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n else\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n fi\ndone\n\n# Archive's PATH has no node, and the npm shim's shebang searches PATH.\nif [ ! -x \"$NODE_BINARY\" ]; then\n if [ -f \"${PROJECT_DIR}/.xcode.env\" ]; then\n . \"${PROJECT_DIR}/.xcode.env\"\n fi\n if [ -f \"${PROJECT_DIR}/.xcode.env.local\" ]; then\n . \"${PROJECT_DIR}/.xcode.env.local\"\n fi\nfi\nif [ ! -x \"$NODE_BINARY\" ]; then\n RN_FIND=\"\"\n if [ -n \"$REACT_NATIVE_PATH\" ] && [ -f \"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\"\n elif [ -f \"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\"\n fi\n if [ -n \"$RN_FIND\" ]; then\n NODE_BINARY=$(/bin/bash -c '. \"$1\" >/dev/null 2>&1; command -v node' _ \"$RN_FIND\" || true)\n fi\nfi\nif [ -n \"$NODE_BINARY\" ] && [ -x \"$NODE_BINARY\" ]; then\n PATH=\"$(dirname \"$NODE_BINARY\"):$PATH\"\n export PATH NODE_BINARY\n for dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\n do\n if [ -f \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" ]; then\n \"$NODE_BINARY\" \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" xcode post-action\n exit $?\n fi\n done\nfi\n\necho \"bugsee-cli: not found under node_modules\" >&2\nexit 1\n"; diff --git a/packages/react-native/plugin/build/dsym-script.js b/packages/react-native/plugin/build/dsym-script.js new file mode 100644 index 0000000..cc8de7f --- /dev/null +++ b/packages/react-native/plugin/build/dsym-script.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DSYM_POST_ACTION_SCRIPT = void 0; +// The Archive post-action from examples/bare BareExample.xcscheme. +// Copied, not rewritten: the plugin inserts this script into an Expo scheme. +exports.DSYM_POST_ACTION_SCRIPT = "CREDS=\"${PROJECT_DIR}/../credentials.json\"\nTOKEN=\"$BUGSEE_APP_TOKEN\"\nif [ -z \"$TOKEN\" ]; then\n TOKEN=\"$BUGSEE_TOKEN_IOS\"\nfi\nif [ -z \"$TOKEN\" ] && [ -f \"$CREDS\" ]; then\n TOKEN=$(/usr/bin/plutil -extract ios raw -o - \"$CREDS\" 2>/dev/null || true)\nfi\nif [ -n \"$TOKEN\" ]; then\n export BUGSEE_APP_TOKEN=\"$TOKEN\"\nfi\nif [ -z \"$BUGSEE_ENDPOINT\" ] && [ -f \"$CREDS\" ]; then\n ENDPOINT=$(/usr/bin/plutil -extract endpoint raw -o - \"$CREDS\" 2>/dev/null || true)\n if [ -n \"$ENDPOINT\" ]; then\n export BUGSEE_ENDPOINT=\"$ENDPOINT\"\n fi\nfi\n\ntry_bin() {\n if [ -x \"$1\" ]; then\n \"$1\" xcode post-action\n exit $?\n fi\n}\n\nfor dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\ndo\n if [ \"$(uname -m)\" = \"x86_64\" ]; then\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n else\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n fi\ndone\n\n# Archive's PATH has no node, and the npm shim's shebang searches PATH.\nif [ ! -x \"$NODE_BINARY\" ]; then\n if [ -f \"${PROJECT_DIR}/.xcode.env\" ]; then\n . \"${PROJECT_DIR}/.xcode.env\"\n fi\n if [ -f \"${PROJECT_DIR}/.xcode.env.local\" ]; then\n . \"${PROJECT_DIR}/.xcode.env.local\"\n fi\nfi\nif [ ! -x \"$NODE_BINARY\" ]; then\n RN_FIND=\"\"\n if [ -n \"$REACT_NATIVE_PATH\" ] && [ -f \"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\"\n elif [ -f \"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\"\n fi\n if [ -n \"$RN_FIND\" ]; then\n NODE_BINARY=$(/bin/bash -c '. \"$1\" >/dev/null 2>&1; command -v node' _ \"$RN_FIND\" || true)\n fi\nfi\nif [ -n \"$NODE_BINARY\" ] && [ -x \"$NODE_BINARY\" ]; then\n PATH=\"$(dirname \"$NODE_BINARY\"):$PATH\"\n export PATH NODE_BINARY\n for dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\n do\n if [ -f \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" ]; then\n \"$NODE_BINARY\" \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" xcode post-action\n exit $?\n fi\n done\nfi\n\necho \"bugsee-cli: not found under node_modules\" >&2\nexit 1\n"; +//# sourceMappingURL=dsym-script.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/dsym-script.js.map b/packages/react-native/plugin/build/dsym-script.js.map new file mode 100644 index 0000000..46accd2 --- /dev/null +++ b/packages/react-native/plugin/build/dsym-script.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dsym-script.js","sourceRoot":"","sources":["../src/dsym-script.ts"],"names":[],"mappings":";;;AAAA,mEAAmE;AACnE,6EAA6E;AAChE,QAAA,uBAAuB,GAAG,g8FAAg8F,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/gradle.d.ts b/packages/react-native/plugin/build/gradle.d.ts new file mode 100644 index 0000000..44e7d0f --- /dev/null +++ b/packages/react-native/plugin/build/gradle.d.ts @@ -0,0 +1,13 @@ +/** + * The plugin marker is on Maven Central, not the Plugin Portal. Declaring + * any repositories block replaces Gradle's implicit Plugin Portal, so a + * missing block gets the portal, Google, and Maven Central together. + */ +export declare function ensureMavenCentral(settingsGradle: string): string; +export declare function ensureGradlePluginDeclared(projectBuildGradle: string, version: string): string; +/** + * `ndkVersion` is `android.sdk` from native-versions.json, or null when + * native crash reporting is opted out. Null skips the artifact; the plugin + * is still applied so mapping upload can run. + */ +export declare function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string; diff --git a/packages/react-native/plugin/build/gradle.js b/packages/react-native/plugin/build/gradle.js new file mode 100644 index 0000000..b56f0ed --- /dev/null +++ b/packages/react-native/plugin/build/gradle.js @@ -0,0 +1,129 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ensureMavenCentral = ensureMavenCentral; +exports.ensureGradlePluginDeclared = ensureGradlePluginDeclared; +exports.ensureAppAppliesPlugin = ensureAppAppliesPlugin; +const PLUGIN_ID = 'com.bugsee.android.gradle'; +function blockExtent(source, keyword) { + const start = source.indexOf(keyword); + if (start < 0) { + return null; + } + const open = source.indexOf('{', start); + if (open < 0) { + return null; + } + let depth = 0; + for (let i = open; i < source.length; i += 1) { + const ch = source[i]; + if (ch === '{') { + depth += 1; + } + else if (ch === '}') { + depth -= 1; + if (depth === 0) { + return { bodyStart: open + 1, bodyEnd: i }; + } + } + } + return null; +} +/** + * The plugin marker is on Maven Central, not the Plugin Portal. Declaring + * any repositories block replaces Gradle's implicit Plugin Portal, so a + * missing block gets the portal, Google, and Maven Central together. + */ +function ensureMavenCentral(settingsGradle) { + const extent = blockExtent(settingsGradle, 'pluginManagement'); + if (!extent) { + const header = [ + 'pluginManagement {', + ' repositories {', + ' gradlePluginPortal()', + ' google()', + ' mavenCentral()', + ' }', + '}', + '', + ].join('\n'); + return header + settingsGradle; + } + const body = settingsGradle.slice(extent.bodyStart, extent.bodyEnd); + if (/mavenCentral\s*\(/.test(body)) { + return settingsGradle; + } + const repositories = blockExtent(body, 'repositories'); + if (repositories) { + const insertAt = extent.bodyStart + repositories.bodyEnd; + return (settingsGradle.slice(0, insertAt) + + '\n mavenCentral()' + + settingsGradle.slice(insertAt)); + } + const addition = [ + '', + ' repositories {', + ' gradlePluginPortal()', + ' google()', + ' mavenCentral()', + ' }', + '', + ].join('\n'); + return (settingsGradle.slice(0, extent.bodyEnd) + addition + settingsGradle.slice(extent.bodyEnd)); +} +function ensureGradlePluginDeclared(projectBuildGradle, version) { + if (!/^[0-9A-Za-z.+_-]+$/.test(version)) { + throw new Error(`refusing Gradle plugin version ${version}`); + } + if (projectBuildGradle.includes(PLUGIN_ID)) { + return projectBuildGradle; + } + // apply false: the plugin has to be applied on the application module. + // Applied to the root project it fails configuration, because it hangs + // its tasks off an Android variant. + const declaration = [ + '', + 'plugins {', + ` id '${PLUGIN_ID}' version '${version}' apply false`, + '}', + '', + ].join('\n'); + // plugins {} has to stay with the buildscript block. A later allprojects + // or apply statement makes Gradle reject the block. + const buildscript = blockExtent(projectBuildGradle, 'buildscript'); + if (buildscript) { + const at = buildscript.bodyEnd + 1; + return projectBuildGradle.slice(0, at) + declaration + projectBuildGradle.slice(at); + } + return declaration + projectBuildGradle; +} +/** + * `ndkVersion` is `android.sdk` from native-versions.json, or null when + * native crash reporting is opted out. Null skips the artifact; the plugin + * is still applied so mapping upload can run. + */ +function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { + let next = appBuildGradle; + if (!next.includes(PLUGIN_ID)) { + const react = 'apply plugin: "com.facebook.react"'; + if (next.includes(react)) { + next = next.replace(react, `${react}\napply plugin: "${PLUGIN_ID}"`); + } + else { + next = `apply plugin: "${PLUGIN_ID}"\n${next}`; + } + } + if (ndkVersion === null || next.includes('bugsee-android-ndk')) { + return next; + } + if (!/^[0-9A-Za-z.+_-]+$/.test(ndkVersion)) { + throw new Error(`refusing NDK artifact version ${ndkVersion}`); + } + const dep = ` implementation "com.bugsee:bugsee-android-ndk:${ndkVersion}"`; + const deps = next.indexOf('dependencies {'); + if (deps < 0) { + return `${next.replace(/\s*$/, '')}\n\ndependencies {\n${dep}\n}\n`; + } + const brace = next.indexOf('{', deps); + return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; +} +//# sourceMappingURL=gradle.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/gradle.js.map b/packages/react-native/plugin/build/gradle.js.map new file mode 100644 index 0000000..c61a5fc --- /dev/null +++ b/packages/react-native/plugin/build/gradle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/index.d.ts b/packages/react-native/plugin/build/index.d.ts new file mode 100644 index 0000000..e507b24 --- /dev/null +++ b/packages/react-native/plugin/build/index.d.ts @@ -0,0 +1,23 @@ +import type { ConfigPlugin } from '@expo/config-plugins'; +export interface BugseePluginProps { + /** Unprefixed `app_token` in android/bugsee.properties. */ + appToken?: string; + /** + * Accepted for the spec's option list. The settled Xcode hook injects + * debug ids on the composed map and does not execute the upload. + */ + uploadSourcemaps?: boolean; + /** Defaults on. `false` skips the Archive dSYM post-action. */ + uploadSymbols?: boolean; + /** + * Defaults on. Writes `plugin.ndk.enabled=true` for a real token and adds + * `com.bugsee:bugsee-android-ndk`. `false` opts out of both. + */ + nativeCrashReporting?: boolean; + /** Defaults to native-versions.json `android.gradlePlugin`. */ + gradlePluginVersion?: string; + /** Defaults off. Writes `com.bugsee.app-token` manifest meta-data. */ + autoLaunch?: boolean; +} +declare const _default: ConfigPlugin; +export default _default; diff --git a/packages/react-native/plugin/build/index.js b/packages/react-native/plugin/build/index.js new file mode 100644 index 0000000..82da00e --- /dev/null +++ b/packages/react-native/plugin/build/index.js @@ -0,0 +1,100 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const node_fs_1 = require("node:fs"); +const promises_1 = require("node:fs/promises"); +const node_path_1 = require("node:path"); +const config_plugins_1 = require("@expo/config-plugins"); +const bundle_phase_1 = require("./bundle-phase"); +const gradle_1 = require("./gradle"); +const manifest_1 = require("./manifest"); +const native_versions_1 = require("./native-versions"); +const properties_1 = require("./properties"); +const scheme_1 = require("./scheme"); +const withBugsee = (config, props) => { + const options = props ?? {}; + const versions = (0, native_versions_1.loadNativeVersions)(__dirname); + const gradlePluginVersion = options.gradlePluginVersion ?? versions.gradlePlugin; + const ndkVersion = options.nativeCrashReporting === false ? null : versions.sdk; + config = (0, config_plugins_1.withSettingsGradle)(config, (cfg) => { + cfg.modResults.contents = (0, gradle_1.ensureMavenCentral)(cfg.modResults.contents); + return cfg; + }); + config = (0, config_plugins_1.withProjectBuildGradle)(config, (cfg) => { + cfg.modResults.contents = (0, gradle_1.ensureGradlePluginDeclared)(cfg.modResults.contents, gradlePluginVersion); + return cfg; + }); + config = (0, config_plugins_1.withAppBuildGradle)(config, (cfg) => { + cfg.modResults.contents = (0, gradle_1.ensureAppAppliesPlugin)(cfg.modResults.contents, ndkVersion); + return cfg; + }); + config = (0, config_plugins_1.withDangerousMod)(config, [ + 'android', + async (cfg) => { + await (0, promises_1.writeFile)((0, node_path_1.join)(cfg.modRequest.platformProjectRoot, 'bugsee.properties'), (0, properties_1.bugseePropertiesText)(options)); + return cfg; + }, + ]); + config = (0, config_plugins_1.withAndroidManifest)(config, (cfg) => { + const token = (0, manifest_1.manifestAutoLaunchToken)(options); + if (!token) { + return cfg; + } + const mainApplication = config_plugins_1.AndroidConfig.Manifest.getMainApplicationOrThrow(cfg.modResults); + config_plugins_1.AndroidConfig.Manifest.addMetaDataItemToMainApplication(mainApplication, 'com.bugsee.app-token', token); + return cfg; + }); + config = (0, config_plugins_1.withXcodeProject)(config, (cfg) => { + (0, bundle_phase_1.rewriteProjectBundlePhase)(cfg.modResults); + return cfg; + }); + if (options.uploadSymbols !== false) { + config = (0, config_plugins_1.withDangerousMod)(config, [ + 'ios', + async (cfg) => { + for (const schemePath of listSchemes(cfg.modRequest.platformProjectRoot)) { + const xml = await (0, promises_1.readFile)(schemePath, 'utf8'); + const next = (0, scheme_1.insertDsymPostAction)(xml); + if (next !== xml) { + await (0, promises_1.writeFile)(schemePath, next); + } + } + return cfg; + }, + ]); + } + return config; +}; +function listSchemes(iosRoot) { + let entries; + try { + entries = (0, node_fs_1.readdirSync)(iosRoot); + } + catch (error) { + throw new Error(`ios project not found at ${iosRoot}`, { cause: error }); + } + const schemes = []; + for (const entry of entries) { + if (!entry.endsWith('.xcodeproj')) { + continue; + } + const dir = (0, node_path_1.join)(iosRoot, entry, 'xcshareddata', 'xcschemes'); + let names; + try { + names = (0, node_fs_1.readdirSync)(dir); + } + catch { + continue; + } + for (const name of names) { + if (name.endsWith('.xcscheme')) { + schemes.push((0, node_path_1.join)(dir, name)); + } + } + } + if (schemes.length === 0) { + throw new Error(`no shared xcscheme under ${iosRoot}`); + } + return schemes; +} +exports.default = (0, config_plugins_1.createRunOncePlugin)(withBugsee, '@bugsee/react-native', '0.0.0'); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/index.js.map b/packages/react-native/plugin/build/index.js.map new file mode 100644 index 0000000..1158337 --- /dev/null +++ b/packages/react-native/plugin/build/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/manifest.d.ts b/packages/react-native/plugin/build/manifest.d.ts new file mode 100644 index 0000000..7f06d13 --- /dev/null +++ b/packages/react-native/plugin/build/manifest.d.ts @@ -0,0 +1,11 @@ +export interface AutoLaunchInput { + readonly appToken?: string; + /** Off unless set. Manifest auto-launch starts the native SDK before JS. */ + readonly autoLaunch?: boolean; +} +/** + * The `com.bugsee.app-token` meta-data value, or null when the manifest + * should be left alone. A placeholder token is not written: the native SDK + * would launch it against the production API. + */ +export declare function manifestAutoLaunchToken(input: AutoLaunchInput): string | null; diff --git a/packages/react-native/plugin/build/manifest.js b/packages/react-native/plugin/build/manifest.js new file mode 100644 index 0000000..0462862 --- /dev/null +++ b/packages/react-native/plugin/build/manifest.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.manifestAutoLaunchToken = manifestAutoLaunchToken; +const properties_1 = require("./properties"); +/** + * The `com.bugsee.app-token` meta-data value, or null when the manifest + * should be left alone. A placeholder token is not written: the native SDK + * would launch it against the production API. + */ +function manifestAutoLaunchToken(input) { + if (input.autoLaunch !== true) { + return null; + } + const token = input.appToken ?? ''; + if (token.length === 0 || (0, properties_1.isPlaceholderToken)(token)) { + return null; + } + return token; +} +//# sourceMappingURL=manifest.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/manifest.js.map b/packages/react-native/plugin/build/manifest.js.map new file mode 100644 index 0000000..c4b6e0b --- /dev/null +++ b/packages/react-native/plugin/build/manifest.js.map @@ -0,0 +1 @@ +{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":";;AAaA,0DASC;AAtBD,6CAAkD;AAQlD;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,KAAsB;IAC5D,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;IACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAA,+BAAkB,EAAC,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/native-versions.d.ts b/packages/react-native/plugin/build/native-versions.d.ts new file mode 100644 index 0000000..3133f96 --- /dev/null +++ b/packages/react-native/plugin/build/native-versions.d.ts @@ -0,0 +1,10 @@ +export interface AndroidNativeVersions { + readonly sdk: string; + readonly gradlePlugin: string; +} +/** + * Walk up from the plugin until `native-versions.json` appears. That file + * is the only pin: the Gradle plugin version is `android.gradlePlugin` and + * the NDK artifact version is `android.sdk`. + */ +export declare function loadNativeVersions(startDir: string): AndroidNativeVersions; diff --git a/packages/react-native/plugin/build/native-versions.js b/packages/react-native/plugin/build/native-versions.js new file mode 100644 index 0000000..4e5d7ec --- /dev/null +++ b/packages/react-native/plugin/build/native-versions.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.loadNativeVersions = loadNativeVersions; +const node_fs_1 = require("node:fs"); +const node_path_1 = require("node:path"); +/** + * Walk up from the plugin until `native-versions.json` appears. That file + * is the only pin: the Gradle plugin version is `android.gradlePlugin` and + * the NDK artifact version is `android.sdk`. + */ +function loadNativeVersions(startDir) { + let dir = startDir; + for (let i = 0; i < 10; i += 1) { + const candidate = (0, node_path_1.join)(dir, 'native-versions.json'); + if ((0, node_fs_1.existsSync)(candidate)) { + const parsed = JSON.parse((0, node_fs_1.readFileSync)(candidate, 'utf8')); + const sdk = parsed.android?.sdk; + const gradlePlugin = parsed.android?.gradlePlugin; + if (!sdk || !gradlePlugin) { + throw new Error(`${candidate} is missing android.sdk or android.gradlePlugin`); + } + return { sdk, gradlePlugin }; + } + const parent = (0, node_path_1.dirname)(dir); + if (parent === dir) { + break; + } + dir = parent; + } + throw new Error(`native-versions.json not found above ${startDir}`); +} +//# sourceMappingURL=native-versions.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/native-versions.js.map b/packages/react-native/plugin/build/native-versions.js.map new file mode 100644 index 0000000..ade96dd --- /dev/null +++ b/packages/react-native/plugin/build/native-versions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"native-versions.js","sourceRoot":"","sources":["../src/native-versions.ts"],"names":[],"mappings":";;AAoBA,gDAoBC;AAxCD,qCAAmD;AACnD,yCAA0C;AAc1C;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,QAAgB;IACjD,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;QACpD,IAAI,IAAA,oBAAU,EAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,SAAS,EAAE,MAAM,CAAC,CAAuB,CAAC;YACjF,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;YAChC,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC;YAClD,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,iDAAiD,CAAC,CAAC;YACjF,CAAC;YACD,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;QAC/B,CAAC;QACD,MAAM,MAAM,GAAG,IAAA,mBAAO,EAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,MAAM;QACR,CAAC;QACD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wCAAwC,QAAQ,EAAE,CAAC,CAAC;AACtE,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/pbx-string.d.ts b/packages/react-native/plugin/build/pbx-string.d.ts new file mode 100644 index 0000000..55426b5 --- /dev/null +++ b/packages/react-native/plugin/build/pbx-string.d.ts @@ -0,0 +1,8 @@ +/** + * pbxproj quoted strings keep their quotes in the xcode project's object + * model, and escapes (`\n`, `\"`, `\\`) stay as two characters. The writer + * prints the value unchanged, so a shell script has to be stored in that + * same shape. + */ +export declare function decodePbxString(stored: string): string; +export declare function encodePbxString(value: string): string; diff --git a/packages/react-native/plugin/build/pbx-string.js b/packages/react-native/plugin/build/pbx-string.js new file mode 100644 index 0000000..36b491e --- /dev/null +++ b/packages/react-native/plugin/build/pbx-string.js @@ -0,0 +1,53 @@ +"use strict"; +/** + * pbxproj quoted strings keep their quotes in the xcode project's object + * model, and escapes (`\n`, `\"`, `\\`) stay as two characters. The writer + * prints the value unchanged, so a shell script has to be stored in that + * same shape. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodePbxString = decodePbxString; +exports.encodePbxString = encodePbxString; +function unescapeBody(body) { + let out = ''; + for (let i = 0; i < body.length; i += 1) { + const current = body[i]; + if (current === '\\' && i + 1 < body.length) { + const next = body[i + 1]; + if (next === 'n') { + out += '\n'; + } + else if (next === 'r') { + out += '\r'; + } + else if (next === 't') { + out += '\t'; + } + else if (next !== undefined) { + out += next; + } + i += 1; + continue; + } + if (current !== undefined) { + out += current; + } + } + return out; +} +function decodePbxString(stored) { + if (stored.startsWith('"') && stored.endsWith('"')) { + return unescapeBody(stored.slice(1, -1)); + } + return stored; +} +function encodePbxString(value) { + const escaped = value + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t'); + return `"${escaped}"`; +} +//# sourceMappingURL=pbx-string.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/pbx-string.js.map b/packages/react-native/plugin/build/pbx-string.js.map new file mode 100644 index 0000000..0b38db4 --- /dev/null +++ b/packages/react-native/plugin/build/pbx-string.js.map @@ -0,0 +1 @@ +{"version":3,"file":"pbx-string.js","sourceRoot":"","sources":["../src/pbx-string.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA2BH,0CAKC;AAED,0CAQC;AAxCD,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,GAAG,IAAI,IAAI,CAAC;YACd,CAAC;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACxB,GAAG,IAAI,IAAI,CAAC;YACd,CAAC;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACxB,GAAG,IAAI,IAAI,CAAC;YACd,CAAC;iBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9B,GAAG,IAAI,IAAI,CAAC;YACd,CAAC;YACD,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,GAAG,IAAI,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,eAAe,CAAC,MAAc;IAC5C,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,eAAe,CAAC,KAAa;IAC3C,MAAM,OAAO,GAAG,KAAK;SAClB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzB,OAAO,IAAI,OAAO,GAAG,CAAC;AACxB,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/properties.d.ts b/packages/react-native/plugin/build/properties.d.ts new file mode 100644 index 0000000..b2f201a --- /dev/null +++ b/packages/react-native/plugin/build/properties.d.ts @@ -0,0 +1,15 @@ +export declare function isPlaceholderToken(token: string): boolean; +export interface PropertiesInput { + readonly appToken?: string; + /** Defaults on. Opt out with `false`. */ + readonly nativeCrashReporting?: boolean; +} +/** + * `/bugsee.properties`. The token is the unprefixed `app_token` + * key. `plugin.ndk.enabled=true` is written only for a real, non-placeholder + * token while native crash reporting is on (the default). `plugin.appToken` + * is not a key the Gradle plugin reads, and this file never emits it. + * No endpoint key: a placeholder token omits the upload flag instead of + * pointing the build at another host. + */ +export declare function bugseePropertiesText(input?: PropertiesInput): string; diff --git a/packages/react-native/plugin/build/properties.js b/packages/react-native/plugin/build/properties.js new file mode 100644 index 0000000..3d6cd81 --- /dev/null +++ b/packages/react-native/plugin/build/properties.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isPlaceholderToken = isPlaceholderToken; +exports.bugseePropertiesText = bugseePropertiesText; +/** + * Same rule as `isPlaceholderToken` in examples/bare/endpoint.ts. The CI + * token `00000000-0000-4000-8000-000000000000` matches. Copied here so the + * plugin does not import the example app. + */ +const PLACEHOLDER_TOKEN = /^0{12}[0-9a-f]0{3}[0-9a-f]0{15}$/i; +function isPlaceholderToken(token) { + return PLACEHOLDER_TOKEN.test(token.replace(/-/g, '')); +} +/** + * `/bugsee.properties`. The token is the unprefixed `app_token` + * key. `plugin.ndk.enabled=true` is written only for a real, non-placeholder + * token while native crash reporting is on (the default). `plugin.appToken` + * is not a key the Gradle plugin reads, and this file never emits it. + * No endpoint key: a placeholder token omits the upload flag instead of + * pointing the build at another host. + */ +function bugseePropertiesText(input = {}) { + const token = input.appToken ?? ''; + const lines = []; + if (token.length > 0) { + lines.push(`app_token=${token}`); + } + const ndkOn = input.nativeCrashReporting !== false; + if (ndkOn && token.length > 0 && !isPlaceholderToken(token)) { + lines.push('plugin.ndk.enabled=true'); + } + if (lines.length === 0) { + return '# Generated by @bugsee/react-native. No app token configured.\n'; + } + return `${lines.join('\n')}\n`; +} +//# sourceMappingURL=properties.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/properties.js.map b/packages/react-native/plugin/build/properties.js.map new file mode 100644 index 0000000..60e161d --- /dev/null +++ b/packages/react-native/plugin/build/properties.js.map @@ -0,0 +1 @@ +{"version":3,"file":"properties.js","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":";;AAOA,gDAEC;AAgBD,oDAcC;AAvCD;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,mCAAmC,CAAC;AAE9D,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAQD;;;;;;;GAOG;AACH,SAAgB,oBAAoB,CAAC,QAAyB,EAAE;IAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,oBAAoB,KAAK,KAAK,CAAC;IACnD,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,iEAAiE,CAAC;IAC3E,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/scheme.d.ts b/packages/react-native/plugin/build/scheme.d.ts new file mode 100644 index 0000000..7e83564 --- /dev/null +++ b/packages/react-native/plugin/build/scheme.d.ts @@ -0,0 +1,9 @@ +import { DSYM_POST_ACTION_SCRIPT } from './dsym-script'; +export { DSYM_POST_ACTION_SCRIPT }; +export declare function encodeXmlAttr(value: string): string; +/** + * Inserts the bare example's Archive post-action. The script is not + * rewritten. The EnvironmentBuildable is the scheme's own app target, so + * ARCHIVE_PATH is provided. + */ +export declare function insertDsymPostAction(scheme: string, script?: string): string; diff --git a/packages/react-native/plugin/build/scheme.js b/packages/react-native/plugin/build/scheme.js new file mode 100644 index 0000000..3aa3752 --- /dev/null +++ b/packages/react-native/plugin/build/scheme.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DSYM_POST_ACTION_SCRIPT = void 0; +exports.encodeXmlAttr = encodeXmlAttr; +exports.insertDsymPostAction = insertDsymPostAction; +const dsym_script_1 = require("./dsym-script"); +Object.defineProperty(exports, "DSYM_POST_ACTION_SCRIPT", { enumerable: true, get: function () { return dsym_script_1.DSYM_POST_ACTION_SCRIPT; } }); +function encodeXmlAttr(value) { + return value + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>') + .replace(/\r/g, ' ') + .replace(/\n/g, ' '); +} +function appBuildableReference(scheme) { + const refs = scheme.match(//g) ?? []; + const app = refs.find((ref) => /BuildableName\s*=\s*"[^"]+\.app"/.test(ref)); + if (!app) { + throw new Error('scheme has no .app BuildableReference'); + } + return app; +} +/** + * Inserts the bare example's Archive post-action. The script is not + * rewritten. The EnvironmentBuildable is the scheme's own app target, so + * ARCHIVE_PATH is provided. + */ +function insertDsymPostAction(scheme, script = dsym_script_1.DSYM_POST_ACTION_SCRIPT) { + if (scheme.includes('xcode post-action')) { + return scheme; + } + const archive = scheme.match(//); + if (!archive?.[0]) { + throw new Error('ArchiveAction missing'); + } + const reference = appBuildableReference(scheme); + const block = [ + ' ', + ' ', + ' `, + ' ', + reference.trimEnd(), + ' ', + ' ', + ' ', + ' ', + ].join('\n'); + const updated = archive[0].replace('', `${block}\n `); + return scheme.replace(archive[0], updated); +} +//# sourceMappingURL=scheme.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/scheme.js.map b/packages/react-native/plugin/build/scheme.js.map new file mode 100644 index 0000000..3788e11 --- /dev/null +++ b/packages/react-native/plugin/build/scheme.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scheme.js","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":";;;AAIA,sCAQC;AAgBD,oDAyBC;AArDD,+CAAwD;AAE/C,wGAFA,qCAAuB,OAEA;AAEhC,SAAgB,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,IAAI,EAAE,CAAC;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kCAAkC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,MAAc,EAAE,SAAiB,qCAAuB;IAC3F,IAAI,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG;QACZ,qBAAqB;QACrB,2BAA2B;QAC3B,yGAAyG;QACzG,4BAA4B;QAC5B,uCAAuC;QACvC,gCAAgC,aAAa,CAAC,MAAM,CAAC,IAAI;QACzD,uCAAuC;QACvC,SAAS,CAAC,OAAO,EAAE;QACnB,wCAAwC;QACxC,8BAA8B;QAC9B,6BAA6B;QAC7B,sBAAsB;KACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,KAAK,uBAAuB,CAAC,CAAC;IACxF,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts new file mode 100644 index 0000000..6b76a7a --- /dev/null +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -0,0 +1,258 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +import { isPlaceholderToken as exampleIsPlaceholderToken } from '../../../../../examples/bare/endpoint'; +import { rewriteBundlePhase, BARE_BUNDLE_SCRIPT } from '../bundle-phase'; +import { decodePbxString, encodePbxString } from '../pbx-string'; +import { bugseePropertiesText, isPlaceholderToken } from '../properties'; +import { ensureAppAppliesPlugin, ensureGradlePluginDeclared, ensureMavenCentral } from '../gradle'; +import { insertDsymPostAction } from '../scheme'; +import { DSYM_POST_ACTION_SCRIPT } from '../dsym-script'; +import { manifestAutoLaunchToken } from '../manifest'; +import { loadNativeVersions } from '../native-versions'; + +const repoRoot = join(__dirname, '..', '..', '..', '..', '..'); +const barePbx = join( + repoRoot, + 'examples/bare/ios/BareExample.xcodeproj/project.pbxproj', +); +const bareScheme = join( + repoRoot, + 'examples/bare/ios/BareExample.xcodeproj/xcshareddata/xcschemes/BareExample.xcscheme', +); + +function decodeXml(value: string): string { + return value + .replace(/ /g, '\n') + .replace(/ /g, '\r') + .replace(/"/g, '"') + .replace(/'/g, "'") + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&'); +} + +function bareBundleScript(): string { + const pbx = readFileSync(barePbx, 'utf8'); + const line = pbx.split('\n').find((entry) => entry.includes('shellScript') && entry.includes('bugsee-xcode.sh')); + if (!line) { + throw new Error('bare bundle phase missing'); + } + const quoted = line.trim().replace(/^shellScript = /, '').replace(/;$/, ''); + return decodePbxString(quoted); +} + +function barePostActionScript(): string { + const scheme = readFileSync(bareScheme, 'utf8'); + const match = scheme.match(/\bscriptText\s*=\s*"([^"]*)"/); + const encoded = match?.[1]; + if (encoded === undefined) { + throw new Error('bare scheme has no scriptText'); + } + return decodeXml(encoded); +} + +const REAL_TOKEN = 'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee'; +const PLACEHOLDER = '00000000-0000-4000-8000-000000000000'; + +describe('bugsee.properties', () => { + it('writes app_token and enables NDK upload for a real token', () => { + const text = bugseePropertiesText({ appToken: REAL_TOKEN }); + expect(text).toContain(`app_token=${REAL_TOKEN}`); + expect(text).toContain('plugin.ndk.enabled=true'); + expect(text).not.toContain('plugin.appToken'); + }); + + it('does not enable NDK upload for the placeholder UUID', () => { + const text = bugseePropertiesText({ appToken: PLACEHOLDER }); + expect(text).not.toContain('plugin.ndk.enabled'); + expect(text).not.toContain('plugin.appToken'); + expect(isPlaceholderToken(PLACEHOLDER)).toBe(true); + }); + + it('omits the NDK upload flag when native crash reporting is off', () => { + const text = bugseePropertiesText({ appToken: REAL_TOKEN, nativeCrashReporting: false }); + expect(text).toContain(`app_token=${REAL_TOKEN}`); + expect(text).not.toContain('plugin.ndk.enabled'); + }); + + it('omits both lines when the token is empty', () => { + const text = bugseePropertiesText({ appToken: '' }); + expect(text).not.toContain('app_token='); + expect(text).not.toContain('plugin.ndk.enabled'); + expect(text).not.toContain('plugin.endpoint'); + expect(text).not.toContain('plugin.appToken'); + }); + + it('uses the same placeholder rule as the bare example', () => { + const samples = [ + PLACEHOLDER, + '00000000-0000-0000-0000-000000000000', + '00000000000040008000000000000000', + REAL_TOKEN, + '00000000-0000-4000-8000-000000000001', + '10000000-0000-4000-8000-000000000000', + '', + ]; + for (const sample of samples) { + expect(isPlaceholderToken(sample)).toBe(exampleIsPlaceholderToken(sample)); + } + }); +}); + +describe('settled iOS hooks', () => { + it('copies the bare bundle phase script', () => { + expect(BARE_BUNDLE_SCRIPT).toBe(bareBundleScript()); + expect(BARE_BUNDLE_SCRIPT).toContain('bugsee-xcode.sh'); + expect(BARE_BUNDLE_SCRIPT).not.toContain('react-native-xcode.sh'); + }); + + it('copies the bare Archive post-action script', () => { + expect(DSYM_POST_ACTION_SCRIPT).toBe(barePostActionScript()); + expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/\.bin\/bugsee-cli/); + expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/with-environment\.sh/); + expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/\/v2/); + expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/https?:\/\//); + expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/--force-foreground/); + expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/BUGSEE_BUILD_INFO_ALL_ACTIONS/); + expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/BUGSEE_BUILD_INFO_ALL_CONFIGURATIONS/); + }); + + it('replaces a classic bundle phase with the bare hook', () => { + const classic = [ + 'set -e', + '', + 'WITH_ENVIRONMENT="$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh"', + 'REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh"', + '/bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE"', + '', + ].join('\n'); + expect(rewriteBundlePhase(classic)).toBe(BARE_BUNDLE_SCRIPT); + }); + + it('points the Expo bundle phase at bugsee-xcode.sh without a second script', () => { + const expo = [ + 'export PROJECT_ROOT="$PROJECT_DIR"/..', + 'export CLI_PATH="$("$NODE_BINARY" --print "require.resolve(\'@expo/cli\', { paths: [require.resolve(\'expo/package.json\')] })")"', + 'export BUNDLE_COMMAND="export:embed"', + 'export ENTRY_FILE="$("$NODE_BINARY" -e "require(\'expo/scripts/resolveAppEntry\')" "$PROJECT_ROOT" ios absolute | tail -n 1)"', + '`"$NODE_BINARY" --print "require(\'path\').dirname(require.resolve(\'react-native/package.json\')) + \'/scripts/react-native-xcode.sh\'"`', + '', + ].join('\n'); + const rewritten = rewriteBundlePhase(expo); + expect(rewritten).toContain('bugsee-xcode.sh'); + expect(rewritten).toContain('export:embed'); + expect(rewritten).toContain('resolveAppEntry'); + expect(rewritten).not.toContain('react-native-xcode.sh'); + expect(rewritten).toContain('REACT_NATIVE_PATH'); + }); + + it('round-trips a pbxproj shell script', () => { + expect(decodePbxString(encodePbxString(BARE_BUNDLE_SCRIPT))).toBe(BARE_BUNDLE_SCRIPT); + }); +}); + +describe('Android Gradle edits', () => { + const versions = loadNativeVersions(join(__dirname, '..')); + + const settings = [ + 'pluginManagement {', + ' includeBuild(reactNativeGradlePlugin)', + '}', + '', + 'plugins { id("com.facebook.react.settings") }', + '', + ].join('\n'); + + it('adds mavenCentral inside pluginManagement', () => { + const next = ensureMavenCentral(settings); + const block = next.slice(next.indexOf('pluginManagement'), next.indexOf('plugins {')); + expect(block).toContain('mavenCentral()'); + expect(block).toContain('gradlePluginPortal()'); + expect(ensureMavenCentral(next)).toBe(next); + }); + + it('declares the Gradle plugin version from native-versions.json', () => { + const project = [ + 'buildscript { repositories { google(); mavenCentral() } }', + 'apply plugin: "com.facebook.react.rootproject"', + '', + ].join('\n'); + const next = ensureGradlePluginDeclared(project, versions.gradlePlugin); + expect(next).toContain( + `id 'com.bugsee.android.gradle' version '${versions.gradlePlugin}' apply false`, + ); + expect(next).not.toContain("id 'com.bugsee.android.gradle' version '9.9.9'"); + const overridden = ensureGradlePluginDeclared(project, '9.9.9'); + expect(overridden).toContain("version '9.9.9'"); + expect(overridden).not.toContain(`version '${versions.gradlePlugin}'`); + }); + + it('applies the plugin on the app module and adds the NDK artifact', () => { + const app = [ + 'apply plugin: "com.android.application"', + 'apply plugin: "com.facebook.react"', + '', + 'dependencies {', + ' implementation("com.facebook.react:react-android")', + '}', + '', + ].join('\n'); + const next = ensureAppAppliesPlugin(app, versions.sdk); + expect(next).toContain('apply plugin: "com.bugsee.android.gradle"'); + expect(next).toContain(`implementation "com.bugsee:bugsee-android-ndk:${versions.sdk}"`); + expect(ensureAppAppliesPlugin(next, versions.sdk)).toBe(next); + }); + + it('skips the NDK artifact when native crash reporting is off', () => { + const app = 'apply plugin: "com.facebook.react"\n\ndependencies {\n}\n'; + const next = ensureAppAppliesPlugin(app, null); + expect(next).toContain('apply plugin: "com.bugsee.android.gradle"'); + expect(next).not.toContain('bugsee-android-ndk'); + }); +}); + +describe('scheme post-action', () => { + const scheme = ` + + + + + + + + + + + + +`; + + it('inserts the copied script on Archive and keeps the app target', () => { + const next = insertDsymPostAction(scheme, DSYM_POST_ACTION_SCRIPT); + expect(next).toContain(''); + expect(next).toContain('title = "Upload dSYMs"'); + const encoded = next.match(/\bscriptText\s*=\s*"([^"]*)"/)?.[1]; + expect(encoded).toEqual(expect.any(String)); + expect(decodeXml(encoded ?? '')).toBe(DSYM_POST_ACTION_SCRIPT); + expect(next).toContain('BlueprintName = "BugseeExpo"'); + expect(next).not.toContain('BareExample'); + expect(insertDsymPostAction(next, DSYM_POST_ACTION_SCRIPT)).toBe(next); + }); +}); + +describe('manifest auto-launch', () => { + it('writes the meta-data value only when autoLaunch is set and the token is real', () => { + expect(manifestAutoLaunchToken({ appToken: REAL_TOKEN, autoLaunch: true })).toBe(REAL_TOKEN); + expect(manifestAutoLaunchToken({ appToken: REAL_TOKEN })).toBeNull(); + expect(manifestAutoLaunchToken({ appToken: PLACEHOLDER, autoLaunch: true })).toBeNull(); + expect(manifestAutoLaunchToken({ appToken: '', autoLaunch: true })).toBeNull(); + }); +}); diff --git a/packages/react-native/plugin/src/bundle-phase.ts b/packages/react-native/plugin/src/bundle-phase.ts new file mode 100644 index 0000000..b20a293 --- /dev/null +++ b/packages/react-native/plugin/src/bundle-phase.ts @@ -0,0 +1,94 @@ +import { decodePbxString, encodePbxString } from './pbx-string'; + +/** + * The "Bundle React Native code and images" shell script from the bare + * example's pbxproj. It runs `bugsee-xcode.sh`, which makes + * `REACT_NATIVE_PATH` absolute with `cd`/`pwd` and injects after compose. + * The upload function in that script is not executed. + */ +export const BARE_BUNDLE_SCRIPT = [ + 'set -e', + '', + 'WITH_ENVIRONMENT="$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh"', + 'BUGSEE_XCODE="${SRCROOT}/../node_modules/@bugsee/react-native/scripts/bugsee-xcode.sh"', + '', + '/bin/sh -c "\\"$WITH_ENVIRONMENT\\" \\"$BUGSEE_XCODE\\""', + '', +].join('\n'); + +const BUGSEE_XCODE = '"${SRCROOT}/../node_modules/@bugsee/react-native/scripts/bugsee-xcode.sh"'; + +/** + * Expo's bundle phase sets ENTRY_FILE, CLI_PATH and BUNDLE_COMMAND, then + * runs react-native-xcode.sh. Replacing the whole phase would drop those + * and the Expo bundle would not be the one bugsee-xcode.sh injects into. + * Swap only that invocation for the existing hook. + */ +const EXPO_XCODE_INVOCATION = + /`"\$NODE_BINARY" --print "require\('path'\)\.dirname\(require\.resolve\('react-native\/package\.json'\)\) \+ '\/scripts\/react-native-xcode\.sh'"`/; + +const EXPO_REPLACEMENT = [ + 'export REACT_NATIVE_PATH="$("$NODE_BINARY" --print "require(\'path\').dirname(require.resolve(\'react-native/package.json\'))")"', + `/bin/bash ${BUGSEE_XCODE}`, +].join('\n'); + +export function rewriteBundlePhase(script: string): string { + if (script.includes('bugsee-xcode.sh')) { + return script; + } + if (EXPO_XCODE_INVOCATION.test(script)) { + return script.replace(EXPO_XCODE_INVOCATION, EXPO_REPLACEMENT); + } + if (script.includes('with-environment.sh') && script.includes('react-native-xcode.sh')) { + return BARE_BUNDLE_SCRIPT; + } + if (script.includes('react-native-xcode.sh')) { + return `${script.replace(/react-native-xcode\.sh/g, 'bugsee-xcode.sh')}\n${EXPO_REPLACEMENT}\n`; + } + return `${script.replace(/\s*$/, '')}\n${EXPO_REPLACEMENT}\n`; +} + +export interface ShellPhase { + isa?: string; + name?: string; + shellScript?: string; +} + +export interface XcodeProjectLike { + hash?: { + project?: { + objects?: { + PBXShellScriptBuildPhase?: Record; + }; + }; + }; +} + +export function rewriteProjectBundlePhase(project: XcodeProjectLike): void { + const section = project.hash?.project?.objects?.PBXShellScriptBuildPhase; + if (!section) { + throw new Error('PBXShellScriptBuildPhase is missing from the Xcode project'); + } + let found = false; + for (const [key, phase] of Object.entries(section)) { + if (key.endsWith('_comment') || !phase || typeof phase === 'string') { + continue; + } + const name = phase.name ? phase.name.replace(/^"|"$/g, '') : ''; + if (name !== 'Bundle React Native code and images') { + continue; + } + if (typeof phase.shellScript !== 'string') { + throw new Error('Bundle React Native code and images has no shellScript'); + } + const current = phase.shellScript.startsWith('"') + ? decodePbxString(phase.shellScript) + : phase.shellScript; + const next = rewriteBundlePhase(current); + phase.shellScript = phase.shellScript.startsWith('"') ? encodePbxString(next) : next; + found = true; + } + if (!found) { + throw new Error('Bundle React Native code and images build phase not found'); + } +} diff --git a/packages/react-native/plugin/src/dsym-script.ts b/packages/react-native/plugin/src/dsym-script.ts new file mode 100644 index 0000000..8bb5e5f --- /dev/null +++ b/packages/react-native/plugin/src/dsym-script.ts @@ -0,0 +1,3 @@ +// The Archive post-action from examples/bare BareExample.xcscheme. +// Copied, not rewritten: the plugin inserts this script into an Expo scheme. +export const DSYM_POST_ACTION_SCRIPT = "CREDS=\"${PROJECT_DIR}/../credentials.json\"\nTOKEN=\"$BUGSEE_APP_TOKEN\"\nif [ -z \"$TOKEN\" ]; then\n TOKEN=\"$BUGSEE_TOKEN_IOS\"\nfi\nif [ -z \"$TOKEN\" ] && [ -f \"$CREDS\" ]; then\n TOKEN=$(/usr/bin/plutil -extract ios raw -o - \"$CREDS\" 2>/dev/null || true)\nfi\nif [ -n \"$TOKEN\" ]; then\n export BUGSEE_APP_TOKEN=\"$TOKEN\"\nfi\nif [ -z \"$BUGSEE_ENDPOINT\" ] && [ -f \"$CREDS\" ]; then\n ENDPOINT=$(/usr/bin/plutil -extract endpoint raw -o - \"$CREDS\" 2>/dev/null || true)\n if [ -n \"$ENDPOINT\" ]; then\n export BUGSEE_ENDPOINT=\"$ENDPOINT\"\n fi\nfi\n\ntry_bin() {\n if [ -x \"$1\" ]; then\n \"$1\" xcode post-action\n exit $?\n fi\n}\n\nfor dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\ndo\n if [ \"$(uname -m)\" = \"x86_64\" ]; then\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n else\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n fi\ndone\n\n# Archive's PATH has no node, and the npm shim's shebang searches PATH.\nif [ ! -x \"$NODE_BINARY\" ]; then\n if [ -f \"${PROJECT_DIR}/.xcode.env\" ]; then\n . \"${PROJECT_DIR}/.xcode.env\"\n fi\n if [ -f \"${PROJECT_DIR}/.xcode.env.local\" ]; then\n . \"${PROJECT_DIR}/.xcode.env.local\"\n fi\nfi\nif [ ! -x \"$NODE_BINARY\" ]; then\n RN_FIND=\"\"\n if [ -n \"$REACT_NATIVE_PATH\" ] && [ -f \"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\"\n elif [ -f \"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\"\n fi\n if [ -n \"$RN_FIND\" ]; then\n NODE_BINARY=$(/bin/bash -c '. \"$1\" >/dev/null 2>&1; command -v node' _ \"$RN_FIND\" || true)\n fi\nfi\nif [ -n \"$NODE_BINARY\" ] && [ -x \"$NODE_BINARY\" ]; then\n PATH=\"$(dirname \"$NODE_BINARY\"):$PATH\"\n export PATH NODE_BINARY\n for dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\n do\n if [ -f \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" ]; then\n \"$NODE_BINARY\" \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" xcode post-action\n exit $?\n fi\n done\nfi\n\necho \"bugsee-cli: not found under node_modules\" >&2\nexit 1\n"; diff --git a/packages/react-native/plugin/src/gradle.ts b/packages/react-native/plugin/src/gradle.ts new file mode 100644 index 0000000..1782e87 --- /dev/null +++ b/packages/react-native/plugin/src/gradle.ts @@ -0,0 +1,129 @@ +const PLUGIN_ID = 'com.bugsee.android.gradle'; + +function blockExtent(source: string, keyword: string): { bodyStart: number; bodyEnd: number } | null { + const start = source.indexOf(keyword); + if (start < 0) { + return null; + } + const open = source.indexOf('{', start); + if (open < 0) { + return null; + } + let depth = 0; + for (let i = open; i < source.length; i += 1) { + const ch = source[i]; + if (ch === '{') { + depth += 1; + } else if (ch === '}') { + depth -= 1; + if (depth === 0) { + return { bodyStart: open + 1, bodyEnd: i }; + } + } + } + return null; +} + +/** + * The plugin marker is on Maven Central, not the Plugin Portal. Declaring + * any repositories block replaces Gradle's implicit Plugin Portal, so a + * missing block gets the portal, Google, and Maven Central together. + */ +export function ensureMavenCentral(settingsGradle: string): string { + const extent = blockExtent(settingsGradle, 'pluginManagement'); + if (!extent) { + const header = [ + 'pluginManagement {', + ' repositories {', + ' gradlePluginPortal()', + ' google()', + ' mavenCentral()', + ' }', + '}', + '', + ].join('\n'); + return header + settingsGradle; + } + const body = settingsGradle.slice(extent.bodyStart, extent.bodyEnd); + if (/mavenCentral\s*\(/.test(body)) { + return settingsGradle; + } + const repositories = blockExtent(body, 'repositories'); + if (repositories) { + const insertAt = extent.bodyStart + repositories.bodyEnd; + return ( + settingsGradle.slice(0, insertAt) + + '\n mavenCentral()' + + settingsGradle.slice(insertAt) + ); + } + const addition = [ + '', + ' repositories {', + ' gradlePluginPortal()', + ' google()', + ' mavenCentral()', + ' }', + '', + ].join('\n'); + return ( + settingsGradle.slice(0, extent.bodyEnd) + addition + settingsGradle.slice(extent.bodyEnd) + ); +} + +export function ensureGradlePluginDeclared(projectBuildGradle: string, version: string): string { + if (!/^[0-9A-Za-z.+_-]+$/.test(version)) { + throw new Error(`refusing Gradle plugin version ${version}`); + } + if (projectBuildGradle.includes(PLUGIN_ID)) { + return projectBuildGradle; + } + // apply false: the plugin has to be applied on the application module. + // Applied to the root project it fails configuration, because it hangs + // its tasks off an Android variant. + const declaration = [ + '', + 'plugins {', + ` id '${PLUGIN_ID}' version '${version}' apply false`, + '}', + '', + ].join('\n'); + // plugins {} has to stay with the buildscript block. A later allprojects + // or apply statement makes Gradle reject the block. + const buildscript = blockExtent(projectBuildGradle, 'buildscript'); + if (buildscript) { + const at = buildscript.bodyEnd + 1; + return projectBuildGradle.slice(0, at) + declaration + projectBuildGradle.slice(at); + } + return declaration + projectBuildGradle; +} + +/** + * `ndkVersion` is `android.sdk` from native-versions.json, or null when + * native crash reporting is opted out. Null skips the artifact; the plugin + * is still applied so mapping upload can run. + */ +export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string { + let next = appBuildGradle; + if (!next.includes(PLUGIN_ID)) { + const react = 'apply plugin: "com.facebook.react"'; + if (next.includes(react)) { + next = next.replace(react, `${react}\napply plugin: "${PLUGIN_ID}"`); + } else { + next = `apply plugin: "${PLUGIN_ID}"\n${next}`; + } + } + if (ndkVersion === null || next.includes('bugsee-android-ndk')) { + return next; + } + if (!/^[0-9A-Za-z.+_-]+$/.test(ndkVersion)) { + throw new Error(`refusing NDK artifact version ${ndkVersion}`); + } + const dep = ` implementation "com.bugsee:bugsee-android-ndk:${ndkVersion}"`; + const deps = next.indexOf('dependencies {'); + if (deps < 0) { + return `${next.replace(/\s*$/, '')}\n\ndependencies {\n${dep}\n}\n`; + } + const brace = next.indexOf('{', deps); + return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; +} diff --git a/packages/react-native/plugin/src/index.ts b/packages/react-native/plugin/src/index.ts new file mode 100644 index 0000000..faca578 --- /dev/null +++ b/packages/react-native/plugin/src/index.ts @@ -0,0 +1,150 @@ +import { readdirSync } from 'node:fs'; +import { readFile, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +import { + AndroidConfig, + createRunOncePlugin, + withAndroidManifest, + withAppBuildGradle, + withDangerousMod, + withProjectBuildGradle, + withSettingsGradle, + withXcodeProject, +} from '@expo/config-plugins'; +import type { ConfigPlugin } from '@expo/config-plugins'; + +import type { XcodeProjectLike } from './bundle-phase'; +import { rewriteProjectBundlePhase } from './bundle-phase'; +import { ensureAppAppliesPlugin, ensureGradlePluginDeclared, ensureMavenCentral } from './gradle'; +import { manifestAutoLaunchToken } from './manifest'; +import { loadNativeVersions } from './native-versions'; +import { bugseePropertiesText } from './properties'; +import { insertDsymPostAction } from './scheme'; + +export interface BugseePluginProps { + /** Unprefixed `app_token` in android/bugsee.properties. */ + appToken?: string; + /** + * Accepted for the spec's option list. The settled Xcode hook injects + * debug ids on the composed map and does not execute the upload. + */ + uploadSourcemaps?: boolean; + /** Defaults on. `false` skips the Archive dSYM post-action. */ + uploadSymbols?: boolean; + /** + * Defaults on. Writes `plugin.ndk.enabled=true` for a real token and adds + * `com.bugsee:bugsee-android-ndk`. `false` opts out of both. + */ + nativeCrashReporting?: boolean; + /** Defaults to native-versions.json `android.gradlePlugin`. */ + gradlePluginVersion?: string; + /** Defaults off. Writes `com.bugsee.app-token` manifest meta-data. */ + autoLaunch?: boolean; +} + +const withBugsee: ConfigPlugin = (config, props) => { + const options: BugseePluginProps = props ?? {}; + const versions = loadNativeVersions(__dirname); + const gradlePluginVersion = options.gradlePluginVersion ?? versions.gradlePlugin; + const ndkVersion = options.nativeCrashReporting === false ? null : versions.sdk; + + config = withSettingsGradle(config, (cfg) => { + cfg.modResults.contents = ensureMavenCentral(cfg.modResults.contents); + return cfg; + }); + + config = withProjectBuildGradle(config, (cfg) => { + cfg.modResults.contents = ensureGradlePluginDeclared( + cfg.modResults.contents, + gradlePluginVersion, + ); + return cfg; + }); + + config = withAppBuildGradle(config, (cfg) => { + cfg.modResults.contents = ensureAppAppliesPlugin(cfg.modResults.contents, ndkVersion); + return cfg; + }); + + config = withDangerousMod(config, [ + 'android', + async (cfg) => { + await writeFile( + join(cfg.modRequest.platformProjectRoot, 'bugsee.properties'), + bugseePropertiesText(options), + ); + return cfg; + }, + ]); + + config = withAndroidManifest(config, (cfg) => { + const token = manifestAutoLaunchToken(options); + if (!token) { + return cfg; + } + const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(cfg.modResults); + AndroidConfig.Manifest.addMetaDataItemToMainApplication( + mainApplication, + 'com.bugsee.app-token', + token, + ); + return cfg; + }); + + config = withXcodeProject(config, (cfg) => { + rewriteProjectBundlePhase(cfg.modResults as unknown as XcodeProjectLike); + return cfg; + }); + + if (options.uploadSymbols !== false) { + config = withDangerousMod(config, [ + 'ios', + async (cfg) => { + for (const schemePath of listSchemes(cfg.modRequest.platformProjectRoot)) { + const xml = await readFile(schemePath, 'utf8'); + const next = insertDsymPostAction(xml); + if (next !== xml) { + await writeFile(schemePath, next); + } + } + return cfg; + }, + ]); + } + + return config; +}; + +function listSchemes(iosRoot: string): string[] { + let entries: string[]; + try { + entries = readdirSync(iosRoot); + } catch (error) { + throw new Error(`ios project not found at ${iosRoot}`, { cause: error }); + } + const schemes: string[] = []; + for (const entry of entries) { + if (!entry.endsWith('.xcodeproj')) { + continue; + } + const dir = join(iosRoot, entry, 'xcshareddata', 'xcschemes'); + let names: string[]; + try { + names = readdirSync(dir); + } catch { + continue; + } + for (const name of names) { + if (name.endsWith('.xcscheme')) { + schemes.push(join(dir, name)); + } + } + } + if (schemes.length === 0) { + throw new Error(`no shared xcscheme under ${iosRoot}`); + } + return schemes; +} + +export default createRunOncePlugin(withBugsee, '@bugsee/react-native', '0.0.0'); diff --git a/packages/react-native/plugin/src/manifest.ts b/packages/react-native/plugin/src/manifest.ts new file mode 100644 index 0000000..d4365a2 --- /dev/null +++ b/packages/react-native/plugin/src/manifest.ts @@ -0,0 +1,23 @@ +import { isPlaceholderToken } from './properties'; + +export interface AutoLaunchInput { + readonly appToken?: string; + /** Off unless set. Manifest auto-launch starts the native SDK before JS. */ + readonly autoLaunch?: boolean; +} + +/** + * The `com.bugsee.app-token` meta-data value, or null when the manifest + * should be left alone. A placeholder token is not written: the native SDK + * would launch it against the production API. + */ +export function manifestAutoLaunchToken(input: AutoLaunchInput): string | null { + if (input.autoLaunch !== true) { + return null; + } + const token = input.appToken ?? ''; + if (token.length === 0 || isPlaceholderToken(token)) { + return null; + } + return token; +} diff --git a/packages/react-native/plugin/src/native-versions.ts b/packages/react-native/plugin/src/native-versions.ts new file mode 100644 index 0000000..db84169 --- /dev/null +++ b/packages/react-native/plugin/src/native-versions.ts @@ -0,0 +1,41 @@ +import { existsSync, readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; + +export interface AndroidNativeVersions { + readonly sdk: string; + readonly gradlePlugin: string; +} + +interface NativeVersionsFile { + readonly android?: { + readonly sdk?: string; + readonly gradlePlugin?: string; + }; +} + +/** + * Walk up from the plugin until `native-versions.json` appears. That file + * is the only pin: the Gradle plugin version is `android.gradlePlugin` and + * the NDK artifact version is `android.sdk`. + */ +export function loadNativeVersions(startDir: string): AndroidNativeVersions { + let dir = startDir; + for (let i = 0; i < 10; i += 1) { + const candidate = join(dir, 'native-versions.json'); + if (existsSync(candidate)) { + const parsed = JSON.parse(readFileSync(candidate, 'utf8')) as NativeVersionsFile; + const sdk = parsed.android?.sdk; + const gradlePlugin = parsed.android?.gradlePlugin; + if (!sdk || !gradlePlugin) { + throw new Error(`${candidate} is missing android.sdk or android.gradlePlugin`); + } + return { sdk, gradlePlugin }; + } + const parent = dirname(dir); + if (parent === dir) { + break; + } + dir = parent; + } + throw new Error(`native-versions.json not found above ${startDir}`); +} diff --git a/packages/react-native/plugin/src/pbx-string.ts b/packages/react-native/plugin/src/pbx-string.ts new file mode 100644 index 0000000..16c8026 --- /dev/null +++ b/packages/react-native/plugin/src/pbx-string.ts @@ -0,0 +1,48 @@ +/** + * pbxproj quoted strings keep their quotes in the xcode project's object + * model, and escapes (`\n`, `\"`, `\\`) stay as two characters. The writer + * prints the value unchanged, so a shell script has to be stored in that + * same shape. + */ + +function unescapeBody(body: string): string { + let out = ''; + for (let i = 0; i < body.length; i += 1) { + const current = body[i]; + if (current === '\\' && i + 1 < body.length) { + const next = body[i + 1]; + if (next === 'n') { + out += '\n'; + } else if (next === 'r') { + out += '\r'; + } else if (next === 't') { + out += '\t'; + } else if (next !== undefined) { + out += next; + } + i += 1; + continue; + } + if (current !== undefined) { + out += current; + } + } + return out; +} + +export function decodePbxString(stored: string): string { + if (stored.startsWith('"') && stored.endsWith('"')) { + return unescapeBody(stored.slice(1, -1)); + } + return stored; +} + +export function encodePbxString(value: string): string { + const escaped = value + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t'); + return `"${escaped}"`; +} diff --git a/packages/react-native/plugin/src/properties.ts b/packages/react-native/plugin/src/properties.ts new file mode 100644 index 0000000..0be539e --- /dev/null +++ b/packages/react-native/plugin/src/properties.ts @@ -0,0 +1,40 @@ +/** + * Same rule as `isPlaceholderToken` in examples/bare/endpoint.ts. The CI + * token `00000000-0000-4000-8000-000000000000` matches. Copied here so the + * plugin does not import the example app. + */ +const PLACEHOLDER_TOKEN = /^0{12}[0-9a-f]0{3}[0-9a-f]0{15}$/i; + +export function isPlaceholderToken(token: string): boolean { + return PLACEHOLDER_TOKEN.test(token.replace(/-/g, '')); +} + +export interface PropertiesInput { + readonly appToken?: string; + /** Defaults on. Opt out with `false`. */ + readonly nativeCrashReporting?: boolean; +} + +/** + * `/bugsee.properties`. The token is the unprefixed `app_token` + * key. `plugin.ndk.enabled=true` is written only for a real, non-placeholder + * token while native crash reporting is on (the default). `plugin.appToken` + * is not a key the Gradle plugin reads, and this file never emits it. + * No endpoint key: a placeholder token omits the upload flag instead of + * pointing the build at another host. + */ +export function bugseePropertiesText(input: PropertiesInput = {}): string { + const token = input.appToken ?? ''; + const lines: string[] = []; + if (token.length > 0) { + lines.push(`app_token=${token}`); + } + const ndkOn = input.nativeCrashReporting !== false; + if (ndkOn && token.length > 0 && !isPlaceholderToken(token)) { + lines.push('plugin.ndk.enabled=true'); + } + if (lines.length === 0) { + return '# Generated by @bugsee/react-native. No app token configured.\n'; + } + return `${lines.join('\n')}\n`; +} diff --git a/packages/react-native/plugin/src/scheme.ts b/packages/react-native/plugin/src/scheme.ts new file mode 100644 index 0000000..6b2f2b2 --- /dev/null +++ b/packages/react-native/plugin/src/scheme.ts @@ -0,0 +1,54 @@ +import { DSYM_POST_ACTION_SCRIPT } from './dsym-script'; + +export { DSYM_POST_ACTION_SCRIPT }; + +export function encodeXmlAttr(value: string): string { + return value + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>') + .replace(/\r/g, ' ') + .replace(/\n/g, ' '); +} + +function appBuildableReference(scheme: string): string { + const refs = scheme.match(//g) ?? []; + const app = refs.find((ref) => /BuildableName\s*=\s*"[^"]+\.app"/.test(ref)); + if (!app) { + throw new Error('scheme has no .app BuildableReference'); + } + return app; +} + +/** + * Inserts the bare example's Archive post-action. The script is not + * rewritten. The EnvironmentBuildable is the scheme's own app target, so + * ARCHIVE_PATH is provided. + */ +export function insertDsymPostAction(scheme: string, script: string = DSYM_POST_ACTION_SCRIPT): string { + if (scheme.includes('xcode post-action')) { + return scheme; + } + const archive = scheme.match(//); + if (!archive?.[0]) { + throw new Error('ArchiveAction missing'); + } + const reference = appBuildableReference(scheme); + const block = [ + ' ', + ' ', + ' `, + ' ', + reference.trimEnd(), + ' ', + ' ', + ' ', + ' ', + ].join('\n'); + const updated = archive[0].replace('', `${block}\n `); + return scheme.replace(archive[0], updated); +} diff --git a/packages/react-native/plugin/tsconfig.json b/packages/react-native/plugin/tsconfig.json new file mode 100644 index 0000000..4178cb5 --- /dev/null +++ b/packages/react-native/plugin/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "commonjs", + "moduleResolution": "node", + "outDir": "build", + "rootDir": "src", + "strict": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "esModuleInterop": true, + "skipLibCheck": true, + "declaration": true, + "sourceMap": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/__tests__/**"] +} diff --git a/yarn.lock b/yarn.lock index 319137e..72cf3bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,7 +5,7 @@ __metadata: version: 8 cacheKey: 10c0 -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.29.7": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.20.0, @babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.29.7": version: 7.29.7 resolution: "@babel/code-frame@npm:7.29.7" dependencies: @@ -40,7 +40,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4, @babel/core@npm:^7.25.2": +"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.20.0, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4, @babel/core@npm:^7.25.2": version: 7.29.7 resolution: "@babel/core@npm:7.29.7" dependencies: @@ -101,7 +101,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.29.1, @babel/generator@npm:^7.29.7, @babel/generator@npm:^7.29.8, @babel/generator@npm:^7.7.2": +"@babel/generator@npm:^7.20.5, @babel/generator@npm:^7.29.1, @babel/generator@npm:^7.29.7, @babel/generator@npm:^7.29.8, @babel/generator@npm:^7.7.2": version: 7.29.8 resolution: "@babel/generator@npm:7.29.8" dependencies: @@ -268,7 +268,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.29.7": +"@babel/helper-module-imports@npm:^7.25.9, @babel/helper-module-imports@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-module-imports@npm:7.29.7" dependencies: @@ -573,6 +573,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-proposal-decorators@npm:^7.12.9": + version: 7.29.7 + resolution: "@babel/plugin-proposal-decorators@npm:7.29.7" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/plugin-syntax-decorators": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/9c0ce48ac70952d4419f0ceb250cefe2eff96d1e7393bcb7db2e15abe655ee04e25e6f7ce4346f27bdfa781a4386963e3e5c1d1ef7cb1c765a0d811debc9a645 + languageName: node + linkType: hard + "@babel/plugin-proposal-decorators@npm:~8.0.0": version: 8.0.2 resolution: "@babel/plugin-proposal-decorators@npm:8.0.2" @@ -650,6 +663,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-decorators@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-syntax-decorators@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/5a5644ecd899345a92788c2d3a832541a09ab1558accbde396036920d76405b8cb7b073eb01fad468181719962cc0dfdf8377c4744fc4ceb042432e03f64e13e + languageName: node + linkType: hard + "@babel/plugin-syntax-decorators@npm:^8.0.1": version: 8.0.1 resolution: "@babel/plugin-syntax-decorators@npm:8.0.1" @@ -953,7 +977,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.29.7": +"@babel/plugin-transform-class-static-block@npm:^7.27.1, @babel/plugin-transform-class-static-block@npm:^7.29.7": version: 7.29.7 resolution: "@babel/plugin-transform-class-static-block@npm:7.29.7" dependencies: @@ -1097,7 +1121,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.29.7": +"@babel/plugin-transform-export-namespace-from@npm:^7.25.9, @babel/plugin-transform-export-namespace-from@npm:^7.29.7": version: 7.29.7 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.29.7" dependencies: @@ -1167,7 +1191,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.29.7": +"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7, @babel/plugin-transform-logical-assignment-operators@npm:^7.29.7": version: 7.29.7 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.29.7" dependencies: @@ -1296,7 +1320,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.29.7": +"@babel/plugin-transform-object-rest-spread@npm:^7.24.7, @babel/plugin-transform-object-rest-spread@npm:^7.29.7": version: 7.29.7 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.29.7" dependencies: @@ -1346,7 +1370,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.29.7": +"@babel/plugin-transform-parameters@npm:^7.24.7, @babel/plugin-transform-parameters@npm:^7.29.7": version: 7.29.7 resolution: "@babel/plugin-transform-parameters@npm:7.29.7" dependencies: @@ -1415,6 +1439,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-jsx-development@npm:^7.27.1": + version: 7.29.7 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.29.7" + dependencies: + "@babel/plugin-transform-react-jsx": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/a2d44d068d35f8e6bc0437ba0da86526d4473491a43108caf77cba467a3ab522cbd09bcd8184b7a49f3d2b52e0883ad797ed2f91c090b857a80a6f383e88f449 + languageName: node + linkType: hard + "@babel/plugin-transform-react-jsx-development@npm:^8.0.1": version: 8.0.1 resolution: "@babel/plugin-transform-react-jsx-development@npm:8.0.1" @@ -1448,7 +1483,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.25.2": +"@babel/plugin-transform-react-jsx@npm:^7.25.2, @babel/plugin-transform-react-jsx@npm:^7.28.6, @babel/plugin-transform-react-jsx@npm:^7.29.7": version: 7.29.7 resolution: "@babel/plugin-transform-react-jsx@npm:7.29.7" dependencies: @@ -1478,6 +1513,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-pure-annotations@npm:^7.27.1": + version: 7.29.7 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.29.7" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/ad85d57dfa105cd19dc5271f68c9a3e134ab96edce9b8c6b521fdb158499bc616df9d4ee9b386e9dc5532e67bd5682ba2047b88550699d7f1060eaaba80fb6d1 + languageName: node + linkType: hard + "@babel/plugin-transform-react-pure-annotations@npm:^8.0.1": version: 8.0.1 resolution: "@babel/plugin-transform-react-pure-annotations@npm:8.0.1" @@ -1611,6 +1658,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.29.7": + version: 7.29.9 + resolution: "@babel/plugin-transform-typescript@npm:7.29.9" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.29.7" + "@babel/helper-create-class-features-plugin": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" + "@babel/plugin-syntax-typescript": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/6caf62e8359fa08b112d7762036cd3c82ec5c5fd604f5faf4446a7f7b8fa8a85e5536e8425dc61dc3846316b5fdc9adb59de0cc51e39d3354a89bb31705f36de + languageName: node + linkType: hard + "@babel/plugin-transform-typescript@npm:^8.0.1": version: 8.0.5 resolution: "@babel/plugin-transform-typescript@npm:8.0.5" @@ -1783,6 +1845,21 @@ __metadata: languageName: node linkType: hard +"@babel/preset-typescript@npm:^7.23.0": + version: 7.29.7 + resolution: "@babel/preset-typescript@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-validator-option": "npm:^7.29.7" + "@babel/plugin-syntax-jsx": "npm:^7.29.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.29.7" + "@babel/plugin-transform-typescript": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/40746a23a7ab46c0beb1c02d69883d9ffbe3043685cb3ae5363644391376b9261189fdad317191349e322c2c9bc550b031daa42470a1f8987362e4c56e492194 + languageName: node + linkType: hard + "@babel/preset-typescript@npm:~8.0.0": version: 8.0.1 resolution: "@babel/preset-typescript@npm:8.0.1" @@ -1797,7 +1874,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.25.0": +"@babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.25.0": version: 7.29.7 resolution: "@babel/runtime@npm:7.29.7" checksum: 10c0/ca11572f7146b21e0bde6a9ed4bb6a89eafbee5f0944c7eb54d0d8a2dac962c33638a1d611e14faa71dfbb92b4b5f9236232208568a6b7d5c6f3f39ddb91771e @@ -1856,7 +1933,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.28.2, @babel/types@npm:^7.29.0, @babel/types@npm:^7.29.7, @babel/types@npm:^7.29.8, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.26.0, @babel/types@npm:^7.28.2, @babel/types@npm:^7.29.0, @babel/types@npm:^7.29.7, @babel/types@npm:^7.29.8, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": version: 7.29.8 resolution: "@babel/types@npm:7.29.8" dependencies: @@ -1971,6 +2048,7 @@ __metadata: resolution: "@bugsee/react-native@workspace:packages/react-native" dependencies: "@bugsee/cli": "npm:0.7.11" + "@expo/config-plugins": "npm:~57.0.9" react-native: "npm:0.87.1" peerDependencies: react: "*" @@ -2109,231 +2187,742 @@ __metadata: languageName: node linkType: hard -"@hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0": - version: 9.3.0 - resolution: "@hapi/hoek@npm:9.3.0" - checksum: 10c0/a096063805051fb8bba4c947e293c664b05a32b47e13bc654c0dd43813a1cec993bdd8f29ceb838020299e1d0f89f68dc0d62a603c13c9cc8541963f0beca055 +"@expo/cli@npm:^57.0.27": + version: 57.0.27 + resolution: "@expo/cli@npm:57.0.27" + dependencies: + "@expo/code-signing-certificates": "npm:^0.0.6" + "@expo/config": "npm:~57.0.9" + "@expo/config-plugins": "npm:~57.0.9" + "@expo/devcert": "npm:^1.2.1" + "@expo/env": "npm:~2.4.3" + "@expo/image-utils": "npm:^0.11.5" + "@expo/inline-modules": "npm:^0.1.7" + "@expo/json-file": "npm:^11.0.1" + "@expo/log-box": "npm:^57.0.4" + "@expo/metro": "npm:~56.0.2" + "@expo/metro-config": "npm:~57.0.12" + "@expo/metro-file-map": "npm:^57.0.3" + "@expo/osascript": "npm:^2.7.1" + "@expo/package-manager": "npm:^1.13.1" + "@expo/plist": "npm:^0.8.1" + "@expo/prebuild-config": "npm:^57.0.16" + "@expo/require-utils": "npm:^57.0.5" + "@expo/router-server": "npm:^57.0.11" + "@expo/schema-utils": "npm:^57.0.2" + "@expo/spawn-async": "npm:^1.8.0" + "@expo/ws-tunnel": "npm:^2.0.0" + "@expo/xcpretty": "npm:^4.4.4" + "@react-native/dev-middleware": "npm:0.86.3" + accepts: "npm:^1.3.8" + agent-cli-detector: "npm:0.1.7" + arg: "npm:^5.0.2" + bplist-creator: "npm:0.1.0" + bplist-parser: "npm:^0.3.1" + chalk: "npm:^4.0.0" + ci-info: "npm:^3.3.0" + compression: "npm:^1.7.4" + connect: "npm:^3.7.0" + debug: "npm:^4.3.4" + dnssd-advertise: "npm:^1.1.4" + expo-server: "npm:^57.0.3" + fetch-nodeshim: "npm:^0.4.10" + getenv: "npm:^2.0.0" + glob: "npm:^13.0.0" + lan-network: "npm:^0.2.1" + multitars: "npm:^1.0.2" + node-forge: "npm:^1.3.3" + npm-package-arg: "npm:^11.0.0" + ora: "npm:^3.4.0" + picomatch: "npm:^4.0.4" + pretty-format: "npm:^29.7.0" + progress: "npm:^2.0.3" + prompts: "npm:^2.3.2" + resolve-from: "npm:^5.0.0" + sandbox-cli-detector: "npm:^0.2.0" + semver: "npm:^7.6.0" + send: "npm:^0.19.0" + slugify: "npm:^1.3.4" + stacktrace-parser: "npm:^0.1.10" + structured-headers: "npm:^0.4.1" + terminal-link: "npm:^2.1.1" + toqr: "npm:^0.1.1" + wrap-ansi: "npm:^7.0.0" + ws: "npm:^8.12.1" + zod: "npm:^3.25.76" + peerDependencies: + expo: "*" + expo-router: "*" + react-native: "*" + peerDependenciesMeta: + expo-router: + optional: true + react-native: + optional: true + bin: + expo-internal: main.js + checksum: 10c0/e781f5d38850f8dd1fa93ec0d80783759a256bf22783b59828111925ad38776beff901178a7003494293258152bffc442ff091398324a540c941006fdf94d8e9 languageName: node linkType: hard -"@hapi/topo@npm:^5.1.0": - version: 5.1.0 - resolution: "@hapi/topo@npm:5.1.0" +"@expo/code-signing-certificates@npm:^0.0.6": + version: 0.0.6 + resolution: "@expo/code-signing-certificates@npm:0.0.6" dependencies: - "@hapi/hoek": "npm:^9.0.0" - checksum: 10c0/b16b06d9357947149e032bdf10151eb71aea8057c79c4046bf32393cb89d0d0f7ca501c40c0f7534a5ceca078de0700d2257ac855c15e59fe4e00bba2f25c86f + node-forge: "npm:^1.3.3" + checksum: 10c0/3c60be55fb056ccebf7355c1dbe959cee191eaa1c33c6ff5a7331c1ffe1cfa66edc6b62e8005b4a9023bbd40462d81d35284e79eaa8893facb2493801685bbea languageName: node linkType: hard -"@humanfs/core@npm:^0.19.2": - version: 0.19.2 - resolution: "@humanfs/core@npm:0.19.2" +"@expo/config-plugins@npm:~57.0.9": + version: 57.0.9 + resolution: "@expo/config-plugins@npm:57.0.9" dependencies: - "@humanfs/types": "npm:^0.15.0" - checksum: 10c0/d0a1d52d7b30c27d49475a53072d1510b81c5803e44b342fb8faf3887f1aa27593a1e6dc76a45268e7892d3f4e198146659281f6b6d55eacf3fd5a38bac30c5c + "@expo/config-types": "npm:^57.0.2" + "@expo/json-file": "npm:~11.0.1" + "@expo/plist": "npm:^0.8.1" + "@expo/require-utils": "npm:^57.0.5" + "@expo/sdk-runtime-versions": "npm:^1.0.0" + chalk: "npm:^4.1.2" + debug: "npm:^4.3.5" + getenv: "npm:^2.0.0" + glob: "npm:^13.0.0" + semver: "npm:^7.5.4" + slugify: "npm:^1.6.6" + xcode: "npm:^3.0.1" + xml2js: "npm:0.6.0" + checksum: 10c0/a980ceea445860797dd8d5f446b9dd1710b4101a0d9ac362157c9af2f5777ed7365c09c13f2fd42c00252060105e92e44a390841c294d52dbcb0362cac21c5c0 languageName: node linkType: hard -"@humanfs/node@npm:^0.16.6": - version: 0.16.8 - resolution: "@humanfs/node@npm:0.16.8" - dependencies: - "@humanfs/core": "npm:^0.19.2" - "@humanfs/types": "npm:^0.15.0" - "@humanwhocodes/retry": "npm:^0.4.0" - checksum: 10c0/56140579db811af4e160b195d45d0f29acf644d192c93fe24c9e594ebf06f19dfc157494a07c84540b8a071c0e4b37209c2362765d31734f4d0be869c2422e25 +"@expo/config-types@npm:^57.0.2": + version: 57.0.2 + resolution: "@expo/config-types@npm:57.0.2" + checksum: 10c0/3e3a8abcab03791dfccc758bde5ce85f0fa4b14c22df072e6cc72c670945fc65433239bf2ce39f86bbda422b338d19323612d61eabb2442f988713214837a6dc languageName: node linkType: hard -"@humanfs/types@npm:^0.15.0": - version: 0.15.0 - resolution: "@humanfs/types@npm:0.15.0" - checksum: 10c0/fc26b9a024b0e55f7eaf64036df94345bf5d36d6a41ef80ef38e78f1f7430ce26cf435af736adae58913baae18eac3f38c18739054a3d379102015978eae862e +"@expo/config@npm:~57.0.9": + version: 57.0.9 + resolution: "@expo/config@npm:57.0.9" + dependencies: + "@expo/config-plugins": "npm:~57.0.9" + "@expo/config-types": "npm:^57.0.2" + "@expo/json-file": "npm:^11.0.1" + "@expo/require-utils": "npm:^57.0.5" + deepmerge: "npm:^4.3.1" + getenv: "npm:^2.0.0" + glob: "npm:^13.0.0" + resolve-workspace-root: "npm:^2.0.0" + semver: "npm:^7.6.0" + slugify: "npm:^1.3.4" + checksum: 10c0/b70700a5bdf405c7b71878f5c4549f034a0080ba427069089326017e5b777cbdddaf9abf094aa0de83c80202fea479078fe452ae3ac11c3b75ca7922376ac409 languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.13.0": - version: 0.13.0 - resolution: "@humanwhocodes/config-array@npm:0.13.0" +"@expo/devcert@npm:^1.2.1": + version: 1.2.2 + resolution: "@expo/devcert@npm:1.2.2" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.3" - debug: "npm:^4.3.1" - minimatch: "npm:^3.0.5" - checksum: 10c0/205c99e756b759f92e1f44a3dc6292b37db199beacba8f26c2165d4051fe73a4ae52fdcfd08ffa93e7e5cb63da7c88648f0e84e197d154bbbbe137b2e0dd332e + "@expo/sudo-prompt": "npm:^9.3.1" + debug: "npm:^3.1.0" + checksum: 10c0/1c56dfee5029d4d33efd6e572223493fecf87afbcb6b998fb329eae89a0211687e6ed472a3f16a1cbb2e91c8d5e83d6368f3c42edb5b4d821b087e535fd0fb07 languageName: node linkType: hard -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 +"@expo/devtools@npm:~57.0.1": + version: 57.0.1 + resolution: "@expo/devtools@npm:57.0.1" + dependencies: + chalk: "npm:^4.1.2" + peerDependencies: + react: "*" + react-native: "*" + peerDependenciesMeta: + react: + optional: true + react-native: + optional: true + checksum: 10c0/bf3a24db47725ebeb79adbb95c3cddb71ea26e0040e80ef9aeb50b538417581765617a8fa6c5c63b78cb1d633548da8fc926d892331515e8fb180e99831f0156 languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.3": - version: 2.0.3 - resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c +"@expo/dom-webview@npm:^57.0.1, @expo/dom-webview@npm:~57.0.1": + version: 57.0.1 + resolution: "@expo/dom-webview@npm:57.0.1" + peerDependencies: + expo: "*" + react: "*" + react-native: "*" + checksum: 10c0/22c2868e9c6c2eea2f607b1f9b4afc966b4fba3a03a6b05cabe9c8c51540fae4252f60ff171ce406ebcccca8b3e5931d07d0dd04c777020669a1dd11d5cca8a6 languageName: node linkType: hard -"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": - version: 0.4.3 - resolution: "@humanwhocodes/retry@npm:0.4.3" - checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42 +"@expo/env@npm:^2.4.3": + version: 2.5.1 + resolution: "@expo/env@npm:2.5.1" + dependencies: + chalk: "npm:^4.0.0" + debug: "npm:^4.3.4" + getenv: "npm:^2.0.0" + checksum: 10c0/1ca2010411fe5aaf2d14e0ead0039b83e92a4ce96316ce2584293d290493d6530a7eefaf648455cadd38d739a2068f6a26a132387891a64b35608fb5e9b534bb languageName: node linkType: hard -"@inquirer/ansi@npm:^2.0.8": - version: 2.0.8 - resolution: "@inquirer/ansi@npm:2.0.8" - checksum: 10c0/2149a358f6227260815aac389bb0b5aedecc54452ad9c40e8aedcec07e0df91a046771571617d0734d074450637f5edde38752e17e79ede0d2bf657413acf3cb +"@expo/env@npm:~2.4.3": + version: 2.4.3 + resolution: "@expo/env@npm:2.4.3" + dependencies: + chalk: "npm:^4.0.0" + debug: "npm:^4.3.4" + getenv: "npm:^2.0.0" + checksum: 10c0/36eb2dacda0765eca69b3df7aaa3e5a74fb05561f5e223ca19a376a70ed18934edb1782345299fb9b026f0d1e4773f047835f1c16035151c1a76a1e373b29412 languageName: node linkType: hard -"@inquirer/checkbox@npm:^5.2.5": - version: 5.2.5 - resolution: "@inquirer/checkbox@npm:5.2.5" - dependencies: - "@inquirer/ansi": "npm:^2.0.8" - "@inquirer/core": "npm:^12.0.3" - "@inquirer/figures": "npm:^2.0.9" - "@inquirer/type": "npm:4.1.1" - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 10c0/d427ef80cda8f955b215e96d1543514311401eba65d7d0643ccca8f1c66f0ff96505f277c19c39110a890b04de66e2078af24df5df54679fdbf859717b8d0a6c +"@expo/expo-modules-macros-plugin@npm:0.6.1": + version: 0.6.1 + resolution: "@expo/expo-modules-macros-plugin@npm:0.6.1" + checksum: 10c0/1cad524b3468650f1504c09f300b2be2f469b2e997788d7d6a443a1d13944bae679f6976fc1d13d4ffa485ccc5ddb562919dca79aa1d3b46e6adaa78cb787842 languageName: node linkType: hard -"@inquirer/confirm@npm:^6.3.2": - version: 6.3.2 - resolution: "@inquirer/confirm@npm:6.3.2" +"@expo/fingerprint@npm:^0.20.13": + version: 0.20.13 + resolution: "@expo/fingerprint@npm:0.20.13" dependencies: - "@inquirer/core": "npm:^12.0.3" - "@inquirer/type": "npm:4.1.1" - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 10c0/5ed7d94b6d2148f9e71130a6130c4f2f821791ffc1edaac98d2821a185279e1020dbdca9eecb80116fa967f87e57052f3a67fcee1c28ec4ad090cba04f26fcc9 + "@expo/env": "npm:^2.4.3" + "@expo/spawn-async": "npm:^1.8.0" + arg: "npm:^5.0.2" + chalk: "npm:^4.1.2" + debug: "npm:^4.3.4" + getenv: "npm:^2.0.0" + glob: "npm:^13.0.0" + ignore: "npm:^5.3.1" + minimatch: "npm:^10.2.2" + resolve-from: "npm:^5.0.0" + semver: "npm:^7.6.0" + bin: + fingerprint: bin/cli.js + checksum: 10c0/0fc278d17080b5855db1d0afd3b6d5d4c8eaccbe53542c9d8fc5c7e385b43b03c4445ba11d085fc8c86308347efb774d75a9c0201973e7b0d8a6823af36e1159 languageName: node linkType: hard -"@inquirer/core@npm:^12.0.3": - version: 12.0.3 - resolution: "@inquirer/core@npm:12.0.3" +"@expo/image-utils@npm:^0.11.5": + version: 0.11.5 + resolution: "@expo/image-utils@npm:0.11.5" dependencies: - "@inquirer/ansi": "npm:^2.0.8" - "@inquirer/figures": "npm:^2.0.9" - "@inquirer/type": "npm:4.1.1" - cli-width: "npm:^4.1.0" - fast-wrap-ansi: "npm:^0.2.0" - mute-stream: "npm:^3.0.0" - signal-exit: "npm:^4.1.0" - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 10c0/df323f8abb84d5ab8fd290ff2401067a107e22d7172b014068fcba23000838e0c102e7858e09afc58a5d8755dd4a50fafa66d03fd4921d60ec588cb41c61f8c1 + "@expo/require-utils": "npm:^57.0.5" + "@expo/spawn-async": "npm:^1.8.0" + chalk: "npm:^4.0.0" + getenv: "npm:^2.0.0" + jimp-compact: "npm:0.16.1" + parse-png: "npm:^2.1.0" + semver: "npm:^7.6.0" + checksum: 10c0/bca05d61164c88eafcbb01e82eea92679b9fcbc435ad50f0b8f7b0c74259ea50a7e7535d5403ea747be241c9560b04be66df8f3e0f926a6da1e5a1954a41a45d languageName: node linkType: hard -"@inquirer/editor@npm:^5.3.3": - version: 5.3.3 - resolution: "@inquirer/editor@npm:5.3.3" +"@expo/inline-modules@npm:^0.1.7": + version: 0.1.7 + resolution: "@expo/inline-modules@npm:0.1.7" dependencies: - "@inquirer/core": "npm:^12.0.3" - "@inquirer/external-editor": "npm:^3.0.5" - "@inquirer/type": "npm:4.1.1" - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 10c0/9b1b1d3de6bf5f8f95616b723908cfde1a05a201126e9fcabb1b04b9baa1077ca3ca9a7a82c6a7e8831d4226fae362f7fccbc70fca3f88b5ccd6dd8fdae81a84 + "@expo/config-plugins": "npm:~57.0.9" + checksum: 10c0/3dff95ce7d61915a20687cf4d3112acfa1c5865d2ca6fa814783355fb4220f074344718c81ec319849f3d9a8e2b942ca540ba7ed1a4377af844b7e6637da2191 languageName: node linkType: hard -"@inquirer/expand@npm:^5.1.5": - version: 5.1.5 - resolution: "@inquirer/expand@npm:5.1.5" +"@expo/json-file@npm:^11.0.1, @expo/json-file@npm:^11.2.1": + version: 11.2.1 + resolution: "@expo/json-file@npm:11.2.1" dependencies: - "@inquirer/core": "npm:^12.0.3" - "@inquirer/type": "npm:4.1.1" - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 10c0/30791746f2f7ba061daccb2f601d293442b1d3f6b30436bd3b3f47ed2ffcae40b1cd178e6e575237f14e85a9e2e48ca884d7c4d316ae0cfd9d2c1007b8761613 + "@babel/code-frame": "npm:^7.20.0" + json5: "npm:^2.2.3" + checksum: 10c0/45cc14ea1b4f4bc124d6ee2d5412e3f7d23832c82bd21180558c2a070df425d700c1e84d49de57ec946b06e1287ecb63eda15addc2bf5c582bad916ae8ab7b46 languageName: node linkType: hard -"@inquirer/external-editor@npm:^3.0.5": - version: 3.0.5 - resolution: "@inquirer/external-editor@npm:3.0.5" +"@expo/json-file@npm:~11.0.1": + version: 11.0.1 + resolution: "@expo/json-file@npm:11.0.1" dependencies: - chardet: "npm:^2.1.1" - iconv-lite: "npm:^0.7.2" - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 10c0/66ad34d4d6d6b8e1e26691b32a67309b066b74ed7eb5f0b8b8d87e20d095316c7f6cf9bcae1fa3e85ad655d4741b713bbd6dce355413ffb4bac2b3a927fa0a82 + "@babel/code-frame": "npm:^7.20.0" + json5: "npm:^2.2.3" + checksum: 10c0/b93e8bf0654c7d417bf00a418932a3f676bc24bed75ff63a8c683229e2d1f3b7a48206fc3af7db307ed93a776adab51cb62ebb6a0ed77f86067c7ae85cc2f74d languageName: node linkType: hard -"@inquirer/figures@npm:^2.0.9": - version: 2.0.9 - resolution: "@inquirer/figures@npm:2.0.9" - checksum: 10c0/24198eb05c7ba32cf5b2eeee0a641b708fcd23f78ac6c568d18858191a40aa456e1626c52e088df1882ebe2e34c0f4cd08c78ca3c506429d4032f0a8833230a2 +"@expo/local-build-cache-provider@npm:^57.0.8": + version: 57.0.8 + resolution: "@expo/local-build-cache-provider@npm:57.0.8" + dependencies: + "@expo/config": "npm:~57.0.9" + chalk: "npm:^4.1.2" + checksum: 10c0/9750ae6dbf91a0fc5eb3ffef7f2974c1193a9c212e5cbf80fee78d777c1545cf0445544ea7bc61f0f77767dea7c40b263643caf0d75e54dc84aa9139eaa40795 languageName: node linkType: hard -"@inquirer/input@npm:^5.1.6": - version: 5.1.6 - resolution: "@inquirer/input@npm:5.1.6" +"@expo/log-box@npm:^57.0.4": + version: 57.0.4 + resolution: "@expo/log-box@npm:57.0.4" dependencies: - "@inquirer/core": "npm:^12.0.3" - "@inquirer/type": "npm:4.1.1" + "@expo/dom-webview": "npm:^57.0.1" + anser: "npm:^1.4.9" + stacktrace-parser: "npm:^0.1.10" peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 10c0/aaf2a5db5e4ce9d45905ec4006d8772e49785682fa4cd0be66fe8324eaaffc77b9ef47ad5656d617c90be2f2a395c10e3a22e65f4b20ed09a0b5453161fa6125 + "@expo/dom-webview": ^57.0.1 + expo: "*" + react: "*" + react-native: "*" + checksum: 10c0/750b3482d657f450d545130ffe8c3b4e8f860561ad55f75f3058d1e08e0b37c16d512470a52d33cac1d459bbfb695784b199acd15134ec4309bc67287d88709f languageName: node linkType: hard -"@inquirer/number@npm:^4.2.3": - version: 4.2.3 - resolution: "@inquirer/number@npm:4.2.3" +"@expo/metro-config@npm:~57.0.12": + version: 57.0.12 + resolution: "@expo/metro-config@npm:57.0.12" dependencies: - "@inquirer/core": "npm:^12.0.3" - "@inquirer/type": "npm:4.1.1" + "@babel/code-frame": "npm:^7.20.0" + "@babel/core": "npm:^7.20.0" + "@babel/generator": "npm:^7.20.5" + "@expo/config": "npm:~57.0.9" + "@expo/env": "npm:~2.4.3" + "@expo/json-file": "npm:~11.0.1" + "@expo/metro": "npm:~56.0.2" + "@expo/require-utils": "npm:^57.0.5" + "@expo/spawn-async": "npm:^1.8.0" + "@jridgewell/gen-mapping": "npm:^0.3.13" + "@jridgewell/remapping": "npm:^2.3.5" + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + browserslist: "npm:^4.25.0" + chalk: "npm:^4.1.0" + debug: "npm:^4.3.2" + getenv: "npm:^2.0.0" + glob: "npm:^13.0.0" + hermes-parser: "npm:^0.36.0" + jsc-safe-url: "npm:^0.2.4" + lightningcss: "npm:^1.30.1" + picomatch: "npm:^4.0.4" + postcss: "npm:^8.5.14" + resolve-from: "npm:^5.0.0" peerDependencies: - "@types/node": ">=18" + expo: "*" peerDependenciesMeta: - "@types/node": + expo: optional: true - checksum: 10c0/912017dabde45b1150e8c7746471e19e728ea73cf9229e7d84e4d4d0462743e95c5f70d166f3b2f148af0984de3cd769376343b9f4c021a19c9cf47a99b3af88 + checksum: 10c0/eeb34426026d7b1188ba528c4e2c3c1f1023d9a2b0af192b120c6bcf0c89aa9d2c9c6af1086a02a05444a21a5eac4b2bdd89e11288abceacd7debd380edd864a languageName: node linkType: hard -"@inquirer/password@npm:^5.2.2": - version: 5.2.2 - resolution: "@inquirer/password@npm:5.2.2" +"@expo/metro-file-map@npm:^57.0.3": + version: 57.0.3 + resolution: "@expo/metro-file-map@npm:57.0.3" dependencies: - "@inquirer/ansi": "npm:^2.0.8" - "@inquirer/core": "npm:^12.0.3" - "@inquirer/type": "npm:4.1.1" - peerDependencies: + debug: "npm:^4.3.4" + fb-watchman: "npm:^2.0.2" + invariant: "npm:^2.2.4" + jest-worker: "npm:^29.7.0" + micromatch: "npm:^4.0.4" + walker: "npm:^1.0.8" + checksum: 10c0/57770deb2f83b21418ef86a9484521d27a66c20156a7aed33fc72a035d2b445b81bc9a10f464fb691a934cecf95da1fd30b759b09eee1bb6818f244d7d92d453 + languageName: node + linkType: hard + +"@expo/metro@npm:~56.0.2": + version: 56.0.2 + resolution: "@expo/metro@npm:56.0.2" + dependencies: + metro: "npm:0.84.5" + metro-babel-transformer: "npm:0.84.5" + metro-cache: "npm:0.84.5" + metro-cache-key: "npm:0.84.5" + metro-config: "npm:0.84.5" + metro-core: "npm:0.84.5" + metro-file-map: "npm:0.84.5" + metro-minify-terser: "npm:0.84.5" + metro-resolver: "npm:0.84.5" + metro-runtime: "npm:0.84.5" + metro-source-map: "npm:0.84.5" + metro-symbolicate: "npm:0.84.5" + metro-transform-plugins: "npm:0.84.5" + metro-transform-worker: "npm:0.84.5" + checksum: 10c0/5cf6b2ffe125d6d54138757e8fada0d88515ee0ec2113595ca224babf8baf95b866e12eba51cdb1d89aae4476a7982a653e46ea2091b22e1433984ae608cc380 + languageName: node + linkType: hard + +"@expo/osascript@npm:^2.7.1": + version: 2.8.1 + resolution: "@expo/osascript@npm:2.8.1" + dependencies: + "@expo/spawn-async": "npm:^1.8.0" + checksum: 10c0/e9237ea4524108a4d99d271da0cbd7eb1a7a001597fe574e463e784ad7c564e597ca6a0a9d0fedeab718bf251e2374a522a6d20d7441ffd60d1bc897b2761721 + languageName: node + linkType: hard + +"@expo/package-manager@npm:^1.13.1": + version: 1.14.1 + resolution: "@expo/package-manager@npm:1.14.1" + dependencies: + "@expo/json-file": "npm:^11.2.1" + "@expo/spawn-async": "npm:^1.8.0" + chalk: "npm:^4.0.0" + npm-package-arg: "npm:^11.0.0" + ora: "npm:^3.4.0" + resolve-workspace-root: "npm:^2.0.0" + checksum: 10c0/095567e0296475dbd1edfc53ee8e4ff4ddea1b7032e02d9505c2e8dc373f676335682b19c8ab5eb119bd06035f990b741eb8defa79ce5fceb2d6abb3e3a5229e + languageName: node + linkType: hard + +"@expo/plist@npm:^0.8.1": + version: 0.8.1 + resolution: "@expo/plist@npm:0.8.1" + dependencies: + "@xmldom/xmldom": "npm:^0.8.8" + base64-js: "npm:^1.5.1" + xmlbuilder: "npm:^15.1.1" + checksum: 10c0/45f130f3d5155d46dc415ab61b97449d5cc7bf47e41ed37965f12e50cc9728aa7c4da83fc958a8d7113e31e4342baebc1b2517de7e20186f3e64d53be378a9ce + languageName: node + linkType: hard + +"@expo/prebuild-config@npm:^57.0.16": + version: 57.0.16 + resolution: "@expo/prebuild-config@npm:57.0.16" + dependencies: + "@expo/config": "npm:~57.0.9" + "@expo/config-plugins": "npm:~57.0.9" + "@expo/config-types": "npm:^57.0.2" + "@expo/image-utils": "npm:^0.11.5" + "@expo/json-file": "npm:^11.0.1" + "@react-native/normalize-colors": "npm:0.86.3" + debug: "npm:^4.3.1" + expo-modules-autolinking: "npm:~57.0.13" + resolve-from: "npm:^5.0.0" + semver: "npm:^7.6.0" + checksum: 10c0/3c57618fcde5bc7cbbb55b20ff130e7b64f098668a904434b17d9471c69a7df26c73429cbd51e504961d658882da82db41e03631ccbd5df1d538584c0e079a99 + languageName: node + linkType: hard + +"@expo/require-utils@npm:^57.0.5": + version: 57.0.5 + resolution: "@expo/require-utils@npm:57.0.5" + dependencies: + "@babel/code-frame": "npm:^7.20.0" + "@babel/core": "npm:^7.25.2" + "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" + peerDependencies: + typescript: ^5.0.0 || ^5.0.0-0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/42841b76d6540098b664bee633e6ef9825ac84041e7c91045bd15a84d6aed4f2ad1f5027da263755a1e2dc2190283e7b7d6c4fb9ec3335c7a87016606b443754 + languageName: node + linkType: hard + +"@expo/router-server@npm:^57.0.11": + version: 57.0.11 + resolution: "@expo/router-server@npm:57.0.11" + dependencies: + debug: "npm:^4.3.4" + peerDependencies: + "@expo/metro-runtime": ^57.0.16 + expo: "*" + expo-constants: ^57.0.19 + expo-font: ^57.0.4 + expo-router: "*" + expo-server: ^57.0.3 + react: "*" + react-dom: "*" + react-server-dom-webpack: ~19.0.1 || ~19.1.2 || ~19.2.1 + peerDependenciesMeta: + "@expo/metro-runtime": + optional: true + expo-router: + optional: true + react-dom: + optional: true + react-server-dom-webpack: + optional: true + checksum: 10c0/1b5d19bff610db858d2921a39b3e94cc9699ed66bbdc2147f9268faa7f26921bab51efd6e7c2ffe50a86b8a191780fff2e55f00690e76b0616bce3d647c2cae4 + languageName: node + linkType: hard + +"@expo/schema-utils@npm:^57.0.2": + version: 57.0.2 + resolution: "@expo/schema-utils@npm:57.0.2" + checksum: 10c0/5438d6dd1cb58c35c1202cefd7bb44f38eb7078da08b706849154bd6d97f0a9db7a41862110e34d7e111edf50ac44ffe132b0af64ebfdcce8203eb8e5ecd51b9 + languageName: node + linkType: hard + +"@expo/sdk-runtime-versions@npm:^1.0.0": + version: 1.0.1 + resolution: "@expo/sdk-runtime-versions@npm:1.0.1" + checksum: 10c0/729c3d99ad8cb7acca41c3e76f63d4b216eae22fea04f3a99ec67bf189f29d36aa4880d863445f8d7e008d7ae67cf6f414539d1676bd82cb49a6dc7a6105e5a2 + languageName: node + linkType: hard + +"@expo/spawn-async@npm:^1.8.0": + version: 1.8.0 + resolution: "@expo/spawn-async@npm:1.8.0" + dependencies: + cross-spawn: "npm:^7.0.6" + checksum: 10c0/08d3c63f9cc097ce9c8cf6850ca482fd7999a6fddc4cb38a3a9915a1662cb674fe7353de2eb3c693728542bf57db732ae433e82b2d698be141d07cea3092ebf3 + languageName: node + linkType: hard + +"@expo/sudo-prompt@npm:^9.3.1": + version: 9.3.2 + resolution: "@expo/sudo-prompt@npm:9.3.2" + checksum: 10c0/032652bf1c3f326c9c194f336de5821b9ece9d48b22e3e277950d939fcd728c85459680a9771705904d375f128221cca2e1e91c5d7a85cf3c07fe6f88c361e9d + languageName: node + linkType: hard + +"@expo/ws-tunnel@npm:^2.0.0": + version: 2.0.1 + resolution: "@expo/ws-tunnel@npm:2.0.1" + peerDependencies: + ws: ^8.0.0 + checksum: 10c0/091e87213da4b9b32c714765fa028aecf9f5c268413b8794721264d875b49134642c24864ea21455d0757832c8c778b2db6c6de6d93ec8cf4dfe1bf50da934ad + languageName: node + linkType: hard + +"@expo/xcpretty@npm:^4.4.4": + version: 4.4.6 + resolution: "@expo/xcpretty@npm:4.4.6" + dependencies: + "@babel/code-frame": "npm:^7.20.0" + chalk: "npm:^4.1.0" + js-yaml: "npm:^4.1.0" + bin: + excpretty: build/cli.js + checksum: 10c0/8006971bd536a10f3c19c5aa6f823fde3fb816ed3caa0973b92d2eba36766a6afa82708f1ac247e9bb66596689fc3d57dfd0341c62eb316de25b454fa7e9e38b + languageName: node + linkType: hard + +"@hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0": + version: 9.3.0 + resolution: "@hapi/hoek@npm:9.3.0" + checksum: 10c0/a096063805051fb8bba4c947e293c664b05a32b47e13bc654c0dd43813a1cec993bdd8f29ceb838020299e1d0f89f68dc0d62a603c13c9cc8541963f0beca055 + languageName: node + linkType: hard + +"@hapi/topo@npm:^5.1.0": + version: 5.1.0 + resolution: "@hapi/topo@npm:5.1.0" + dependencies: + "@hapi/hoek": "npm:^9.0.0" + checksum: 10c0/b16b06d9357947149e032bdf10151eb71aea8057c79c4046bf32393cb89d0d0f7ca501c40c0f7534a5ceca078de0700d2257ac855c15e59fe4e00bba2f25c86f + languageName: node + linkType: hard + +"@humanfs/core@npm:^0.19.2": + version: 0.19.2 + resolution: "@humanfs/core@npm:0.19.2" + dependencies: + "@humanfs/types": "npm:^0.15.0" + checksum: 10c0/d0a1d52d7b30c27d49475a53072d1510b81c5803e44b342fb8faf3887f1aa27593a1e6dc76a45268e7892d3f4e198146659281f6b6d55eacf3fd5a38bac30c5c + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.8 + resolution: "@humanfs/node@npm:0.16.8" + dependencies: + "@humanfs/core": "npm:^0.19.2" + "@humanfs/types": "npm:^0.15.0" + "@humanwhocodes/retry": "npm:^0.4.0" + checksum: 10c0/56140579db811af4e160b195d45d0f29acf644d192c93fe24c9e594ebf06f19dfc157494a07c84540b8a071c0e4b37209c2362765d31734f4d0be869c2422e25 + languageName: node + linkType: hard + +"@humanfs/types@npm:^0.15.0": + version: 0.15.0 + resolution: "@humanfs/types@npm:0.15.0" + checksum: 10c0/fc26b9a024b0e55f7eaf64036df94345bf5d36d6a41ef80ef38e78f1f7430ce26cf435af736adae58913baae18eac3f38c18739054a3d379102015978eae862e + languageName: node + linkType: hard + +"@humanwhocodes/config-array@npm:^0.13.0": + version: 0.13.0 + resolution: "@humanwhocodes/config-array@npm:0.13.0" + dependencies: + "@humanwhocodes/object-schema": "npm:^2.0.3" + debug: "npm:^4.3.1" + minimatch: "npm:^3.0.5" + checksum: 10c0/205c99e756b759f92e1f44a3dc6292b37db199beacba8f26c2165d4051fe73a4ae52fdcfd08ffa93e7e5cb63da7c88648f0e84e197d154bbbbe137b2e0dd332e + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^2.0.3": + version: 2.0.3 + resolution: "@humanwhocodes/object-schema@npm:2.0.3" + checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": + version: 0.4.3 + resolution: "@humanwhocodes/retry@npm:0.4.3" + checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42 + languageName: node + linkType: hard + +"@inquirer/ansi@npm:^2.0.8": + version: 2.0.8 + resolution: "@inquirer/ansi@npm:2.0.8" + checksum: 10c0/2149a358f6227260815aac389bb0b5aedecc54452ad9c40e8aedcec07e0df91a046771571617d0734d074450637f5edde38752e17e79ede0d2bf657413acf3cb + languageName: node + linkType: hard + +"@inquirer/checkbox@npm:^5.2.5": + version: 5.2.5 + resolution: "@inquirer/checkbox@npm:5.2.5" + dependencies: + "@inquirer/ansi": "npm:^2.0.8" + "@inquirer/core": "npm:^12.0.3" + "@inquirer/figures": "npm:^2.0.9" + "@inquirer/type": "npm:4.1.1" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/d427ef80cda8f955b215e96d1543514311401eba65d7d0643ccca8f1c66f0ff96505f277c19c39110a890b04de66e2078af24df5df54679fdbf859717b8d0a6c + languageName: node + linkType: hard + +"@inquirer/confirm@npm:^6.3.2": + version: 6.3.2 + resolution: "@inquirer/confirm@npm:6.3.2" + dependencies: + "@inquirer/core": "npm:^12.0.3" + "@inquirer/type": "npm:4.1.1" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/5ed7d94b6d2148f9e71130a6130c4f2f821791ffc1edaac98d2821a185279e1020dbdca9eecb80116fa967f87e57052f3a67fcee1c28ec4ad090cba04f26fcc9 + languageName: node + linkType: hard + +"@inquirer/core@npm:^12.0.3": + version: 12.0.3 + resolution: "@inquirer/core@npm:12.0.3" + dependencies: + "@inquirer/ansi": "npm:^2.0.8" + "@inquirer/figures": "npm:^2.0.9" + "@inquirer/type": "npm:4.1.1" + cli-width: "npm:^4.1.0" + fast-wrap-ansi: "npm:^0.2.0" + mute-stream: "npm:^3.0.0" + signal-exit: "npm:^4.1.0" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/df323f8abb84d5ab8fd290ff2401067a107e22d7172b014068fcba23000838e0c102e7858e09afc58a5d8755dd4a50fafa66d03fd4921d60ec588cb41c61f8c1 + languageName: node + linkType: hard + +"@inquirer/editor@npm:^5.3.3": + version: 5.3.3 + resolution: "@inquirer/editor@npm:5.3.3" + dependencies: + "@inquirer/core": "npm:^12.0.3" + "@inquirer/external-editor": "npm:^3.0.5" + "@inquirer/type": "npm:4.1.1" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/9b1b1d3de6bf5f8f95616b723908cfde1a05a201126e9fcabb1b04b9baa1077ca3ca9a7a82c6a7e8831d4226fae362f7fccbc70fca3f88b5ccd6dd8fdae81a84 + languageName: node + linkType: hard + +"@inquirer/expand@npm:^5.1.5": + version: 5.1.5 + resolution: "@inquirer/expand@npm:5.1.5" + dependencies: + "@inquirer/core": "npm:^12.0.3" + "@inquirer/type": "npm:4.1.1" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/30791746f2f7ba061daccb2f601d293442b1d3f6b30436bd3b3f47ed2ffcae40b1cd178e6e575237f14e85a9e2e48ca884d7c4d316ae0cfd9d2c1007b8761613 + languageName: node + linkType: hard + +"@inquirer/external-editor@npm:^3.0.5": + version: 3.0.5 + resolution: "@inquirer/external-editor@npm:3.0.5" + dependencies: + chardet: "npm:^2.1.1" + iconv-lite: "npm:^0.7.2" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/66ad34d4d6d6b8e1e26691b32a67309b066b74ed7eb5f0b8b8d87e20d095316c7f6cf9bcae1fa3e85ad655d4741b713bbd6dce355413ffb4bac2b3a927fa0a82 + languageName: node + linkType: hard + +"@inquirer/figures@npm:^2.0.9": + version: 2.0.9 + resolution: "@inquirer/figures@npm:2.0.9" + checksum: 10c0/24198eb05c7ba32cf5b2eeee0a641b708fcd23f78ac6c568d18858191a40aa456e1626c52e088df1882ebe2e34c0f4cd08c78ca3c506429d4032f0a8833230a2 + languageName: node + linkType: hard + +"@inquirer/input@npm:^5.1.6": + version: 5.1.6 + resolution: "@inquirer/input@npm:5.1.6" + dependencies: + "@inquirer/core": "npm:^12.0.3" + "@inquirer/type": "npm:4.1.1" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/aaf2a5db5e4ce9d45905ec4006d8772e49785682fa4cd0be66fe8324eaaffc77b9ef47ad5656d617c90be2f2a395c10e3a22e65f4b20ed09a0b5453161fa6125 + languageName: node + linkType: hard + +"@inquirer/number@npm:^4.2.3": + version: 4.2.3 + resolution: "@inquirer/number@npm:4.2.3" + dependencies: + "@inquirer/core": "npm:^12.0.3" + "@inquirer/type": "npm:4.1.1" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/912017dabde45b1150e8c7746471e19e728ea73cf9229e7d84e4d4d0462743e95c5f70d166f3b2f148af0984de3cd769376343b9f4c021a19c9cf47a99b3af88 + languageName: node + linkType: hard + +"@inquirer/password@npm:^5.2.2": + version: 5.2.2 + resolution: "@inquirer/password@npm:5.2.2" + dependencies: + "@inquirer/ansi": "npm:^2.0.8" + "@inquirer/core": "npm:^12.0.3" + "@inquirer/type": "npm:4.1.1" + peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": @@ -2701,7 +3290,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.13, @jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.13 resolution: "@jridgewell/gen-mapping@npm:0.3.13" dependencies: @@ -2738,7 +3327,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.6.0-beta.0": +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5, @jridgewell/sourcemap-codec@npm:^1.6.0-beta.0": version: 1.6.0 resolution: "@jridgewell/sourcemap-codec@npm:1.6.0" checksum: 10c0/b5be700e45a775f218589c3466c4ffea630582b4988657652da464e5ab8a7d18bf928ee4fd2363fb346ede4bea9c6ff0bae05a538358c4565ece6199531b5f72 @@ -3012,6 +3601,23 @@ __metadata: languageName: node linkType: hard +"@react-native/assets-registry@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/assets-registry@npm:0.86.3" + checksum: 10c0/7971ecc2f7ca8037ed9ae2eb36fd0d9c2f7abb08a14e4a6b79f92d5047c232a963001f516a859e284546cd406dd3dc35bb6d2f6a01a03552b790a2586507df54 + languageName: node + linkType: hard + +"@react-native/babel-plugin-codegen@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/babel-plugin-codegen@npm:0.86.3" + dependencies: + "@babel/traverse": "npm:^7.29.0" + "@react-native/codegen": "npm:0.86.3" + checksum: 10c0/e381c2769e05308d85a5705e803387de5a61726c9dd36c48e84e916e790489f65fb8cb0024b257fca54146a03ef62ee96ef14391ea3370f8db77d59b204cb8d2 + languageName: node + linkType: hard + "@react-native/babel-plugin-codegen@npm:0.87.1": version: 0.87.1 resolution: "@react-native/babel-plugin-codegen@npm:0.87.1" @@ -3065,6 +3671,23 @@ __metadata: languageName: node linkType: hard +"@react-native/codegen@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/codegen@npm:0.86.3" + dependencies: + "@babel/core": "npm:^7.25.2" + "@babel/parser": "npm:^7.29.0" + hermes-parser: "npm:0.36.0" + invariant: "npm:^2.2.4" + nullthrows: "npm:^1.1.1" + tinyglobby: "npm:^0.2.15" + yargs: "npm:^17.6.2" + peerDependencies: + "@babel/core": "*" + checksum: 10c0/2dc1f49b342d009c2efd56d6d2839fdffac4afefba2e0f2159c8491ce48aef9eb60a0cec2fa88569f956eabd6915f47a5b27ad1cf43463a55e67b213edb84fe7 + languageName: node + linkType: hard + "@react-native/codegen@npm:0.87.1": version: 0.87.1 resolution: "@react-native/codegen@npm:0.87.1" @@ -3082,6 +3705,29 @@ __metadata: languageName: node linkType: hard +"@react-native/community-cli-plugin@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/community-cli-plugin@npm:0.86.3" + dependencies: + "@react-native/dev-middleware": "npm:0.86.3" + debug: "npm:^4.4.0" + invariant: "npm:^2.2.4" + metro: "npm:^0.84.3" + metro-config: "npm:^0.84.3" + metro-core: "npm:^0.84.3" + semver: "npm:^7.1.3" + peerDependencies: + "@react-native-community/cli": "*" + "@react-native/metro-config": 0.86.3 + peerDependenciesMeta: + "@react-native-community/cli": + optional: true + "@react-native/metro-config": + optional: true + checksum: 10c0/3fe9b5eef5e35a3c89f5659f9fd7c4429844c82c442f252d03195d60db67515a81deb2633711b8b4070cd479685e7dc6d62c4d2a7c4ef130b4ae17e2a00bc22f + languageName: node + linkType: hard + "@react-native/community-cli-plugin@npm:0.87.1": version: 0.87.1 resolution: "@react-native/community-cli-plugin@npm:0.87.1" @@ -3104,6 +3750,13 @@ __metadata: languageName: node linkType: hard +"@react-native/debugger-frontend@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/debugger-frontend@npm:0.86.3" + checksum: 10c0/377e3cb20097d6f298513f2ab4a98581c212cf7b54e50df85384bc5e6ae73a70f97d4e27047658abe60f39d3ab533e8904033678be732aff52a66355c7c8101d + languageName: node + linkType: hard + "@react-native/debugger-frontend@npm:0.87.1": version: 0.87.1 resolution: "@react-native/debugger-frontend@npm:0.87.1" @@ -3111,6 +3764,17 @@ __metadata: languageName: node linkType: hard +"@react-native/debugger-shell@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/debugger-shell@npm:0.86.3" + dependencies: + cross-spawn: "npm:^7.0.6" + debug: "npm:^4.4.0" + fb-dotslash: "npm:0.5.8" + checksum: 10c0/f6c0c7f15e9f9aed247d96be3bca5768f94a65cace549b62bf899c72e0aaff5a564b7898f3f63dc5e987728d4b73db2f786c4373e64272b029a43fef64153395 + languageName: node + linkType: hard + "@react-native/debugger-shell@npm:0.87.1": version: 0.87.1 resolution: "@react-native/debugger-shell@npm:0.87.1" @@ -3122,6 +3786,26 @@ __metadata: languageName: node linkType: hard +"@react-native/dev-middleware@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/dev-middleware@npm:0.86.3" + dependencies: + "@isaacs/ttlcache": "npm:^1.4.1" + "@react-native/debugger-frontend": "npm:0.86.3" + "@react-native/debugger-shell": "npm:0.86.3" + chrome-launcher: "npm:^0.15.2" + chromium-edge-launcher: "npm:^0.3.0" + connect: "npm:^3.6.5" + debug: "npm:^4.4.0" + invariant: "npm:^2.2.4" + nullthrows: "npm:^1.1.1" + open: "npm:^7.0.3" + serve-static: "npm:^1.16.2" + ws: "npm:^7.5.10" + checksum: 10c0/d313ed01d6e8e7ddff84fee8285a23138863486af02466fb7431891928cab3c51d90859ac883f64cd25051b90bba609990224e9f8d31e8be474f8355deec631d + languageName: node + linkType: hard + "@react-native/dev-middleware@npm:0.87.1": version: 0.87.1 resolution: "@react-native/dev-middleware@npm:0.87.1" @@ -3172,6 +3856,13 @@ __metadata: languageName: node linkType: hard +"@react-native/gradle-plugin@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/gradle-plugin@npm:0.86.3" + checksum: 10c0/ebbf2959e99990e97eb16892e6e9b7d9115b8710ce7759a33e7fe3b58610e451841ef4fa58b4820230680dd9af4cee6a39916952f2dfc5463396a4aad80f88f6 + languageName: node + linkType: hard + "@react-native/gradle-plugin@npm:0.87.1": version: 0.87.1 resolution: "@react-native/gradle-plugin@npm:0.87.1" @@ -3179,6 +3870,13 @@ __metadata: languageName: node linkType: hard +"@react-native/js-polyfills@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/js-polyfills@npm:0.86.3" + checksum: 10c0/8b1fca9f5405cb556d28afb09fc6aa6f3117c1e550269ece8b4f8c61e9f13d278fc92d8d2e055663d5cdda9e7896be8761b3beb420c25fdaffec00e3540cd7b8 + languageName: node + linkType: hard + "@react-native/js-polyfills@npm:0.87.1": version: 0.87.1 resolution: "@react-native/js-polyfills@npm:0.87.1" @@ -3212,6 +3910,13 @@ __metadata: languageName: node linkType: hard +"@react-native/normalize-colors@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/normalize-colors@npm:0.86.3" + checksum: 10c0/33893681bdb3235d35dcb9f2fff5e1b2b0996be08c3cef24afed32c3a931298349ad5cbd33c3bb7fbf506f735d3e37995684d26ba9241795bbd3e709bd8d3165 + languageName: node + linkType: hard + "@react-native/normalize-colors@npm:0.87.1": version: 0.87.1 resolution: "@react-native/normalize-colors@npm:0.87.1" @@ -3226,6 +3931,23 @@ __metadata: languageName: node linkType: hard +"@react-native/virtualized-lists@npm:0.86.3": + version: 0.86.3 + resolution: "@react-native/virtualized-lists@npm:0.86.3" + dependencies: + invariant: "npm:^2.2.4" + nullthrows: "npm:^1.1.1" + peerDependencies: + "@types/react": ^19.2.0 + react: "*" + react-native: 0.86.3 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/eee86f802cda4e95dc414ff27f7283a505e19d58d2f00d1a577c0d6b33b3d25439d239ea3c24033dd5820cebf970162f458c710695991bfe5794b9f8f1129159 + languageName: node + linkType: hard + "@react-native/virtualized-lists@npm:0.87.1": version: 0.87.1 resolution: "@react-native/virtualized-lists@npm:0.87.1" @@ -3738,7 +4460,7 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.2.0": +"@ungap/structured-clone@npm:^1.2.0, @ungap/structured-clone@npm:^1.3.0": version: 1.4.0 resolution: "@ungap/structured-clone@npm:1.4.0" checksum: 10c0/be74a389850d02901c836c07f10c1070d7604dab4070ba3c4b77c91665b90b4175d9f186189a02a399cf054fc051d3251418238564a4491d0164969e05c802a2 @@ -3752,6 +4474,20 @@ __metadata: languageName: node linkType: hard +"@xmldom/xmldom@npm:^0.8.8": + version: 0.8.15 + resolution: "@xmldom/xmldom@npm:0.8.15" + checksum: 10c0/59d09b85824b684fba5a0a224d5b43abea1a0d745e8d8b8136a7013e996eb6da122fdbb3deb32ed1621923a10e1937b1f7917cea43481d9d5b976e8c1ff836c1 + languageName: node + linkType: hard + +"@xmldom/xmldom@npm:^0.9.10": + version: 0.9.12 + resolution: "@xmldom/xmldom@npm:0.9.12" + checksum: 10c0/0a9ef38e203213717dde8d16c62743c26c37eb4195aeb4f286550a0aec2145c063a6c3633f253c29f75202f922d7c961d1acaad4dd93e5db1ef05c813354d178 + languageName: node + linkType: hard + "abbrev@npm:^5.0.0": version: 5.0.0 resolution: "abbrev@npm:5.0.0" @@ -3759,17 +4495,16 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^2.0.0": - version: 2.0.0 - resolution: "accepts@npm:2.0.0" +"abort-controller@npm:^3.0.0": + version: 3.0.0 + resolution: "abort-controller@npm:3.0.0" dependencies: - mime-types: "npm:^3.0.0" - negotiator: "npm:^1.0.0" - checksum: 10c0/98374742097e140891546076215f90c32644feacf652db48412329de4c2a529178a81aa500fbb13dd3e6cbf6e68d829037b123ac037fc9a08bcec4b87b358eef + event-target-shim: "npm:^5.0.0" + checksum: 10c0/90ccc50f010250152509a344eb2e71977fbf8db0ab8f1061197e3275ddf6c61a41a6edfd7b9409c664513131dd96e962065415325ef23efa5db931b382d24ca5 languageName: node linkType: hard -"accepts@npm:~1.3.8": +"accepts@npm:^1.3.8, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -3779,6 +4514,16 @@ __metadata: languageName: node linkType: hard +"accepts@npm:^2.0.0": + version: 2.0.0 + resolution: "accepts@npm:2.0.0" + dependencies: + mime-types: "npm:^3.0.0" + negotiator: "npm:^1.0.0" + checksum: 10c0/98374742097e140891546076215f90c32644feacf652db48412329de4c2a529178a81aa500fbb13dd3e6cbf6e68d829037b123ac037fc9a08bcec4b87b358eef + languageName: node + linkType: hard + "acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" @@ -3813,6 +4558,15 @@ __metadata: languageName: node linkType: hard +"agent-cli-detector@npm:0.1.7": + version: 0.1.7 + resolution: "agent-cli-detector@npm:0.1.7" + bin: + agent-cli-detector: dist/cli.js + checksum: 10c0/4ff016e5fad2d96a0c53db9fd75c2359bb005a672969e8e6e7bce5c910e94107c226cbcba1303409d1da3a1cdf8f22290e63049705bb530823cce4699d39fc1d + languageName: node + linkType: hard + "ajv@npm:^6.12.4, ajv@npm:^6.14.0": version: 6.15.0 resolution: "ajv@npm:6.15.0" @@ -3885,7 +4639,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^3.2.0": +"ansi-styles@npm:^3.2.0, ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" dependencies: @@ -3941,6 +4695,13 @@ __metadata: languageName: node linkType: hard +"arg@npm:^5.0.2": + version: 5.0.2 + resolution: "arg@npm:5.0.2" + checksum: 10c0/ccaf86f4e05d342af6666c569f844bec426595c567d32a8289715087825c2ca7edd8a3d204e4d2fb2aa4602e09a57d0c13ea8c9eea75aac3dbb4af5514e6800e + languageName: node + linkType: hard + "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10" @@ -4183,7 +4944,32 @@ __metadata: languageName: node linkType: hard -"babel-plugin-syntax-hermes-parser@npm:0.36.1": +"babel-plugin-react-compiler@npm:^1.0.0": + version: 1.0.0 + resolution: "babel-plugin-react-compiler@npm:1.0.0" + dependencies: + "@babel/types": "npm:^7.26.0" + checksum: 10c0/9406267ada8d7dbdfe8906b40ecadb816a5f4cee2922bee23f7729293b369624ee135b5a9b0f263851c263c9787522ac5d97016c9a2b82d1668300e42b18aff8 + languageName: node + linkType: hard + +"babel-plugin-react-native-web@npm:~0.21.0": + version: 0.21.3 + resolution: "babel-plugin-react-native-web@npm:0.21.3" + checksum: 10c0/854faf8ca5e7cf59c4e885e7c4c1dd5369e58d505a39e31d0f8eb04293b6e35bd4c49d178002ad9a06a0d070d9163393132e7f6431689d90e4090a6cc5e4a81f + languageName: node + linkType: hard + +"babel-plugin-syntax-hermes-parser@npm:0.36.0": + version: 0.36.0 + resolution: "babel-plugin-syntax-hermes-parser@npm:0.36.0" + dependencies: + hermes-parser: "npm:0.36.0" + checksum: 10c0/3c20d2b2595e890bf7bf14b48a1dc6eb2ad2625e04f942254f3676440e20489eb8266fba8f8077194d294dfb67552b6b969bb40b93c873b88fdc319528dc2606 + languageName: node + linkType: hard + +"babel-plugin-syntax-hermes-parser@npm:0.36.1, babel-plugin-syntax-hermes-parser@npm:^0.36.0": version: 0.36.1 resolution: "babel-plugin-syntax-hermes-parser@npm:0.36.1" dependencies: @@ -4221,8 +5007,70 @@ __metadata: "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" peerDependencies: - "@babel/core": ^7.0.0 || ^8.0.0-0 - checksum: 10c0/94a4f81cddf9b051045d08489e4fff7336292016301664c138cfa3d9ffe3fe2ba10a24ad6ae589fd95af1ac72ba0216e1653555c187e694d7b17be0c002bea10 + "@babel/core": ^7.0.0 || ^8.0.0-0 + checksum: 10c0/94a4f81cddf9b051045d08489e4fff7336292016301664c138cfa3d9ffe3fe2ba10a24ad6ae589fd95af1ac72ba0216e1653555c187e694d7b17be0c002bea10 + languageName: node + linkType: hard + +"babel-preset-expo@npm:~57.0.13": + version: 57.0.13 + resolution: "babel-preset-expo@npm:57.0.13" + dependencies: + "@babel/generator": "npm:^7.20.5" + "@babel/helper-module-imports": "npm:^7.25.9" + "@babel/plugin-proposal-decorators": "npm:^7.12.9" + "@babel/plugin-proposal-export-default-from": "npm:^7.24.7" + "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" + "@babel/plugin-syntax-export-default-from": "npm:^7.24.7" + "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" + "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" + "@babel/plugin-transform-async-generator-functions": "npm:^7.25.4" + "@babel/plugin-transform-async-to-generator": "npm:^7.24.7" + "@babel/plugin-transform-block-scoping": "npm:^7.25.0" + "@babel/plugin-transform-class-properties": "npm:^7.25.4" + "@babel/plugin-transform-class-static-block": "npm:^7.27.1" + "@babel/plugin-transform-classes": "npm:^7.25.4" + "@babel/plugin-transform-destructuring": "npm:^7.24.8" + "@babel/plugin-transform-export-namespace-from": "npm:^7.25.9" + "@babel/plugin-transform-flow-strip-types": "npm:^7.25.2" + "@babel/plugin-transform-for-of": "npm:^7.24.7" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.7" + "@babel/plugin-transform-object-rest-spread": "npm:^7.24.7" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7" + "@babel/plugin-transform-optional-chaining": "npm:^7.24.8" + "@babel/plugin-transform-parameters": "npm:^7.24.7" + "@babel/plugin-transform-private-methods": "npm:^7.24.7" + "@babel/plugin-transform-private-property-in-object": "npm:^7.24.7" + "@babel/plugin-transform-react-display-name": "npm:^7.24.7" + "@babel/plugin-transform-react-jsx": "npm:^7.28.6" + "@babel/plugin-transform-react-jsx-development": "npm:^7.27.1" + "@babel/plugin-transform-react-pure-annotations": "npm:^7.27.1" + "@babel/plugin-transform-runtime": "npm:^7.24.7" + "@babel/plugin-transform-typescript": "npm:^7.25.2" + "@babel/plugin-transform-unicode-regex": "npm:^7.24.7" + "@babel/preset-typescript": "npm:^7.23.0" + "@react-native/babel-plugin-codegen": "npm:0.86.3" + babel-plugin-react-compiler: "npm:^1.0.0" + babel-plugin-react-native-web: "npm:~0.21.0" + babel-plugin-syntax-hermes-parser: "npm:^0.36.0" + babel-plugin-transform-flow-enums: "npm:^0.0.2" + debug: "npm:^4.3.4" + peerDependencies: + "@babel/runtime": ^7.20.0 + expo: "*" + expo-widgets: ^57.0.21 + react-refresh: ">=0.14.0 <1.0.0" + peerDependenciesMeta: + "@babel/runtime": + optional: true + expo: + optional: true + expo-widgets: + optional: true + checksum: 10c0/a667996292102735876d8b0c6b0e8a3990a9c895415fbf0cc689daba7dbe1f688de6ad8ac54bb935e83350da3f23a663350d4c796ab4c5d6e7ba2c2db5188524 languageName: node linkType: hard @@ -4268,6 +5116,22 @@ __metadata: languageName: node linkType: hard +"baseline-browser-mapping@npm:^2.11.26": + version: 2.11.27 + resolution: "baseline-browser-mapping@npm:2.11.27" + bin: + baseline-browser-mapping: dist/cli.cjs + checksum: 10c0/4a06cfab5ad4f57633c0092340af41388f3fc71e6a91a3309942a23c60b65e9ec6f243edbd2f484d3d0ee40f5f33d974c8a85c9c207e104ea17ba429cfb4d3df + languageName: node + linkType: hard + +"big-integer@npm:1.6.x": + version: 1.6.52 + resolution: "big-integer@npm:1.6.52" + checksum: 10c0/9604224b4c2ab3c43c075d92da15863077a9f59e5d4205f4e7e76acd0cd47e8d469ec5e5dba8d9b32aa233951893b29329ca56ac80c20ce094b4a647a66abae0 + languageName: node + linkType: hard + "bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" @@ -4296,6 +5160,33 @@ __metadata: languageName: node linkType: hard +"bplist-creator@npm:0.1.0": + version: 0.1.0 + resolution: "bplist-creator@npm:0.1.0" + dependencies: + stream-buffers: "npm:2.2.x" + checksum: 10c0/86f5fe95f34abd369b381abf0f726e220ecebd60a3d932568ae94895ccf1989a87553e4aee9ab3cfb4f35e6f72319f52aa73028165eec82819ed39f15189d493 + languageName: node + linkType: hard + +"bplist-creator@npm:0.1.1": + version: 0.1.1 + resolution: "bplist-creator@npm:0.1.1" + dependencies: + stream-buffers: "npm:2.2.x" + checksum: 10c0/427ec37263ce0e8c68a83f595fc9889a9cbf2e6fda2de18e1f8ef7f0c6ce68c0cdbb7c9c1f3bb3f2d217407af8cffbdf254bf0f71c99f2186175d07752f08a47 + languageName: node + linkType: hard + +"bplist-parser@npm:0.3.2, bplist-parser@npm:^0.3.1": + version: 0.3.2 + resolution: "bplist-parser@npm:0.3.2" + dependencies: + big-integer: "npm:1.6.x" + checksum: 10c0/4dc307c11d2511a01255e87e370d4ab6f1962b35fdc27605fd4ce9a557a259c2dc9f87822617ddb1f7aa062a71e30ef20d6103329ac7ce235628f637fb0ed763 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.21 resolution: "brace-expansion@npm:1.1.21" @@ -4339,6 +5230,21 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.25.0": + version: 4.29.3 + resolution: "browserslist@npm:4.29.3" + dependencies: + baseline-browser-mapping: "npm:^2.11.26" + caniuse-lite: "npm:^1.0.30001813" + electron-to-chromium: "npm:^1.5.439" + node-releases: "npm:^2.0.57" + update-browserslist-db: "npm:^1.3.3" + bin: + browserslist: cli.js + checksum: 10c0/6e1a1fcae77369260e936fe63e7994105f04c6b7aea4f2139fdf3ecccfcb1eb24d4522c2828c6ed48ef71206a33f4346e11cf714c5aac0f7496cead06bb66bac + languageName: node + linkType: hard + "bs-logger@npm:^0.2.6": version: 0.2.6 resolution: "bs-logger@npm:0.2.6" @@ -4414,6 +5320,18 @@ __metadata: languageName: unknown linkType: soft +"bugsee-example-expo@workspace:examples/expo": + version: 0.0.0-use.local + resolution: "bugsee-example-expo@workspace:examples/expo" + dependencies: + "@babel/core": "npm:^7.25.2" + "@bugsee/react-native": "workspace:*" + expo: "npm:~57.0.26" + react: "npm:19.2.3" + react-native: "npm:0.86.3" + languageName: unknown + linkType: soft + "bugsee-react-native-workspace@workspace:.": version: 0.0.0-use.local resolution: "bugsee-react-native-workspace@workspace:." @@ -4516,7 +5434,25 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.0": +"caniuse-lite@npm:^1.0.30001813": + version: 1.0.30001814 + resolution: "caniuse-lite@npm:1.0.30001814" + checksum: 10c0/c1b93b8cd43528241e1a97d0a683ad0cbbf825a2d5a6a021ac1abaee966a861095d2bbffa9903638ee590534a243b024f18d7440e514d0f9c2bb90cfcf4651fb + languageName: node + linkType: hard + +"chalk@npm:^2.0.1, chalk@npm:^2.4.2": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: "npm:^3.2.1" + escape-string-regexp: "npm:^1.0.5" + supports-color: "npm:^5.3.0" + checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 + languageName: node + linkType: hard + +"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -4581,7 +5517,14 @@ __metadata: languageName: node linkType: hard -"ci-info@npm:^3.2.0": +"ci-info@npm:^2.0.0": + version: 2.0.0 + resolution: "ci-info@npm:2.0.0" + checksum: 10c0/8c5fa3830a2bcee2b53c2e5018226f0141db9ec9f7b1e27a5c57db5512332cde8a0beb769bcbaf0d8775a78afbf2bb841928feca4ea6219638a5b088f9884b46 + languageName: node + linkType: hard + +"ci-info@npm:^3.2.0, ci-info@npm:^3.3.0": version: 3.9.0 resolution: "ci-info@npm:3.9.0" checksum: 10c0/6f0109e36e111684291d46123d491bc4e7b7a1934c3a20dea28cba89f1d4a03acd892f5f6a81ed3855c38647e285a150e3c9ba062e38943bef57fee6c1554c3a @@ -4595,6 +5538,15 @@ __metadata: languageName: node linkType: hard +"cli-cursor@npm:^2.1.0": + version: 2.1.0 + resolution: "cli-cursor@npm:2.1.0" + dependencies: + restore-cursor: "npm:^2.0.0" + checksum: 10c0/09ee6d8b5b818d840bf80ec9561eaf696672197d3a02a7daee2def96d5f52ce6e0bbe7afca754ccf14f04830b5a1b4556273e983507d5029f95bba3016618eda + languageName: node + linkType: hard + "cli-cursor@npm:^3.1.0": version: 3.1.0 resolution: "cli-cursor@npm:3.1.0" @@ -4604,7 +5556,7 @@ __metadata: languageName: node linkType: hard -"cli-spinners@npm:^2.5.0": +"cli-spinners@npm:^2.0.0, cli-spinners@npm:^2.5.0": version: 2.9.2 resolution: "cli-spinners@npm:2.9.2" checksum: 10c0/907a1c227ddf0d7a101e7ab8b300affc742ead4b4ebe920a5bf1bc6d45dce2958fcd195eb28fa25275062fe6fa9b109b93b63bc8033396ed3bcb50297008b3a3 @@ -4721,6 +5673,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^7.2.0": + version: 7.2.0 + resolution: "commander@npm:7.2.0" + checksum: 10c0/8d690ff13b0356df7e0ebbe6c59b4712f754f4b724d4f473d3cc5b3fdcf978e3a5dc3078717858a2ceb50b0f84d0660a7f22a96cdc50fb877d0c9bb31593d23a + languageName: node + linkType: hard + "commander@npm:^9.4.1": version: 9.5.0 resolution: "commander@npm:9.5.0" @@ -4744,7 +5703,7 @@ __metadata: languageName: node linkType: hard -"compression@npm:^1.7.1": +"compression@npm:^1.7.1, compression@npm:^1.7.4": version: 1.8.2 resolution: "compression@npm:1.8.2" dependencies: @@ -4767,7 +5726,7 @@ __metadata: languageName: node linkType: hard -"connect@npm:^3.6.5": +"connect@npm:^3.6.5, connect@npm:^3.7.0": version: 3.7.0 resolution: "connect@npm:3.7.0" dependencies: @@ -4910,7 +5869,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.4.0, debug@npm:^4.4.3": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -4922,6 +5881,15 @@ __metadata: languageName: node linkType: hard +"debug@npm:^3.1.0": + version: 3.2.7 + resolution: "debug@npm:3.2.7" + dependencies: + ms: "npm:^2.1.1" + checksum: 10c0/37d96ae42cbc71c14844d2ae3ba55adf462ec89fd3a999459dec3833944cd999af6007ff29c780f1c61153bcaaf2c842d1e4ce1ec621e4fc4923244942e4a02a + languageName: node + linkType: hard + "decamelize@npm:^1.2.0": version: 1.2.0 resolution: "decamelize@npm:1.2.0" @@ -4948,7 +5916,7 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.0": +"deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.0, deepmerge@npm:^4.3.1": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" checksum: 10c0/e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044 @@ -5010,6 +5978,13 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^2.0.3": + version: 2.1.2 + resolution: "detect-libc@npm:2.1.2" + checksum: 10c0/acc675c29a5649fa1fb6e255f993b8ee829e510b6b56b0910666949c80c364738833417d0edb5f90e4e46be17228b0f2b66a010513984e18b15deeeac49369c4 + languageName: node + linkType: hard + "detect-newline@npm:^3.0.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -5038,6 +6013,13 @@ __metadata: languageName: node linkType: hard +"dnssd-advertise@npm:^1.1.4": + version: 1.1.6 + resolution: "dnssd-advertise@npm:1.1.6" + checksum: 10c0/6f0639a45b2d6ae7b285501b711c314893c46eb2966539674220abb7b9c9c7b00de7bf0cfcd4cad0413f0e614ac7e2399e70faeb8bf7b875d9dc7be67862e4a7 + languageName: node + linkType: hard + "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0" @@ -5081,6 +6063,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.439": + version: 1.5.444 + resolution: "electron-to-chromium@npm:1.5.444" + checksum: 10c0/ad8e61961707a2e95515c121e1f5059c8864c79f7d5612f64eb4065a468c93a83228afa41a1a8877ed762d323908c6189847468dcec9ee1b5276b123d8c08c23 + languageName: node + linkType: hard + "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -5700,6 +6689,13 @@ __metadata: languageName: node linkType: hard +"event-target-shim@npm:^5.0.0": + version: 5.0.1 + resolution: "event-target-shim@npm:5.0.1" + checksum: 10c0/0255d9f936215fd206156fd4caa9e8d35e62075d720dc7d847e89b417e5e62cf1ce6c9b4e0a1633a9256de0efefaf9f8d26924b1f3c8620cffb9db78e7d3076b + languageName: node + linkType: hard + "execa@npm:^5.0.0": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -5757,6 +6753,167 @@ __metadata: languageName: node linkType: hard +"expo-asset@npm:~57.0.18": + version: 57.0.18 + resolution: "expo-asset@npm:57.0.18" + dependencies: + "@expo/image-utils": "npm:^0.11.5" + expo-constants: "npm:~57.0.19" + peerDependencies: + expo: "*" + react: "*" + react-native: "*" + checksum: 10c0/b4c944ad85c5c0bc0bbd2888712ba30a3e582ff9c0d9a47dc4189bfac53beafdad1c5b0e10a8fd39aee587948fcf83a5ec31aa42b99263756a00a750e7c318a2 + languageName: node + linkType: hard + +"expo-constants@npm:~57.0.19, expo-constants@npm:~57.0.20": + version: 57.0.20 + resolution: "expo-constants@npm:57.0.20" + dependencies: + "@expo/env": "npm:~2.4.3" + peerDependencies: + expo: "*" + react-native: "*" + checksum: 10c0/5d719dd67b92e30f7ba67917cd83010438572e5475037f9a98f7aadec40a514f1417ce3b2c8ec8a4d9c01991fb98cac656eaf068cd598d49de1b9ef5ce834523 + languageName: node + linkType: hard + +"expo-file-system@npm:~57.0.7": + version: 57.0.7 + resolution: "expo-file-system@npm:57.0.7" + peerDependencies: + expo: "*" + react-native: "*" + checksum: 10c0/ca02903e7b918f2b73f9f009d13e2f3f2eda46b04d479af770385c463631feb843f6a742c34a75ad7e892862dfb4b4311fa0520d7599a9f01e478014b105d3b0 + languageName: node + linkType: hard + +"expo-font@npm:~57.0.4": + version: 57.0.4 + resolution: "expo-font@npm:57.0.4" + dependencies: + fontfaceobserver: "npm:^2.1.0" + peerDependencies: + expo: "*" + react: "*" + react-native: "*" + checksum: 10c0/b9e13197971c3a3b354e498315033e11d4a834de695637914273225a24fd7c88172b23ab7eb1dde88620dbe093b6958d361751d839b87d4bf09d9ad5ca2b0117 + languageName: node + linkType: hard + +"expo-keep-awake@npm:~57.0.2": + version: 57.0.2 + resolution: "expo-keep-awake@npm:57.0.2" + peerDependencies: + expo: "*" + react: "*" + checksum: 10c0/2e7cd81adea1c62f49f4e9ba76b606960969779222626abc90c6b4cd872c0e47c062eebb5e1688550676f55300677348252d9fe8a7c95d03e1320496a2c136ca + languageName: node + linkType: hard + +"expo-modules-autolinking@npm:~57.0.13": + version: 57.0.13 + resolution: "expo-modules-autolinking@npm:57.0.13" + dependencies: + "@expo/require-utils": "npm:^57.0.5" + "@expo/spawn-async": "npm:^1.8.0" + chalk: "npm:^4.1.0" + commander: "npm:^7.2.0" + bin: + expo-modules-autolinking: bin/expo-modules-autolinking.js + checksum: 10c0/cf6105f72c4f5545d8d8791aeda3210ad0281919bf67ea2efa8956a6191a377e1d87885b11969bd18c79d1200ed695b1e27f96743c564ebb3a2d0a0ac5de7bcb + languageName: node + linkType: hard + +"expo-modules-core@npm:~57.0.20": + version: 57.0.20 + resolution: "expo-modules-core@npm:57.0.20" + dependencies: + "@expo/expo-modules-macros-plugin": "npm:0.6.1" + expo-modules-jsi: "npm:~57.1.1" + invariant: "npm:^2.2.4" + peerDependencies: + react: "*" + react-native: "*" + react-native-worklets: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + peerDependenciesMeta: + react-native-worklets: + optional: true + checksum: 10c0/cb630d9db9a5d1f7d4f2c229a54238e3e52c52849ed2c064ac61f7d617d22d692ac1d61270f37e3c8c834dd628a56dd432ccb0edb73cf0c37c5b55aae379ef73 + languageName: node + linkType: hard + +"expo-modules-jsi@npm:~57.1.1": + version: 57.1.1 + resolution: "expo-modules-jsi@npm:57.1.1" + peerDependencies: + react-native: "*" + checksum: 10c0/48ba18200a38dd27c2035e2234ff182a03730764fa20c1be4957156b7d49f950beeb394dab52527c5951a3ea6669d6ce1adb40e384f9b18803e8bb00039b172a + languageName: node + linkType: hard + +"expo-server@npm:^57.0.3": + version: 57.0.3 + resolution: "expo-server@npm:57.0.3" + checksum: 10c0/541d9b319ba513df718868c87a8d57e30161c3879b7d5b43f308923290ce5ee349a1b3469901c2f382984b6595f4cf6beaee9d870f5eb874c45ddc0a42a13e56 + languageName: node + linkType: hard + +"expo@npm:~57.0.26": + version: 57.0.26 + resolution: "expo@npm:57.0.26" + dependencies: + "@babel/runtime": "npm:^7.20.0" + "@expo/cli": "npm:^57.0.27" + "@expo/config": "npm:~57.0.9" + "@expo/config-plugins": "npm:~57.0.9" + "@expo/devtools": "npm:~57.0.1" + "@expo/dom-webview": "npm:~57.0.1" + "@expo/fingerprint": "npm:^0.20.13" + "@expo/local-build-cache-provider": "npm:^57.0.8" + "@expo/log-box": "npm:^57.0.4" + "@expo/metro": "npm:~56.0.2" + "@expo/metro-config": "npm:~57.0.12" + "@ungap/structured-clone": "npm:^1.3.0" + babel-preset-expo: "npm:~57.0.13" + expo-asset: "npm:~57.0.18" + expo-constants: "npm:~57.0.20" + expo-file-system: "npm:~57.0.7" + expo-font: "npm:~57.0.4" + expo-keep-awake: "npm:~57.0.2" + expo-modules-autolinking: "npm:~57.0.13" + expo-modules-core: "npm:~57.0.20" + pretty-format: "npm:^29.7.0" + react-refresh: "npm:^0.14.2" + whatwg-url-minimum: "npm:^0.1.2" + peerDependencies: + "@expo/dom-webview": "*" + "@expo/metro-runtime": "*" + react: "*" + react-dom: "*" + react-native: "*" + react-native-web: "*" + react-native-webview: "*" + peerDependenciesMeta: + "@expo/dom-webview": + optional: true + "@expo/metro-runtime": + optional: true + react-dom: + optional: true + react-native-web: + optional: true + react-native-webview: + optional: true + bin: + expo: bin/cli + expo-modules-autolinking: bin/autolinking + fingerprint: bin/fingerprint + checksum: 10c0/8dbd41fe0d74b50b1238f642f9b3a6ef7725f031d2df524a92636dd473140448ab6751a4dfc1b3a75eb6806e8d36f37149c81c2c6dd8c0092b871d5f4a04f2ae + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.3 resolution: "exponential-backoff@npm:3.1.3" @@ -5874,7 +7031,7 @@ __metadata: languageName: node linkType: hard -"fb-watchman@npm:^2.0.0": +"fb-watchman@npm:^2.0.0, fb-watchman@npm:^2.0.2": version: 2.0.2 resolution: "fb-watchman@npm:2.0.2" dependencies: @@ -5895,6 +7052,13 @@ __metadata: languageName: node linkType: hard +"fetch-nodeshim@npm:^0.4.10": + version: 0.4.10 + resolution: "fetch-nodeshim@npm:0.4.10" + checksum: 10c0/73b840b5d1252e82c416b350526ff24f5aebf554bfe911c713a19fbe4ad1218fb4c488f95055362a132f5dd733679c929fbe6a65ee23339592290c4d107ade92 + languageName: node + linkType: hard + "figures@npm:^6.1.0": version: 6.1.0 resolution: "figures@npm:6.1.0" @@ -6018,6 +7182,13 @@ __metadata: languageName: node linkType: hard +"fontfaceobserver@npm:^2.1.0": + version: 2.3.0 + resolution: "fontfaceobserver@npm:2.3.0" + checksum: 10c0/9b539d5021757d3ed73c355bdb839296d6654de473a992aa98993ef46d951f0361545323de68f6d70c5334d7e3e9f409c1ae7a03c168b00cb0f6c5dea6c77bfa + languageName: node + linkType: hard + "for-each@npm:^0.3.3, for-each@npm:^0.3.5": version: 0.3.5 resolution: "for-each@npm:0.3.5" @@ -6189,6 +7360,13 @@ __metadata: languageName: node linkType: hard +"getenv@npm:^2.0.0": + version: 2.0.0 + resolution: "getenv@npm:2.0.0" + checksum: 10c0/397ff641dd70cd78e414430258651e9a2228d3c5553a8cf15ae7840f75d3f10dfcb83f668f84829e84ea665b0fce2f08a9eddda3c9dcd7faa2d3da1c182c1854 + languageName: node + linkType: hard + "glob-parent@npm:^5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -6207,6 +7385,17 @@ __metadata: languageName: node linkType: hard +"glob@npm:^13.0.0": + version: 13.0.6 + resolution: "glob@npm:13.0.6" + dependencies: + minimatch: "npm:^10.2.2" + minipass: "npm:^7.1.3" + path-scurry: "npm:^2.0.2" + checksum: 10c0/269c236f11a9b50357fe7a8c6aadac667e01deb5242b19c84975628f05f4438d8ee1354bb62c5d6c10f37fd59911b54d7799730633a2786660d8c69f1d18120a + languageName: node + linkType: hard + "glob@npm:^7.1.3, glob@npm:^7.1.4": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -6286,6 +7475,13 @@ __metadata: languageName: node linkType: hard +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 + languageName: node + linkType: hard + "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -6359,6 +7555,20 @@ __metadata: languageName: node linkType: hard +"hermes-estree@npm:0.35.0": + version: 0.35.0 + resolution: "hermes-estree@npm:0.35.0" + checksum: 10c0/a88c9dc63b8b3679b1aeb43e72e977597096c1bd7d59978c952f1d6df6d1a517c4a817c70b1b701854996b485adfa66c2fc7f80871029a7f0c04306f6717b59a + languageName: node + linkType: hard + +"hermes-estree@npm:0.36.0": + version: 0.36.0 + resolution: "hermes-estree@npm:0.36.0" + checksum: 10c0/fe27f57b0f8c3921e9dc48c517e25f4399609ca386353f90e04d3f859bacbee93184af80a6b930db5e981e8953a5c4083147556b21b19519917e131e7533b27c + languageName: node + linkType: hard + "hermes-estree@npm:0.36.1": version: 0.36.1 resolution: "hermes-estree@npm:0.36.1" @@ -6366,7 +7576,25 @@ __metadata: languageName: node linkType: hard -"hermes-parser@npm:0.36.1": +"hermes-parser@npm:0.35.0": + version: 0.35.0 + resolution: "hermes-parser@npm:0.35.0" + dependencies: + hermes-estree: "npm:0.35.0" + checksum: 10c0/49d98093a2094758db5b536627c6cf5146b140f66e63143acf471c62f1d3fd8bd6ae10a33f2372f72e3653deda5d4615c6dae89d01248849440916209901fc4a + languageName: node + linkType: hard + +"hermes-parser@npm:0.36.0": + version: 0.36.0 + resolution: "hermes-parser@npm:0.36.0" + dependencies: + hermes-estree: "npm:0.36.0" + checksum: 10c0/76e726366ac2ea91e9464853f439d582ddee9c07ccb84cac35297ce1a5d197bf96b84ab030423a22940b55a0fa5bb191bc0ebeebd95f8e34116900decdccdb86 + languageName: node + linkType: hard + +"hermes-parser@npm:0.36.1, hermes-parser@npm:^0.36.0": version: 0.36.1 resolution: "hermes-parser@npm:0.36.1" dependencies: @@ -6398,6 +7626,15 @@ __metadata: languageName: node linkType: hard +"hosted-git-info@npm:^7.0.0": + version: 7.0.2 + resolution: "hosted-git-info@npm:7.0.2" + dependencies: + lru-cache: "npm:^10.0.1" + checksum: 10c0/b19dbd92d3c0b4b0f1513cf79b0fc189f54d6af2129eeb201de2e9baaa711f1936929c848b866d9c8667a0f956f34bf4f07418c12be1ee9ca74fd9246335ca1f + languageName: node + linkType: hard + "html-escaper@npm:^2.0.0": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" @@ -6458,7 +7695,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.0.5, ignore@npm:^5.2.0": +"ignore@npm:^5.0.5, ignore@npm:^5.2.0, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 @@ -7435,6 +8672,13 @@ __metadata: languageName: node linkType: hard +"jimp-compact@npm:0.16.1": + version: 0.16.1 + resolution: "jimp-compact@npm:0.16.1" + checksum: 10c0/2d73bb927d840ce6dc093d089d770eddbb81472635ced7cad1d7c4545d8734aecf5bd3dedf7178a6cfab4d06c9d6cbbf59e5cb274ed99ca11cd4835a6374f16c + languageName: node + linkType: hard + "joi@npm:^17.2.1": version: 17.13.8 resolution: "joi@npm:17.13.8" @@ -7492,7 +8736,7 @@ __metadata: languageName: node linkType: hard -"jsc-safe-url@npm:^0.2.2": +"jsc-safe-url@npm:^0.2.2, jsc-safe-url@npm:^0.2.4": version: 0.2.4 resolution: "jsc-safe-url@npm:0.2.4" checksum: 10c0/429bd645f8a35938f08f5b01c282e5ef55ed8be30a9ca23517b7ca01dcbf84b4b0632042caceab50f8f5c0c1e76816fe3c74de3e59be84da7f89ae1503bd3c68 @@ -7608,6 +8852,15 @@ __metadata: languageName: node linkType: hard +"lan-network@npm:^0.2.1": + version: 0.2.1 + resolution: "lan-network@npm:0.2.1" + bin: + lan-network: dist/lan-network-cli.js + checksum: 10c0/14995644bab174cde57e41c80ed828a52d6b788f8701b8a8347c536f3ecade3e71bd33b98091484b27a1df1e35b7f6f1921ac59521bf905b5dd06ab123e82e94 + languageName: node + linkType: hard + "launch-editor@npm:^2.9.1": version: 2.14.1 resolution: "launch-editor@npm:2.14.1" @@ -7645,6 +8898,126 @@ __metadata: languageName: node linkType: hard +"lightningcss-android-arm64@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-android-arm64@npm:1.33.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-arm64@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-darwin-arm64@npm:1.33.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-x64@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-darwin-x64@npm:1.33.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-freebsd-x64@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-freebsd-x64@npm:1.33.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-linux-arm-gnueabihf@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.33.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"lightningcss-linux-arm64-gnu@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-linux-arm64-gnu@npm:1.33.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-arm64-musl@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-linux-arm64-musl@npm:1.33.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-linux-x64-gnu@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-linux-x64-gnu@npm:1.33.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-x64-musl@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-linux-x64-musl@npm:1.33.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-win32-arm64-msvc@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-win32-arm64-msvc@npm:1.33.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-win32-x64-msvc@npm:1.33.0": + version: 1.33.0 + resolution: "lightningcss-win32-x64-msvc@npm:1.33.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"lightningcss@npm:^1.30.1": + version: 1.33.0 + resolution: "lightningcss@npm:1.33.0" + dependencies: + detect-libc: "npm:^2.0.3" + lightningcss-android-arm64: "npm:1.33.0" + lightningcss-darwin-arm64: "npm:1.33.0" + lightningcss-darwin-x64: "npm:1.33.0" + lightningcss-freebsd-x64: "npm:1.33.0" + lightningcss-linux-arm-gnueabihf: "npm:1.33.0" + lightningcss-linux-arm64-gnu: "npm:1.33.0" + lightningcss-linux-arm64-musl: "npm:1.33.0" + lightningcss-linux-x64-gnu: "npm:1.33.0" + lightningcss-linux-x64-musl: "npm:1.33.0" + lightningcss-win32-arm64-msvc: "npm:1.33.0" + lightningcss-win32-x64-msvc: "npm:1.33.0" + dependenciesMeta: + lightningcss-android-arm64: + optional: true + lightningcss-darwin-arm64: + optional: true + lightningcss-darwin-x64: + optional: true + lightningcss-freebsd-x64: + optional: true + lightningcss-linux-arm-gnueabihf: + optional: true + lightningcss-linux-arm64-gnu: + optional: true + lightningcss-linux-arm64-musl: + optional: true + lightningcss-linux-x64-gnu: + optional: true + lightningcss-linux-x64-musl: + optional: true + lightningcss-win32-arm64-msvc: + optional: true + lightningcss-win32-x64-msvc: + optional: true + checksum: 10c0/ce1f8279fbae636dbf37fa6e7385d5f98ed881d72af3362f24afbd4685e19c1fcdfecf17e5dd77f2ebee3d0c23ade276230d85842d07292229a2cffba8ff20a3 + languageName: node + linkType: hard + "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" @@ -7712,6 +9085,15 @@ __metadata: languageName: node linkType: hard +"log-symbols@npm:^2.2.0": + version: 2.2.0 + resolution: "log-symbols@npm:2.2.0" + dependencies: + chalk: "npm:^2.0.1" + checksum: 10c0/574eb4205f54f0605021aa67ebb372c30ca64e8ddd439efeb8507af83c776dce789e83614e80059014d9e48dcc94c4b60cef2e85f0dc944eea27c799cec62353 + languageName: node + linkType: hard + "log-symbols@npm:^4.1.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" @@ -7746,6 +9128,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^10.0.1": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb + languageName: node + linkType: hard + "lru-cache@npm:^11.0.0": version: 11.5.2 resolution: "lru-cache@npm:11.5.2" @@ -7829,6 +9218,32 @@ __metadata: languageName: node linkType: hard +"metro-babel-transformer@npm:0.84.5": + version: 0.84.5 + resolution: "metro-babel-transformer@npm:0.84.5" + dependencies: + "@babel/core": "npm:^7.25.2" + flow-enums-runtime: "npm:^0.0.6" + hermes-parser: "npm:0.35.0" + metro-cache-key: "npm:0.84.5" + nullthrows: "npm:^1.1.1" + checksum: 10c0/d105413dbe7887f05bf46b2c187e17abc7432bbabb6ac50caff2bf7460e5fa029654dd7478d502eb39987e0a1a0ec1d7660f1786cea53c7738da909ac319c59d + languageName: node + linkType: hard + +"metro-babel-transformer@npm:0.84.6": + version: 0.84.6 + resolution: "metro-babel-transformer@npm:0.84.6" + dependencies: + "@babel/core": "npm:^7.25.2" + flow-enums-runtime: "npm:^0.0.6" + hermes-parser: "npm:0.35.0" + metro-cache-key: "npm:0.84.6" + nullthrows: "npm:^1.1.1" + checksum: 10c0/4bcdd9f695935384328e8be733328357d8e7a59ceb27d88643c419cc4c68dc09f156766817d031659e1e2509179f9869a9af173c84414f1db37bc301ebaaa17b + languageName: node + linkType: hard + "metro-babel-transformer@npm:0.87.1": version: 0.87.1 resolution: "metro-babel-transformer@npm:0.87.1" @@ -7842,6 +9257,24 @@ __metadata: languageName: node linkType: hard +"metro-cache-key@npm:0.84.5": + version: 0.84.5 + resolution: "metro-cache-key@npm:0.84.5" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + checksum: 10c0/2e3507b31b2d21f833a5cf78fadbb3d7042921212c418ffc870aeef05759d954e20d347e9b2c1953847ca43c64e85cedfa7e0e2b7ad5dcb685826b2dc6346bb9 + languageName: node + linkType: hard + +"metro-cache-key@npm:0.84.6": + version: 0.84.6 + resolution: "metro-cache-key@npm:0.84.6" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + checksum: 10c0/53be969296377c811e27730a150022c14fac2e4766993c030675868795ae5014b7381f576b1977155a9a7d5c1563f801e28d8f0d5403e313c0ab11882b23b976 + languageName: node + linkType: hard + "metro-cache-key@npm:0.87.1": version: 0.87.1 resolution: "metro-cache-key@npm:0.87.1" @@ -7851,6 +9284,30 @@ __metadata: languageName: node linkType: hard +"metro-cache@npm:0.84.5": + version: 0.84.5 + resolution: "metro-cache@npm:0.84.5" + dependencies: + exponential-backoff: "npm:^3.1.1" + flow-enums-runtime: "npm:^0.0.6" + https-proxy-agent: "npm:^7.0.5" + metro-core: "npm:0.84.5" + checksum: 10c0/fa590e17d8e16274c09b874e34df5d6cbf8912aec329d563a1d751a4ebc8c8cfa7c6133df1a240be1e2ebdada1f1d65e30ea97dbf58549fbeec81d632c073be8 + languageName: node + linkType: hard + +"metro-cache@npm:0.84.6": + version: 0.84.6 + resolution: "metro-cache@npm:0.84.6" + dependencies: + exponential-backoff: "npm:^3.1.1" + flow-enums-runtime: "npm:^0.0.6" + https-proxy-agent: "npm:^7.0.5" + metro-core: "npm:0.84.6" + checksum: 10c0/388b2535e8e7833dfbbcedd89a06c12e9ca22a1dd4fb1717f5c680112fbed1a6054869d2f599c5661c146327403c7056f453447da3b83bdd125f3525358970fc + languageName: node + linkType: hard + "metro-cache@npm:0.87.1": version: 0.87.1 resolution: "metro-cache@npm:0.87.1" @@ -7863,6 +9320,38 @@ __metadata: languageName: node linkType: hard +"metro-config@npm:0.84.5": + version: 0.84.5 + resolution: "metro-config@npm:0.84.5" + dependencies: + connect: "npm:^3.6.5" + flow-enums-runtime: "npm:^0.0.6" + jest-validate: "npm:^29.7.0" + metro: "npm:0.84.5" + metro-cache: "npm:0.84.5" + metro-core: "npm:0.84.5" + metro-runtime: "npm:0.84.5" + yaml: "npm:^2.6.1" + checksum: 10c0/ba946982432e442a8187ca955a65dca18903c087e6f279433a9173a9283b72e32bb2bdd2ca0ccda491e5c068b9378725c6a6ba73dbe3e180cf0f089cd5523bdc + languageName: node + linkType: hard + +"metro-config@npm:0.84.6, metro-config@npm:^0.84.3": + version: 0.84.6 + resolution: "metro-config@npm:0.84.6" + dependencies: + connect: "npm:^3.6.5" + flow-enums-runtime: "npm:^0.0.6" + jest-validate: "npm:^29.7.0" + metro: "npm:0.84.6" + metro-cache: "npm:0.84.6" + metro-core: "npm:0.84.6" + metro-runtime: "npm:0.84.6" + yaml: "npm:^2.6.1" + checksum: 10c0/8c8dd3f738743fbdb5aeda75e3b500ced5d04032835c815cb0ff38e55e6319a6a86a82fbe1568b339947ad08cdae82199b6b6f941ce7860c6c2af642fd4d444a + languageName: node + linkType: hard + "metro-config@npm:0.87.1, metro-config@npm:^0.87.0": version: 0.87.1 resolution: "metro-config@npm:0.87.1" @@ -7878,6 +9367,28 @@ __metadata: languageName: node linkType: hard +"metro-core@npm:0.84.5": + version: 0.84.5 + resolution: "metro-core@npm:0.84.5" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + lodash.throttle: "npm:^4.1.1" + metro-resolver: "npm:0.84.5" + checksum: 10c0/f351c27f84f83bd3ec1db4e06566dfbfb01c6ebe193c4aa59850661374208b548e5738091525fe642a63c6117c64b053489f529e0aa29c311ff871cf290c00c3 + languageName: node + linkType: hard + +"metro-core@npm:0.84.6, metro-core@npm:^0.84.3": + version: 0.84.6 + resolution: "metro-core@npm:0.84.6" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + lodash.throttle: "npm:^4.1.1" + metro-resolver: "npm:0.84.6" + checksum: 10c0/069b74c01471fcdfe13188ee087192e06ab2e42e769f6bbfe1068c6a7b4a1005d6adede0b1100e22b192a37e0397501c91b420f9669229d36253901d1fb59b53 + languageName: node + linkType: hard + "metro-core@npm:0.87.1": version: 0.87.1 resolution: "metro-core@npm:0.87.1" @@ -7889,6 +9400,40 @@ __metadata: languageName: node linkType: hard +"metro-file-map@npm:0.84.5": + version: 0.84.5 + resolution: "metro-file-map@npm:0.84.5" + dependencies: + debug: "npm:^4.4.0" + fb-watchman: "npm:^2.0.0" + flow-enums-runtime: "npm:^0.0.6" + graceful-fs: "npm:^4.2.4" + invariant: "npm:^2.2.4" + jest-worker: "npm:^29.7.0" + micromatch: "npm:^4.0.4" + nullthrows: "npm:^1.1.1" + walker: "npm:^1.0.7" + checksum: 10c0/16c0fbdc0e50c1785048e707f3b70813d89c72388ef024fcd16a78d18705e335c14649e842f594d5146d6f592616b4cc13953e6abbf0769006b5a6219d4c22d4 + languageName: node + linkType: hard + +"metro-file-map@npm:0.84.6": + version: 0.84.6 + resolution: "metro-file-map@npm:0.84.6" + dependencies: + debug: "npm:^4.4.0" + fb-watchman: "npm:^2.0.0" + flow-enums-runtime: "npm:^0.0.6" + graceful-fs: "npm:^4.2.4" + invariant: "npm:^2.2.4" + jest-worker: "npm:^29.7.0" + micromatch: "npm:^4.0.4" + nullthrows: "npm:^1.1.1" + walker: "npm:^1.0.7" + checksum: 10c0/7f9f3585b0e4caa80dc054e650c5aa0b1f42ee5fc58f9cb1d8895d29651fa3ea618e9c7bec4e1777a13ff6723812788b4ba241a7202eb6f571af97749c5c5bbe + languageName: node + linkType: hard + "metro-file-map@npm:0.87.1": version: 0.87.1 resolution: "metro-file-map@npm:0.87.1" @@ -7905,6 +9450,26 @@ __metadata: languageName: node linkType: hard +"metro-minify-terser@npm:0.84.5": + version: 0.84.5 + resolution: "metro-minify-terser@npm:0.84.5" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + terser: "npm:^5.15.0" + checksum: 10c0/0fb7f2882d66698110027565a8a4ccd099d28df660ac3853a328575b457b24e2eb0a5ab06a000464fc86f25da34502e60cc1314c5decb90c98098378f90386d2 + languageName: node + linkType: hard + +"metro-minify-terser@npm:0.84.6": + version: 0.84.6 + resolution: "metro-minify-terser@npm:0.84.6" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + terser: "npm:^5.15.0" + checksum: 10c0/1d29d51758c4fe1d37472602e7c36b49a352bfedd027323c08e02a6f195837c63989c1813aca898910f33a41ab18a8709c75fa59b566af35c9f346e44402a429 + languageName: node + linkType: hard + "metro-minify-terser@npm:0.87.1": version: 0.87.1 resolution: "metro-minify-terser@npm:0.87.1" @@ -7915,6 +9480,24 @@ __metadata: languageName: node linkType: hard +"metro-resolver@npm:0.84.5": + version: 0.84.5 + resolution: "metro-resolver@npm:0.84.5" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + checksum: 10c0/44822149fbd52f680461e94ac7f8bf0855461607ed8d286a5ad615b8bd4a6b113cf0f3c2c403285514c6e1f46cfe7c95e52d9b59633506701dee735b6e788599 + languageName: node + linkType: hard + +"metro-resolver@npm:0.84.6": + version: 0.84.6 + resolution: "metro-resolver@npm:0.84.6" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + checksum: 10c0/318cccc86d6e51ccc45f5cf369d98ee620d4090fb66bf4fefb1edaa287a6c19073d87228b3527147073985690773d8d89ab91026cf0801992284025385072d78 + languageName: node + linkType: hard + "metro-resolver@npm:0.87.1": version: 0.87.1 resolution: "metro-resolver@npm:0.87.1" @@ -7924,6 +9507,26 @@ __metadata: languageName: node linkType: hard +"metro-runtime@npm:0.84.5": + version: 0.84.5 + resolution: "metro-runtime@npm:0.84.5" + dependencies: + "@babel/runtime": "npm:^7.25.0" + flow-enums-runtime: "npm:^0.0.6" + checksum: 10c0/8f4de088ed0946b153d4afb51bb0e1dc7a36d276821ad7ee81fdbddcc72a7a8391f49d044c351c377387dbb955654078843a8fd11d3a3e41be4017d5d59a0848 + languageName: node + linkType: hard + +"metro-runtime@npm:0.84.6, metro-runtime@npm:^0.84.3": + version: 0.84.6 + resolution: "metro-runtime@npm:0.84.6" + dependencies: + "@babel/runtime": "npm:^7.25.0" + flow-enums-runtime: "npm:^0.0.6" + checksum: 10c0/44f6287ef8a2e816102301b08c450f38dad7e2580dc5c9b86f6449bf942fbd8880e5ffc04129327aa26e51e57c6a1bba53606feb289f6c789bfd5bfe006ae718 + languageName: node + linkType: hard + "metro-runtime@npm:0.87.1, metro-runtime@npm:^0.87.0": version: 0.87.1 resolution: "metro-runtime@npm:0.87.1" @@ -7934,6 +9537,40 @@ __metadata: languageName: node linkType: hard +"metro-source-map@npm:0.84.5": + version: 0.84.5 + resolution: "metro-source-map@npm:0.84.5" + dependencies: + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + flow-enums-runtime: "npm:^0.0.6" + invariant: "npm:^2.2.4" + metro-symbolicate: "npm:0.84.5" + nullthrows: "npm:^1.1.1" + ob1: "npm:0.84.5" + source-map: "npm:^0.5.6" + vlq: "npm:^1.0.0" + checksum: 10c0/9aedfc28c2f04b41bf68844b6daa4141455e9b748b5651384d5eea22b3c65457aaa3470a845f2b464cb3a2d9c16e1a8fd5b04a2347ea6241d5c9912b3b9755bd + languageName: node + linkType: hard + +"metro-source-map@npm:0.84.6, metro-source-map@npm:^0.84.3": + version: 0.84.6 + resolution: "metro-source-map@npm:0.84.6" + dependencies: + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + flow-enums-runtime: "npm:^0.0.6" + invariant: "npm:^2.2.4" + metro-symbolicate: "npm:0.84.6" + nullthrows: "npm:^1.1.1" + ob1: "npm:0.84.6" + source-map: "npm:^0.5.6" + vlq: "npm:^1.0.0" + checksum: 10c0/8cae2e68b69bf34744f4a1c1cc3df7498c664ccb77bbf7a6777691ba7f378a594387374f55a3c4236ad0363a72fe7b1a8600100bbdab9b38954e2992d1281fb0 + languageName: node + linkType: hard + "metro-source-map@npm:0.87.1, metro-source-map@npm:^0.87.0": version: 0.87.1 resolution: "metro-source-map@npm:0.87.1" @@ -7951,6 +9588,38 @@ __metadata: languageName: node linkType: hard +"metro-symbolicate@npm:0.84.5": + version: 0.84.5 + resolution: "metro-symbolicate@npm:0.84.5" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + invariant: "npm:^2.2.4" + metro-source-map: "npm:0.84.5" + nullthrows: "npm:^1.1.1" + source-map: "npm:^0.5.6" + vlq: "npm:^1.0.0" + bin: + metro-symbolicate: src/index.js + checksum: 10c0/75defd592eea1a4b6ef5e0e1610bb21188764b9d56ccf52b16031524377ac9127d7af66dbc259bc85b1fe8afa9cd51b677c97a4c1d0fcc37d4494a08656f5fe6 + languageName: node + linkType: hard + +"metro-symbolicate@npm:0.84.6": + version: 0.84.6 + resolution: "metro-symbolicate@npm:0.84.6" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + invariant: "npm:^2.2.4" + metro-source-map: "npm:0.84.6" + nullthrows: "npm:^1.1.1" + source-map: "npm:^0.5.6" + vlq: "npm:^1.0.0" + bin: + metro-symbolicate: src/index.js + checksum: 10c0/aaae6a7db27d9a9f5961726a00c102fbfe16bf6be8b6ddb8fbae0e7fe0a760d252266c492c707094fe289ed34eef27122707cc894170cc5b98be6845c1533874 + languageName: node + linkType: hard + "metro-symbolicate@npm:0.87.1": version: 0.87.1 resolution: "metro-symbolicate@npm:0.87.1" @@ -7967,6 +9636,34 @@ __metadata: languageName: node linkType: hard +"metro-transform-plugins@npm:0.84.5": + version: 0.84.5 + resolution: "metro-transform-plugins@npm:0.84.5" + dependencies: + "@babel/core": "npm:^7.25.2" + "@babel/generator": "npm:^7.29.1" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" + flow-enums-runtime: "npm:^0.0.6" + nullthrows: "npm:^1.1.1" + checksum: 10c0/3ef1e0c487c6b91b1f9eacfffb2f152094d67fb1b0d536030dd7a02d95da881acb19f0d03c0c4cffc7bca6e3d57538559e1d6fea9e610fe88946c2c0d9c1b9d7 + languageName: node + linkType: hard + +"metro-transform-plugins@npm:0.84.6": + version: 0.84.6 + resolution: "metro-transform-plugins@npm:0.84.6" + dependencies: + "@babel/core": "npm:^7.25.2" + "@babel/generator": "npm:^7.29.1" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" + flow-enums-runtime: "npm:^0.0.6" + nullthrows: "npm:^1.1.1" + checksum: 10c0/06ad6021f0f07771d8a984a0c9302b2833a169654f4582647e60f2b8098652acd4a7811a58b7a4a2575560a709f48a6f9c6524b67037d6061c73ac58f2189625 + languageName: node + linkType: hard + "metro-transform-plugins@npm:0.87.1": version: 0.87.1 resolution: "metro-transform-plugins@npm:0.87.1" @@ -7977,28 +9674,166 @@ __metadata: "@babel/traverse": "npm:^7.29.0" flow-enums-runtime: "npm:^0.0.6" nullthrows: "npm:^1.1.1" - checksum: 10c0/6ffc825d59fb4af9198114063b27627522de5f6ec20a4c840fbae8b99b6a3896e45f4e53800435e824cac9b708c10af270a90aee98714fbfb2105d4724e5800a + checksum: 10c0/6ffc825d59fb4af9198114063b27627522de5f6ec20a4c840fbae8b99b6a3896e45f4e53800435e824cac9b708c10af270a90aee98714fbfb2105d4724e5800a + languageName: node + linkType: hard + +"metro-transform-worker@npm:0.84.5": + version: 0.84.5 + resolution: "metro-transform-worker@npm:0.84.5" + dependencies: + "@babel/core": "npm:^7.25.2" + "@babel/generator": "npm:^7.29.1" + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + flow-enums-runtime: "npm:^0.0.6" + metro: "npm:0.84.5" + metro-babel-transformer: "npm:0.84.5" + metro-cache: "npm:0.84.5" + metro-cache-key: "npm:0.84.5" + metro-minify-terser: "npm:0.84.5" + metro-source-map: "npm:0.84.5" + metro-transform-plugins: "npm:0.84.5" + nullthrows: "npm:^1.1.1" + checksum: 10c0/b4f147f97555feb0fe91114b7a49e8345a8065d88739ff217d26d17bc56fe707b2b1ed0533432dd27aa7169bd7542709ffee5edcfee7dc999c276cc891fbee7d + languageName: node + linkType: hard + +"metro-transform-worker@npm:0.84.6": + version: 0.84.6 + resolution: "metro-transform-worker@npm:0.84.6" + dependencies: + "@babel/core": "npm:^7.25.2" + "@babel/generator": "npm:^7.29.1" + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + flow-enums-runtime: "npm:^0.0.6" + metro: "npm:0.84.6" + metro-babel-transformer: "npm:0.84.6" + metro-cache: "npm:0.84.6" + metro-cache-key: "npm:0.84.6" + metro-minify-terser: "npm:0.84.6" + metro-source-map: "npm:0.84.6" + metro-transform-plugins: "npm:0.84.6" + nullthrows: "npm:^1.1.1" + checksum: 10c0/569d3482631a4378740e3bf354535e697e33835bdbb920f698be4560bc0384254cdad61274ee290bc933871de3cd519890efa29867fe699079b0d5a3ff8ecf6e + languageName: node + linkType: hard + +"metro-transform-worker@npm:0.87.1": + version: 0.87.1 + resolution: "metro-transform-worker@npm:0.87.1" + dependencies: + "@babel/core": "npm:^7.25.2" + "@babel/generator": "npm:^7.29.1" + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + flow-enums-runtime: "npm:^0.0.6" + metro: "npm:0.87.1" + metro-babel-transformer: "npm:0.87.1" + metro-cache: "npm:0.87.1" + metro-cache-key: "npm:0.87.1" + metro-minify-terser: "npm:0.87.1" + metro-source-map: "npm:0.87.1" + metro-transform-plugins: "npm:0.87.1" + nullthrows: "npm:^1.1.1" + checksum: 10c0/50401e5aa9249591d940140465c81c7c2088e8e925993a589f6e99a03c8b1cb3cd3ced8e0c5e528f9041a2d15b1904e5a972a1a2945298277d5ed6f9a0558440 + languageName: node + linkType: hard + +"metro@npm:0.84.5": + version: 0.84.5 + resolution: "metro@npm:0.84.5" + dependencies: + "@babel/code-frame": "npm:^7.29.0" + "@babel/core": "npm:^7.25.2" + "@babel/generator": "npm:^7.29.1" + "@babel/parser": "npm:^7.29.0" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + accepts: "npm:^2.0.0" + ci-info: "npm:^2.0.0" + connect: "npm:^3.6.5" + debug: "npm:^4.4.0" + error-stack-parser: "npm:^2.0.6" + flow-enums-runtime: "npm:^0.0.6" + graceful-fs: "npm:^4.2.4" + hermes-parser: "npm:0.35.0" + invariant: "npm:^2.2.4" + jest-worker: "npm:^29.7.0" + jsc-safe-url: "npm:^0.2.2" + lodash.throttle: "npm:^4.1.1" + metro-babel-transformer: "npm:0.84.5" + metro-cache: "npm:0.84.5" + metro-cache-key: "npm:0.84.5" + metro-config: "npm:0.84.5" + metro-core: "npm:0.84.5" + metro-file-map: "npm:0.84.5" + metro-resolver: "npm:0.84.5" + metro-runtime: "npm:0.84.5" + metro-source-map: "npm:0.84.5" + metro-symbolicate: "npm:0.84.5" + metro-transform-plugins: "npm:0.84.5" + metro-transform-worker: "npm:0.84.5" + mime-types: "npm:^3.0.1" + nullthrows: "npm:^1.1.1" + serialize-error: "npm:^2.1.0" + source-map: "npm:^0.5.6" + throat: "npm:^5.0.0" + ws: "npm:^7.5.10" + yargs: "npm:^17.6.2" + bin: + metro: src/cli.js + checksum: 10c0/be9981927748f56c2f50f10d1de06e11917421718f3107dad95ee149892a8e0fb91bddc0b17f091984259c1b41bb01a193dc6280785ae6e4a5ad804fbd61c6d2 languageName: node linkType: hard -"metro-transform-worker@npm:0.87.1": - version: 0.87.1 - resolution: "metro-transform-worker@npm:0.87.1" +"metro@npm:0.84.6, metro@npm:^0.84.3": + version: 0.84.6 + resolution: "metro@npm:0.84.6" dependencies: + "@babel/code-frame": "npm:^7.29.0" "@babel/core": "npm:^7.25.2" "@babel/generator": "npm:^7.29.1" "@babel/parser": "npm:^7.29.0" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" "@babel/types": "npm:^7.29.0" + accepts: "npm:^2.0.0" + ci-info: "npm:^2.0.0" + connect: "npm:^3.6.5" + debug: "npm:^4.4.0" + error-stack-parser: "npm:^2.0.6" flow-enums-runtime: "npm:^0.0.6" - metro: "npm:0.87.1" - metro-babel-transformer: "npm:0.87.1" - metro-cache: "npm:0.87.1" - metro-cache-key: "npm:0.87.1" - metro-minify-terser: "npm:0.87.1" - metro-source-map: "npm:0.87.1" - metro-transform-plugins: "npm:0.87.1" + graceful-fs: "npm:^4.2.4" + hermes-parser: "npm:0.35.0" + invariant: "npm:^2.2.4" + jest-worker: "npm:^29.7.0" + jsc-safe-url: "npm:^0.2.2" + lodash.throttle: "npm:^4.1.1" + metro-babel-transformer: "npm:0.84.6" + metro-cache: "npm:0.84.6" + metro-cache-key: "npm:0.84.6" + metro-config: "npm:0.84.6" + metro-core: "npm:0.84.6" + metro-file-map: "npm:0.84.6" + metro-resolver: "npm:0.84.6" + metro-runtime: "npm:0.84.6" + metro-source-map: "npm:0.84.6" + metro-symbolicate: "npm:0.84.6" + metro-transform-plugins: "npm:0.84.6" + metro-transform-worker: "npm:0.84.6" + mime-types: "npm:^3.0.1" nullthrows: "npm:^1.1.1" - checksum: 10c0/50401e5aa9249591d940140465c81c7c2088e8e925993a589f6e99a03c8b1cb3cd3ced8e0c5e528f9041a2d15b1904e5a972a1a2945298277d5ed6f9a0558440 + serialize-error: "npm:^2.1.0" + source-map: "npm:^0.5.6" + throat: "npm:^5.0.0" + ws: "npm:^7.5.10" + yargs: "npm:^17.6.2" + bin: + metro: src/cli.js + checksum: 10c0/04e1b9f6f234795c9274b9b68b0690d62bce285c2bfcc4f7deddc217a97882b85d56db1c8cd285fda2b0a67b1fb81255a7469496fcc49e48d7c8bcc6a7f8dac8 languageName: node linkType: hard @@ -8109,6 +9944,13 @@ __metadata: languageName: node linkType: hard +"mimic-fn@npm:^1.0.0": + version: 1.2.0 + resolution: "mimic-fn@npm:1.2.0" + checksum: 10c0/ad55214aec6094c0af4c0beec1a13787556f8116ed88807cf3f05828500f21f93a9482326bcd5a077ae91e3e8795b4e76b5b4c8bb12237ff0e4043a365516cba + languageName: node + linkType: hard + "mimic-fn@npm:^2.1.0": version: 2.1.0 resolution: "mimic-fn@npm:2.1.0" @@ -8148,7 +9990,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^7.0.4, minipass@npm:^7.1.2": +"minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3": version: 7.1.3 resolution: "minipass@npm:7.1.3" checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb @@ -8180,13 +10022,20 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.3, ms@npm:^2.1.3": +"ms@npm:2.1.3, ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 languageName: node linkType: hard +"multitars@npm:^1.0.2": + version: 1.0.2 + resolution: "multitars@npm:1.0.2" + checksum: 10c0/3ba8805a66bcdb95a9841e13b59370bd737777a0435fed661e321af89e6f235ef286ca5b5d7992c4f079795826e8734e9aa7db368e389bc7a008550b50d928d2 + languageName: node + linkType: hard + "mutation-server-protocol@npm:~0.4.0": version: 0.4.1 resolution: "mutation-server-protocol@npm:0.4.1" @@ -8226,6 +10075,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^3.3.18": + version: 3.3.19 + resolution: "nanoid@npm:3.3.19" + bin: + nanoid: bin/nanoid.cjs + checksum: 10c0/ce7afa6258bfaa00bdc8de291cfe9913280eaa403b7d9cff3db4e4200c1913e7163577df74897958da144db473a96c67f74f57db0f542fbfe409df677bae3255 + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -8282,6 +10140,13 @@ __metadata: languageName: node linkType: hard +"node-forge@npm:^1.3.3": + version: 1.4.0 + resolution: "node-forge@npm:1.4.0" + checksum: 10c0/67330a5f1f95257a4c8a93b7d555abe87b5f15e350123aa396c97a21a8ca94f9c6549008eb2c73668a91e0d7e3a905785acbd8f8bd0751c29401292011f8f8e1 + languageName: node + linkType: hard + "node-gyp@npm:latest": version: 13.0.2 resolution: "node-gyp@npm:13.0.2" @@ -8316,6 +10181,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.57": + version: 2.0.57 + resolution: "node-releases@npm:2.0.57" + checksum: 10c0/fe5b68fba1fef524243b54828a118f13a4a40db08bb42c0b92680c3ca5c246f4ae6f139515071d46b9a3a9195945f5ac78064f5b7674c4dcc3dd6bfe933ff9e8 + languageName: node + linkType: hard + "node-stream-zip@npm:^1.9.1": version: 1.16.0 resolution: "node-stream-zip@npm:1.16.0" @@ -8341,6 +10213,18 @@ __metadata: languageName: node linkType: hard +"npm-package-arg@npm:^11.0.0": + version: 11.0.3 + resolution: "npm-package-arg@npm:11.0.3" + dependencies: + hosted-git-info: "npm:^7.0.0" + proc-log: "npm:^4.0.0" + semver: "npm:^7.3.5" + validate-npm-package-name: "npm:^5.0.0" + checksum: 10c0/e18333485e05c3a8774f4b5701ef74f4799533e650b70a68ca8dd697666c9a8d46932cb765fc593edce299521033bd4025a40323d5240cea8a393c784c0c285a + languageName: node + linkType: hard + "npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" @@ -8367,6 +10251,24 @@ __metadata: languageName: node linkType: hard +"ob1@npm:0.84.5": + version: 0.84.5 + resolution: "ob1@npm:0.84.5" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + checksum: 10c0/f00c3bdb8c8b53de03a3352a062e170e1ba1cf1977b3dfab492882a0f6fa9eccb5503dde012b1ef7d24c5060f5a6439457e850b98bd4148e2578ffa650b414b8 + languageName: node + linkType: hard + +"ob1@npm:0.84.6": + version: 0.84.6 + resolution: "ob1@npm:0.84.6" + dependencies: + flow-enums-runtime: "npm:^0.0.6" + checksum: 10c0/f65a3afcbf8a31df1f7e9cf8bf92dd1579e2993fbe308bda570d09eb11b51aac3ce74da15b8e3ae0c900edd83ed58afedafceaa6e5a6c8e27f83b39fc25b66b9 + languageName: node + linkType: hard + "ob1@npm:0.87.1": version: 0.87.1 resolution: "ob1@npm:0.87.1" @@ -8488,6 +10390,15 @@ __metadata: languageName: node linkType: hard +"onetime@npm:^2.0.0": + version: 2.0.1 + resolution: "onetime@npm:2.0.1" + dependencies: + mimic-fn: "npm:^1.0.0" + checksum: 10c0/b4e44a8c34e70e02251bfb578a6e26d6de6eedbed106cd78211d2fd64d28b6281d54924696554e4e966559644243753ac5df73c87f283b0927533d3315696215 + languageName: node + linkType: hard + "onetime@npm:^5.1.0, onetime@npm:^5.1.2": version: 5.1.2 resolution: "onetime@npm:5.1.2" @@ -8530,6 +10441,20 @@ __metadata: languageName: node linkType: hard +"ora@npm:^3.4.0": + version: 3.4.0 + resolution: "ora@npm:3.4.0" + dependencies: + chalk: "npm:^2.4.2" + cli-cursor: "npm:^2.1.0" + cli-spinners: "npm:^2.0.0" + log-symbols: "npm:^2.2.0" + strip-ansi: "npm:^5.2.0" + wcwidth: "npm:^1.0.1" + checksum: 10c0/04cb375f222c36a16a95e6c39c473644a99a42fc34d35c37507cb836ea0a71f4d831fcd53198a460869114b2730891d63cc1047304afe5ddb078974d468edfb1 + languageName: node + linkType: hard + "ora@npm:^5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" @@ -8630,6 +10555,15 @@ __metadata: languageName: node linkType: hard +"parse-png@npm:^2.1.0": + version: 2.1.0 + resolution: "parse-png@npm:2.1.0" + dependencies: + pngjs: "npm:^3.3.0" + checksum: 10c0/5157a8bbb976ae1ca990fc53c7014d42aac0967cb30e2daf36c3fef1876c8db0d551e695400c904f33c5c5add76a572c65b5044721d62417d8cc7abe4c4ffa41 + languageName: node + linkType: hard + "parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" @@ -8679,6 +10613,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^2.0.2": + version: 2.0.2 + resolution: "path-scurry@npm:2.0.2" + dependencies: + lru-cache: "npm:^11.0.0" + minipass: "npm:^7.1.2" + checksum: 10c0/b35ad37cf6557a87fd057121ce2be7695380c9138d93e87ae928609da259ea0a170fac6f3ef1eb3ece8a068e8b7f2f3adf5bb2374cf4d4a57fe484954fcc9482 + languageName: node + linkType: hard + "picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" @@ -8716,6 +10660,24 @@ __metadata: languageName: node linkType: hard +"plist@npm:^3.0.5": + version: 3.1.1 + resolution: "plist@npm:3.1.1" + dependencies: + "@xmldom/xmldom": "npm:^0.9.10" + base64-js: "npm:^1.5.1" + xmlbuilder: "npm:^15.1.1" + checksum: 10c0/af681277c2e541c6aab0ddee57f59459c43beeea1ee7aa2d4218aa39595fb41c068e2d2be3e4abb17e3252eaf2c1b806ecfb1d402fa5a3f4a6e1a7a32c880c9a + languageName: node + linkType: hard + +"pngjs@npm:^3.3.0": + version: 3.4.0 + resolution: "pngjs@npm:3.4.0" + checksum: 10c0/88ee73e2ad3f736e0b2573722309eb80bd2aa28916f0862379b4fd0f904751b4f61bb6bd1ecd7d4242d331f2b5c28c13309dd4b7d89a9b78306e35122fdc5011 + languageName: node + linkType: hard + "possible-typed-array-names@npm:^1.0.0, possible-typed-array-names@npm:^1.1.0": version: 1.1.0 resolution: "possible-typed-array-names@npm:1.1.0" @@ -8723,6 +10685,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.5.14": + version: 8.5.28 + resolution: "postcss@npm:8.5.28" + dependencies: + nanoid: "npm:^3.3.18" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/9fe44215a6628d89c8a75184b92f5b2f77e16f9e5b13b39b9009bb7e8e6eccddf82c8854bae922db1f17ace6ef3445073fe38abff513caeb03e5285b1b55620a + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -8759,6 +10732,13 @@ __metadata: languageName: node linkType: hard +"proc-log@npm:^4.0.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 10c0/17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9 + languageName: node + linkType: hard + "proc-log@npm:^7.0.0": version: 7.0.0 resolution: "proc-log@npm:7.0.0" @@ -8766,7 +10746,7 @@ __metadata: languageName: node linkType: hard -"progress@npm:~2.0.3": +"progress@npm:^2.0.3, progress@npm:~2.0.3": version: 2.0.3 resolution: "progress@npm:2.0.3" checksum: 10c0/1697e07cb1068055dbe9fe858d242368ff5d2073639e652b75a7eb1f2a1a8d4afd404d719de23c7b48481a6aa0040686310e2dac2f53d776daa2176d3f96369c @@ -8782,7 +10762,7 @@ __metadata: languageName: node linkType: hard -"prompts@npm:^2.0.1, prompts@npm:^2.4.2": +"prompts@npm:^2.0.1, prompts@npm:^2.3.2, prompts@npm:^2.4.2": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: @@ -8902,6 +10882,57 @@ __metadata: languageName: node linkType: hard +"react-native@npm:0.86.3": + version: 0.86.3 + resolution: "react-native@npm:0.86.3" + dependencies: + "@react-native/assets-registry": "npm:0.86.3" + "@react-native/codegen": "npm:0.86.3" + "@react-native/community-cli-plugin": "npm:0.86.3" + "@react-native/gradle-plugin": "npm:0.86.3" + "@react-native/js-polyfills": "npm:0.86.3" + "@react-native/normalize-colors": "npm:0.86.3" + "@react-native/virtualized-lists": "npm:0.86.3" + abort-controller: "npm:^3.0.0" + anser: "npm:^1.4.9" + ansi-regex: "npm:^5.0.0" + babel-plugin-syntax-hermes-parser: "npm:0.36.0" + base64-js: "npm:^1.5.1" + commander: "npm:^12.0.0" + flow-enums-runtime: "npm:^0.0.6" + hermes-compiler: "npm:250829098.0.17" + invariant: "npm:^2.2.4" + memoize-one: "npm:^5.0.0" + metro-runtime: "npm:^0.84.3" + metro-source-map: "npm:^0.84.3" + nullthrows: "npm:^1.1.1" + pretty-format: "npm:^29.7.0" + promise: "npm:^8.3.0" + react-devtools-core: "npm:^6.1.5" + react-refresh: "npm:^0.14.0" + regenerator-runtime: "npm:^0.13.2" + scheduler: "npm:0.27.0" + semver: "npm:^7.1.3" + stacktrace-parser: "npm:^0.1.10" + tinyglobby: "npm:^0.2.15" + whatwg-fetch: "npm:^3.0.0" + ws: "npm:^7.5.10" + yargs: "npm:^17.6.2" + peerDependencies: + "@react-native/jest-preset": 0.86.3 + "@types/react": ^19.1.1 + react: ^19.2.3 + peerDependenciesMeta: + "@react-native/jest-preset": + optional: true + "@types/react": + optional: true + bin: + react-native: cli.js + checksum: 10c0/a8354c58be9ca1509c48d4c06194f4be4b902c17ef6f4fc5bdfb05960b079b156b453998c69ed08ee0a4d60b00aeac7eaf8a9cfc428d24bec46304c06063b4c0 + languageName: node + linkType: hard + "react-native@npm:0.87.1": version: 0.87.1 resolution: "react-native@npm:0.87.1" @@ -8948,7 +10979,7 @@ __metadata: languageName: node linkType: hard -"react-refresh@npm:^0.14.0": +"react-refresh@npm:^0.14.0, react-refresh@npm:^0.14.2": version: 0.14.2 resolution: "react-refresh@npm:0.14.2" checksum: 10c0/875b72ef56b147a131e33f2abd6ec059d1989854b3ff438898e4f9310bfcc73acff709445b7ba843318a953cb9424bcc2c05af2b3d80011cee28f25aef3e2ebb @@ -9114,6 +11145,13 @@ __metadata: languageName: node linkType: hard +"resolve-workspace-root@npm:^2.0.0": + version: 2.0.1 + resolution: "resolve-workspace-root@npm:2.0.1" + checksum: 10c0/83104ea8476ba451a4bac32db42cf1dc79a7b98810764e507830a2f63af20cfb00fe7da5b0c324d77d4fcfda7a24e9e17895690d6f6a498735b633fd7fc372ca + languageName: node + linkType: hard + "resolve.exports@npm:^2.0.0": version: 2.0.3 resolution: "resolve.exports@npm:2.0.3" @@ -9181,6 +11219,16 @@ __metadata: languageName: node linkType: hard +"restore-cursor@npm:^2.0.0": + version: 2.0.0 + resolution: "restore-cursor@npm:2.0.0" + dependencies: + onetime: "npm:^2.0.0" + signal-exit: "npm:^3.0.2" + checksum: 10c0/f5b335bee06f440445e976a7031a3ef53691f9b7c4a9d42a469a0edaf8a5508158a0d561ff2b26a1f4f38783bcca2c0e5c3a44f927326f6694d5b44d7a4993e6 + languageName: node + linkType: hard + "restore-cursor@npm:^3.1.0": version: 3.1.0 resolution: "restore-cursor@npm:3.1.0" @@ -9275,6 +11323,22 @@ __metadata: languageName: node linkType: hard +"sandbox-cli-detector@npm:^0.2.0": + version: 0.2.0 + resolution: "sandbox-cli-detector@npm:0.2.0" + bin: + sandbox-cli-detector: dist/cli.js + checksum: 10c0/e70964918150079a3183948a8adadcde736823da2ad1135b4ccead2baa8d24d6487ddd222c030f94c9ef54e84bc41aa525a5452ef4cb9239f6f64b2ac03337bc + languageName: node + linkType: hard + +"sax@npm:>=0.6.0": + version: 1.6.1 + resolution: "sax@npm:1.6.1" + checksum: 10c0/c91a71043d60da50fdf1e2cee936fc7ad4c9376afb8d1022aef5655f279433640859ec06b3b49abfcbe578fc7da2828cc1661e45aaedf835f5393496193437fa + languageName: node + linkType: hard + "scheduler@npm:0.27.0, scheduler@npm:^0.27.0": version: 0.27.0 resolution: "scheduler@npm:0.27.0" @@ -9291,7 +11355,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.3, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.3, semver@npm:^7.7.3, semver@npm:^7.8.5, semver@npm:~7.8.0": +"semver@npm:^7.1.3, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.3, semver@npm:^7.8.5, semver@npm:~7.8.0": version: 7.8.5 resolution: "semver@npm:7.8.5" bin: @@ -9300,7 +11364,7 @@ __metadata: languageName: node linkType: hard -"send@npm:~0.19.1": +"send@npm:^0.19.0, send@npm:~0.19.1": version: 0.19.2 resolution: "send@npm:0.19.2" dependencies: @@ -9476,6 +11540,17 @@ __metadata: languageName: node linkType: hard +"simple-plist@npm:^1.1.0": + version: 1.4.0 + resolution: "simple-plist@npm:1.4.0" + dependencies: + bplist-creator: "npm:0.1.1" + bplist-parser: "npm:0.3.2" + plist: "npm:^3.0.5" + checksum: 10c0/226c283492d8518d715e4133d94bdbd15c0619561bcde583b4807b36cde106c0078c615b9b4e25c0e8758a4ae4e79ed5dd76e57cd528d8b7001ecab5ad35e343 + languageName: node + linkType: hard + "sisteransi@npm:^1.0.5": version: 1.0.5 resolution: "sisteransi@npm:1.0.5" @@ -9501,6 +11576,20 @@ __metadata: languageName: node linkType: hard +"slugify@npm:^1.3.4, slugify@npm:^1.6.6": + version: 1.6.9 + resolution: "slugify@npm:1.6.9" + checksum: 10c0/8473c566ae00c5db26bfbf6182a4a9478ab3c912a9c926e1fdb410736a77228bfca4fdc5c755b46fafa7d2d9900de482fd7a9bd5e5c91128c4743c2c072d88da + languageName: node + linkType: hard + +"source-map-js@npm:^1.2.1": + version: 1.2.2 + resolution: "source-map-js@npm:1.2.2" + checksum: 10c0/d5d6dec62266834f83dd4f8a2606a196fb1a006ca5d53b0ef80ee513b7eba2f4e2ae241f4bc129ae7e9b80dea24f6e3d92b446b7e6e96be7653cab8888168a94 + languageName: node + linkType: hard + "source-map-support@npm:0.5.13": version: 0.5.13 resolution: "source-map-support@npm:0.5.13" @@ -9598,6 +11687,13 @@ __metadata: languageName: node linkType: hard +"stream-buffers@npm:2.2.x": + version: 2.2.0 + resolution: "stream-buffers@npm:2.2.0" + checksum: 10c0/14a351f0a066eaa08c8c64a74f4aedd87dd7a8e59d4be224703da33dca3eb370828ee6c0ae3fff59a9c743e8098728fc95c5f052ae7741672a31e6b1430ba50a + languageName: node + linkType: hard + "string-length@npm:^4.0.1": version: 4.0.2 resolution: "string-length@npm:4.0.2" @@ -9705,7 +11801,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^5.0.0": +"strip-ansi@npm:^5.0.0, strip-ansi@npm:^5.2.0": version: 5.2.0 resolution: "strip-ansi@npm:5.2.0" dependencies: @@ -9760,7 +11856,23 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^7.1.0": +"structured-headers@npm:^0.4.1": + version: 0.4.1 + resolution: "structured-headers@npm:0.4.1" + checksum: 10c0/b7d326f6fec7e7f7901d1e0542577293b5d029bf3e1fb84995e33d9aabe47d03259f64ca2d778ef5c427f6f00c78bafa051b6f233131e1556f8bb9102b11ed64 + languageName: node + linkType: hard + +"supports-color@npm:^5.3.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 + languageName: node + linkType: hard + +"supports-color@npm:^7.0.0, supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" dependencies: @@ -9778,6 +11890,16 @@ __metadata: languageName: node linkType: hard +"supports-hyperlinks@npm:^2.0.0": + version: 2.3.0 + resolution: "supports-hyperlinks@npm:2.3.0" + dependencies: + has-flag: "npm:^4.0.0" + supports-color: "npm:^7.0.0" + checksum: 10c0/4057f0d86afb056cd799602f72d575b8fdd79001c5894bcb691176f14e870a687e7981e50bc1484980e8b688c6d5bcd4931e1609816abb5a7dc1486b7babf6a1 + languageName: node + linkType: hard + "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" @@ -9798,6 +11920,16 @@ __metadata: languageName: node linkType: hard +"terminal-link@npm:^2.1.1": + version: 2.1.1 + resolution: "terminal-link@npm:2.1.1" + dependencies: + ansi-escapes: "npm:^4.2.1" + supports-hyperlinks: "npm:^2.0.0" + checksum: 10c0/947458a5cd5408d2ffcdb14aee50bec8fb5022ae683b896b2f08ed6db7b2e7d42780d5c8b51e930e9c322bd7c7a517f4fa7c76983d0873c83245885ac5ee13e3 + languageName: node + linkType: hard + "terser@npm:^5.15.0": version: 5.51.2 resolution: "terser@npm:5.51.2" @@ -9870,6 +12002,13 @@ __metadata: languageName: node linkType: hard +"toqr@npm:^0.1.1": + version: 0.1.1 + resolution: "toqr@npm:0.1.1" + checksum: 10c0/eec346afae2eede8886938992a7eba59f765b3d3a3d5e7ce4984cb25b124e1a3d02531ed1ef3100d60fe443eeb1c7f83ca1fa0bbb04915d67baa5380e7c9eda4 + languageName: node + linkType: hard + "tree-kill@npm:~1.2.2": version: 1.2.2 resolution: "tree-kill@npm:1.2.2" @@ -10301,6 +12440,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^7.0.3": + version: 7.0.3 + resolution: "uuid@npm:7.0.3" + bin: + uuid: dist/bin/uuid + checksum: 10c0/2eee5723b0fcce8256f5bfd3112af6c453b5471db00af9c3533e3d5a6e57de83513f9a145a570890457bd7abf2c2aa05797291d950ac666e5a074895dc63168b + languageName: node + linkType: hard + "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -10319,6 +12467,13 @@ __metadata: languageName: node linkType: hard +"validate-npm-package-name@npm:^5.0.0": + version: 5.0.1 + resolution: "validate-npm-package-name@npm:5.0.1" + checksum: 10c0/903e738f7387404bb72f7ac34e45d7010c877abd2803dc2d614612527927a40a6d024420033132e667b1bade94544b8a1f65c9431a4eb30d0ce0d80093cd1f74 + languageName: node + linkType: hard + "vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" @@ -10340,7 +12495,7 @@ __metadata: languageName: node linkType: hard -"walker@npm:^1.0.8": +"walker@npm:^1.0.7, walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" dependencies: @@ -10372,6 +12527,13 @@ __metadata: languageName: node linkType: hard +"whatwg-url-minimum@npm:^0.1.2": + version: 0.1.2 + resolution: "whatwg-url-minimum@npm:0.1.2" + checksum: 10c0/5437bc4e1f49d89ff58b7565214db4640c4ad5d90de6c61207e0dc766dae9b9894a0ea7b7883b8576524601586705c5dc359681c388d76c18eddb51f50de558f + languageName: node + linkType: hard + "which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1": version: 1.1.1 resolution: "which-boxed-primitive@npm:1.1.1" @@ -10539,6 +12701,31 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.12.1": + version: 8.22.0 + resolution: "ws@npm:8.22.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/7304d14ef38898dd366a528a85e2da389c4eebf30f4ce8a007bd2dce6025f9b619cefe44fe2354f0bad0ec541b1c9a4da06a3f3e046ab56f01fd52d5784ecfb2 + languageName: node + linkType: hard + +"xcode@npm:^3.0.1": + version: 3.0.1 + resolution: "xcode@npm:3.0.1" + dependencies: + simple-plist: "npm:^1.1.0" + uuid: "npm:^7.0.3" + checksum: 10c0/51bf35cee52909aeb18f868ecf9828f93b8042fadf968159320f9f11e757a52e43f6563a53b586986cfe5a34d576f3300c4c0cf1e14300084344ae206eaa53c3 + languageName: node + linkType: hard + "xml-naming@npm:^0.3.0": version: 0.3.0 resolution: "xml-naming@npm:0.3.0" @@ -10546,6 +12733,30 @@ __metadata: languageName: node linkType: hard +"xml2js@npm:0.6.0": + version: 0.6.0 + resolution: "xml2js@npm:0.6.0" + dependencies: + sax: "npm:>=0.6.0" + xmlbuilder: "npm:~11.0.0" + checksum: 10c0/db1ad659210eda4b77929aa692271308ec7e04830112161b8c707f3bcc7138947409c8461ae5c8bcb36b378d62594a8d1cb78770ff5c3dc46a68c67a0838b486 + languageName: node + linkType: hard + +"xmlbuilder@npm:^15.1.1": + version: 15.1.1 + resolution: "xmlbuilder@npm:15.1.1" + checksum: 10c0/665266a8916498ff8d82b3d46d3993913477a254b98149ff7cff060d9b7cc0db7cf5a3dae99aed92355254a808c0e2e3ec74ad1b04aa1061bdb8dfbea26c18b8 + languageName: node + linkType: hard + +"xmlbuilder@npm:~11.0.0": + version: 11.0.1 + resolution: "xmlbuilder@npm:11.0.1" + checksum: 10c0/74b979f89a0a129926bc786b913459bdbcefa809afaa551c5ab83f89b1915bdaea14c11c759284bb9b931e3b53004dbc2181e21d3ca9553eeb0b2a7b4e40c35b + languageName: node + linkType: hard + "y18n@npm:^4.0.0": version: 4.0.3 resolution: "y18n@npm:4.0.3" @@ -10574,7 +12785,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.2.1": +"yaml@npm:^2.2.1, yaml@npm:^2.6.1": version: 2.9.1 resolution: "yaml@npm:2.9.1" bin: @@ -10670,3 +12881,10 @@ __metadata: checksum: 10c0/32eb6c5e98becbe045675b2141c3611451c16ba567f9779231d79af41c4d651ca1c22f154aef7e6c6e77b929f23e43f1154ca05b82e119e922353725d6776af5 languageName: node linkType: hard + +"zod@npm:^3.25.76": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: 10c0/5718ec35e3c40b600316c5b4c5e4976f7fee68151bc8f8d90ec18a469be9571f072e1bbaace10f1e85cf8892ea12d90821b200e980ab46916a6166a4260a983c + languageName: node + linkType: hard From 94b43504f60862b3c431ca4565fa26a5fa907569 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 02:46:11 +0500 Subject: [PATCH 02/11] Task 13.4: bake native pins into the published plugin. A published install has no repo-root native-versions.json to walk to, the Expo bundle phase assumed a sibling node_modules, and nativeCrashReporting: false still left the wrapper NDK AAR on the APK. Co-authored-by: Cursor --- packages/react-native/package.json | 2 +- .../plugin/bake-native-versions.js | 23 +++++++++ .../react-native/plugin/build/bundle-phase.js | 7 +-- .../plugin/build/bundle-phase.js.map | 2 +- .../react-native/plugin/build/gradle.d.ts | 7 +-- packages/react-native/plugin/build/gradle.js | 20 ++++++-- .../react-native/plugin/build/gradle.js.map | 2 +- packages/react-native/plugin/build/index.d.ts | 3 +- .../react-native/plugin/build/index.js.map | 2 +- .../plugin/build/native-versions.baked.json | 4 ++ .../plugin/build/native-versions.d.ts | 8 +-- .../plugin/build/native-versions.js | 39 +++++++-------- .../plugin/build/native-versions.js.map | 2 +- .../plugin/src/__tests__/plugin.test.ts | 45 +++++++++++++++-- .../react-native/plugin/src/bundle-phase.ts | 8 +-- packages/react-native/plugin/src/gradle.ts | 22 ++++++-- packages/react-native/plugin/src/index.ts | 3 +- .../plugin/src/native-versions.ts | 50 ++++++++----------- 18 files changed, 165 insertions(+), 84 deletions(-) create mode 100644 packages/react-native/plugin/bake-native-versions.js create mode 100644 packages/react-native/plugin/build/native-versions.baked.json diff --git a/packages/react-native/package.json b/packages/react-native/package.json index a13a5bd..99eb29c 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -30,7 +30,7 @@ "react-native": "0.87.1" }, "scripts": { - "build:plugin": "node ../../node_modules/typescript/lib/tsc.js -p plugin/tsconfig.json", + "build:plugin": "node ../../node_modules/typescript/lib/tsc.js -p plugin/tsconfig.json && node plugin/bake-native-versions.js", "prepack": "node ../../scripts/cli-check-releasable-pins.ts" }, "codegenConfig": { diff --git a/packages/react-native/plugin/bake-native-versions.js b/packages/react-native/plugin/bake-native-versions.js new file mode 100644 index 0000000..59f6157 --- /dev/null +++ b/packages/react-native/plugin/bake-native-versions.js @@ -0,0 +1,23 @@ +/** + * Copy android.sdk and android.gradlePlugin from the repo-root + * native-versions.json into plugin/build. The published package cannot + * ship the repo-root file, so the plugin reads this copy at runtime. + */ +const { mkdirSync, readFileSync, writeFileSync } = require('node:fs'); +const { dirname, join } = require('node:path'); + +const repoRoot = join(__dirname, '..', '..', '..'); +const source = join(repoRoot, 'native-versions.json'); +const parsed = JSON.parse(readFileSync(source, 'utf8')); +const sdk = parsed.android && parsed.android.sdk; +const gradlePlugin = parsed.android && parsed.android.gradlePlugin; +if (typeof sdk !== 'string' || typeof gradlePlugin !== 'string') { + throw new Error(`${source} is missing android.sdk or android.gradlePlugin`); +} +if (!/^[0-9A-Za-z.+_-]+$/.test(sdk) || !/^[0-9A-Za-z.+_-]+$/.test(gradlePlugin)) { + throw new Error(`refusing to bake native versions from ${source}`); +} + +const out = join(__dirname, 'build', 'native-versions.baked.json'); +mkdirSync(dirname(out), { recursive: true }); +writeFileSync(out, `${JSON.stringify({ sdk, gradlePlugin }, null, 2)}\n`); diff --git a/packages/react-native/plugin/build/bundle-phase.js b/packages/react-native/plugin/build/bundle-phase.js index 908621b..91db4a7 100644 --- a/packages/react-native/plugin/build/bundle-phase.js +++ b/packages/react-native/plugin/build/bundle-phase.js @@ -19,17 +19,18 @@ exports.BARE_BUNDLE_SCRIPT = [ '/bin/sh -c "\\"$WITH_ENVIRONMENT\\" \\"$BUGSEE_XCODE\\""', '', ].join('\n'); -const BUGSEE_XCODE = '"${SRCROOT}/../node_modules/@bugsee/react-native/scripts/bugsee-xcode.sh"'; /** * Expo's bundle phase sets ENTRY_FILE, CLI_PATH and BUNDLE_COMMAND, then * runs react-native-xcode.sh. Replacing the whole phase would drop those * and the Expo bundle would not be the one bugsee-xcode.sh injects into. - * Swap only that invocation for the existing hook. + * Swap only that invocation. Resolve the hook the way Expo resolves + * react-native-xcode.sh, so a hoisted node_modules still finds it. */ const EXPO_XCODE_INVOCATION = /`"\$NODE_BINARY" --print "require\('path'\)\.dirname\(require\.resolve\('react-native\/package\.json'\)\) \+ '\/scripts\/react-native-xcode\.sh'"`/; const EXPO_REPLACEMENT = [ 'export REACT_NATIVE_PATH="$("$NODE_BINARY" --print "require(\'path\').dirname(require.resolve(\'react-native/package.json\'))")"', - `/bin/bash ${BUGSEE_XCODE}`, + 'BUGSEE_XCODE="$("$NODE_BINARY" --print "require(\'path\').join(require(\'path\').dirname(require.resolve(\'@bugsee/react-native/package.json\')), \'scripts/bugsee-xcode.sh\')")"', + '/bin/bash "$BUGSEE_XCODE"', ].join('\n'); function rewriteBundlePhase(script) { if (script.includes('bugsee-xcode.sh')) { diff --git a/packages/react-native/plugin/build/bundle-phase.js.map b/packages/react-native/plugin/build/bundle-phase.js.map index ee07bc9..3475647 100644 --- a/packages/react-native/plugin/build/bundle-phase.js.map +++ b/packages/react-native/plugin/build/bundle-phase.js.map @@ -1 +1 @@ -{"version":3,"file":"bundle-phase.js","sourceRoot":"","sources":["../src/bundle-phase.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"bundle-phase.js","sourceRoot":"","sources":["../src/bundle-phase.ts"],"names":[],"mappings":";;;AAkCA,gDAcC;AAkBD,8DA2BC;AA7FD,6CAAgE;AAEhE;;;;;GAKG;AACU,QAAA,kBAAkB,GAAG;IAChC,QAAQ;IACR,EAAE;IACF,yEAAyE;IACzE,wFAAwF;IACxF,EAAE;IACF,0DAA0D;IAC1D,EAAE;CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb;;;;;;GAMG;AACH,MAAM,qBAAqB,GACzB,oJAAoJ,CAAC;AAEvJ,MAAM,gBAAgB,GAAG;IACvB,kIAAkI;IAClI,mLAAmL;IACnL,2BAA2B;CAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,SAAgB,kBAAkB,CAAC,MAAc;IAC/C,IAAI,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACvF,OAAO,0BAAkB,CAAC;IAC5B,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAC7C,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,EAAE,iBAAiB,CAAC,KAAK,gBAAgB,IAAI,CAAC;IAClG,CAAC;IACD,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,gBAAgB,IAAI,CAAC;AAChE,CAAC;AAkBD,SAAgB,yBAAyB,CAAC,OAAyB;IACjE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,wBAAwB,CAAC;IACzE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACpE,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,IAAI,IAAI,KAAK,qCAAqC,EAAE,CAAC;YACnD,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC;YAC/C,CAAC,CAAC,IAAA,4BAAe,EAAC,KAAK,CAAC,WAAW,CAAC;YACpC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;QACtB,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACzC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAA,4BAAe,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrF,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/gradle.d.ts b/packages/react-native/plugin/build/gradle.d.ts index 44e7d0f..b39e4d1 100644 --- a/packages/react-native/plugin/build/gradle.d.ts +++ b/packages/react-native/plugin/build/gradle.d.ts @@ -6,8 +6,9 @@ export declare function ensureMavenCentral(settingsGradle: string): string; export declare function ensureGradlePluginDeclared(projectBuildGradle: string, version: string): string; /** - * `ndkVersion` is `android.sdk` from native-versions.json, or null when - * native crash reporting is opted out. Null skips the artifact; the plugin - * is still applied so mapping upload can run. + * `ndkVersion` is the baked `android.sdk`, or null when native crash + * reporting is explicitly off. Null does not add an implementation line. + * It excludes the wrapper's `api` NDK artifact so that AAR stays off the + * APK. The wrapper declaration itself is left in place. */ export declare function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string; diff --git a/packages/react-native/plugin/build/gradle.js b/packages/react-native/plugin/build/gradle.js index b56f0ed..49fc28a 100644 --- a/packages/react-native/plugin/build/gradle.js +++ b/packages/react-native/plugin/build/gradle.js @@ -96,10 +96,12 @@ function ensureGradlePluginDeclared(projectBuildGradle, version) { } return declaration + projectBuildGradle; } +const NDK_EXCLUDE = "exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"; /** - * `ndkVersion` is `android.sdk` from native-versions.json, or null when - * native crash reporting is opted out. Null skips the artifact; the plugin - * is still applied so mapping upload can run. + * `ndkVersion` is the baked `android.sdk`, or null when native crash + * reporting is explicitly off. Null does not add an implementation line. + * It excludes the wrapper's `api` NDK artifact so that AAR stays off the + * APK. The wrapper declaration itself is left in place. */ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { let next = appBuildGradle; @@ -112,7 +114,10 @@ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { next = `apply plugin: "${PLUGIN_ID}"\n${next}`; } } - if (ndkVersion === null || next.includes('bugsee-android-ndk')) { + if (ndkVersion === null) { + return ensureNdkExcluded(next); + } + if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(next)) { return next; } if (!/^[0-9A-Za-z.+_-]+$/.test(ndkVersion)) { @@ -126,4 +131,11 @@ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { const brace = next.indexOf('{', deps); return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; } +function ensureNdkExcluded(source) { + if (source.includes(NDK_EXCLUDE)) { + return source; + } + const block = ['', 'configurations.configureEach {', ` ${NDK_EXCLUDE}`, '}', ''].join('\n'); + return `${source.replace(/\s*$/, '')}\n${block}`; +} //# sourceMappingURL=gradle.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/gradle.js.map b/packages/react-native/plugin/build/gradle.js.map index c61a5fc..497c194 100644 --- a/packages/react-native/plugin/build/gradle.js.map +++ b/packages/react-native/plugin/build/gradle.js.map @@ -1 +1 @@ -{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/index.d.ts b/packages/react-native/plugin/build/index.d.ts index e507b24..9801601 100644 --- a/packages/react-native/plugin/build/index.d.ts +++ b/packages/react-native/plugin/build/index.d.ts @@ -11,7 +11,8 @@ export interface BugseePluginProps { uploadSymbols?: boolean; /** * Defaults on. Writes `plugin.ndk.enabled=true` for a real token and adds - * `com.bugsee:bugsee-android-ndk`. `false` opts out of both. + * `com.bugsee:bugsee-android-ndk`. `false` skips both and excludes the + * wrapper's NDK AAR from the app. */ nativeCrashReporting?: boolean; /** Defaults to native-versions.json `android.gradlePlugin`. */ diff --git a/packages/react-native/plugin/build/index.js.map b/packages/react-native/plugin/build/index.js.map index 1158337..40db5ed 100644 --- a/packages/react-native/plugin/build/index.js.map +++ b/packages/react-native/plugin/build/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/native-versions.baked.json b/packages/react-native/plugin/build/native-versions.baked.json new file mode 100644 index 0000000..95aedd6 --- /dev/null +++ b/packages/react-native/plugin/build/native-versions.baked.json @@ -0,0 +1,4 @@ +{ + "sdk": "7.3.0", + "gradlePlugin": "4.0.7" +} diff --git a/packages/react-native/plugin/build/native-versions.d.ts b/packages/react-native/plugin/build/native-versions.d.ts index 3133f96..2ab4736 100644 --- a/packages/react-native/plugin/build/native-versions.d.ts +++ b/packages/react-native/plugin/build/native-versions.d.ts @@ -3,8 +3,8 @@ export interface AndroidNativeVersions { readonly gradlePlugin: string; } /** - * Walk up from the plugin until `native-versions.json` appears. That file - * is the only pin: the Gradle plugin version is `android.gradlePlugin` and - * the NDK artifact version is `android.sdk`. + * `build:plugin` copies `android.sdk` and `android.gradlePlugin` from the + * repo-root native-versions.json into `native-versions.baked.json` beside + * this module. A published install has no repo-root JSON to walk to. */ -export declare function loadNativeVersions(startDir: string): AndroidNativeVersions; +export declare function loadNativeVersions(moduleDir?: string): AndroidNativeVersions; diff --git a/packages/react-native/plugin/build/native-versions.js b/packages/react-native/plugin/build/native-versions.js index 4e5d7ec..cffb517 100644 --- a/packages/react-native/plugin/build/native-versions.js +++ b/packages/react-native/plugin/build/native-versions.js @@ -4,29 +4,24 @@ exports.loadNativeVersions = loadNativeVersions; const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); /** - * Walk up from the plugin until `native-versions.json` appears. That file - * is the only pin: the Gradle plugin version is `android.gradlePlugin` and - * the NDK artifact version is `android.sdk`. + * `build:plugin` copies `android.sdk` and `android.gradlePlugin` from the + * repo-root native-versions.json into `native-versions.baked.json` beside + * this module. A published install has no repo-root JSON to walk to. */ -function loadNativeVersions(startDir) { - let dir = startDir; - for (let i = 0; i < 10; i += 1) { - const candidate = (0, node_path_1.join)(dir, 'native-versions.json'); - if ((0, node_fs_1.existsSync)(candidate)) { - const parsed = JSON.parse((0, node_fs_1.readFileSync)(candidate, 'utf8')); - const sdk = parsed.android?.sdk; - const gradlePlugin = parsed.android?.gradlePlugin; - if (!sdk || !gradlePlugin) { - throw new Error(`${candidate} is missing android.sdk or android.gradlePlugin`); - } - return { sdk, gradlePlugin }; - } - const parent = (0, node_path_1.dirname)(dir); - if (parent === dir) { - break; - } - dir = parent; +function loadNativeVersions(moduleDir = __dirname) { + const file = (0, node_path_1.join)(moduleDir, 'native-versions.baked.json'); + let parsed; + try { + parsed = JSON.parse((0, node_fs_1.readFileSync)(file, 'utf8')); } - throw new Error(`native-versions.json not found above ${startDir}`); + catch (error) { + throw new Error(`baked native versions not found at ${file}`, { cause: error }); + } + const sdk = parsed.sdk; + const gradlePlugin = parsed.gradlePlugin; + if (!sdk || !gradlePlugin) { + throw new Error(`${file} is missing sdk or gradlePlugin`); + } + return { sdk, gradlePlugin }; } //# sourceMappingURL=native-versions.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/native-versions.js.map b/packages/react-native/plugin/build/native-versions.js.map index ade96dd..c2c6aa9 100644 --- a/packages/react-native/plugin/build/native-versions.js.map +++ b/packages/react-native/plugin/build/native-versions.js.map @@ -1 +1 @@ -{"version":3,"file":"native-versions.js","sourceRoot":"","sources":["../src/native-versions.ts"],"names":[],"mappings":";;AAoBA,gDAoBC;AAxCD,qCAAmD;AACnD,yCAA0C;AAc1C;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,QAAgB;IACjD,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;QACpD,IAAI,IAAA,oBAAU,EAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,SAAS,EAAE,MAAM,CAAC,CAAuB,CAAC;YACjF,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;YAChC,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC;YAClD,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,iDAAiD,CAAC,CAAC;YACjF,CAAC;YACD,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;QAC/B,CAAC;QACD,MAAM,MAAM,GAAG,IAAA,mBAAO,EAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,MAAM;QACR,CAAC;QACD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wCAAwC,QAAQ,EAAE,CAAC,CAAC;AACtE,CAAC"} \ No newline at end of file +{"version":3,"file":"native-versions.js","sourceRoot":"","sources":["../src/native-versions.ts"],"names":[],"mappings":";;AAkBA,gDAcC;AAhCD,qCAAuC;AACvC,yCAAiC;AAYjC;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,YAAoB,SAAS;IAC9D,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,4BAA4B,CAAC,CAAC;IAC3D,IAAI,MAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAkB,CAAC;IACnE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACvB,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IACzC,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,iCAAiC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;AAC/B,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index 6b76a7a..db61ad4 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -1,4 +1,6 @@ -import { readFileSync } from 'node:fs'; +import { cpSync, existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs'; +import { createRequire } from 'node:module'; +import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { isPlaceholderToken as exampleIsPlaceholderToken } from '../../../../../examples/bare/endpoint'; @@ -143,8 +145,16 @@ describe('settled iOS hooks', () => { expect(rewritten).toContain('bugsee-xcode.sh'); expect(rewritten).toContain('export:embed'); expect(rewritten).toContain('resolveAppEntry'); + expect(rewritten).toContain('CLI_PATH'); + expect(rewritten).toContain('ENTRY_FILE'); expect(rewritten).not.toContain('react-native-xcode.sh'); expect(rewritten).toContain('REACT_NATIVE_PATH'); + expect(rewritten).toContain( + 'BUGSEE_XCODE="$("$NODE_BINARY" --print "require(\'path\').join(require(\'path\').dirname(require.resolve(\'@bugsee/react-native/package.json\')), \'scripts/bugsee-xcode.sh\')")"', + ); + expect(rewritten).toContain('/bin/bash "$BUGSEE_XCODE"'); + expect(rewritten).not.toContain('${SRCROOT}/../node_modules'); + expect(rewritten.match(/\/bin\/bash/g)).toHaveLength(1); }); it('round-trips a pbxproj shell script', () => { @@ -153,7 +163,7 @@ describe('settled iOS hooks', () => { }); describe('Android Gradle edits', () => { - const versions = loadNativeVersions(join(__dirname, '..')); + const versions = loadNativeVersions(join(__dirname, '..', '..', 'build')); const settings = [ 'pluginManagement {', @@ -201,14 +211,41 @@ describe('Android Gradle edits', () => { const next = ensureAppAppliesPlugin(app, versions.sdk); expect(next).toContain('apply plugin: "com.bugsee.android.gradle"'); expect(next).toContain(`implementation "com.bugsee:bugsee-android-ndk:${versions.sdk}"`); + expect(next).not.toContain("exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"); expect(ensureAppAppliesPlugin(next, versions.sdk)).toBe(next); }); - it('skips the NDK artifact when native crash reporting is off', () => { + it('excludes the NDK artifact when native crash reporting is off', () => { const app = 'apply plugin: "com.facebook.react"\n\ndependencies {\n}\n'; const next = ensureAppAppliesPlugin(app, null); expect(next).toContain('apply plugin: "com.bugsee.android.gradle"'); - expect(next).not.toContain('bugsee-android-ndk'); + expect(next).toContain("exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"); + expect(next).not.toMatch(/implementation\s+["']com\.bugsee:bugsee-android-ndk:/); + expect(ensureAppAppliesPlugin(next, null)).toBe(next); + }); +}); + +describe('published native versions', () => { + it('loads baked versions from a tree that has only the published plugin files', () => { + const source = JSON.parse(readFileSync(join(repoRoot, 'native-versions.json'), 'utf8')) as { + android: { sdk: string; gradlePlugin: string }; + }; + const temp = mkdtempSync(join(tmpdir(), 'bugsee-published-')); + try { + const build = join(temp, 'plugin', 'build'); + cpSync(join(__dirname, '..', '..', 'build'), build, { recursive: true }); + expect(existsSync(join(temp, 'native-versions.json'))).toBe(false); + expect(existsSync(join(temp, 'plugin', 'native-versions.json'))).toBe(false); + const loaded = createRequire(join(build, 'native-versions.js'))( + join(build, 'native-versions.js'), + ) as { loadNativeVersions: () => { sdk: string; gradlePlugin: string } }; + expect(loaded.loadNativeVersions()).toEqual({ + sdk: source.android.sdk, + gradlePlugin: source.android.gradlePlugin, + }); + } finally { + rmSync(temp, { recursive: true, force: true }); + } }); }); diff --git a/packages/react-native/plugin/src/bundle-phase.ts b/packages/react-native/plugin/src/bundle-phase.ts index b20a293..9d41fc7 100644 --- a/packages/react-native/plugin/src/bundle-phase.ts +++ b/packages/react-native/plugin/src/bundle-phase.ts @@ -16,20 +16,20 @@ export const BARE_BUNDLE_SCRIPT = [ '', ].join('\n'); -const BUGSEE_XCODE = '"${SRCROOT}/../node_modules/@bugsee/react-native/scripts/bugsee-xcode.sh"'; - /** * Expo's bundle phase sets ENTRY_FILE, CLI_PATH and BUNDLE_COMMAND, then * runs react-native-xcode.sh. Replacing the whole phase would drop those * and the Expo bundle would not be the one bugsee-xcode.sh injects into. - * Swap only that invocation for the existing hook. + * Swap only that invocation. Resolve the hook the way Expo resolves + * react-native-xcode.sh, so a hoisted node_modules still finds it. */ const EXPO_XCODE_INVOCATION = /`"\$NODE_BINARY" --print "require\('path'\)\.dirname\(require\.resolve\('react-native\/package\.json'\)\) \+ '\/scripts\/react-native-xcode\.sh'"`/; const EXPO_REPLACEMENT = [ 'export REACT_NATIVE_PATH="$("$NODE_BINARY" --print "require(\'path\').dirname(require.resolve(\'react-native/package.json\'))")"', - `/bin/bash ${BUGSEE_XCODE}`, + 'BUGSEE_XCODE="$("$NODE_BINARY" --print "require(\'path\').join(require(\'path\').dirname(require.resolve(\'@bugsee/react-native/package.json\')), \'scripts/bugsee-xcode.sh\')")"', + '/bin/bash "$BUGSEE_XCODE"', ].join('\n'); export function rewriteBundlePhase(script: string): string { diff --git a/packages/react-native/plugin/src/gradle.ts b/packages/react-native/plugin/src/gradle.ts index 1782e87..89edbad 100644 --- a/packages/react-native/plugin/src/gradle.ts +++ b/packages/react-native/plugin/src/gradle.ts @@ -98,10 +98,13 @@ export function ensureGradlePluginDeclared(projectBuildGradle: string, version: return declaration + projectBuildGradle; } +const NDK_EXCLUDE = "exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"; + /** - * `ndkVersion` is `android.sdk` from native-versions.json, or null when - * native crash reporting is opted out. Null skips the artifact; the plugin - * is still applied so mapping upload can run. + * `ndkVersion` is the baked `android.sdk`, or null when native crash + * reporting is explicitly off. Null does not add an implementation line. + * It excludes the wrapper's `api` NDK artifact so that AAR stays off the + * APK. The wrapper declaration itself is left in place. */ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string { let next = appBuildGradle; @@ -113,7 +116,10 @@ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: strin next = `apply plugin: "${PLUGIN_ID}"\n${next}`; } } - if (ndkVersion === null || next.includes('bugsee-android-ndk')) { + if (ndkVersion === null) { + return ensureNdkExcluded(next); + } + if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(next)) { return next; } if (!/^[0-9A-Za-z.+_-]+$/.test(ndkVersion)) { @@ -127,3 +133,11 @@ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: strin const brace = next.indexOf('{', deps); return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; } + +function ensureNdkExcluded(source: string): string { + if (source.includes(NDK_EXCLUDE)) { + return source; + } + const block = ['', 'configurations.configureEach {', ` ${NDK_EXCLUDE}`, '}', ''].join('\n'); + return `${source.replace(/\s*$/, '')}\n${block}`; +} diff --git a/packages/react-native/plugin/src/index.ts b/packages/react-native/plugin/src/index.ts index faca578..0ef70c4 100644 --- a/packages/react-native/plugin/src/index.ts +++ b/packages/react-native/plugin/src/index.ts @@ -34,7 +34,8 @@ export interface BugseePluginProps { uploadSymbols?: boolean; /** * Defaults on. Writes `plugin.ndk.enabled=true` for a real token and adds - * `com.bugsee:bugsee-android-ndk`. `false` opts out of both. + * `com.bugsee:bugsee-android-ndk`. `false` skips both and excludes the + * wrapper's NDK AAR from the app. */ nativeCrashReporting?: boolean; /** Defaults to native-versions.json `android.gradlePlugin`. */ diff --git a/packages/react-native/plugin/src/native-versions.ts b/packages/react-native/plugin/src/native-versions.ts index db84169..f270d17 100644 --- a/packages/react-native/plugin/src/native-versions.ts +++ b/packages/react-native/plugin/src/native-versions.ts @@ -1,41 +1,33 @@ -import { existsSync, readFileSync } from 'node:fs'; -import { dirname, join } from 'node:path'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; export interface AndroidNativeVersions { readonly sdk: string; readonly gradlePlugin: string; } -interface NativeVersionsFile { - readonly android?: { - readonly sdk?: string; - readonly gradlePlugin?: string; - }; +interface BakedVersions { + readonly sdk?: string; + readonly gradlePlugin?: string; } /** - * Walk up from the plugin until `native-versions.json` appears. That file - * is the only pin: the Gradle plugin version is `android.gradlePlugin` and - * the NDK artifact version is `android.sdk`. + * `build:plugin` copies `android.sdk` and `android.gradlePlugin` from the + * repo-root native-versions.json into `native-versions.baked.json` beside + * this module. A published install has no repo-root JSON to walk to. */ -export function loadNativeVersions(startDir: string): AndroidNativeVersions { - let dir = startDir; - for (let i = 0; i < 10; i += 1) { - const candidate = join(dir, 'native-versions.json'); - if (existsSync(candidate)) { - const parsed = JSON.parse(readFileSync(candidate, 'utf8')) as NativeVersionsFile; - const sdk = parsed.android?.sdk; - const gradlePlugin = parsed.android?.gradlePlugin; - if (!sdk || !gradlePlugin) { - throw new Error(`${candidate} is missing android.sdk or android.gradlePlugin`); - } - return { sdk, gradlePlugin }; - } - const parent = dirname(dir); - if (parent === dir) { - break; - } - dir = parent; +export function loadNativeVersions(moduleDir: string = __dirname): AndroidNativeVersions { + const file = join(moduleDir, 'native-versions.baked.json'); + let parsed: BakedVersions; + try { + parsed = JSON.parse(readFileSync(file, 'utf8')) as BakedVersions; + } catch (error) { + throw new Error(`baked native versions not found at ${file}`, { cause: error }); } - throw new Error(`native-versions.json not found above ${startDir}`); + const sdk = parsed.sdk; + const gradlePlugin = parsed.gradlePlugin; + if (!sdk || !gradlePlugin) { + throw new Error(`${file} is missing sdk or gradlePlugin`); + } + return { sdk, gradlePlugin }; } From 3a49e4b1700ca15161d4f1313ba0b90c14be42f0 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 02:56:09 +0500 Subject: [PATCH 03/11] Task 13.4: drop a stale NDK exclude when crash reporting is on. A later prebuild with the option omitted or true kept the exclude a false run had written, so the NDK artifact stayed off the app. Co-authored-by: Cursor --- .../react-native/plugin/build/gradle.d.ts | 4 ++- packages/react-native/plugin/build/gradle.js | 30 +++++++++++++++-- .../react-native/plugin/build/gradle.js.map | 2 +- .../plugin/src/__tests__/plugin.test.ts | 20 ++++++++++++ packages/react-native/plugin/src/gradle.ts | 32 +++++++++++++++++-- 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/packages/react-native/plugin/build/gradle.d.ts b/packages/react-native/plugin/build/gradle.d.ts index b39e4d1..419cb12 100644 --- a/packages/react-native/plugin/build/gradle.d.ts +++ b/packages/react-native/plugin/build/gradle.d.ts @@ -9,6 +9,8 @@ export declare function ensureGradlePluginDeclared(projectBuildGradle: string, v * `ndkVersion` is the baked `android.sdk`, or null when native crash * reporting is explicitly off. Null does not add an implementation line. * It excludes the wrapper's `api` NDK artifact so that AAR stays off the - * APK. The wrapper declaration itself is left in place. + * APK. A later run with the option omitted or on removes that exclude and + * adds the implementation line. The wrapper declaration itself is left in + * place. */ export declare function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string; diff --git a/packages/react-native/plugin/build/gradle.js b/packages/react-native/plugin/build/gradle.js index 49fc28a..46ed5a6 100644 --- a/packages/react-native/plugin/build/gradle.js +++ b/packages/react-native/plugin/build/gradle.js @@ -101,7 +101,9 @@ const NDK_EXCLUDE = "exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"; * `ndkVersion` is the baked `android.sdk`, or null when native crash * reporting is explicitly off. Null does not add an implementation line. * It excludes the wrapper's `api` NDK artifact so that AAR stays off the - * APK. The wrapper declaration itself is left in place. + * APK. A later run with the option omitted or on removes that exclude and + * adds the implementation line. The wrapper declaration itself is left in + * place. */ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { let next = appBuildGradle; @@ -117,6 +119,7 @@ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { if (ndkVersion === null) { return ensureNdkExcluded(next); } + next = dropNdkExclude(next); if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(next)) { return next; } @@ -131,11 +134,32 @@ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { const brace = next.indexOf('{', deps); return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; } +const NDK_EXCLUDE_BLOCK = [ + 'configurations.configureEach {', + ` ${NDK_EXCLUDE}`, + '}', +].join('\n'); function ensureNdkExcluded(source) { - if (source.includes(NDK_EXCLUDE)) { + if (source.includes(NDK_EXCLUDE_BLOCK)) { return source; } - const block = ['', 'configurations.configureEach {', ` ${NDK_EXCLUDE}`, '}', ''].join('\n'); + const block = ['', NDK_EXCLUDE_BLOCK, ''].join('\n'); return `${source.replace(/\s*$/, '')}\n${block}`; } +function dropNdkExclude(source) { + const at = source.indexOf(NDK_EXCLUDE_BLOCK); + if (at < 0) { + return source; + } + let start = at; + if (start > 0 && source[start - 1] === '\n') { + start -= 1; + } + let end = at + NDK_EXCLUDE_BLOCK.length; + while (end < source.length && source[end] === '\n') { + end += 1; + } + const next = source.slice(0, start) + source.slice(end); + return next.endsWith('\n') || next.length === 0 ? next : `${next}\n`; +} //# sourceMappingURL=gradle.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/gradle.js.map b/packages/react-native/plugin/build/gradle.js.map index 497c194..50079a5 100644 --- a/packages/react-native/plugin/build/gradle.js.map +++ b/packages/react-native/plugin/build/gradle.js.map @@ -1 +1 @@ -{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index db61ad4..cd8d26f 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -223,6 +223,26 @@ describe('Android Gradle edits', () => { expect(next).not.toMatch(/implementation\s+["']com\.bugsee:bugsee-android-ndk:/); expect(ensureAppAppliesPlugin(next, null)).toBe(next); }); + + it('removes a previous NDK exclude when native crash reporting is on', () => { + const app = [ + 'apply plugin: "com.facebook.react"', + 'apply plugin: "com.bugsee.android.gradle"', + '', + 'dependencies {', + '}', + '', + 'configurations.configureEach {', + " exclude group: 'com.bugsee', module: 'bugsee-android-ndk'", + '}', + '', + ].join('\n'); + const next = ensureAppAppliesPlugin(app, versions.sdk); + expect(next).not.toContain('configurations.configureEach'); + expect(next).not.toContain("exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"); + expect(next).toContain(`implementation "com.bugsee:bugsee-android-ndk:${versions.sdk}"`); + expect(ensureAppAppliesPlugin(next, versions.sdk)).toBe(next); + }); }); describe('published native versions', () => { diff --git a/packages/react-native/plugin/src/gradle.ts b/packages/react-native/plugin/src/gradle.ts index 89edbad..8507dce 100644 --- a/packages/react-native/plugin/src/gradle.ts +++ b/packages/react-native/plugin/src/gradle.ts @@ -104,7 +104,9 @@ const NDK_EXCLUDE = "exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"; * `ndkVersion` is the baked `android.sdk`, or null when native crash * reporting is explicitly off. Null does not add an implementation line. * It excludes the wrapper's `api` NDK artifact so that AAR stays off the - * APK. The wrapper declaration itself is left in place. + * APK. A later run with the option omitted or on removes that exclude and + * adds the implementation line. The wrapper declaration itself is left in + * place. */ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string { let next = appBuildGradle; @@ -119,6 +121,7 @@ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: strin if (ndkVersion === null) { return ensureNdkExcluded(next); } + next = dropNdkExclude(next); if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(next)) { return next; } @@ -134,10 +137,33 @@ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: strin return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; } +const NDK_EXCLUDE_BLOCK = [ + 'configurations.configureEach {', + ` ${NDK_EXCLUDE}`, + '}', +].join('\n'); + function ensureNdkExcluded(source: string): string { - if (source.includes(NDK_EXCLUDE)) { + if (source.includes(NDK_EXCLUDE_BLOCK)) { return source; } - const block = ['', 'configurations.configureEach {', ` ${NDK_EXCLUDE}`, '}', ''].join('\n'); + const block = ['', NDK_EXCLUDE_BLOCK, ''].join('\n'); return `${source.replace(/\s*$/, '')}\n${block}`; } + +function dropNdkExclude(source: string): string { + const at = source.indexOf(NDK_EXCLUDE_BLOCK); + if (at < 0) { + return source; + } + let start = at; + if (start > 0 && source[start - 1] === '\n') { + start -= 1; + } + let end = at + NDK_EXCLUDE_BLOCK.length; + while (end < source.length && source[end] === '\n') { + end += 1; + } + const next = source.slice(0, start) + source.slice(end); + return next.endsWith('\n') || next.length === 0 ? next : `${next}\n`; +} From d1571cb3f0f7aff82abe0207c64a91ddd1f9c1fd Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 03:30:57 +0500 Subject: [PATCH 04/11] Task 13.4: resolve bugsee-cli from the package graph. The Archive post-action only searched three node_modules directories, so a hoisted Expo app never found the CLI and the dSYM upload failed. Co-authored-by: Cursor --- .../plugin/build/dsym-script.d.ts | 2 +- .../react-native/plugin/build/dsym-script.js | 71 ++++++++++++++++++- .../plugin/build/dsym-script.js.map | 2 +- .../react-native/plugin/build/scheme.d.ts | 5 +- packages/react-native/plugin/build/scheme.js | 5 +- .../react-native/plugin/build/scheme.js.map | 2 +- .../plugin/src/__tests__/plugin.test.ts | 32 ++++----- .../react-native/plugin/src/dsym-script.ts | 71 ++++++++++++++++++- packages/react-native/plugin/src/scheme.ts | 5 +- 9 files changed, 161 insertions(+), 34 deletions(-) diff --git a/packages/react-native/plugin/build/dsym-script.d.ts b/packages/react-native/plugin/build/dsym-script.d.ts index 3739ce4..c4a25ed 100644 --- a/packages/react-native/plugin/build/dsym-script.d.ts +++ b/packages/react-native/plugin/build/dsym-script.d.ts @@ -1 +1 @@ -export declare const DSYM_POST_ACTION_SCRIPT = "CREDS=\"${PROJECT_DIR}/../credentials.json\"\nTOKEN=\"$BUGSEE_APP_TOKEN\"\nif [ -z \"$TOKEN\" ]; then\n TOKEN=\"$BUGSEE_TOKEN_IOS\"\nfi\nif [ -z \"$TOKEN\" ] && [ -f \"$CREDS\" ]; then\n TOKEN=$(/usr/bin/plutil -extract ios raw -o - \"$CREDS\" 2>/dev/null || true)\nfi\nif [ -n \"$TOKEN\" ]; then\n export BUGSEE_APP_TOKEN=\"$TOKEN\"\nfi\nif [ -z \"$BUGSEE_ENDPOINT\" ] && [ -f \"$CREDS\" ]; then\n ENDPOINT=$(/usr/bin/plutil -extract endpoint raw -o - \"$CREDS\" 2>/dev/null || true)\n if [ -n \"$ENDPOINT\" ]; then\n export BUGSEE_ENDPOINT=\"$ENDPOINT\"\n fi\nfi\n\ntry_bin() {\n if [ -x \"$1\" ]; then\n \"$1\" xcode post-action\n exit $?\n fi\n}\n\nfor dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\ndo\n if [ \"$(uname -m)\" = \"x86_64\" ]; then\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n else\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n fi\ndone\n\n# Archive's PATH has no node, and the npm shim's shebang searches PATH.\nif [ ! -x \"$NODE_BINARY\" ]; then\n if [ -f \"${PROJECT_DIR}/.xcode.env\" ]; then\n . \"${PROJECT_DIR}/.xcode.env\"\n fi\n if [ -f \"${PROJECT_DIR}/.xcode.env.local\" ]; then\n . \"${PROJECT_DIR}/.xcode.env.local\"\n fi\nfi\nif [ ! -x \"$NODE_BINARY\" ]; then\n RN_FIND=\"\"\n if [ -n \"$REACT_NATIVE_PATH\" ] && [ -f \"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\"\n elif [ -f \"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\"\n fi\n if [ -n \"$RN_FIND\" ]; then\n NODE_BINARY=$(/bin/bash -c '. \"$1\" >/dev/null 2>&1; command -v node' _ \"$RN_FIND\" || true)\n fi\nfi\nif [ -n \"$NODE_BINARY\" ] && [ -x \"$NODE_BINARY\" ]; then\n PATH=\"$(dirname \"$NODE_BINARY\"):$PATH\"\n export PATH NODE_BINARY\n for dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\n do\n if [ -f \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" ]; then\n \"$NODE_BINARY\" \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" xcode post-action\n exit $?\n fi\n done\nfi\n\necho \"bugsee-cli: not found under node_modules\" >&2\nexit 1\n"; +export declare const DSYM_POST_ACTION_SCRIPT: string; diff --git a/packages/react-native/plugin/build/dsym-script.js b/packages/react-native/plugin/build/dsym-script.js index cc8de7f..d2ea3f6 100644 --- a/packages/react-native/plugin/build/dsym-script.js +++ b/packages/react-native/plugin/build/dsym-script.js @@ -1,7 +1,72 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DSYM_POST_ACTION_SCRIPT = void 0; -// The Archive post-action from examples/bare BareExample.xcscheme. -// Copied, not rewritten: the plugin inserts this script into an Expo scheme. -exports.DSYM_POST_ACTION_SCRIPT = "CREDS=\"${PROJECT_DIR}/../credentials.json\"\nTOKEN=\"$BUGSEE_APP_TOKEN\"\nif [ -z \"$TOKEN\" ]; then\n TOKEN=\"$BUGSEE_TOKEN_IOS\"\nfi\nif [ -z \"$TOKEN\" ] && [ -f \"$CREDS\" ]; then\n TOKEN=$(/usr/bin/plutil -extract ios raw -o - \"$CREDS\" 2>/dev/null || true)\nfi\nif [ -n \"$TOKEN\" ]; then\n export BUGSEE_APP_TOKEN=\"$TOKEN\"\nfi\nif [ -z \"$BUGSEE_ENDPOINT\" ] && [ -f \"$CREDS\" ]; then\n ENDPOINT=$(/usr/bin/plutil -extract endpoint raw -o - \"$CREDS\" 2>/dev/null || true)\n if [ -n \"$ENDPOINT\" ]; then\n export BUGSEE_ENDPOINT=\"$ENDPOINT\"\n fi\nfi\n\ntry_bin() {\n if [ -x \"$1\" ]; then\n \"$1\" xcode post-action\n exit $?\n fi\n}\n\nfor dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\ndo\n if [ \"$(uname -m)\" = \"x86_64\" ]; then\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n else\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n fi\ndone\n\n# Archive's PATH has no node, and the npm shim's shebang searches PATH.\nif [ ! -x \"$NODE_BINARY\" ]; then\n if [ -f \"${PROJECT_DIR}/.xcode.env\" ]; then\n . \"${PROJECT_DIR}/.xcode.env\"\n fi\n if [ -f \"${PROJECT_DIR}/.xcode.env.local\" ]; then\n . \"${PROJECT_DIR}/.xcode.env.local\"\n fi\nfi\nif [ ! -x \"$NODE_BINARY\" ]; then\n RN_FIND=\"\"\n if [ -n \"$REACT_NATIVE_PATH\" ] && [ -f \"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\"\n elif [ -f \"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\"\n fi\n if [ -n \"$RN_FIND\" ]; then\n NODE_BINARY=$(/bin/bash -c '. \"$1\" >/dev/null 2>&1; command -v node' _ \"$RN_FIND\" || true)\n fi\nfi\nif [ -n \"$NODE_BINARY\" ] && [ -x \"$NODE_BINARY\" ]; then\n PATH=\"$(dirname \"$NODE_BINARY\"):$PATH\"\n export PATH NODE_BINARY\n for dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\n do\n if [ -f \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" ]; then\n \"$NODE_BINARY\" \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" xcode post-action\n exit $?\n fi\n done\nfi\n\necho \"bugsee-cli: not found under node_modules\" >&2\nexit 1\n"; +// Archive post-action inserted into the Expo scheme. After NODE_BINARY is +// known, the CLI is resolved from the package graph so a hoisted install +// still finds it. Tokens are exported only when non-empty. +exports.DSYM_POST_ACTION_SCRIPT = [ + 'CREDS="${PROJECT_DIR}/../credentials.json"', + 'TOKEN="$BUGSEE_APP_TOKEN"', + 'if [ -z "$TOKEN" ]; then', + ' TOKEN="$BUGSEE_TOKEN_IOS"', + 'fi', + 'if [ -z "$TOKEN" ] && [ -f "$CREDS" ]; then', + ' TOKEN=$(/usr/bin/plutil -extract ios raw -o - "$CREDS" 2>/dev/null || true)', + 'fi', + 'if [ -n "$TOKEN" ]; then', + ' export BUGSEE_APP_TOKEN="$TOKEN"', + 'fi', + 'if [ -z "$BUGSEE_ENDPOINT" ] && [ -f "$CREDS" ]; then', + ' ENDPOINT=$(/usr/bin/plutil -extract endpoint raw -o - "$CREDS" 2>/dev/null || true)', + ' if [ -n "$ENDPOINT" ]; then', + ' export BUGSEE_ENDPOINT="$ENDPOINT"', + ' fi', + 'fi', + '', + "# Archive's PATH has no node, and the npm shim's shebang searches PATH.", + 'if [ ! -x "$NODE_BINARY" ]; then', + ' if [ -f "${PROJECT_DIR}/.xcode.env" ]; then', + ' . "${PROJECT_DIR}/.xcode.env"', + ' fi', + ' if [ -f "${PROJECT_DIR}/.xcode.env.local" ]; then', + ' . "${PROJECT_DIR}/.xcode.env.local"', + ' fi', + 'fi', + 'if [ ! -x "$NODE_BINARY" ]; then', + ' RN_FIND=""', + ' if [ -n "$REACT_NATIVE_PATH" ] && [ -f "$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh" ]; then', + ' RN_FIND="$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh"', + ' elif [ -f "${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh" ]; then', + ' RN_FIND="${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh"', + ' fi', + ' if [ -n "$RN_FIND" ]; then', + ' NODE_BINARY=$(/bin/bash -c \'. "$1" >/dev/null 2>&1; command -v node\' _ "$RN_FIND" || true)', + ' fi', + 'fi', + 'if [ -n "$NODE_BINARY" ] && [ -x "$NODE_BINARY" ]; then', + ' PATH="$(dirname "$NODE_BINARY"):$PATH"', + ' export PATH NODE_BINARY', + ' if [ "$(uname -m)" = "x86_64" ]; then', + ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-x64/package.json\') } catch (e) { \'\' }")"', + ' else', + ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-arm64/package.json\') } catch (e) { \'\' }")"', + ' fi', + ' if [ -n "$NATIVE_PKG" ]; then', + ' NATIVE_BIN="$(dirname "$NATIVE_PKG")/bin/bugsee-cli"', + ' if [ -x "$NATIVE_BIN" ]; then', + ' "$NATIVE_BIN" xcode post-action', + ' exit $?', + ' fi', + ' fi', + ' CLI_JS="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli/bin/bugsee-cli.js\') } catch (e) { \'\' }")"', + ' if [ -n "$CLI_JS" ]; then', + ' "$NODE_BINARY" "$CLI_JS" xcode post-action', + ' exit $?', + ' fi', + 'fi', + '', + 'echo "bugsee-cli: not found" >&2', + 'exit 1', + '', +].join('\n'); //# sourceMappingURL=dsym-script.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/dsym-script.js.map b/packages/react-native/plugin/build/dsym-script.js.map index 46accd2..524c876 100644 --- a/packages/react-native/plugin/build/dsym-script.js.map +++ b/packages/react-native/plugin/build/dsym-script.js.map @@ -1 +1 @@ -{"version":3,"file":"dsym-script.js","sourceRoot":"","sources":["../src/dsym-script.ts"],"names":[],"mappings":";;;AAAA,mEAAmE;AACnE,6EAA6E;AAChE,QAAA,uBAAuB,GAAG,g8FAAg8F,CAAC"} \ No newline at end of file +{"version":3,"file":"dsym-script.js","sourceRoot":"","sources":["../src/dsym-script.ts"],"names":[],"mappings":";;;AAAA,0EAA0E;AAC1E,yEAAyE;AACzE,2DAA2D;AAC9C,QAAA,uBAAuB,GAAG;IACrC,4CAA4C;IAC5C,2BAA2B;IAC3B,0BAA0B;IAC1B,6BAA6B;IAC7B,IAAI;IACJ,6CAA6C;IAC7C,+EAA+E;IAC/E,IAAI;IACJ,0BAA0B;IAC1B,oCAAoC;IACpC,IAAI;IACJ,uDAAuD;IACvD,uFAAuF;IACvF,+BAA+B;IAC/B,wCAAwC;IACxC,MAAM;IACN,IAAI;IACJ,EAAE;IACF,yEAAyE;IACzE,kCAAkC;IAClC,+CAA+C;IAC/C,mCAAmC;IACnC,MAAM;IACN,qDAAqD;IACrD,yCAAyC;IACzC,MAAM;IACN,IAAI;IACJ,kCAAkC;IAClC,cAAc;IACd,sGAAsG;IACtG,iEAAiE;IACjE,kGAAkG;IAClG,0FAA0F;IAC1F,MAAM;IACN,8BAA8B;IAC9B,kGAAkG;IAClG,MAAM;IACN,IAAI;IACJ,yDAAyD;IACzD,0CAA0C;IAC1C,2BAA2B;IAC3B,yCAAyC;IACzC,kIAAkI;IAClI,QAAQ;IACR,oIAAoI;IACpI,MAAM;IACN,iCAAiC;IACjC,0DAA0D;IAC1D,mCAAmC;IACnC,uCAAuC;IACvC,eAAe;IACf,QAAQ;IACR,MAAM;IACN,sHAAsH;IACtH,6BAA6B;IAC7B,gDAAgD;IAChD,aAAa;IACb,MAAM;IACN,IAAI;IACJ,EAAE;IACF,kCAAkC;IAClC,QAAQ;IACR,EAAE;CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/scheme.d.ts b/packages/react-native/plugin/build/scheme.d.ts index 7e83564..ea95a00 100644 --- a/packages/react-native/plugin/build/scheme.d.ts +++ b/packages/react-native/plugin/build/scheme.d.ts @@ -2,8 +2,7 @@ import { DSYM_POST_ACTION_SCRIPT } from './dsym-script'; export { DSYM_POST_ACTION_SCRIPT }; export declare function encodeXmlAttr(value: string): string; /** - * Inserts the bare example's Archive post-action. The script is not - * rewritten. The EnvironmentBuildable is the scheme's own app target, so - * ARCHIVE_PATH is provided. + * Inserts the Archive post-action. The EnvironmentBuildable is the scheme's + * own app target, so ARCHIVE_PATH is provided. */ export declare function insertDsymPostAction(scheme: string, script?: string): string; diff --git a/packages/react-native/plugin/build/scheme.js b/packages/react-native/plugin/build/scheme.js index 3aa3752..14976da 100644 --- a/packages/react-native/plugin/build/scheme.js +++ b/packages/react-native/plugin/build/scheme.js @@ -23,9 +23,8 @@ function appBuildableReference(scheme) { return app; } /** - * Inserts the bare example's Archive post-action. The script is not - * rewritten. The EnvironmentBuildable is the scheme's own app target, so - * ARCHIVE_PATH is provided. + * Inserts the Archive post-action. The EnvironmentBuildable is the scheme's + * own app target, so ARCHIVE_PATH is provided. */ function insertDsymPostAction(scheme, script = dsym_script_1.DSYM_POST_ACTION_SCRIPT) { if (scheme.includes('xcode post-action')) { diff --git a/packages/react-native/plugin/build/scheme.js.map b/packages/react-native/plugin/build/scheme.js.map index 3788e11..2d3f0e3 100644 --- a/packages/react-native/plugin/build/scheme.js.map +++ b/packages/react-native/plugin/build/scheme.js.map @@ -1 +1 @@ -{"version":3,"file":"scheme.js","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":";;;AAIA,sCAQC;AAgBD,oDAyBC;AArDD,+CAAwD;AAE/C,wGAFA,qCAAuB,OAEA;AAEhC,SAAgB,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,IAAI,EAAE,CAAC;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kCAAkC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,MAAc,EAAE,SAAiB,qCAAuB;IAC3F,IAAI,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG;QACZ,qBAAqB;QACrB,2BAA2B;QAC3B,yGAAyG;QACzG,4BAA4B;QAC5B,uCAAuC;QACvC,gCAAgC,aAAa,CAAC,MAAM,CAAC,IAAI;QACzD,uCAAuC;QACvC,SAAS,CAAC,OAAO,EAAE;QACnB,wCAAwC;QACxC,8BAA8B;QAC9B,6BAA6B;QAC7B,sBAAsB;KACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,KAAK,uBAAuB,CAAC,CAAC;IACxF,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC"} \ No newline at end of file +{"version":3,"file":"scheme.js","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":";;;AAIA,sCAQC;AAeD,oDAyBC;AApDD,+CAAwD;AAE/C,wGAFA,qCAAuB,OAEA;AAEhC,SAAgB,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,IAAI,EAAE,CAAC;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kCAAkC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,MAAc,EAAE,SAAiB,qCAAuB;IAC3F,IAAI,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG;QACZ,qBAAqB;QACrB,2BAA2B;QAC3B,yGAAyG;QACzG,4BAA4B;QAC5B,uCAAuC;QACvC,gCAAgC,aAAa,CAAC,MAAM,CAAC,IAAI;QACzD,uCAAuC;QACvC,SAAS,CAAC,OAAO,EAAE;QACnB,wCAAwC;QACxC,8BAA8B;QAC9B,6BAA6B;QAC7B,sBAAsB;KACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,KAAK,uBAAuB,CAAC,CAAC;IACxF,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index cd8d26f..f135533 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -18,10 +18,6 @@ const barePbx = join( repoRoot, 'examples/bare/ios/BareExample.xcodeproj/project.pbxproj', ); -const bareScheme = join( - repoRoot, - 'examples/bare/ios/BareExample.xcodeproj/xcshareddata/xcschemes/BareExample.xcscheme', -); function decodeXml(value: string): string { return value @@ -44,16 +40,6 @@ function bareBundleScript(): string { return decodePbxString(quoted); } -function barePostActionScript(): string { - const scheme = readFileSync(bareScheme, 'utf8'); - const match = scheme.match(/\bscriptText\s*=\s*"([^"]*)"/); - const encoded = match?.[1]; - if (encoded === undefined) { - throw new Error('bare scheme has no scriptText'); - } - return decodeXml(encoded); -} - const REAL_TOKEN = 'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee'; const PLACEHOLDER = '00000000-0000-4000-8000-000000000000'; @@ -109,8 +95,9 @@ describe('settled iOS hooks', () => { expect(BARE_BUNDLE_SCRIPT).not.toContain('react-native-xcode.sh'); }); - it('copies the bare Archive post-action script', () => { - expect(DSYM_POST_ACTION_SCRIPT).toBe(barePostActionScript()); + it('keeps the Archive post-action upload guards', () => { + expect(DSYM_POST_ACTION_SCRIPT).toContain('xcode post-action'); + expect(DSYM_POST_ACTION_SCRIPT).not.toContain('xcode upload-dsyms'); expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/\.bin\/bugsee-cli/); expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/with-environment\.sh/); expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/\/v2/); @@ -118,6 +105,19 @@ describe('settled iOS hooks', () => { expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/--force-foreground/); expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/BUGSEE_BUILD_INFO_ALL_ACTIONS/); expect(DSYM_POST_ACTION_SCRIPT).not.toMatch(/BUGSEE_BUILD_INFO_ALL_CONFIGURATIONS/); + expect(DSYM_POST_ACTION_SCRIPT).toContain('if [ -n "$TOKEN" ]; then'); + expect(DSYM_POST_ACTION_SCRIPT).toContain('export BUGSEE_APP_TOKEN="$TOKEN"'); + expect(DSYM_POST_ACTION_SCRIPT).toContain('if [ -n "$ENDPOINT" ]; then'); + expect(DSYM_POST_ACTION_SCRIPT).toContain('export BUGSEE_ENDPOINT="$ENDPOINT"'); + }); + + it('resolves bugsee-cli from the package graph', () => { + expect(DSYM_POST_ACTION_SCRIPT).toContain("require.resolve('@bugsee/cli"); + expect(DSYM_POST_ACTION_SCRIPT).not.toContain('packages/react-native/node_modules'); + const resolveAt = DSYM_POST_ACTION_SCRIPT.indexOf("require.resolve('@bugsee/cli"); + const exitAt = DSYM_POST_ACTION_SCRIPT.lastIndexOf('exit 1'); + expect(resolveAt).toBeGreaterThan(-1); + expect(exitAt).toBeGreaterThan(resolveAt); }); it('replaces a classic bundle phase with the bare hook', () => { diff --git a/packages/react-native/plugin/src/dsym-script.ts b/packages/react-native/plugin/src/dsym-script.ts index 8bb5e5f..ca1d61e 100644 --- a/packages/react-native/plugin/src/dsym-script.ts +++ b/packages/react-native/plugin/src/dsym-script.ts @@ -1,3 +1,68 @@ -// The Archive post-action from examples/bare BareExample.xcscheme. -// Copied, not rewritten: the plugin inserts this script into an Expo scheme. -export const DSYM_POST_ACTION_SCRIPT = "CREDS=\"${PROJECT_DIR}/../credentials.json\"\nTOKEN=\"$BUGSEE_APP_TOKEN\"\nif [ -z \"$TOKEN\" ]; then\n TOKEN=\"$BUGSEE_TOKEN_IOS\"\nfi\nif [ -z \"$TOKEN\" ] && [ -f \"$CREDS\" ]; then\n TOKEN=$(/usr/bin/plutil -extract ios raw -o - \"$CREDS\" 2>/dev/null || true)\nfi\nif [ -n \"$TOKEN\" ]; then\n export BUGSEE_APP_TOKEN=\"$TOKEN\"\nfi\nif [ -z \"$BUGSEE_ENDPOINT\" ] && [ -f \"$CREDS\" ]; then\n ENDPOINT=$(/usr/bin/plutil -extract endpoint raw -o - \"$CREDS\" 2>/dev/null || true)\n if [ -n \"$ENDPOINT\" ]; then\n export BUGSEE_ENDPOINT=\"$ENDPOINT\"\n fi\nfi\n\ntry_bin() {\n if [ -x \"$1\" ]; then\n \"$1\" xcode post-action\n exit $?\n fi\n}\n\nfor dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\ndo\n if [ \"$(uname -m)\" = \"x86_64\" ]; then\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n else\n try_bin \"${dir}/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-arm64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n try_bin \"${dir}/@bugsee/cli/node_modules/@bugsee/cli-darwin-x64/bin/bugsee-cli\"\n fi\ndone\n\n# Archive's PATH has no node, and the npm shim's shebang searches PATH.\nif [ ! -x \"$NODE_BINARY\" ]; then\n if [ -f \"${PROJECT_DIR}/.xcode.env\" ]; then\n . \"${PROJECT_DIR}/.xcode.env\"\n fi\n if [ -f \"${PROJECT_DIR}/.xcode.env.local\" ]; then\n . \"${PROJECT_DIR}/.xcode.env.local\"\n fi\nfi\nif [ ! -x \"$NODE_BINARY\" ]; then\n RN_FIND=\"\"\n if [ -n \"$REACT_NATIVE_PATH\" ] && [ -f \"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh\"\n elif [ -f \"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\" ]; then\n RN_FIND=\"${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh\"\n fi\n if [ -n \"$RN_FIND\" ]; then\n NODE_BINARY=$(/bin/bash -c '. \"$1\" >/dev/null 2>&1; command -v node' _ \"$RN_FIND\" || true)\n fi\nfi\nif [ -n \"$NODE_BINARY\" ] && [ -x \"$NODE_BINARY\" ]; then\n PATH=\"$(dirname \"$NODE_BINARY\"):$PATH\"\n export PATH NODE_BINARY\n for dir in \\\n \"${PROJECT_DIR}/../node_modules\" \\\n \"${PROJECT_DIR}/../node_modules/@bugsee/react-native/node_modules\" \\\n \"${PROJECT_DIR}/../../../packages/react-native/node_modules\"\n do\n if [ -f \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" ]; then\n \"$NODE_BINARY\" \"${dir}/@bugsee/cli/bin/bugsee-cli.js\" xcode post-action\n exit $?\n fi\n done\nfi\n\necho \"bugsee-cli: not found under node_modules\" >&2\nexit 1\n"; +// Archive post-action inserted into the Expo scheme. After NODE_BINARY is +// known, the CLI is resolved from the package graph so a hoisted install +// still finds it. Tokens are exported only when non-empty. +export const DSYM_POST_ACTION_SCRIPT = [ + 'CREDS="${PROJECT_DIR}/../credentials.json"', + 'TOKEN="$BUGSEE_APP_TOKEN"', + 'if [ -z "$TOKEN" ]; then', + ' TOKEN="$BUGSEE_TOKEN_IOS"', + 'fi', + 'if [ -z "$TOKEN" ] && [ -f "$CREDS" ]; then', + ' TOKEN=$(/usr/bin/plutil -extract ios raw -o - "$CREDS" 2>/dev/null || true)', + 'fi', + 'if [ -n "$TOKEN" ]; then', + ' export BUGSEE_APP_TOKEN="$TOKEN"', + 'fi', + 'if [ -z "$BUGSEE_ENDPOINT" ] && [ -f "$CREDS" ]; then', + ' ENDPOINT=$(/usr/bin/plutil -extract endpoint raw -o - "$CREDS" 2>/dev/null || true)', + ' if [ -n "$ENDPOINT" ]; then', + ' export BUGSEE_ENDPOINT="$ENDPOINT"', + ' fi', + 'fi', + '', + "# Archive's PATH has no node, and the npm shim's shebang searches PATH.", + 'if [ ! -x "$NODE_BINARY" ]; then', + ' if [ -f "${PROJECT_DIR}/.xcode.env" ]; then', + ' . "${PROJECT_DIR}/.xcode.env"', + ' fi', + ' if [ -f "${PROJECT_DIR}/.xcode.env.local" ]; then', + ' . "${PROJECT_DIR}/.xcode.env.local"', + ' fi', + 'fi', + 'if [ ! -x "$NODE_BINARY" ]; then', + ' RN_FIND=""', + ' if [ -n "$REACT_NATIVE_PATH" ] && [ -f "$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh" ]; then', + ' RN_FIND="$REACT_NATIVE_PATH/scripts/find-node-for-xcode.sh"', + ' elif [ -f "${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh" ]; then', + ' RN_FIND="${PROJECT_DIR}/../node_modules/react-native/scripts/find-node-for-xcode.sh"', + ' fi', + ' if [ -n "$RN_FIND" ]; then', + ' NODE_BINARY=$(/bin/bash -c \'. "$1" >/dev/null 2>&1; command -v node\' _ "$RN_FIND" || true)', + ' fi', + 'fi', + 'if [ -n "$NODE_BINARY" ] && [ -x "$NODE_BINARY" ]; then', + ' PATH="$(dirname "$NODE_BINARY"):$PATH"', + ' export PATH NODE_BINARY', + ' if [ "$(uname -m)" = "x86_64" ]; then', + ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-x64/package.json\') } catch (e) { \'\' }")"', + ' else', + ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-arm64/package.json\') } catch (e) { \'\' }")"', + ' fi', + ' if [ -n "$NATIVE_PKG" ]; then', + ' NATIVE_BIN="$(dirname "$NATIVE_PKG")/bin/bugsee-cli"', + ' if [ -x "$NATIVE_BIN" ]; then', + ' "$NATIVE_BIN" xcode post-action', + ' exit $?', + ' fi', + ' fi', + ' CLI_JS="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli/bin/bugsee-cli.js\') } catch (e) { \'\' }")"', + ' if [ -n "$CLI_JS" ]; then', + ' "$NODE_BINARY" "$CLI_JS" xcode post-action', + ' exit $?', + ' fi', + 'fi', + '', + 'echo "bugsee-cli: not found" >&2', + 'exit 1', + '', +].join('\n'); diff --git a/packages/react-native/plugin/src/scheme.ts b/packages/react-native/plugin/src/scheme.ts index 6b2f2b2..feadfcd 100644 --- a/packages/react-native/plugin/src/scheme.ts +++ b/packages/react-native/plugin/src/scheme.ts @@ -22,9 +22,8 @@ function appBuildableReference(scheme: string): string { } /** - * Inserts the bare example's Archive post-action. The script is not - * rewritten. The EnvironmentBuildable is the scheme's own app target, so - * ARCHIVE_PATH is provided. + * Inserts the Archive post-action. The EnvironmentBuildable is the scheme's + * own app target, so ARCHIVE_PATH is provided. */ export function insertDsymPostAction(scheme: string, script: string = DSYM_POST_ACTION_SCRIPT): string { if (scheme.includes('xcode post-action')) { From 16f9cd6a5241bc9c851c36a2a35f93492d7cd299 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 03:44:33 +0500 Subject: [PATCH 05/11] Task 13.4: resolve bugsee-cli from the app root passed into node. @bugsee/cli does not export its bin subpath, and an Xcode post-action does not run from the app directory. Co-authored-by: Cursor --- .../react-native/plugin/build/dsym-script.js | 13 ++-- .../plugin/build/dsym-script.js.map | 2 +- .../plugin/src/__tests__/plugin.test.ts | 71 +++++++++++++++++-- .../react-native/plugin/src/dsym-script.ts | 13 ++-- 4 files changed, 83 insertions(+), 16 deletions(-) diff --git a/packages/react-native/plugin/build/dsym-script.js b/packages/react-native/plugin/build/dsym-script.js index d2ea3f6..ad4479d 100644 --- a/packages/react-native/plugin/build/dsym-script.js +++ b/packages/react-native/plugin/build/dsym-script.js @@ -2,8 +2,10 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.DSYM_POST_ACTION_SCRIPT = void 0; // Archive post-action inserted into the Expo scheme. After NODE_BINARY is -// known, the CLI is resolved from the package graph so a hoisted install -// still finds it. Tokens are exported only when non-empty. +// known, the app root (${PROJECT_DIR}/..) is passed to node so resolution +// does not use the post-action working directory. The native optional +// dependency is preferred; otherwise the JS CLI path comes from the package +// bin field. Tokens are exported only when non-empty. exports.DSYM_POST_ACTION_SCRIPT = [ 'CREDS="${PROJECT_DIR}/../credentials.json"', 'TOKEN="$BUGSEE_APP_TOKEN"', @@ -46,10 +48,11 @@ exports.DSYM_POST_ACTION_SCRIPT = [ 'if [ -n "$NODE_BINARY" ] && [ -x "$NODE_BINARY" ]; then', ' PATH="$(dirname "$NODE_BINARY"):$PATH"', ' export PATH NODE_BINARY', + ' APP_ROOT="${PROJECT_DIR}/.."', ' if [ "$(uname -m)" = "x86_64" ]; then', - ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-x64/package.json\') } catch (e) { \'\' }")"', + ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-x64/package.json\', { paths: [process.argv[1]] }) } catch (e) { \'\' }" "$APP_ROOT")"', ' else', - ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-arm64/package.json\') } catch (e) { \'\' }")"', + ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-arm64/package.json\', { paths: [process.argv[1]] }) } catch (e) { \'\' }" "$APP_ROOT")"', ' fi', ' if [ -n "$NATIVE_PKG" ]; then', ' NATIVE_BIN="$(dirname "$NATIVE_PKG")/bin/bugsee-cli"', @@ -58,7 +61,7 @@ exports.DSYM_POST_ACTION_SCRIPT = [ ' exit $?', ' fi', ' fi', - ' CLI_JS="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli/bin/bugsee-cli.js\') } catch (e) { \'\' }")"', + ' CLI_JS="$("$NODE_BINARY" --print "try { const fs = require(\'fs\'); const path = require(\'path\'); const pkg = require.resolve(\'@bugsee/cli/package.json\', { paths: [process.argv[1]] }); const rel = JSON.parse(fs.readFileSync(pkg, \'utf8\')).bin[\'bugsee-cli\']; rel ? path.join(path.dirname(pkg), rel) : \'\'; } catch (e) { \'\' }" "$APP_ROOT")"', ' if [ -n "$CLI_JS" ]; then', ' "$NODE_BINARY" "$CLI_JS" xcode post-action', ' exit $?', diff --git a/packages/react-native/plugin/build/dsym-script.js.map b/packages/react-native/plugin/build/dsym-script.js.map index 524c876..c1e278a 100644 --- a/packages/react-native/plugin/build/dsym-script.js.map +++ b/packages/react-native/plugin/build/dsym-script.js.map @@ -1 +1 @@ -{"version":3,"file":"dsym-script.js","sourceRoot":"","sources":["../src/dsym-script.ts"],"names":[],"mappings":";;;AAAA,0EAA0E;AAC1E,yEAAyE;AACzE,2DAA2D;AAC9C,QAAA,uBAAuB,GAAG;IACrC,4CAA4C;IAC5C,2BAA2B;IAC3B,0BAA0B;IAC1B,6BAA6B;IAC7B,IAAI;IACJ,6CAA6C;IAC7C,+EAA+E;IAC/E,IAAI;IACJ,0BAA0B;IAC1B,oCAAoC;IACpC,IAAI;IACJ,uDAAuD;IACvD,uFAAuF;IACvF,+BAA+B;IAC/B,wCAAwC;IACxC,MAAM;IACN,IAAI;IACJ,EAAE;IACF,yEAAyE;IACzE,kCAAkC;IAClC,+CAA+C;IAC/C,mCAAmC;IACnC,MAAM;IACN,qDAAqD;IACrD,yCAAyC;IACzC,MAAM;IACN,IAAI;IACJ,kCAAkC;IAClC,cAAc;IACd,sGAAsG;IACtG,iEAAiE;IACjE,kGAAkG;IAClG,0FAA0F;IAC1F,MAAM;IACN,8BAA8B;IAC9B,kGAAkG;IAClG,MAAM;IACN,IAAI;IACJ,yDAAyD;IACzD,0CAA0C;IAC1C,2BAA2B;IAC3B,yCAAyC;IACzC,kIAAkI;IAClI,QAAQ;IACR,oIAAoI;IACpI,MAAM;IACN,iCAAiC;IACjC,0DAA0D;IAC1D,mCAAmC;IACnC,uCAAuC;IACvC,eAAe;IACf,QAAQ;IACR,MAAM;IACN,sHAAsH;IACtH,6BAA6B;IAC7B,gDAAgD;IAChD,aAAa;IACb,MAAM;IACN,IAAI;IACJ,EAAE;IACF,kCAAkC;IAClC,QAAQ;IACR,EAAE;CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"dsym-script.js","sourceRoot":"","sources":["../src/dsym-script.ts"],"names":[],"mappings":";;;AAAA,0EAA0E;AAC1E,0EAA0E;AAC1E,sEAAsE;AACtE,4EAA4E;AAC5E,sDAAsD;AACzC,QAAA,uBAAuB,GAAG;IACrC,4CAA4C;IAC5C,2BAA2B;IAC3B,0BAA0B;IAC1B,6BAA6B;IAC7B,IAAI;IACJ,6CAA6C;IAC7C,+EAA+E;IAC/E,IAAI;IACJ,0BAA0B;IAC1B,oCAAoC;IACpC,IAAI;IACJ,uDAAuD;IACvD,uFAAuF;IACvF,+BAA+B;IAC/B,wCAAwC;IACxC,MAAM;IACN,IAAI;IACJ,EAAE;IACF,yEAAyE;IACzE,kCAAkC;IAClC,+CAA+C;IAC/C,mCAAmC;IACnC,MAAM;IACN,qDAAqD;IACrD,yCAAyC;IACzC,MAAM;IACN,IAAI;IACJ,kCAAkC;IAClC,cAAc;IACd,sGAAsG;IACtG,iEAAiE;IACjE,kGAAkG;IAClG,0FAA0F;IAC1F,MAAM;IACN,8BAA8B;IAC9B,kGAAkG;IAClG,MAAM;IACN,IAAI;IACJ,yDAAyD;IACzD,0CAA0C;IAC1C,2BAA2B;IAC3B,gCAAgC;IAChC,yCAAyC;IACzC,4KAA4K;IAC5K,QAAQ;IACR,8KAA8K;IAC9K,MAAM;IACN,iCAAiC;IACjC,0DAA0D;IAC1D,mCAAmC;IACnC,uCAAuC;IACvC,eAAe;IACf,QAAQ;IACR,MAAM;IACN,gWAAgW;IAChW,6BAA6B;IAC7B,gDAAgD;IAChD,aAAa;IACb,MAAM;IACN,IAAI;IACJ,EAAE;IACF,kCAAkC;IAClC,QAAQ;IACR,EAAE;CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index f135533..b6b2a48 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -19,6 +19,31 @@ const barePbx = join( 'examples/bare/ios/BareExample.xcodeproj/project.pbxproj', ); +function requireResolveCalls(script: string): string[] { + const calls: string[] = []; + const needle = 'require.resolve('; + let from = 0; + while (from < script.length) { + const start = script.indexOf(needle, from); + if (start < 0) break; + let depth = 0; + let i = start + needle.length - 1; + for (; i < script.length; i++) { + if (script[i] === '(') depth++; + else if (script[i] === ')') { + depth--; + if (depth === 0) { + i++; + break; + } + } + } + calls.push(script.slice(start, i)); + from = i; + } + return calls; +} + function decodeXml(value: string): string { return value .replace(/ /g, '\n') @@ -111,13 +136,49 @@ describe('settled iOS hooks', () => { expect(DSYM_POST_ACTION_SCRIPT).toContain('export BUGSEE_ENDPOINT="$ENDPOINT"'); }); - it('resolves bugsee-cli from the package graph', () => { - expect(DSYM_POST_ACTION_SCRIPT).toContain("require.resolve('@bugsee/cli"); + it('resolves bugsee-cli from the app root, not the bin subpath', () => { + expect(DSYM_POST_ACTION_SCRIPT).not.toContain( + "require.resolve('@bugsee/cli/bin/bugsee-cli.js')", + ); + expect(DSYM_POST_ACTION_SCRIPT).not.toMatch( + /require\.resolve\(['"]@bugsee\/cli\/bin\/bugsee-cli\.js['"]\)/, + ); expect(DSYM_POST_ACTION_SCRIPT).not.toContain('packages/react-native/node_modules'); - const resolveAt = DSYM_POST_ACTION_SCRIPT.indexOf("require.resolve('@bugsee/cli"); + expect(DSYM_POST_ACTION_SCRIPT).toContain('APP_ROOT="${PROJECT_DIR}/.."'); + + const calls = requireResolveCalls(DSYM_POST_ACTION_SCRIPT); + expect(calls).toEqual([ + "require.resolve('@bugsee/cli-darwin-x64/package.json', { paths: [process.argv[1]] })", + "require.resolve('@bugsee/cli-darwin-arm64/package.json', { paths: [process.argv[1]] })", + "require.resolve('@bugsee/cli/package.json', { paths: [process.argv[1]] })", + ]); + for (const call of calls) { + expect(call).toContain('paths:'); + expect(call).toContain('process.argv[1]'); + } + + const printScripts = [...DSYM_POST_ACTION_SCRIPT.matchAll(/--print "([^"]*)"/g)].map( + (match) => match[1], + ); + expect(printScripts).toHaveLength(calls.length); + for (const src of printScripts) { + expect(src).not.toContain('PROJECT_DIR'); + expect(src).not.toContain('APP_ROOT'); + expect(src).not.toContain('process.cwd'); + } + expect(DSYM_POST_ACTION_SCRIPT.match(/--print "[^"]*" "\$APP_ROOT"/g)).toHaveLength( + calls.length, + ); + expect(DSYM_POST_ACTION_SCRIPT).toContain(".bin['bugsee-cli']"); + + const nativeAt = DSYM_POST_ACTION_SCRIPT.indexOf('@bugsee/cli-darwin-arm64/package.json'); + const jsAt = DSYM_POST_ACTION_SCRIPT.indexOf( + "require.resolve('@bugsee/cli/package.json'", + ); const exitAt = DSYM_POST_ACTION_SCRIPT.lastIndexOf('exit 1'); - expect(resolveAt).toBeGreaterThan(-1); - expect(exitAt).toBeGreaterThan(resolveAt); + expect(nativeAt).toBeGreaterThan(-1); + expect(jsAt).toBeGreaterThan(nativeAt); + expect(exitAt).toBeGreaterThan(jsAt); }); it('replaces a classic bundle phase with the bare hook', () => { diff --git a/packages/react-native/plugin/src/dsym-script.ts b/packages/react-native/plugin/src/dsym-script.ts index ca1d61e..bd3dcfc 100644 --- a/packages/react-native/plugin/src/dsym-script.ts +++ b/packages/react-native/plugin/src/dsym-script.ts @@ -1,6 +1,8 @@ // Archive post-action inserted into the Expo scheme. After NODE_BINARY is -// known, the CLI is resolved from the package graph so a hoisted install -// still finds it. Tokens are exported only when non-empty. +// known, the app root (${PROJECT_DIR}/..) is passed to node so resolution +// does not use the post-action working directory. The native optional +// dependency is preferred; otherwise the JS CLI path comes from the package +// bin field. Tokens are exported only when non-empty. export const DSYM_POST_ACTION_SCRIPT = [ 'CREDS="${PROJECT_DIR}/../credentials.json"', 'TOKEN="$BUGSEE_APP_TOKEN"', @@ -43,10 +45,11 @@ export const DSYM_POST_ACTION_SCRIPT = [ 'if [ -n "$NODE_BINARY" ] && [ -x "$NODE_BINARY" ]; then', ' PATH="$(dirname "$NODE_BINARY"):$PATH"', ' export PATH NODE_BINARY', + ' APP_ROOT="${PROJECT_DIR}/.."', ' if [ "$(uname -m)" = "x86_64" ]; then', - ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-x64/package.json\') } catch (e) { \'\' }")"', + ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-x64/package.json\', { paths: [process.argv[1]] }) } catch (e) { \'\' }" "$APP_ROOT")"', ' else', - ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-arm64/package.json\') } catch (e) { \'\' }")"', + ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-arm64/package.json\', { paths: [process.argv[1]] }) } catch (e) { \'\' }" "$APP_ROOT")"', ' fi', ' if [ -n "$NATIVE_PKG" ]; then', ' NATIVE_BIN="$(dirname "$NATIVE_PKG")/bin/bugsee-cli"', @@ -55,7 +58,7 @@ export const DSYM_POST_ACTION_SCRIPT = [ ' exit $?', ' fi', ' fi', - ' CLI_JS="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli/bin/bugsee-cli.js\') } catch (e) { \'\' }")"', + ' CLI_JS="$("$NODE_BINARY" --print "try { const fs = require(\'fs\'); const path = require(\'path\'); const pkg = require.resolve(\'@bugsee/cli/package.json\', { paths: [process.argv[1]] }); const rel = JSON.parse(fs.readFileSync(pkg, \'utf8\')).bin[\'bugsee-cli\']; rel ? path.join(path.dirname(pkg), rel) : \'\'; } catch (e) { \'\' }" "$APP_ROOT")"', ' if [ -n "$CLI_JS" ]; then', ' "$NODE_BINARY" "$CLI_JS" xcode post-action', ' exit $?', From c92ce65e07898aa95f7ee0b83cec4aa5182972e1 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 04:12:51 +0500 Subject: [PATCH 06/11] Task 13.4: resolve @bugsee/cli from the wrapper directory. Yarn and pnpm nest the CLI under @bugsee/react-native, so an app-root require.resolve misses it and the Archive post-action exits 1. Co-authored-by: Cursor --- .../plugin/build/dsym-script.d.ts | 3 + .../react-native/plugin/build/dsym-script.js | 37 +++- .../plugin/build/dsym-script.js.map | 2 +- .../plugin/src/__tests__/plugin.test.ts | 179 +++++++++++++++--- .../react-native/plugin/src/dsym-script.ts | 38 +++- 5 files changed, 219 insertions(+), 40 deletions(-) diff --git a/packages/react-native/plugin/build/dsym-script.d.ts b/packages/react-native/plugin/build/dsym-script.d.ts index c4a25ed..9616145 100644 --- a/packages/react-native/plugin/build/dsym-script.d.ts +++ b/packages/react-native/plugin/build/dsym-script.d.ts @@ -1 +1,4 @@ +/** Node --print source. Prints the CLI package.json path, or '' when missing. */ +export declare const RESOLVE_BUGSEE_CLI_PACKAGE: string; +export declare function resolveNativeCliPackageSource(packageJson: string): string; export declare const DSYM_POST_ACTION_SCRIPT: string; diff --git a/packages/react-native/plugin/build/dsym-script.js b/packages/react-native/plugin/build/dsym-script.js index ad4479d..f71d4c1 100644 --- a/packages/react-native/plugin/build/dsym-script.js +++ b/packages/react-native/plugin/build/dsym-script.js @@ -1,11 +1,30 @@ "use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.DSYM_POST_ACTION_SCRIPT = void 0; // Archive post-action inserted into the Expo scheme. After NODE_BINARY is -// known, the app root (${PROJECT_DIR}/..) is passed to node so resolution -// does not use the post-action working directory. The native optional -// dependency is preferred; otherwise the JS CLI path comes from the package -// bin field. Tokens are exported only when non-empty. +// known, ${PROJECT_DIR}/.. is passed to node as the app root. The wrapper is +// resolved from that root, @bugsee/cli from the wrapper directory (a nested +// install is not visible from the app root), and the native optional +// dependency from the CLI directory. Otherwise the JS entry comes from the +// CLI package bin field. Tokens are exported only when non-empty. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DSYM_POST_ACTION_SCRIPT = exports.RESOLVE_BUGSEE_CLI_PACKAGE = void 0; +exports.resolveNativeCliPackageSource = resolveNativeCliPackageSource; +const locateBugseeCliPackage = [ + "const path = require('path');", + 'const appRoot = process.argv[1];', + "const wrapperPkg = require.resolve('@bugsee/react-native/package.json', { paths: [appRoot] });", + 'const wrapperDir = path.dirname(wrapperPkg);', + "const cliPkg = require.resolve('@bugsee/cli/package.json', { paths: [wrapperDir] });", + 'const cliDir = path.dirname(cliPkg);', +].join(' '); +/** Node --print source. Prints the CLI package.json path, or '' when missing. */ +exports.RESOLVE_BUGSEE_CLI_PACKAGE = `try { ${locateBugseeCliPackage} cliPkg; } catch (e) { '' }`; +function resolveNativeCliPackageSource(packageJson) { + return `try { ${locateBugseeCliPackage} require.resolve('${packageJson}', { paths: [cliDir] }); } catch (e) { '' }`; +} +const resolveBugseeCliJsSource = `try { const fs = require('fs'); ${locateBugseeCliPackage} const rel = JSON.parse(fs.readFileSync(cliPkg, 'utf8')).bin['bugsee-cli']; rel ? path.join(cliDir, rel) : ''; } catch (e) { '' }`; +function nodePrint(source) { + return `"$("$NODE_BINARY" --print "${source}" "$APP_ROOT")"`; +} exports.DSYM_POST_ACTION_SCRIPT = [ 'CREDS="${PROJECT_DIR}/../credentials.json"', 'TOKEN="$BUGSEE_APP_TOKEN"', @@ -50,9 +69,9 @@ exports.DSYM_POST_ACTION_SCRIPT = [ ' export PATH NODE_BINARY', ' APP_ROOT="${PROJECT_DIR}/.."', ' if [ "$(uname -m)" = "x86_64" ]; then', - ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-x64/package.json\', { paths: [process.argv[1]] }) } catch (e) { \'\' }" "$APP_ROOT")"', + ` NATIVE_PKG=${nodePrint(resolveNativeCliPackageSource('@bugsee/cli-darwin-x64/package.json'))}`, ' else', - ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-arm64/package.json\', { paths: [process.argv[1]] }) } catch (e) { \'\' }" "$APP_ROOT")"', + ` NATIVE_PKG=${nodePrint(resolveNativeCliPackageSource('@bugsee/cli-darwin-arm64/package.json'))}`, ' fi', ' if [ -n "$NATIVE_PKG" ]; then', ' NATIVE_BIN="$(dirname "$NATIVE_PKG")/bin/bugsee-cli"', @@ -61,7 +80,7 @@ exports.DSYM_POST_ACTION_SCRIPT = [ ' exit $?', ' fi', ' fi', - ' CLI_JS="$("$NODE_BINARY" --print "try { const fs = require(\'fs\'); const path = require(\'path\'); const pkg = require.resolve(\'@bugsee/cli/package.json\', { paths: [process.argv[1]] }); const rel = JSON.parse(fs.readFileSync(pkg, \'utf8\')).bin[\'bugsee-cli\']; rel ? path.join(path.dirname(pkg), rel) : \'\'; } catch (e) { \'\' }" "$APP_ROOT")"', + ` CLI_JS=${nodePrint(resolveBugseeCliJsSource)}`, ' if [ -n "$CLI_JS" ]; then', ' "$NODE_BINARY" "$CLI_JS" xcode post-action', ' exit $?', diff --git a/packages/react-native/plugin/build/dsym-script.js.map b/packages/react-native/plugin/build/dsym-script.js.map index c1e278a..b8dee92 100644 --- a/packages/react-native/plugin/build/dsym-script.js.map +++ b/packages/react-native/plugin/build/dsym-script.js.map @@ -1 +1 @@ -{"version":3,"file":"dsym-script.js","sourceRoot":"","sources":["../src/dsym-script.ts"],"names":[],"mappings":";;;AAAA,0EAA0E;AAC1E,0EAA0E;AAC1E,sEAAsE;AACtE,4EAA4E;AAC5E,sDAAsD;AACzC,QAAA,uBAAuB,GAAG;IACrC,4CAA4C;IAC5C,2BAA2B;IAC3B,0BAA0B;IAC1B,6BAA6B;IAC7B,IAAI;IACJ,6CAA6C;IAC7C,+EAA+E;IAC/E,IAAI;IACJ,0BAA0B;IAC1B,oCAAoC;IACpC,IAAI;IACJ,uDAAuD;IACvD,uFAAuF;IACvF,+BAA+B;IAC/B,wCAAwC;IACxC,MAAM;IACN,IAAI;IACJ,EAAE;IACF,yEAAyE;IACzE,kCAAkC;IAClC,+CAA+C;IAC/C,mCAAmC;IACnC,MAAM;IACN,qDAAqD;IACrD,yCAAyC;IACzC,MAAM;IACN,IAAI;IACJ,kCAAkC;IAClC,cAAc;IACd,sGAAsG;IACtG,iEAAiE;IACjE,kGAAkG;IAClG,0FAA0F;IAC1F,MAAM;IACN,8BAA8B;IAC9B,kGAAkG;IAClG,MAAM;IACN,IAAI;IACJ,yDAAyD;IACzD,0CAA0C;IAC1C,2BAA2B;IAC3B,gCAAgC;IAChC,yCAAyC;IACzC,4KAA4K;IAC5K,QAAQ;IACR,8KAA8K;IAC9K,MAAM;IACN,iCAAiC;IACjC,0DAA0D;IAC1D,mCAAmC;IACnC,uCAAuC;IACvC,eAAe;IACf,QAAQ;IACR,MAAM;IACN,gWAAgW;IAChW,6BAA6B;IAC7B,gDAAgD;IAChD,aAAa;IACb,MAAM;IACN,IAAI;IACJ,EAAE;IACF,kCAAkC;IAClC,QAAQ;IACR,EAAE;CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"dsym-script.js","sourceRoot":"","sources":["../src/dsym-script.ts"],"names":[],"mappings":";AAAA,0EAA0E;AAC1E,6EAA6E;AAC7E,4EAA4E;AAC5E,qEAAqE;AACrE,2EAA2E;AAC3E,kEAAkE;;;AAclE,sEAEC;AAdD,MAAM,sBAAsB,GAAG;IAC7B,+BAA+B;IAC/B,kCAAkC;IAClC,gGAAgG;IAChG,8CAA8C;IAC9C,sFAAsF;IACtF,sCAAsC;CACvC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,iFAAiF;AACpE,QAAA,0BAA0B,GAAG,SAAS,sBAAsB,6BAA6B,CAAC;AAEvG,SAAgB,6BAA6B,CAAC,WAAmB;IAC/D,OAAO,SAAS,sBAAsB,qBAAqB,WAAW,6CAA6C,CAAC;AACtH,CAAC;AAED,MAAM,wBAAwB,GAAG,mCAAmC,sBAAsB,mIAAmI,CAAC;AAE9N,SAAS,SAAS,CAAC,MAAc;IAC/B,OAAO,8BAA8B,MAAM,iBAAiB,CAAC;AAC/D,CAAC;AAEY,QAAA,uBAAuB,GAAG;IACrC,4CAA4C;IAC5C,2BAA2B;IAC3B,0BAA0B;IAC1B,6BAA6B;IAC7B,IAAI;IACJ,6CAA6C;IAC7C,+EAA+E;IAC/E,IAAI;IACJ,0BAA0B;IAC1B,oCAAoC;IACpC,IAAI;IACJ,uDAAuD;IACvD,uFAAuF;IACvF,+BAA+B;IAC/B,wCAAwC;IACxC,MAAM;IACN,IAAI;IACJ,EAAE;IACF,yEAAyE;IACzE,kCAAkC;IAClC,+CAA+C;IAC/C,mCAAmC;IACnC,MAAM;IACN,qDAAqD;IACrD,yCAAyC;IACzC,MAAM;IACN,IAAI;IACJ,kCAAkC;IAClC,cAAc;IACd,sGAAsG;IACtG,iEAAiE;IACjE,kGAAkG;IAClG,0FAA0F;IAC1F,MAAM;IACN,8BAA8B;IAC9B,kGAAkG;IAClG,MAAM;IACN,IAAI;IACJ,yDAAyD;IACzD,0CAA0C;IAC1C,2BAA2B;IAC3B,gCAAgC;IAChC,yCAAyC;IACzC,kBAAkB,SAAS,CAAC,6BAA6B,CAAC,qCAAqC,CAAC,CAAC,EAAE;IACnG,QAAQ;IACR,kBAAkB,SAAS,CAAC,6BAA6B,CAAC,uCAAuC,CAAC,CAAC,EAAE;IACrG,MAAM;IACN,iCAAiC;IACjC,0DAA0D;IAC1D,mCAAmC;IACnC,uCAAuC;IACvC,eAAe;IACf,QAAQ;IACR,MAAM;IACN,YAAY,SAAS,CAAC,wBAAwB,CAAC,EAAE;IACjD,6BAA6B;IAC7B,gDAAgD;IAChD,aAAa;IACb,MAAM;IACN,IAAI;IACJ,EAAE;IACF,kCAAkC;IAClC,QAAQ;IACR,EAAE;CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index b6b2a48..e775ce4 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -1,7 +1,8 @@ -import { cpSync, existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs'; +import { spawnSync } from 'node:child_process'; +import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs'; import { createRequire } from 'node:module'; import { tmpdir } from 'node:os'; -import { join } from 'node:path'; +import { dirname, join } from 'node:path'; import { isPlaceholderToken as exampleIsPlaceholderToken } from '../../../../../examples/bare/endpoint'; import { rewriteBundlePhase, BARE_BUNDLE_SCRIPT } from '../bundle-phase'; @@ -9,7 +10,11 @@ import { decodePbxString, encodePbxString } from '../pbx-string'; import { bugseePropertiesText, isPlaceholderToken } from '../properties'; import { ensureAppAppliesPlugin, ensureGradlePluginDeclared, ensureMavenCentral } from '../gradle'; import { insertDsymPostAction } from '../scheme'; -import { DSYM_POST_ACTION_SCRIPT } from '../dsym-script'; +import { + DSYM_POST_ACTION_SCRIPT, + RESOLVE_BUGSEE_CLI_PACKAGE, + resolveNativeCliPackageSource, +} from '../dsym-script'; import { manifestAutoLaunchToken } from '../manifest'; import { loadNativeVersions } from '../native-versions'; @@ -136,7 +141,7 @@ describe('settled iOS hooks', () => { expect(DSYM_POST_ACTION_SCRIPT).toContain('export BUGSEE_ENDPOINT="$ENDPOINT"'); }); - it('resolves bugsee-cli from the app root, not the bin subpath', () => { + it('resolves the CLI from the wrapper and the native package from the CLI', () => { expect(DSYM_POST_ACTION_SCRIPT).not.toContain( "require.resolve('@bugsee/cli/bin/bugsee-cli.js')", ); @@ -144,41 +149,169 @@ describe('settled iOS hooks', () => { /require\.resolve\(['"]@bugsee\/cli\/bin\/bugsee-cli\.js['"]\)/, ); expect(DSYM_POST_ACTION_SCRIPT).not.toContain('packages/react-native/node_modules'); + expect(DSYM_POST_ACTION_SCRIPT).not.toContain( + "require.resolve('@bugsee/cli/package.json', { paths: [appRoot] })", + ); + expect(DSYM_POST_ACTION_SCRIPT).not.toContain( + "require.resolve('@bugsee/cli/package.json', { paths: [process.argv[1]] })", + ); expect(DSYM_POST_ACTION_SCRIPT).toContain('APP_ROOT="${PROJECT_DIR}/.."'); + expect(DSYM_POST_ACTION_SCRIPT).toContain('uname -m'); + expect(DSYM_POST_ACTION_SCRIPT).toContain(".bin['bugsee-cli']"); + expect(RESOLVE_BUGSEE_CLI_PACKAGE).toContain( + "require.resolve('@bugsee/cli/package.json', { paths: [wrapperDir] })", + ); + expect(DSYM_POST_ACTION_SCRIPT).toContain( + "require.resolve('@bugsee/cli/package.json', { paths: [wrapperDir] })", + ); + expect(DSYM_POST_ACTION_SCRIPT).toContain( + "require.resolve('@bugsee/react-native/package.json', { paths: [appRoot] })", + ); + expect(DSYM_POST_ACTION_SCRIPT).toContain( + resolveNativeCliPackageSource('@bugsee/cli-darwin-x64/package.json'), + ); + expect(DSYM_POST_ACTION_SCRIPT).toContain( + resolveNativeCliPackageSource('@bugsee/cli-darwin-arm64/package.json'), + ); const calls = requireResolveCalls(DSYM_POST_ACTION_SCRIPT); expect(calls).toEqual([ - "require.resolve('@bugsee/cli-darwin-x64/package.json', { paths: [process.argv[1]] })", - "require.resolve('@bugsee/cli-darwin-arm64/package.json', { paths: [process.argv[1]] })", - "require.resolve('@bugsee/cli/package.json', { paths: [process.argv[1]] })", + "require.resolve('@bugsee/react-native/package.json', { paths: [appRoot] })", + "require.resolve('@bugsee/cli/package.json', { paths: [wrapperDir] })", + "require.resolve('@bugsee/cli-darwin-x64/package.json', { paths: [cliDir] })", + "require.resolve('@bugsee/react-native/package.json', { paths: [appRoot] })", + "require.resolve('@bugsee/cli/package.json', { paths: [wrapperDir] })", + "require.resolve('@bugsee/cli-darwin-arm64/package.json', { paths: [cliDir] })", + "require.resolve('@bugsee/react-native/package.json', { paths: [appRoot] })", + "require.resolve('@bugsee/cli/package.json', { paths: [wrapperDir] })", ]); - for (const call of calls) { - expect(call).toContain('paths:'); - expect(call).toContain('process.argv[1]'); - } const printScripts = [...DSYM_POST_ACTION_SCRIPT.matchAll(/--print "([^"]*)"/g)].map( (match) => match[1], ); - expect(printScripts).toHaveLength(calls.length); + expect(printScripts).toHaveLength(3); for (const src of printScripts) { expect(src).not.toContain('PROJECT_DIR'); expect(src).not.toContain('APP_ROOT'); expect(src).not.toContain('process.cwd'); } - expect(DSYM_POST_ACTION_SCRIPT.match(/--print "[^"]*" "\$APP_ROOT"/g)).toHaveLength( - calls.length, - ); - expect(DSYM_POST_ACTION_SCRIPT).toContain(".bin['bugsee-cli']"); + expect(DSYM_POST_ACTION_SCRIPT.match(/--print "[^"]*" "\$APP_ROOT"/g)).toHaveLength(3); - const nativeAt = DSYM_POST_ACTION_SCRIPT.indexOf('@bugsee/cli-darwin-arm64/package.json'); - const jsAt = DSYM_POST_ACTION_SCRIPT.indexOf( - "require.resolve('@bugsee/cli/package.json'", - ); + const nativeRun = DSYM_POST_ACTION_SCRIPT.indexOf('"$NATIVE_BIN" xcode post-action'); + const jsRun = DSYM_POST_ACTION_SCRIPT.indexOf('"$NODE_BINARY" "$CLI_JS" xcode post-action'); const exitAt = DSYM_POST_ACTION_SCRIPT.lastIndexOf('exit 1'); - expect(nativeAt).toBeGreaterThan(-1); - expect(jsAt).toBeGreaterThan(nativeAt); - expect(exitAt).toBeGreaterThan(jsAt); + expect(nativeRun).toBeGreaterThan(-1); + expect(jsRun).toBeGreaterThan(nativeRun); + expect(exitAt).toBeGreaterThan(jsRun); + }); + + it('resolves a nested @bugsee/cli from the wrapper and a hoisted one from the app root', () => { + expect(DSYM_POST_ACTION_SCRIPT).not.toContain( + "require.resolve('@bugsee/cli/bin/bugsee-cli.js')", + ); + + const roots: string[] = []; + function makeRoot(): string { + const root = mkdtempSync(join(tmpdir(), 'bugsee-cli-resolve-')); + roots.push(root); + writeFileSync(join(root, 'package.json'), JSON.stringify({ name: 'app' })); + return root; + } + function writePackage(file: string, value: unknown): void { + mkdirSync(dirname(file), { recursive: true }); + writeFileSync(file, JSON.stringify(value)); + } + function nodePrint(source: string, start: string): { status: number | null; stdout: string; stderr: string } { + const result = spawnSync(process.execPath, ['--print', source, start], { + encoding: 'utf8', + env: { ...process.env, NODE_PATH: '' }, + }); + return { + status: result.status, + stdout: (result.stdout ?? '').trim(), + stderr: result.stderr ?? '', + }; + } + + try { + const nested = makeRoot(); + writePackage(join(nested, 'node_modules/@bugsee/react-native/package.json'), { + name: '@bugsee/react-native', + }); + const nestedCli = join( + nested, + 'node_modules/@bugsee/react-native/node_modules/@bugsee/cli/package.json', + ); + writePackage(nestedCli, { + name: '@bugsee/cli', + bin: { 'bugsee-cli': 'bin/bugsee-cli.js' }, + }); + const nestedNative = join( + dirname(nestedCli), + 'node_modules/@bugsee/cli-darwin-arm64/package.json', + ); + writePackage(nestedNative, { name: '@bugsee/cli-darwin-arm64' }); + + const nestedFromApp = nodePrint( + "require.resolve('@bugsee/cli/package.json', { paths: [process.argv[1]] })", + nested, + ); + expect(nestedFromApp.status).not.toBe(0); + expect(nestedFromApp.stderr).toMatch(/MODULE_NOT_FOUND|Cannot find module/); + + const wrapperPkg = nodePrint( + "require.resolve('@bugsee/react-native/package.json', { paths: [process.argv[1]] })", + nested, + ); + expect(wrapperPkg.status).toBe(0); + const nestedFromWrapper = nodePrint( + "require.resolve('@bugsee/cli/package.json', { paths: [process.argv[1]] })", + dirname(wrapperPkg.stdout), + ); + expect(nestedFromWrapper.status).toBe(0); + expect(nestedFromWrapper.stdout).toBe(realpathSync(nestedCli)); + + const nestedViaScript = nodePrint(RESOLVE_BUGSEE_CLI_PACKAGE, nested); + expect(nestedViaScript.status).toBe(0); + expect(nestedViaScript.stdout).toBe(realpathSync(nestedCli)); + + const nativeFromApp = nodePrint( + "require.resolve('@bugsee/cli-darwin-arm64/package.json', { paths: [process.argv[1]] })", + nested, + ); + expect(nativeFromApp.status).not.toBe(0); + const nativeViaScript = nodePrint( + resolveNativeCliPackageSource('@bugsee/cli-darwin-arm64/package.json'), + nested, + ); + expect(nativeViaScript.status).toBe(0); + expect(nativeViaScript.stdout).toBe(realpathSync(nestedNative)); + + const hoisted = makeRoot(); + writePackage(join(hoisted, 'node_modules/@bugsee/react-native/package.json'), { + name: '@bugsee/react-native', + }); + const hoistedCli = join(hoisted, 'node_modules/@bugsee/cli/package.json'); + writePackage(hoistedCli, { + name: '@bugsee/cli', + bin: { 'bugsee-cli': 'bin/bugsee-cli.js' }, + }); + + const hoistedFromApp = nodePrint( + "require.resolve('@bugsee/cli/package.json', { paths: [process.argv[1]] })", + hoisted, + ); + expect(hoistedFromApp.status).toBe(0); + expect(hoistedFromApp.stdout).toBe(realpathSync(hoistedCli)); + + const hoistedViaScript = nodePrint(RESOLVE_BUGSEE_CLI_PACKAGE, hoisted); + expect(hoistedViaScript.status).toBe(0); + expect(hoistedViaScript.stdout).toBe(realpathSync(hoistedCli)); + } finally { + for (const root of roots) { + rmSync(root, { recursive: true, force: true }); + } + } }); it('replaces a classic bundle phase with the bare hook', () => { diff --git a/packages/react-native/plugin/src/dsym-script.ts b/packages/react-native/plugin/src/dsym-script.ts index bd3dcfc..410f0ae 100644 --- a/packages/react-native/plugin/src/dsym-script.ts +++ b/packages/react-native/plugin/src/dsym-script.ts @@ -1,8 +1,32 @@ // Archive post-action inserted into the Expo scheme. After NODE_BINARY is -// known, the app root (${PROJECT_DIR}/..) is passed to node so resolution -// does not use the post-action working directory. The native optional -// dependency is preferred; otherwise the JS CLI path comes from the package -// bin field. Tokens are exported only when non-empty. +// known, ${PROJECT_DIR}/.. is passed to node as the app root. The wrapper is +// resolved from that root, @bugsee/cli from the wrapper directory (a nested +// install is not visible from the app root), and the native optional +// dependency from the CLI directory. Otherwise the JS entry comes from the +// CLI package bin field. Tokens are exported only when non-empty. + +const locateBugseeCliPackage = [ + "const path = require('path');", + 'const appRoot = process.argv[1];', + "const wrapperPkg = require.resolve('@bugsee/react-native/package.json', { paths: [appRoot] });", + 'const wrapperDir = path.dirname(wrapperPkg);', + "const cliPkg = require.resolve('@bugsee/cli/package.json', { paths: [wrapperDir] });", + 'const cliDir = path.dirname(cliPkg);', +].join(' '); + +/** Node --print source. Prints the CLI package.json path, or '' when missing. */ +export const RESOLVE_BUGSEE_CLI_PACKAGE = `try { ${locateBugseeCliPackage} cliPkg; } catch (e) { '' }`; + +export function resolveNativeCliPackageSource(packageJson: string): string { + return `try { ${locateBugseeCliPackage} require.resolve('${packageJson}', { paths: [cliDir] }); } catch (e) { '' }`; +} + +const resolveBugseeCliJsSource = `try { const fs = require('fs'); ${locateBugseeCliPackage} const rel = JSON.parse(fs.readFileSync(cliPkg, 'utf8')).bin['bugsee-cli']; rel ? path.join(cliDir, rel) : ''; } catch (e) { '' }`; + +function nodePrint(source: string): string { + return `"$("$NODE_BINARY" --print "${source}" "$APP_ROOT")"`; +} + export const DSYM_POST_ACTION_SCRIPT = [ 'CREDS="${PROJECT_DIR}/../credentials.json"', 'TOKEN="$BUGSEE_APP_TOKEN"', @@ -47,9 +71,9 @@ export const DSYM_POST_ACTION_SCRIPT = [ ' export PATH NODE_BINARY', ' APP_ROOT="${PROJECT_DIR}/.."', ' if [ "$(uname -m)" = "x86_64" ]; then', - ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-x64/package.json\', { paths: [process.argv[1]] }) } catch (e) { \'\' }" "$APP_ROOT")"', + ` NATIVE_PKG=${nodePrint(resolveNativeCliPackageSource('@bugsee/cli-darwin-x64/package.json'))}`, ' else', - ' NATIVE_PKG="$("$NODE_BINARY" --print "try { require.resolve(\'@bugsee/cli-darwin-arm64/package.json\', { paths: [process.argv[1]] }) } catch (e) { \'\' }" "$APP_ROOT")"', + ` NATIVE_PKG=${nodePrint(resolveNativeCliPackageSource('@bugsee/cli-darwin-arm64/package.json'))}`, ' fi', ' if [ -n "$NATIVE_PKG" ]; then', ' NATIVE_BIN="$(dirname "$NATIVE_PKG")/bin/bugsee-cli"', @@ -58,7 +82,7 @@ export const DSYM_POST_ACTION_SCRIPT = [ ' exit $?', ' fi', ' fi', - ' CLI_JS="$("$NODE_BINARY" --print "try { const fs = require(\'fs\'); const path = require(\'path\'); const pkg = require.resolve(\'@bugsee/cli/package.json\', { paths: [process.argv[1]] }); const rel = JSON.parse(fs.readFileSync(pkg, \'utf8\')).bin[\'bugsee-cli\']; rel ? path.join(path.dirname(pkg), rel) : \'\'; } catch (e) { \'\' }" "$APP_ROOT")"', + ` CLI_JS=${nodePrint(resolveBugseeCliJsSource)}`, ' if [ -n "$CLI_JS" ]; then', ' "$NODE_BINARY" "$CLI_JS" xcode post-action', ' exit $?', From 872ab7106a9be1799067bcfc8dcd1fc250a58c62 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 04:59:30 +0500 Subject: [PATCH 07/11] Task 13.4: drop a direct NDK dependency when crash reporting is off. A configuration exclude only removes the wrapper's transitive api, so an implementation line left by an earlier prebuild still put the NDK AAR on the APK. Co-authored-by: Cursor --- .../react-native/plugin/build/gradle.d.ts | 11 +++++----- packages/react-native/plugin/build/gradle.js | 20 ++++++++++++----- .../react-native/plugin/build/gradle.js.map | 2 +- .../plugin/src/__tests__/plugin.test.ts | 19 ++++++++++++++++ packages/react-native/plugin/src/gradle.ts | 22 ++++++++++++++----- 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/packages/react-native/plugin/build/gradle.d.ts b/packages/react-native/plugin/build/gradle.d.ts index 419cb12..5dc4be5 100644 --- a/packages/react-native/plugin/build/gradle.d.ts +++ b/packages/react-native/plugin/build/gradle.d.ts @@ -7,10 +7,11 @@ export declare function ensureMavenCentral(settingsGradle: string): string; export declare function ensureGradlePluginDeclared(projectBuildGradle: string, version: string): string; /** * `ndkVersion` is the baked `android.sdk`, or null when native crash - * reporting is explicitly off. Null does not add an implementation line. - * It excludes the wrapper's `api` NDK artifact so that AAR stays off the - * APK. A later run with the option omitted or on removes that exclude and - * adds the implementation line. The wrapper declaration itself is left in - * place. + * reporting is explicitly off. Null strips a direct + * `implementation "com.bugsee:bugsee-android-ndk"` line from an earlier + * prebuild and excludes the wrapper's transitive `api` artifact. A + * configuration exclude does not drop a direct dependency. A later run + * with the option omitted or on removes that exclude and adds the + * implementation line. The wrapper `api` itself is left in place. */ export declare function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string; diff --git a/packages/react-native/plugin/build/gradle.js b/packages/react-native/plugin/build/gradle.js index 46ed5a6..0d887cf 100644 --- a/packages/react-native/plugin/build/gradle.js +++ b/packages/react-native/plugin/build/gradle.js @@ -99,11 +99,12 @@ function ensureGradlePluginDeclared(projectBuildGradle, version) { const NDK_EXCLUDE = "exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"; /** * `ndkVersion` is the baked `android.sdk`, or null when native crash - * reporting is explicitly off. Null does not add an implementation line. - * It excludes the wrapper's `api` NDK artifact so that AAR stays off the - * APK. A later run with the option omitted or on removes that exclude and - * adds the implementation line. The wrapper declaration itself is left in - * place. + * reporting is explicitly off. Null strips a direct + * `implementation "com.bugsee:bugsee-android-ndk"` line from an earlier + * prebuild and excludes the wrapper's transitive `api` artifact. A + * configuration exclude does not drop a direct dependency. A later run + * with the option omitted or on removes that exclude and adds the + * implementation line. The wrapper `api` itself is left in place. */ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { let next = appBuildGradle; @@ -117,7 +118,7 @@ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { } } if (ndkVersion === null) { - return ensureNdkExcluded(next); + return ensureNdkExcluded(dropNdkImplementation(next)); } next = dropNdkExclude(next); if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(next)) { @@ -134,6 +135,13 @@ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { const brace = next.indexOf('{', deps); return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; } +const NDK_IMPLEMENTATION = /^\s*implementation\s+["']com\.bugsee:bugsee-android-ndk:/; +function dropNdkImplementation(source) { + return source + .split('\n') + .filter((line) => !NDK_IMPLEMENTATION.test(line)) + .join('\n'); +} const NDK_EXCLUDE_BLOCK = [ 'configurations.configureEach {', ` ${NDK_EXCLUDE}`, diff --git a/packages/react-native/plugin/build/gradle.js.map b/packages/react-native/plugin/build/gradle.js.map index 50079a5..a58d2e2 100644 --- a/packages/react-native/plugin/build/gradle.js.map +++ b/packages/react-native/plugin/build/gradle.js.map @@ -1 +1 @@ -{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":";;AA+BA,gDAwCC;AAED,gEAyBC;AAYD,wDA2BC;AAzID,MAAM,SAAS,GAAG,2BAA2B,CAAC;AAE9C,SAAS,WAAW,CAAC,MAAc,EAAE,OAAe;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACtB,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,OAAO,EAAE,SAAS,EAAE,IAAI,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,cAAsB;IACvD,MAAM,MAAM,GAAG,WAAW,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IAC/D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG;YACb,oBAAoB;YACpB,oBAAoB;YACpB,8BAA8B;YAC9B,kBAAkB;YAClB,wBAAwB;YACxB,OAAO;YACP,GAAG;YACH,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,OAAO,MAAM,GAAG,cAAc,CAAC;IACjC,CAAC;IACD,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACpE,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACvD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QACzD,OAAO,CACL,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;YACjC,0BAA0B;YAC1B,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAC/B,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG;QACf,EAAE;QACF,oBAAoB;QACpB,8BAA8B;QAC9B,kBAAkB;QAClB,wBAAwB;QACxB,OAAO;QACP,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,CACL,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAC1F,CAAC;AACJ,CAAC;AAED,SAAgB,0BAA0B,CAAC,kBAA0B,EAAE,OAAe;IACpF,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,kBAAkB,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACD,uEAAuE;IACvE,uEAAuE;IACvE,oCAAoC;IACpC,MAAM,WAAW,GAAG;QAClB,EAAE;QACF,WAAW;QACX,WAAW,SAAS,cAAc,OAAO,eAAe;QACxD,GAAG;QACH,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,yEAAyE;IACzE,oDAAoD;IACpD,MAAM,WAAW,GAAG,WAAW,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;IACnE,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,GAAG,CAAC,CAAC;QACnC,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,WAAW,GAAG,kBAAkB,CAAC;AAC1C,CAAC;AAED,MAAM,WAAW,GAAG,2DAA2D,CAAC;AAEhF;;;;;;;GAOG;AACH,SAAgB,sBAAsB,CAAC,cAAsB,EAAE,UAAyB;IACtF,IAAI,IAAI,GAAG,cAAc,CAAC;IAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,oCAAoC,CAAC;QACnD,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,KAAK,oBAAoB,SAAS,GAAG,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,kBAAkB,SAAS,MAAM,IAAI,EAAE,CAAC;QACjD,CAAC;IACH,CAAC;IACD,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,sDAAsD,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,iCAAiC,UAAU,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,GAAG,GAAG,qDAAqD,UAAU,GAAG,CAAC;IAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC5C,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,uBAAuB,GAAG,OAAO,CAAC;IACtE,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;AACvE,CAAC;AAED,MAAM,iBAAiB,GAAG;IACxB,gCAAgC;IAChC,OAAO,WAAW,EAAE;IACpB,GAAG;CACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,SAAS,iBAAiB,CAAC,MAAc;IACvC,IAAI,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,EAAE,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC;AACnD,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC7C,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5C,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,IAAI,GAAG,GAAG,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC;IACxC,OAAO,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,GAAG,IAAI,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;AACvE,CAAC"} \ No newline at end of file +{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index e775ce4..93570f3 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -418,6 +418,25 @@ describe('Android Gradle edits', () => { expect(ensureAppAppliesPlugin(next, null)).toBe(next); }); + it('drops a direct NDK implementation when native crash reporting is turned off', () => { + const app = [ + 'apply plugin: "com.android.application"', + 'apply plugin: "com.facebook.react"', + '', + 'dependencies {', + ' implementation("com.facebook.react:react-android")', + '}', + '', + ].join('\n'); + const enabled = ensureAppAppliesPlugin(app, versions.sdk); + expect(enabled).toContain(`implementation "com.bugsee:bugsee-android-ndk:${versions.sdk}"`); + const next = ensureAppAppliesPlugin(enabled, null); + expect(next).not.toMatch(/implementation\s+["']com\.bugsee:bugsee-android-ndk:/); + expect(next).toContain("exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"); + expect(next).toContain('implementation("com.facebook.react:react-android")'); + expect(ensureAppAppliesPlugin(next, null)).toBe(next); + }); + it('removes a previous NDK exclude when native crash reporting is on', () => { const app = [ 'apply plugin: "com.facebook.react"', diff --git a/packages/react-native/plugin/src/gradle.ts b/packages/react-native/plugin/src/gradle.ts index 8507dce..4a9573f 100644 --- a/packages/react-native/plugin/src/gradle.ts +++ b/packages/react-native/plugin/src/gradle.ts @@ -102,11 +102,12 @@ const NDK_EXCLUDE = "exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"; /** * `ndkVersion` is the baked `android.sdk`, or null when native crash - * reporting is explicitly off. Null does not add an implementation line. - * It excludes the wrapper's `api` NDK artifact so that AAR stays off the - * APK. A later run with the option omitted or on removes that exclude and - * adds the implementation line. The wrapper declaration itself is left in - * place. + * reporting is explicitly off. Null strips a direct + * `implementation "com.bugsee:bugsee-android-ndk"` line from an earlier + * prebuild and excludes the wrapper's transitive `api` artifact. A + * configuration exclude does not drop a direct dependency. A later run + * with the option omitted or on removes that exclude and adds the + * implementation line. The wrapper `api` itself is left in place. */ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string { let next = appBuildGradle; @@ -119,7 +120,7 @@ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: strin } } if (ndkVersion === null) { - return ensureNdkExcluded(next); + return ensureNdkExcluded(dropNdkImplementation(next)); } next = dropNdkExclude(next); if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(next)) { @@ -137,6 +138,15 @@ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: strin return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; } +const NDK_IMPLEMENTATION = /^\s*implementation\s+["']com\.bugsee:bugsee-android-ndk:/; + +function dropNdkImplementation(source: string): string { + return source + .split('\n') + .filter((line) => !NDK_IMPLEMENTATION.test(line)) + .join('\n'); +} + const NDK_EXCLUDE_BLOCK = [ 'configurations.configureEach {', ` ${NDK_EXCLUDE}`, From a71ec6ee03e4bee49acd1368e8511f118319deb9 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 05:29:36 +0500 Subject: [PATCH 08/11] Task 13.4: reapply bare Android symbol hooks in Expo prebuild. The config plugin was applying the Gradle plugin without SYMBOL_TABLE or the Hermes preserve and finish hooks, and a second Archive PostActions sibling is not a valid scheme. Co-authored-by: Cursor --- .../react-native/plugin/build/gradle.d.ts | 8 + packages/react-native/plugin/build/gradle.js | 231 +++++++++++++++- .../react-native/plugin/build/gradle.js.map | 2 +- packages/react-native/plugin/build/index.d.ts | 8 +- .../react-native/plugin/build/index.js.map | 2 +- .../react-native/plugin/build/scheme.d.ts | 4 +- packages/react-native/plugin/build/scheme.js | 48 ++-- .../react-native/plugin/build/scheme.js.map | 2 +- .../plugin/src/__tests__/plugin.test.ts | 199 +++++++++++++- packages/react-native/plugin/src/gradle.ts | 251 +++++++++++++++++- packages/react-native/plugin/src/index.ts | 8 +- packages/react-native/plugin/src/scheme.ts | 50 ++-- 12 files changed, 750 insertions(+), 63 deletions(-) diff --git a/packages/react-native/plugin/build/gradle.d.ts b/packages/react-native/plugin/build/gradle.d.ts index 5dc4be5..8bfe093 100644 --- a/packages/react-native/plugin/build/gradle.d.ts +++ b/packages/react-native/plugin/build/gradle.d.ts @@ -13,5 +13,13 @@ export declare function ensureGradlePluginDeclared(projectBuildGradle: string, v * configuration exclude does not drop a direct dependency. A later run * with the option omitted or on removes that exclude and adds the * implementation line. The wrapper `api` itself is left in place. + * + * On (omitted or a version) also writes `debugSymbolLevel 'SYMBOL_TABLE'` + * on existing debug and release build types when that block is absent. + * Off removes only the block this plugin inserted. Maven Hermes and + * `libreactnative.so` are pre-stripped; the comment does not claim those + * two are symbolicated. The Hermes preserve command and the finish hook + * are the JS source-map path, so they are written either way. The hook + * does not upload. */ export declare function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string; diff --git a/packages/react-native/plugin/build/gradle.js b/packages/react-native/plugin/build/gradle.js index 0d887cf..028513d 100644 --- a/packages/react-native/plugin/build/gradle.js +++ b/packages/react-native/plugin/build/gradle.js @@ -105,6 +105,14 @@ const NDK_EXCLUDE = "exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"; * configuration exclude does not drop a direct dependency. A later run * with the option omitted or on removes that exclude and adds the * implementation line. The wrapper `api` itself is left in place. + * + * On (omitted or a version) also writes `debugSymbolLevel 'SYMBOL_TABLE'` + * on existing debug and release build types when that block is absent. + * Off removes only the block this plugin inserted. Maven Hermes and + * `libreactnative.so` are pre-stripped; the comment does not claim those + * two are symbolicated. The Hermes preserve command and the finish hook + * are the JS source-map path, so they are written either way. The hook + * does not upload. */ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { let next = appBuildGradle; @@ -118,22 +126,29 @@ function ensureAppAppliesPlugin(appBuildGradle, ndkVersion) { } } if (ndkVersion === null) { - return ensureNdkExcluded(dropNdkImplementation(next)); + next = ensureNdkExcluded(dropNdkImplementation(next)); } - next = dropNdkExclude(next); - if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(next)) { - return next; + else { + next = dropNdkExclude(next); + next = ensureNdkImplementation(next, ndkVersion); + } + next = ensureSymbolTable(next, ndkVersion !== null); + return ensureHermesHooks(next); +} +function ensureNdkImplementation(source, ndkVersion) { + if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(source)) { + return source; } if (!/^[0-9A-Za-z.+_-]+$/.test(ndkVersion)) { throw new Error(`refusing NDK artifact version ${ndkVersion}`); } const dep = ` implementation "com.bugsee:bugsee-android-ndk:${ndkVersion}"`; - const deps = next.indexOf('dependencies {'); + const deps = source.indexOf('dependencies {'); if (deps < 0) { - return `${next.replace(/\s*$/, '')}\n\ndependencies {\n${dep}\n}\n`; + return `${source.replace(/\s*$/, '')}\n\ndependencies {\n${dep}\n}\n`; } - const brace = next.indexOf('{', deps); - return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; + const brace = source.indexOf('{', deps); + return `${source.slice(0, brace + 1)}\n${dep}${source.slice(brace + 1)}`; } const NDK_IMPLEMENTATION = /^\s*implementation\s+["']com\.bugsee:bugsee-android-ndk:/; function dropNdkImplementation(source) { @@ -170,4 +185,204 @@ function dropNdkExclude(source) { const next = source.slice(0, start) + source.slice(end); return next.endsWith('\n') || next.length === 0 ? next : `${next}\n`; } +/** Identifies the ndk block this plugin inserted, so a user's block stays. */ +const SYMBOL_TABLE_MARKER = 'bugsee-symbol-table:'; +const SYMBOL_TABLE_BLOCK = [ + '// bugsee-symbol-table: AGP defaults this to NONE, so the plugin\'s native upload finds', + '// nothing and skips. SYMBOL_TABLE emits symbols for code this app', + '// builds. Maven Hermes and libreactnative.so are pre-stripped;', + '// this level does not symbolicate those two.', + 'ndk {', + " debugSymbolLevel 'SYMBOL_TABLE'", + '}', +].join('\n'); +function matchingBrace(source, open) { + let depth = 0; + for (let i = open; i < source.length; i += 1) { + const ch = source[i]; + if (ch === '{') { + depth += 1; + } + else if (ch === '}') { + depth -= 1; + if (depth === 0) { + return i; + } + } + } + return null; +} +function buildTypeSpans(source) { + const extent = blockExtent(source, 'buildTypes'); + if (!extent) { + return []; + } + const body = source.slice(extent.bodyStart, extent.bodyEnd); + const spans = []; + let depth = 0; + for (let i = 0; i < body.length; i += 1) { + const ch = body[i]; + if (ch === '{') { + if (depth === 0) { + const named = /([A-Za-z_][A-Za-z0-9_]*)\s*$/.exec(body.slice(0, i)); + const name = named?.[1]; + if (name === 'debug' || name === 'release') { + const open = extent.bodyStart + i; + const close = matchingBrace(source, open); + if (close != null) { + spans.push({ name, open, close }); + } + } + } + depth += 1; + } + else if (ch === '}') { + depth -= 1; + } + } + return spans; +} +function indentBlock(block, indent) { + return block + .split('\n') + .map((line) => (line.length === 0 ? line : indent + line)) + .join('\n'); +} +function insertSymbolTable(source, span) { + const body = source.slice(span.open + 1, span.close); + if (body.includes(SYMBOL_TABLE_MARKER) || + /debugSymbolLevel\s+(['"])SYMBOL_TABLE\1/.test(body) || + /\bndk\s*\{/.test(body)) { + return source; + } + const closing = /\n([ \t]*)$/.exec(body); + const closingIndent = closing?.[1] ?? ''; + const block = indentBlock(SYMBOL_TABLE_BLOCK, `${closingIndent} `); + if (!closing) { + return `${source.slice(0, span.close)}\n${block}\n${source.slice(span.close)}`; + } + const indentStart = span.close - closingIndent.length; + return `${source.slice(0, indentStart)}${block}\n${closingIndent}${source.slice(span.close)}`; +} +function ensureSymbolTable(source, enabled) { + if (!enabled) { + return removeInsertedSymbolTable(source); + } + const spans = buildTypeSpans(source).sort((a, b) => b.open - a.open); + return spans.reduce((current, span) => insertSymbolTable(current, span), source); +} +function removeInsertedSymbolTable(source) { + const lines = source.split('\n'); + const kept = []; + let i = 0; + while (i < lines.length) { + const line = lines[i]; + if (line === undefined || !line.includes(SYMBOL_TABLE_MARKER)) { + if (line !== undefined) { + kept.push(line); + } + i += 1; + continue; + } + let j = i; + while (j < lines.length && (lines[j] ?? '').trim().startsWith('//')) { + j += 1; + } + if ((lines[j] ?? '').trim() === 'ndk {') { + j += 1; + while (j < lines.length && (lines[j] ?? '').trim() !== '}') { + j += 1; + } + if ((lines[j] ?? '').trim() === '}') { + j += 1; + } + i = j; + continue; + } + kept.push(line); + i += 1; + } + return kept.join('\n'); +} +const HERMES_COMMAND_EXPR = 'new File(["node", "--print", "require.resolve(\'@bugsee/react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/scripts/hermesc-preserve-js.sh"'; +const PRESERVE_REFUSAL = 'Bugsee preserve directory is the packaged asset directory'; +const HERMES_FINISH_HOOK = [ + '// After compose-source-maps.js. Release variants only; debug does not bundle.', + '// Upload is not invoked.', + 'def bugseeHermesSourcemaps = new File(new File(["node", "--print", "require.resolve(\'@bugsee/react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile(), "scripts/hermes-sourcemaps.js")', + 'def bugseeComposeSourceMaps = new File(new File(["node", "--print", "require.resolve(\'react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile(), "scripts/compose-source-maps.js")', + 'afterEvaluate {', + ' tasks.matching { task ->', + ' task.name.startsWith("createBundle") && task.name.endsWith("JsAndAssets")', + ' }.configureEach { bundleTask ->', + ' bundleTask.doLast {', + ' def asset = bundleTask.bundleAssetName.get()', + ' def assetDir = bundleTask.jsBundleDir.get().asFile', + ' // Same rewrite as hermesc-preserve-js.sh: assets are packaged, intermediates are not.', + ' def preserveDir = new File(assetDir.absolutePath.replace(', + ' "/generated/assets/",', + ' "/intermediates/bugsee-sourcemaps/"', + ' ))', + ' if (preserveDir.absolutePath == assetDir.absolutePath) {', + ` throw new GradleException("${PRESERVE_REFUSAL}")`, + ' }', + ' def preserved = new File(preserveDir, asset + ".bugsee-js-source")', + ' def packagedCopies = [', + ' new File(assetDir, asset + ".bugsee-js-source"),', + ' new File(assetDir, asset + ".bugsee-hermesc"),', + ' new File(assetDir, asset + ".bugsee-recompile"),', + ' new File(assetDir, asset + ".bugsee-recompile.map"),', + ' ]', + ' try {', + ' if (preserved.isFile()) {', + ' def composed = new File(bundleTask.jsSourceMapsDir.get().asFile, asset + ".map")', + ' def interDir = bundleTask.jsIntermediateSourceMapsDir.get().asFile', + ' def hook = bugseeHermesSourcemaps', + ' def compose = bugseeComposeSourceMaps', + ' def cmd = []', + ' cmd.addAll(bundleTask.nodeExecutableAndArgs.get())', + ' cmd.addAll([', + ' hook.absolutePath, "finish",', + ' "--bundle", preserved.absolutePath,', + ' "--bytecode", new File(assetDir, asset).absolutePath,', + ' "--composed", composed.absolutePath,', + ' "--intermediate", new File(interDir, asset + ".compiler.map").absolutePath,', + ' "--packager", new File(interDir, asset + ".packager.map").absolutePath,', + ' "--compose", compose.absolutePath,', + ' ])', + ' def hermescNote = new File(preserveDir, asset + ".bugsee-hermesc")', + ' if (hermescNote.isFile()) {', + ' cmd.add("--hermesc")', + ' cmd.add(hermescNote.getText("UTF-8").trim())', + ' }', + ' bundleTask.hermesFlags.get().each { flag ->', + ' cmd.add("--hermes-arg")', + ' cmd.add(flag)', + ' }', + ' project.exec {', + ' commandLine cmd', + ' }', + ' }', + ' } finally {', + ' packagedCopies.each { copy -> copy.delete() }', + ' }', + ' }', + ' }', + '}', +].join('\n'); +function rewriteHermesCommand(source) { + return source.replace(/^([ \t]*)hermesCommand\s*=\s*.+$/gm, (line, indent) => { + if (line.includes('hermesc-preserve-js.sh')) { + return line; + } + return `${indent}hermesCommand = ${HERMES_COMMAND_EXPR}`; + }); +} +function ensureHermesHooks(source) { + const rewritten = rewriteHermesCommand(source); + if (rewritten.includes(PRESERVE_REFUSAL)) { + return rewritten; + } + return `${rewritten.replace(/\s*$/, '')}\n\n${HERMES_FINISH_HOOK}\n`; +} //# sourceMappingURL=gradle.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/gradle.js.map b/packages/react-native/plugin/build/gradle.js.map index a58d2e2..5a91f4b 100644 --- a/packages/react-native/plugin/build/gradle.js.map +++ b/packages/react-native/plugin/build/gradle.js.map @@ -1 +1 @@ -{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"gradle.js","sourceRoot":"","sources":["../src/gradle.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/index.d.ts b/packages/react-native/plugin/build/index.d.ts index 9801601..e47e377 100644 --- a/packages/react-native/plugin/build/index.d.ts +++ b/packages/react-native/plugin/build/index.d.ts @@ -10,9 +10,11 @@ export interface BugseePluginProps { /** Defaults on. `false` skips the Archive dSYM post-action. */ uploadSymbols?: boolean; /** - * Defaults on. Writes `plugin.ndk.enabled=true` for a real token and adds - * `com.bugsee:bugsee-android-ndk`. `false` skips both and excludes the - * wrapper's NDK AAR from the app. + * Defaults on. Writes `plugin.ndk.enabled=true` for a real token, adds + * `com.bugsee:bugsee-android-ndk`, and sets `debugSymbolLevel 'SYMBOL_TABLE'` + * on existing debug and release build types. `false` skips the flag, strips + * that direct dependency, excludes the wrapper's NDK AAR, and removes the + * symbol block this plugin inserted. JS source-map hooks stay either way. */ nativeCrashReporting?: boolean; /** Defaults to native-versions.json `android.gradlePlugin`. */ diff --git a/packages/react-native/plugin/build/index.js.map b/packages/react-native/plugin/build/index.js.map index 40db5ed..58cf7b6 100644 --- a/packages/react-native/plugin/build/index.js.map +++ b/packages/react-native/plugin/build/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/scheme.d.ts b/packages/react-native/plugin/build/scheme.d.ts index ea95a00..299307c 100644 --- a/packages/react-native/plugin/build/scheme.d.ts +++ b/packages/react-native/plugin/build/scheme.d.ts @@ -3,6 +3,8 @@ export { DSYM_POST_ACTION_SCRIPT }; export declare function encodeXmlAttr(value: string): string; /** * Inserts the Archive post-action. The EnvironmentBuildable is the scheme's - * own app target, so ARCHIVE_PATH is provided. + * own app target, so ARCHIVE_PATH is provided. Xcode allows one PostActions + * element; a scheme that already has one gets another ExecutionAction inside + * it. A wrapping PostActions is emitted only when ArchiveAction has none. */ export declare function insertDsymPostAction(scheme: string, script?: string): string; diff --git a/packages/react-native/plugin/build/scheme.js b/packages/react-native/plugin/build/scheme.js index 14976da..76f4fed 100644 --- a/packages/react-native/plugin/build/scheme.js +++ b/packages/react-native/plugin/build/scheme.js @@ -22,21 +22,8 @@ function appBuildableReference(scheme) { } return app; } -/** - * Inserts the Archive post-action. The EnvironmentBuildable is the scheme's - * own app target, so ARCHIVE_PATH is provided. - */ -function insertDsymPostAction(scheme, script = dsym_script_1.DSYM_POST_ACTION_SCRIPT) { - if (scheme.includes('xcode post-action')) { - return scheme; - } - const archive = scheme.match(//); - if (!archive?.[0]) { - throw new Error('ArchiveAction missing'); - } - const reference = appBuildableReference(scheme); - const block = [ - ' ', +function executionActionXml(reference, script) { + return [ ' ', ' ', ' ', ' ', - ' ', ].join('\n'); - const updated = archive[0].replace('', `${block}\n `); - return scheme.replace(archive[0], updated); +} +/** + * Inserts the Archive post-action. The EnvironmentBuildable is the scheme's + * own app target, so ARCHIVE_PATH is provided. Xcode allows one PostActions + * element; a scheme that already has one gets another ExecutionAction inside + * it. A wrapping PostActions is emitted only when ArchiveAction has none. + */ +function insertDsymPostAction(scheme, script = dsym_script_1.DSYM_POST_ACTION_SCRIPT) { + if (scheme.includes('xcode post-action')) { + return scheme; + } + const archive = scheme.match(//); + if (!archive?.[0] || archive.index === undefined) { + throw new Error('ArchiveAction missing'); + } + const execution = executionActionXml(appBuildableReference(scheme), script); + const updated = insertArchiveExecution(archive[0], execution); + return scheme.slice(0, archive.index) + updated + scheme.slice(archive.index + archive[0].length); +} +function insertArchiveExecution(archive, execution) { + const open = /]*>/.exec(archive); + const closeAt = archive.indexOf(''); + if (open && closeAt > open.index) { + const lineStart = archive.lastIndexOf('\n', closeAt - 1) + 1; + return archive.slice(0, lineStart) + execution + '\n' + archive.slice(lineStart); + } + const block = [' ', execution, ' '].join('\n'); + return archive.replace('', `${block}\n `); } //# sourceMappingURL=scheme.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/scheme.js.map b/packages/react-native/plugin/build/scheme.js.map index 2d3f0e3..520989f 100644 --- a/packages/react-native/plugin/build/scheme.js.map +++ b/packages/react-native/plugin/build/scheme.js.map @@ -1 +1 @@ -{"version":3,"file":"scheme.js","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":";;;AAIA,sCAQC;AAeD,oDAyBC;AApDD,+CAAwD;AAE/C,wGAFA,qCAAuB,OAEA;AAEhC,SAAgB,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,IAAI,EAAE,CAAC;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kCAAkC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,MAAc,EAAE,SAAiB,qCAAuB;IAC3F,IAAI,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG;QACZ,qBAAqB;QACrB,2BAA2B;QAC3B,yGAAyG;QACzG,4BAA4B;QAC5B,uCAAuC;QACvC,gCAAgC,aAAa,CAAC,MAAM,CAAC,IAAI;QACzD,uCAAuC;QACvC,SAAS,CAAC,OAAO,EAAE;QACnB,wCAAwC;QACxC,8BAA8B;QAC9B,6BAA6B;QAC7B,sBAAsB;KACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,KAAK,uBAAuB,CAAC,CAAC;IACxF,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC"} \ No newline at end of file +{"version":3,"file":"scheme.js","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index 93570f3..a7752e1 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -19,6 +19,56 @@ import { manifestAutoLaunchToken } from '../manifest'; import { loadNativeVersions } from '../native-versions'; const repoRoot = join(__dirname, '..', '..', '..', '..', '..'); + +function expoSdk57AppBuildGradle(): string { + const tarball = join(repoRoot, 'examples/expo/node_modules/expo/template.tgz'); + const result = spawnSync('tar', ['-xOf', tarball, 'package/android/app/build.gradle'], { + encoding: 'utf8', + }); + if (result.status !== 0 || !result.stdout) { + throw new Error(result.stderr || `could not read Expo SDK 57 app/build.gradle from ${tarball}`); + } + return result.stdout; +} + +function buildTypeBody(source: string, name: string): string { + const extentStart = source.indexOf('buildTypes {'); + if (extentStart < 0) { + throw new Error('buildTypes missing'); + } + const openBuild = source.indexOf('{', extentStart); + let depth = 0; + let buildEnd = -1; + for (let i = openBuild; i < source.length; i += 1) { + if (source[i] === '{') { + depth += 1; + } else if (source[i] === '}') { + depth -= 1; + if (depth === 0) { + buildEnd = i; + break; + } + } + } + const region = source.slice(openBuild + 1, buildEnd); + const match = new RegExp(`(?:^|\\n)[ \\t]*${name}[ \\t]*\\{`).exec(region); + if (!match || match.index === undefined) { + throw new Error(`${name} build type missing`); + } + const openRel = match.index + match[0].length - 1; + let inner = 0; + for (let i = openRel; i < region.length; i += 1) { + if (region[i] === '{') { + inner += 1; + } else if (region[i] === '}') { + inner -= 1; + if (inner === 0) { + return region.slice(openRel + 1, i); + } + } + } + throw new Error(`${name} build type unclosed`); +} const barePbx = join( repoRoot, 'examples/bare/ios/BareExample.xcodeproj/project.pbxproj', @@ -456,6 +506,96 @@ describe('Android Gradle edits', () => { expect(next).toContain(`implementation "com.bugsee:bugsee-android-ndk:${versions.sdk}"`); expect(ensureAppAppliesPlugin(next, versions.sdk)).toBe(next); }); + + it('writes Expo SDK 57 symbol hooks and drops them when native crash reporting is off', () => { + const template = expoSdk57AppBuildGradle(); + expect(template).toContain('hermes-compiler/package.json'); + expect(template).not.toContain('hermesc-preserve-js.sh'); + expect(template).not.toContain('SYMBOL_TABLE'); + + const next = ensureAppAppliesPlugin(template, versions.sdk); + expect(next).toContain('apply plugin: "com.bugsee.android.gradle"'); + expect(next).toContain(`implementation "com.bugsee:bugsee-android-ndk:${versions.sdk}"`); + expect(next.match(/com\.bugsee\.android\.gradle/g)).toHaveLength(1); + + const debug = buildTypeBody(next, 'debug'); + const release = buildTypeBody(next, 'release'); + for (const body of [debug, release]) { + expect(body.match(/debugSymbolLevel 'SYMBOL_TABLE'/g)).toHaveLength(1); + expect(body.match(/\bndk\s*\{/g)).toHaveLength(1); + expect(body).toContain('bugsee-symbol-table:'); + expect(body).toContain('AGP defaults this to NONE'); + expect(body).toContain('Maven Hermes and libreactnative.so are pre-stripped'); + expect(body).toContain('this level does not symbolicate those two'); + } + expect(next.match(/debugSymbolLevel 'SYMBOL_TABLE'/g)).toHaveLength(2); + + const hermes = next.split('\n').filter((line) => /^\s*hermesCommand\s*=/.test(line)); + expect(hermes).toEqual([ + ' hermesCommand = new File(["node", "--print", "require.resolve(\'@bugsee/react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/scripts/hermesc-preserve-js.sh"', + ]); + expect(hermes[0]).not.toContain('../../node_modules'); + expect(hermes[0]).not.toContain('hermes-compiler'); + expect(next).toContain('// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"'); + + const hook = next.slice(next.lastIndexOf('// After compose-source-maps.js')); + expect(next.match(/afterEvaluate/g)).toHaveLength(1); + expect(hook).toContain( + 'def bugseeHermesSourcemaps = new File(new File(["node", "--print", "require.resolve(\'@bugsee/react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile(), "scripts/hermes-sourcemaps.js")', + ); + expect(hook).toContain( + 'def bugseeComposeSourceMaps = new File(new File(["node", "--print", "require.resolve(\'react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile(), "scripts/compose-source-maps.js")', + ); + expect(hook).toContain('hook.absolutePath, "finish"'); + expect(hook).toContain('Bugsee preserve directory is the packaged asset directory'); + expect(hook).toContain('/intermediates/bugsee-sourcemaps/'); + expect(hook).toContain('Upload is not invoked.'); + expect(hook).not.toContain('../../node_modules'); + expect(hook).not.toContain('bugsee-cli'); + expect(hook).not.toContain('debug-files'); + expect(ensureAppAppliesPlugin(next, versions.sdk)).toBe(next); + + const off = ensureAppAppliesPlugin(next, null); + expect(off).not.toContain('bugsee-symbol-table:'); + expect(off).not.toContain('SYMBOL_TABLE'); + expect(off).not.toMatch(/implementation\s+["']com\.bugsee:bugsee-android-ndk:/); + expect(off).toContain("exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"); + expect(buildTypeBody(off, 'debug')).toContain('signingConfig signingConfigs.debug'); + expect(buildTypeBody(off, 'release')).toContain('minifyEnabled enableMinifyInReleaseBuilds'); + expect(buildTypeBody(off, 'debug')).not.toContain('ndk'); + expect(buildTypeBody(off, 'release')).not.toContain('ndk'); + expect(off).toContain('hermesc-preserve-js.sh'); + expect(off).toContain('Bugsee preserve directory is the packaged asset directory'); + expect(off.match(/afterEvaluate/g)).toHaveLength(1); + expect(ensureAppAppliesPlugin(off, null)).toBe(off); + }); + + it('leaves a hand-written ndk block when native crash reporting is off', () => { + const template = expoSdk57AppBuildGradle().replace( + ' debug {\n signingConfig signingConfigs.debug\n }', + [ + ' debug {', + ' signingConfig signingConfigs.debug', + ' ndk {', + " debugSymbolLevel 'FULL'", + ' }', + ' }', + ].join('\n'), + ); + const enabled = ensureAppAppliesPlugin(template, versions.sdk); + expect(buildTypeBody(enabled, 'debug')).toContain("debugSymbolLevel 'FULL'"); + expect(buildTypeBody(enabled, 'debug')).not.toContain('SYMBOL_TABLE'); + expect(buildTypeBody(enabled, 'debug')).not.toContain('bugsee-symbol-table:'); + expect(buildTypeBody(enabled, 'release')).toContain("debugSymbolLevel 'SYMBOL_TABLE'"); + expect(buildTypeBody(enabled, 'release').match(/\bndk\s*\{/g)).toHaveLength(1); + + const off = ensureAppAppliesPlugin(enabled, null); + expect(buildTypeBody(off, 'debug')).toContain("debugSymbolLevel 'FULL'"); + expect(buildTypeBody(off, 'debug')).not.toContain('bugsee-symbol-table:'); + expect(off).not.toContain('SYMBOL_TABLE'); + expect(off).not.toContain('bugsee-symbol-table:'); + expect(off).not.toMatch(/implementation\s+["']com\.bugsee:bugsee-android-ndk:/); + }); }); describe('published native versions', () => { @@ -507,7 +647,8 @@ describe('scheme post-action', () => { it('inserts the copied script on Archive and keeps the app target', () => { const next = insertDsymPostAction(scheme, DSYM_POST_ACTION_SCRIPT); - expect(next).toContain(''); + expect(next.match(//g)).toHaveLength(1); + expect(next.match(/<\/PostActions>/g)).toHaveLength(1); expect(next).toContain('title = "Upload dSYMs"'); const encoded = next.match(/\bscriptText\s*=\s*"([^"]*)"/)?.[1]; expect(encoded).toEqual(expect.any(String)); @@ -516,6 +657,62 @@ describe('scheme post-action', () => { expect(next).not.toContain('BareExample'); expect(insertDsymPostAction(next, DSYM_POST_ACTION_SCRIPT)).toBe(next); }); + + it('inserts the Bugsee action into an existing Archive PostActions element', () => { + const scheme = ` + + + + + + + + + + + + + + + + + + + + + + +`; + const next = insertDsymPostAction(scheme, DSYM_POST_ACTION_SCRIPT); + expect(next.match(//g)).toHaveLength(1); + expect(next.match(/<\/PostActions>/g)).toHaveLength(1); + const archive = next.match(//)?.[0] ?? ''; + const open = archive.indexOf(''); + const close = archive.indexOf(''); + const inner = archive.slice(open, close); + expect(inner.match(//g)).toHaveLength(1); + expect(inner).toContain('title = "Notify"'); + expect(inner).toContain('echo archive-finished'); + expect(inner).toContain('title = "Upload dSYMs"'); + expect(archive.match(/\n '); + expect(insertDsymPostAction(next, DSYM_POST_ACTION_SCRIPT)).toBe(next); + }); }); describe('manifest auto-launch', () => { diff --git a/packages/react-native/plugin/src/gradle.ts b/packages/react-native/plugin/src/gradle.ts index 4a9573f..9b9ece0 100644 --- a/packages/react-native/plugin/src/gradle.ts +++ b/packages/react-native/plugin/src/gradle.ts @@ -108,6 +108,14 @@ const NDK_EXCLUDE = "exclude group: 'com.bugsee', module: 'bugsee-android-ndk'"; * configuration exclude does not drop a direct dependency. A later run * with the option omitted or on removes that exclude and adds the * implementation line. The wrapper `api` itself is left in place. + * + * On (omitted or a version) also writes `debugSymbolLevel 'SYMBOL_TABLE'` + * on existing debug and release build types when that block is absent. + * Off removes only the block this plugin inserted. Maven Hermes and + * `libreactnative.so` are pre-stripped; the comment does not claim those + * two are symbolicated. The Hermes preserve command and the finish hook + * are the JS source-map path, so they are written either way. The hook + * does not upload. */ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: string | null): string { let next = appBuildGradle; @@ -120,22 +128,29 @@ export function ensureAppAppliesPlugin(appBuildGradle: string, ndkVersion: strin } } if (ndkVersion === null) { - return ensureNdkExcluded(dropNdkImplementation(next)); + next = ensureNdkExcluded(dropNdkImplementation(next)); + } else { + next = dropNdkExclude(next); + next = ensureNdkImplementation(next, ndkVersion); } - next = dropNdkExclude(next); - if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(next)) { - return next; + next = ensureSymbolTable(next, ndkVersion !== null); + return ensureHermesHooks(next); +} + +function ensureNdkImplementation(source: string, ndkVersion: string): string { + if (/implementation\s+["']com\.bugsee:bugsee-android-ndk:/.test(source)) { + return source; } if (!/^[0-9A-Za-z.+_-]+$/.test(ndkVersion)) { throw new Error(`refusing NDK artifact version ${ndkVersion}`); } const dep = ` implementation "com.bugsee:bugsee-android-ndk:${ndkVersion}"`; - const deps = next.indexOf('dependencies {'); + const deps = source.indexOf('dependencies {'); if (deps < 0) { - return `${next.replace(/\s*$/, '')}\n\ndependencies {\n${dep}\n}\n`; + return `${source.replace(/\s*$/, '')}\n\ndependencies {\n${dep}\n}\n`; } - const brace = next.indexOf('{', deps); - return `${next.slice(0, brace + 1)}\n${dep}${next.slice(brace + 1)}`; + const brace = source.indexOf('{', deps); + return `${source.slice(0, brace + 1)}\n${dep}${source.slice(brace + 1)}`; } const NDK_IMPLEMENTATION = /^\s*implementation\s+["']com\.bugsee:bugsee-android-ndk:/; @@ -177,3 +192,223 @@ function dropNdkExclude(source: string): string { const next = source.slice(0, start) + source.slice(end); return next.endsWith('\n') || next.length === 0 ? next : `${next}\n`; } + +/** Identifies the ndk block this plugin inserted, so a user's block stays. */ +const SYMBOL_TABLE_MARKER = 'bugsee-symbol-table:'; + +const SYMBOL_TABLE_BLOCK = [ + '// bugsee-symbol-table: AGP defaults this to NONE, so the plugin\'s native upload finds', + '// nothing and skips. SYMBOL_TABLE emits symbols for code this app', + '// builds. Maven Hermes and libreactnative.so are pre-stripped;', + '// this level does not symbolicate those two.', + 'ndk {', + " debugSymbolLevel 'SYMBOL_TABLE'", + '}', +].join('\n'); + +interface BuildTypeSpan { + name: string; + open: number; + close: number; +} + +function matchingBrace(source: string, open: number): number | null { + let depth = 0; + for (let i = open; i < source.length; i += 1) { + const ch = source[i]; + if (ch === '{') { + depth += 1; + } else if (ch === '}') { + depth -= 1; + if (depth === 0) { + return i; + } + } + } + return null; +} + +function buildTypeSpans(source: string): BuildTypeSpan[] { + const extent = blockExtent(source, 'buildTypes'); + if (!extent) { + return []; + } + const body = source.slice(extent.bodyStart, extent.bodyEnd); + const spans: BuildTypeSpan[] = []; + let depth = 0; + for (let i = 0; i < body.length; i += 1) { + const ch = body[i]; + if (ch === '{') { + if (depth === 0) { + const named = /([A-Za-z_][A-Za-z0-9_]*)\s*$/.exec(body.slice(0, i)); + const name = named?.[1]; + if (name === 'debug' || name === 'release') { + const open = extent.bodyStart + i; + const close = matchingBrace(source, open); + if (close != null) { + spans.push({ name, open, close }); + } + } + } + depth += 1; + } else if (ch === '}') { + depth -= 1; + } + } + return spans; +} + +function indentBlock(block: string, indent: string): string { + return block + .split('\n') + .map((line) => (line.length === 0 ? line : indent + line)) + .join('\n'); +} + +function insertSymbolTable(source: string, span: BuildTypeSpan): string { + const body = source.slice(span.open + 1, span.close); + if ( + body.includes(SYMBOL_TABLE_MARKER) || + /debugSymbolLevel\s+(['"])SYMBOL_TABLE\1/.test(body) || + /\bndk\s*\{/.test(body) + ) { + return source; + } + const closing = /\n([ \t]*)$/.exec(body); + const closingIndent = closing?.[1] ?? ''; + const block = indentBlock(SYMBOL_TABLE_BLOCK, `${closingIndent} `); + if (!closing) { + return `${source.slice(0, span.close)}\n${block}\n${source.slice(span.close)}`; + } + const indentStart = span.close - closingIndent.length; + return `${source.slice(0, indentStart)}${block}\n${closingIndent}${source.slice(span.close)}`; +} + +function ensureSymbolTable(source: string, enabled: boolean): string { + if (!enabled) { + return removeInsertedSymbolTable(source); + } + const spans = buildTypeSpans(source).sort((a, b) => b.open - a.open); + return spans.reduce((current, span) => insertSymbolTable(current, span), source); +} + +function removeInsertedSymbolTable(source: string): string { + const lines = source.split('\n'); + const kept: string[] = []; + let i = 0; + while (i < lines.length) { + const line = lines[i]; + if (line === undefined || !line.includes(SYMBOL_TABLE_MARKER)) { + if (line !== undefined) { + kept.push(line); + } + i += 1; + continue; + } + let j = i; + while (j < lines.length && (lines[j] ?? '').trim().startsWith('//')) { + j += 1; + } + if ((lines[j] ?? '').trim() === 'ndk {') { + j += 1; + while (j < lines.length && (lines[j] ?? '').trim() !== '}') { + j += 1; + } + if ((lines[j] ?? '').trim() === '}') { + j += 1; + } + i = j; + continue; + } + kept.push(line); + i += 1; + } + return kept.join('\n'); +} + +const HERMES_COMMAND_EXPR = + 'new File(["node", "--print", "require.resolve(\'@bugsee/react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/scripts/hermesc-preserve-js.sh"'; + +const PRESERVE_REFUSAL = 'Bugsee preserve directory is the packaged asset directory'; + +const HERMES_FINISH_HOOK = [ + '// After compose-source-maps.js. Release variants only; debug does not bundle.', + '// Upload is not invoked.', + 'def bugseeHermesSourcemaps = new File(new File(["node", "--print", "require.resolve(\'@bugsee/react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile(), "scripts/hermes-sourcemaps.js")', + 'def bugseeComposeSourceMaps = new File(new File(["node", "--print", "require.resolve(\'react-native/package.json\')"].execute(null, rootDir).text.trim()).getParentFile(), "scripts/compose-source-maps.js")', + 'afterEvaluate {', + ' tasks.matching { task ->', + ' task.name.startsWith("createBundle") && task.name.endsWith("JsAndAssets")', + ' }.configureEach { bundleTask ->', + ' bundleTask.doLast {', + ' def asset = bundleTask.bundleAssetName.get()', + ' def assetDir = bundleTask.jsBundleDir.get().asFile', + ' // Same rewrite as hermesc-preserve-js.sh: assets are packaged, intermediates are not.', + ' def preserveDir = new File(assetDir.absolutePath.replace(', + ' "/generated/assets/",', + ' "/intermediates/bugsee-sourcemaps/"', + ' ))', + ' if (preserveDir.absolutePath == assetDir.absolutePath) {', + ` throw new GradleException("${PRESERVE_REFUSAL}")`, + ' }', + ' def preserved = new File(preserveDir, asset + ".bugsee-js-source")', + ' def packagedCopies = [', + ' new File(assetDir, asset + ".bugsee-js-source"),', + ' new File(assetDir, asset + ".bugsee-hermesc"),', + ' new File(assetDir, asset + ".bugsee-recompile"),', + ' new File(assetDir, asset + ".bugsee-recompile.map"),', + ' ]', + ' try {', + ' if (preserved.isFile()) {', + ' def composed = new File(bundleTask.jsSourceMapsDir.get().asFile, asset + ".map")', + ' def interDir = bundleTask.jsIntermediateSourceMapsDir.get().asFile', + ' def hook = bugseeHermesSourcemaps', + ' def compose = bugseeComposeSourceMaps', + ' def cmd = []', + ' cmd.addAll(bundleTask.nodeExecutableAndArgs.get())', + ' cmd.addAll([', + ' hook.absolutePath, "finish",', + ' "--bundle", preserved.absolutePath,', + ' "--bytecode", new File(assetDir, asset).absolutePath,', + ' "--composed", composed.absolutePath,', + ' "--intermediate", new File(interDir, asset + ".compiler.map").absolutePath,', + ' "--packager", new File(interDir, asset + ".packager.map").absolutePath,', + ' "--compose", compose.absolutePath,', + ' ])', + ' def hermescNote = new File(preserveDir, asset + ".bugsee-hermesc")', + ' if (hermescNote.isFile()) {', + ' cmd.add("--hermesc")', + ' cmd.add(hermescNote.getText("UTF-8").trim())', + ' }', + ' bundleTask.hermesFlags.get().each { flag ->', + ' cmd.add("--hermes-arg")', + ' cmd.add(flag)', + ' }', + ' project.exec {', + ' commandLine cmd', + ' }', + ' }', + ' } finally {', + ' packagedCopies.each { copy -> copy.delete() }', + ' }', + ' }', + ' }', + '}', +].join('\n'); + +function rewriteHermesCommand(source: string): string { + return source.replace(/^([ \t]*)hermesCommand\s*=\s*.+$/gm, (line, indent: string) => { + if (line.includes('hermesc-preserve-js.sh')) { + return line; + } + return `${indent}hermesCommand = ${HERMES_COMMAND_EXPR}`; + }); +} + +function ensureHermesHooks(source: string): string { + const rewritten = rewriteHermesCommand(source); + if (rewritten.includes(PRESERVE_REFUSAL)) { + return rewritten; + } + return `${rewritten.replace(/\s*$/, '')}\n\n${HERMES_FINISH_HOOK}\n`; +} diff --git a/packages/react-native/plugin/src/index.ts b/packages/react-native/plugin/src/index.ts index 0ef70c4..8195dfd 100644 --- a/packages/react-native/plugin/src/index.ts +++ b/packages/react-native/plugin/src/index.ts @@ -33,9 +33,11 @@ export interface BugseePluginProps { /** Defaults on. `false` skips the Archive dSYM post-action. */ uploadSymbols?: boolean; /** - * Defaults on. Writes `plugin.ndk.enabled=true` for a real token and adds - * `com.bugsee:bugsee-android-ndk`. `false` skips both and excludes the - * wrapper's NDK AAR from the app. + * Defaults on. Writes `plugin.ndk.enabled=true` for a real token, adds + * `com.bugsee:bugsee-android-ndk`, and sets `debugSymbolLevel 'SYMBOL_TABLE'` + * on existing debug and release build types. `false` skips the flag, strips + * that direct dependency, excludes the wrapper's NDK AAR, and removes the + * symbol block this plugin inserted. JS source-map hooks stay either way. */ nativeCrashReporting?: boolean; /** Defaults to native-versions.json `android.gradlePlugin`. */ diff --git a/packages/react-native/plugin/src/scheme.ts b/packages/react-native/plugin/src/scheme.ts index feadfcd..f1278d6 100644 --- a/packages/react-native/plugin/src/scheme.ts +++ b/packages/react-native/plugin/src/scheme.ts @@ -21,21 +21,8 @@ function appBuildableReference(scheme: string): string { return app; } -/** - * Inserts the Archive post-action. The EnvironmentBuildable is the scheme's - * own app target, so ARCHIVE_PATH is provided. - */ -export function insertDsymPostAction(scheme: string, script: string = DSYM_POST_ACTION_SCRIPT): string { - if (scheme.includes('xcode post-action')) { - return scheme; - } - const archive = scheme.match(//); - if (!archive?.[0]) { - throw new Error('ArchiveAction missing'); - } - const reference = appBuildableReference(scheme); - const block = [ - ' ', +function executionActionXml(reference: string, script: string): string { + return [ ' ', ' ', ' ', ' ', - ' ', ].join('\n'); - const updated = archive[0].replace('', `${block}\n `); - return scheme.replace(archive[0], updated); +} + +/** + * Inserts the Archive post-action. The EnvironmentBuildable is the scheme's + * own app target, so ARCHIVE_PATH is provided. Xcode allows one PostActions + * element; a scheme that already has one gets another ExecutionAction inside + * it. A wrapping PostActions is emitted only when ArchiveAction has none. + */ +export function insertDsymPostAction(scheme: string, script: string = DSYM_POST_ACTION_SCRIPT): string { + if (scheme.includes('xcode post-action')) { + return scheme; + } + const archive = scheme.match(//); + if (!archive?.[0] || archive.index === undefined) { + throw new Error('ArchiveAction missing'); + } + const execution = executionActionXml(appBuildableReference(scheme), script); + const updated = insertArchiveExecution(archive[0], execution); + return scheme.slice(0, archive.index) + updated + scheme.slice(archive.index + archive[0].length); +} + +function insertArchiveExecution(archive: string, execution: string): string { + const open = /]*>/.exec(archive); + const closeAt = archive.indexOf(''); + if (open && closeAt > open.index) { + const lineStart = archive.lastIndexOf('\n', closeAt - 1) + 1; + return archive.slice(0, lineStart) + execution + '\n' + archive.slice(lineStart); + } + const block = [' ', execution, ' '].join('\n'); + return archive.replace('', `${block}\n `); } From e9ca1d045ef084b7dd3cfb5c7d866d22f72f3449 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 06:25:55 +0500 Subject: [PATCH 09/11] Task 13.4: find nested hermesc and strip a disabled dSYM action. Expo resolves hermes-compiler from the react-native package, which a sibling node_modules walk misses. uploadSymbols false also has to remove an Archive post-action left by an earlier prebuild. Co-authored-by: Cursor --- packages/react-native/plugin/build/index.d.ts | 5 +- packages/react-native/plugin/build/index.js | 27 ++-- .../react-native/plugin/build/index.js.map | 2 +- .../react-native/plugin/build/scheme.d.ts | 8 ++ packages/react-native/plugin/build/scheme.js | 29 +++++ .../react-native/plugin/build/scheme.js.map | 2 +- .../plugin/src/__tests__/plugin.test.ts | 115 +++++++++++++++++- packages/react-native/plugin/src/index.ts | 34 +++--- packages/react-native/plugin/src/scheme.ts | 30 +++++ .../scripts/hermesc-preserve-js.sh | 15 +++ 10 files changed, 232 insertions(+), 35 deletions(-) diff --git a/packages/react-native/plugin/build/index.d.ts b/packages/react-native/plugin/build/index.d.ts index e47e377..413c0bc 100644 --- a/packages/react-native/plugin/build/index.d.ts +++ b/packages/react-native/plugin/build/index.d.ts @@ -7,7 +7,10 @@ export interface BugseePluginProps { * debug ids on the composed map and does not execute the upload. */ uploadSourcemaps?: boolean; - /** Defaults on. `false` skips the Archive dSYM post-action. */ + /** + * Defaults on. `false` removes the Archive dSYM post-action, including + * one left by an earlier prebuild without `--clean`. + */ uploadSymbols?: boolean; /** * Defaults on. Writes `plugin.ndk.enabled=true` for a real token, adds diff --git a/packages/react-native/plugin/build/index.js b/packages/react-native/plugin/build/index.js index 82da00e..4181803 100644 --- a/packages/react-native/plugin/build/index.js +++ b/packages/react-native/plugin/build/index.js @@ -47,21 +47,20 @@ const withBugsee = (config, props) => { (0, bundle_phase_1.rewriteProjectBundlePhase)(cfg.modResults); return cfg; }); - if (options.uploadSymbols !== false) { - config = (0, config_plugins_1.withDangerousMod)(config, [ - 'ios', - async (cfg) => { - for (const schemePath of listSchemes(cfg.modRequest.platformProjectRoot)) { - const xml = await (0, promises_1.readFile)(schemePath, 'utf8'); - const next = (0, scheme_1.insertDsymPostAction)(xml); - if (next !== xml) { - await (0, promises_1.writeFile)(schemePath, next); - } + config = (0, config_plugins_1.withDangerousMod)(config, [ + 'ios', + async (cfg) => { + const edit = options.uploadSymbols === false ? scheme_1.removeDsymPostAction : scheme_1.insertDsymPostAction; + for (const schemePath of listSchemes(cfg.modRequest.platformProjectRoot)) { + const xml = await (0, promises_1.readFile)(schemePath, 'utf8'); + const next = edit(xml); + if (next !== xml) { + await (0, promises_1.writeFile)(schemePath, next); } - return cfg; - }, - ]); - } + } + return cfg; + }, + ]); return config; }; function listSchemes(iosRoot) { diff --git a/packages/react-native/plugin/build/index.js.map b/packages/react-native/plugin/build/index.js.map index 58cf7b6..1a84df3 100644 --- a/packages/react-native/plugin/build/index.js.map +++ b/packages/react-native/plugin/build/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-native/plugin/build/scheme.d.ts b/packages/react-native/plugin/build/scheme.d.ts index 299307c..e457ba4 100644 --- a/packages/react-native/plugin/build/scheme.d.ts +++ b/packages/react-native/plugin/build/scheme.d.ts @@ -8,3 +8,11 @@ export declare function encodeXmlAttr(value: string): string; * it. A wrapping PostActions is emitted only when ArchiveAction has none. */ export declare function insertDsymPostAction(scheme: string, script?: string): string; +/** + * Removes the Archive post-action this plugin inserted. A later prebuild + * with `uploadSymbols: false` has to undo an earlier default-on edit, + * because insert is otherwise one-way. A sibling ExecutionAction stays. + * When the Bugsee action was the only child, the wrapping PostActions + * element goes too, so the scheme stays valid. + */ +export declare function removeDsymPostAction(scheme: string): string; diff --git a/packages/react-native/plugin/build/scheme.js b/packages/react-native/plugin/build/scheme.js index 76f4fed..f92e2f0 100644 --- a/packages/react-native/plugin/build/scheme.js +++ b/packages/react-native/plugin/build/scheme.js @@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.DSYM_POST_ACTION_SCRIPT = void 0; exports.encodeXmlAttr = encodeXmlAttr; exports.insertDsymPostAction = insertDsymPostAction; +exports.removeDsymPostAction = removeDsymPostAction; const dsym_script_1 = require("./dsym-script"); Object.defineProperty(exports, "DSYM_POST_ACTION_SCRIPT", { enumerable: true, get: function () { return dsym_script_1.DSYM_POST_ACTION_SCRIPT; } }); function encodeXmlAttr(value) { @@ -64,4 +65,32 @@ function insertArchiveExecution(archive, execution) { const block = [' ', execution, ' '].join('\n'); return archive.replace('', `${block}\n `); } +const EXECUTION_ACTION = /[ \t]*\n?/g; +const EMPTY_POST_ACTIONS = /\n[ \t]*]*>\s*<\/PostActions>/g; +/** + * Removes the Archive post-action this plugin inserted. A later prebuild + * with `uploadSymbols: false` has to undo an earlier default-on edit, + * because insert is otherwise one-way. A sibling ExecutionAction stays. + * When the Bugsee action was the only child, the wrapping PostActions + * element goes too, so the scheme stays valid. + */ +function removeDsymPostAction(scheme) { + const archive = scheme.match(//); + if (!archive?.[0] || archive.index === undefined) { + return scheme; + } + let removed = false; + let archiveXml = archive[0].replace(EXECUTION_ACTION, (block) => { + if (!block.includes('xcode post-action')) { + return block; + } + removed = true; + return ''; + }); + if (!removed) { + return scheme; + } + archiveXml = archiveXml.replace(EMPTY_POST_ACTIONS, ''); + return scheme.slice(0, archive.index) + archiveXml + scheme.slice(archive.index + archive[0].length); +} //# sourceMappingURL=scheme.js.map \ No newline at end of file diff --git a/packages/react-native/plugin/build/scheme.js.map b/packages/react-native/plugin/build/scheme.js.map index 520989f..7b9d753 100644 --- a/packages/react-native/plugin/build/scheme.js.map +++ b/packages/react-native/plugin/build/scheme.js.map @@ -1 +1 @@ -{"version":3,"file":"scheme.js","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"scheme.js","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":";;;AAIA,sCAQC;AAgCD,oDAWC;AAuBD,oDAkBC;AAhGD,+CAAwD;AAE/C,wGAFA,qCAAuB,OAEA;AAEhC,SAAgB,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,IAAI,EAAE,CAAC;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kCAAkC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,kBAAkB,CAAC,SAAiB,EAAE,MAAc;IAC3D,OAAO;QACL,2BAA2B;QAC3B,yGAAyG;QACzG,4BAA4B;QAC5B,uCAAuC;QACvC,gCAAgC,aAAa,CAAC,MAAM,CAAC,IAAI;QACzD,uCAAuC;QACvC,SAAS,CAAC,OAAO,EAAE;QACnB,wCAAwC;QACxC,8BAA8B;QAC9B,6BAA6B;KAC9B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,MAAc,EAAE,SAAiB,qCAAuB;IAC3F,IAAI,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,SAAS,GAAG,kBAAkB,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACpG,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe,EAAE,SAAiB;IAChE,MAAM,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAClD,IAAI,IAAI,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,qBAAqB,EAAE,SAAS,EAAE,sBAAsB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpF,OAAO,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,KAAK,uBAAuB,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,gBAAgB,GAAG,yDAAyD,CAAC;AACnF,MAAM,kBAAkB,GAAG,iDAAiD,CAAC;AAE7E;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAAC,MAAc;IACjD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;QAC9D,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACvG,CAAC"} \ No newline at end of file diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index a7752e1..3de4eb8 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -1,5 +1,5 @@ import { spawnSync } from 'node:child_process'; -import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs'; +import { chmodSync, cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs'; import { createRequire } from 'node:module'; import { tmpdir } from 'node:os'; import { dirname, join } from 'node:path'; @@ -9,7 +9,7 @@ import { rewriteBundlePhase, BARE_BUNDLE_SCRIPT } from '../bundle-phase'; import { decodePbxString, encodePbxString } from '../pbx-string'; import { bugseePropertiesText, isPlaceholderToken } from '../properties'; import { ensureAppAppliesPlugin, ensureGradlePluginDeclared, ensureMavenCentral } from '../gradle'; -import { insertDsymPostAction } from '../scheme'; +import { insertDsymPostAction, removeDsymPostAction } from '../scheme'; import { DSYM_POST_ACTION_SCRIPT, RESOLVE_BUGSEE_CLI_PACKAGE, @@ -570,6 +570,48 @@ describe('Android Gradle edits', () => { expect(ensureAppAppliesPlugin(off, null)).toBe(off); }); + it('finds hermesc nested under react-native when the app sibling package is missing', () => { + const app = mkdtempSync(join(tmpdir(), 'bugsee-hermesc-')); + try { + const osbin = + process.platform === 'linux' ? 'linux64-bin' : process.platform === 'win32' ? 'win64-bin' : 'osx-bin'; + const bin = process.platform === 'win32' ? 'hermesc.exe' : 'hermesc'; + const nested = join(app, 'node_modules/react-native/node_modules/hermes-compiler'); + mkdirSync(join(nested, 'hermesc', osbin), { recursive: true }); + writeFileSync(join(app, 'node_modules/react-native/package.json'), '{"name":"react-native"}\n'); + writeFileSync(join(nested, 'package.json'), '{"name":"hermes-compiler"}\n'); + const hermesc = join(nested, 'hermesc', osbin, bin); + writeFileSync(hermesc, '#!/bin/sh\nexit 0\n'); + chmodSync(hermesc, 0o755); + + const sibling = join(app, 'node_modules/hermes-compiler/hermesc', osbin, bin); + expect(existsSync(sibling)).toBe(false); + expect(existsSync(join(app, 'node_modules/hermes-compiler'))).toBe(false); + + const jsDir = join(app, 'android/app/build/generated/assets/createBundleReleaseJsAndAssets'); + mkdirSync(jsDir, { recursive: true }); + const js = join(jsDir, 'index.android.bundle'); + writeFileSync(js, 'console.log("app");\n'); + + const script = join(repoRoot, 'packages/react-native/scripts/hermesc-preserve-js.sh'); + const result = spawnSync('bash', [script, '-out', join(app, 'out.hbc'), js], { + cwd: app, + encoding: 'utf8', + }); + expect(result.status).toBe(0); + expect(result.stderr ?? '').not.toContain('hermesc binary not found'); + + const note = join( + app, + 'android/app/build/intermediates/bugsee-sourcemaps/createBundleReleaseJsAndAssets/index.android.bundle.bugsee-hermesc', + ); + const found = readFileSync(note, 'utf8').trim(); + expect(realpathSync(found)).toBe(realpathSync(hermesc)); + } finally { + rmSync(app, { recursive: true, force: true }); + } + }); + it('leaves a hand-written ndk block when native crash reporting is off', () => { const template = expoSdk57AppBuildGradle().replace( ' debug {\n signingConfig signingConfigs.debug\n }', @@ -713,6 +755,75 @@ describe('scheme post-action', () => { expect(next).not.toContain('\n '); expect(insertDsymPostAction(next, DSYM_POST_ACTION_SCRIPT)).toBe(next); }); + + it('removes the Bugsee action from an existing Archive PostActions element and keeps the sibling', () => { + const scheme = ` + + + + + + + + + + + + + + + + + + + + + + +`; + const inserted = insertDsymPostAction(scheme, DSYM_POST_ACTION_SCRIPT); + expect(inserted).toContain('title = "Upload dSYMs"'); + expect(inserted).toContain('xcode post-action'); + const next = removeDsymPostAction(inserted); + expect(next).not.toContain('xcode post-action'); + expect(next).not.toContain('title = "Upload dSYMs"'); + expect(next).toContain('title = "Notify"'); + expect(next).toContain('echo archive-finished'); + const archive = next.match(//)?.[0] ?? ''; + expect(archive.match(//g)).toHaveLength(1); + expect(archive.match(/<\/PostActions>/g)).toHaveLength(1); + expect(archive.match(/ { + const inserted = insertDsymPostAction(scheme, DSYM_POST_ACTION_SCRIPT); + expect(inserted).toContain(''); + expect(inserted).toContain('xcode post-action'); + const next = removeDsymPostAction(inserted); + expect(next).not.toContain('xcode post-action'); + expect(next).not.toContain('Upload dSYMs'); + expect(next).not.toContain(''); + expect(next).toContain('BuildableName = "BugseeExpo.app"'); + expect(removeDsymPostAction(next)).toBe(next); + }); }); describe('manifest auto-launch', () => { diff --git a/packages/react-native/plugin/src/index.ts b/packages/react-native/plugin/src/index.ts index 8195dfd..4deef74 100644 --- a/packages/react-native/plugin/src/index.ts +++ b/packages/react-native/plugin/src/index.ts @@ -20,7 +20,7 @@ import { ensureAppAppliesPlugin, ensureGradlePluginDeclared, ensureMavenCentral import { manifestAutoLaunchToken } from './manifest'; import { loadNativeVersions } from './native-versions'; import { bugseePropertiesText } from './properties'; -import { insertDsymPostAction } from './scheme'; +import { insertDsymPostAction, removeDsymPostAction } from './scheme'; export interface BugseePluginProps { /** Unprefixed `app_token` in android/bugsee.properties. */ @@ -30,7 +30,10 @@ export interface BugseePluginProps { * debug ids on the composed map and does not execute the upload. */ uploadSourcemaps?: boolean; - /** Defaults on. `false` skips the Archive dSYM post-action. */ + /** + * Defaults on. `false` removes the Archive dSYM post-action, including + * one left by an earlier prebuild without `--clean`. + */ uploadSymbols?: boolean; /** * Defaults on. Writes `plugin.ndk.enabled=true` for a real token, adds @@ -100,21 +103,20 @@ const withBugsee: ConfigPlugin = (config, props) => { return cfg; }); - if (options.uploadSymbols !== false) { - config = withDangerousMod(config, [ - 'ios', - async (cfg) => { - for (const schemePath of listSchemes(cfg.modRequest.platformProjectRoot)) { - const xml = await readFile(schemePath, 'utf8'); - const next = insertDsymPostAction(xml); - if (next !== xml) { - await writeFile(schemePath, next); - } + config = withDangerousMod(config, [ + 'ios', + async (cfg) => { + const edit = options.uploadSymbols === false ? removeDsymPostAction : insertDsymPostAction; + for (const schemePath of listSchemes(cfg.modRequest.platformProjectRoot)) { + const xml = await readFile(schemePath, 'utf8'); + const next = edit(xml); + if (next !== xml) { + await writeFile(schemePath, next); } - return cfg; - }, - ]); - } + } + return cfg; + }, + ]); return config; }; diff --git a/packages/react-native/plugin/src/scheme.ts b/packages/react-native/plugin/src/scheme.ts index f1278d6..15c9f0a 100644 --- a/packages/react-native/plugin/src/scheme.ts +++ b/packages/react-native/plugin/src/scheme.ts @@ -65,3 +65,33 @@ function insertArchiveExecution(archive: string, execution: string): string { const block = [' ', execution, ' '].join('\n'); return archive.replace('', `${block}\n `); } + +const EXECUTION_ACTION = /[ \t]*\n?/g; +const EMPTY_POST_ACTIONS = /\n[ \t]*]*>\s*<\/PostActions>/g; + +/** + * Removes the Archive post-action this plugin inserted. A later prebuild + * with `uploadSymbols: false` has to undo an earlier default-on edit, + * because insert is otherwise one-way. A sibling ExecutionAction stays. + * When the Bugsee action was the only child, the wrapping PostActions + * element goes too, so the scheme stays valid. + */ +export function removeDsymPostAction(scheme: string): string { + const archive = scheme.match(//); + if (!archive?.[0] || archive.index === undefined) { + return scheme; + } + let removed = false; + let archiveXml = archive[0].replace(EXECUTION_ACTION, (block) => { + if (!block.includes('xcode post-action')) { + return block; + } + removed = true; + return ''; + }); + if (!removed) { + return scheme; + } + archiveXml = archiveXml.replace(EMPTY_POST_ACTIONS, ''); + return scheme.slice(0, archive.index) + archiveXml + scheme.slice(archive.index + archive[0].length); +} diff --git a/packages/react-native/scripts/hermesc-preserve-js.sh b/packages/react-native/scripts/hermesc-preserve-js.sh index 5f6c764..5b8e3c2 100755 --- a/packages/react-native/scripts/hermesc-preserve-js.sh +++ b/packages/react-native/scripts/hermesc-preserve-js.sh @@ -67,6 +67,21 @@ find_hermesc() { Darwin) osbin="osx-bin" ;; MINGW*|MSYS*|CYGWIN*) osbin="win64-bin"; bin="hermesc.exe" ;; esac + # Expo SDK 57 resolves hermes-compiler from the react-native package, so a + # pnpm or Yarn workspace install under node_modules/react-native/node_modules + # is found. A $PWD/node_modules sibling walk misses that layout. + local pkg="" + if command -v node >/dev/null 2>&1; then + pkg="$(node --print "require.resolve('hermes-compiler/package.json', { paths: [require.resolve('react-native/package.json')] })" 2>/dev/null)" || pkg="" + fi + if [[ -n "$pkg" ]]; then + local resolved + resolved="$(dirname "$pkg")/hermesc/${osbin}/${bin}" + if [[ -x "$resolved" ]]; then + echo "$resolved" + return + fi + fi local candidate for candidate in \ "$PWD/node_modules/hermes-compiler/hermesc/${osbin}/${bin}" \ From ec79c1f522dbfa76fd8aea4f865a65a2ec89b837 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 06:43:09 +0500 Subject: [PATCH 10/11] Task 13.4: find the shipped hermesc on React Native 0.81. Expo SDK 54 has no hermes-compiler package. After that resolve misses, the wrapper uses sdks/hermesc beside react-native, while newer SDKs still prefer hermes-compiler. Co-authored-by: Cursor --- .../plugin/src/__tests__/plugin.test.ts | 44 +++++++++++++++++++ .../scripts/hermesc-preserve-js.sh | 15 ++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/packages/react-native/plugin/src/__tests__/plugin.test.ts b/packages/react-native/plugin/src/__tests__/plugin.test.ts index 3de4eb8..2bd0dda 100644 --- a/packages/react-native/plugin/src/__tests__/plugin.test.ts +++ b/packages/react-native/plugin/src/__tests__/plugin.test.ts @@ -583,6 +583,10 @@ describe('Android Gradle edits', () => { const hermesc = join(nested, 'hermesc', osbin, bin); writeFileSync(hermesc, '#!/bin/sh\nexit 0\n'); chmodSync(hermesc, 0o755); + const shipped = join(app, 'node_modules/react-native/sdks/hermesc', osbin, bin); + mkdirSync(join(app, 'node_modules/react-native/sdks/hermesc', osbin), { recursive: true }); + writeFileSync(shipped, '#!/bin/sh\nexit 0\n'); + chmodSync(shipped, 0o755); const sibling = join(app, 'node_modules/hermes-compiler/hermesc', osbin, bin); expect(existsSync(sibling)).toBe(false); @@ -606,12 +610,52 @@ describe('Android Gradle edits', () => { 'android/app/build/intermediates/bugsee-sourcemaps/createBundleReleaseJsAndAssets/index.android.bundle.bugsee-hermesc', ); const found = readFileSync(note, 'utf8').trim(); + expect(existsSync(shipped)).toBe(true); expect(realpathSync(found)).toBe(realpathSync(hermesc)); } finally { rmSync(app, { recursive: true, force: true }); } }); + it('finds the shipped sdks/hermesc binary when hermes-compiler is absent', () => { + const app = mkdtempSync(join(tmpdir(), 'bugsee-hermesc-081-')); + try { + const osbin = + process.platform === 'linux' ? 'linux64-bin' : process.platform === 'win32' ? 'win64-bin' : 'osx-bin'; + const bin = process.platform === 'win32' ? 'hermesc.exe' : 'hermesc'; + const rn = join(app, 'node_modules/react-native'); + mkdirSync(join(rn, 'sdks/hermesc', osbin), { recursive: true }); + writeFileSync(join(rn, 'package.json'), '{"name":"react-native"}\n'); + const hermesc = join(rn, 'sdks/hermesc', osbin, bin); + writeFileSync(hermesc, '#!/bin/sh\nexit 0\n'); + chmodSync(hermesc, 0o755); + + expect(existsSync(join(app, 'node_modules/hermes-compiler'))).toBe(false); + expect(existsSync(join(rn, 'node_modules/hermes-compiler'))).toBe(false); + + const jsDir = join(app, 'android/app/build/generated/assets/createBundleReleaseJsAndAssets'); + mkdirSync(jsDir, { recursive: true }); + const js = join(jsDir, 'index.android.bundle'); + writeFileSync(js, 'console.log("app");\n'); + + const script = join(repoRoot, 'packages/react-native/scripts/hermesc-preserve-js.sh'); + const result = spawnSync('bash', [script, '-out', join(app, 'out.hbc'), js], { + cwd: app, + encoding: 'utf8', + }); + expect(result.status).toBe(0); + expect(result.stderr ?? '').not.toContain('hermesc binary not found'); + + const note = join( + app, + 'android/app/build/intermediates/bugsee-sourcemaps/createBundleReleaseJsAndAssets/index.android.bundle.bugsee-hermesc', + ); + expect(realpathSync(readFileSync(note, 'utf8').trim())).toBe(realpathSync(hermesc)); + } finally { + rmSync(app, { recursive: true, force: true }); + } + }); + it('leaves a hand-written ndk block when native crash reporting is off', () => { const template = expoSdk57AppBuildGradle().replace( ' debug {\n signingConfig signingConfigs.debug\n }', diff --git a/packages/react-native/scripts/hermesc-preserve-js.sh b/packages/react-native/scripts/hermesc-preserve-js.sh index 5b8e3c2..41ad069 100755 --- a/packages/react-native/scripts/hermesc-preserve-js.sh +++ b/packages/react-native/scripts/hermesc-preserve-js.sh @@ -69,7 +69,8 @@ find_hermesc() { esac # Expo SDK 57 resolves hermes-compiler from the react-native package, so a # pnpm or Yarn workspace install under node_modules/react-native/node_modules - # is found. A $PWD/node_modules sibling walk misses that layout. + # is found. React Native 0.81 (Expo SDK 54) has no hermes-compiler package + # and ships sdks/hermesc beside react-native/package.json. That path is next. local pkg="" if command -v node >/dev/null 2>&1; then pkg="$(node --print "require.resolve('hermes-compiler/package.json', { paths: [require.resolve('react-native/package.json')] })" 2>/dev/null)" || pkg="" @@ -82,6 +83,18 @@ find_hermesc() { return fi fi + local rn_pkg="" + if command -v node >/dev/null 2>&1; then + rn_pkg="$(node --print "require.resolve('react-native/package.json')" 2>/dev/null)" || rn_pkg="" + fi + if [[ -n "$rn_pkg" ]]; then + local shipped + shipped="$(dirname "$rn_pkg")/sdks/hermesc/${osbin}/${bin}" + if [[ -x "$shipped" ]]; then + echo "$shipped" + return + fi + fi local candidate for candidate in \ "$PWD/node_modules/hermes-compiler/hermesc/${osbin}/${bin}" \ From 11e090b20676fc30c1ce5792ce5f721168fbcbf9 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Sat, 3 Oct 2026 07:08:40 +0500 Subject: [PATCH 11/11] Task 13.4: stop pipefail from hiding an instance-handle assignment. grep -q closes the pipe at the first match, so grep -v dies with SIGPIPE and a real assignment is reported as a miss. Read the filtered file to completion instead. Co-authored-by: Cursor --- .../rn-compat-assigns-handle.test.ts | 87 +++++++++++++++++++ scripts/check-rn-compat.sh | 8 +- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 scripts/__tests__/rn-compat-assigns-handle.test.ts diff --git a/scripts/__tests__/rn-compat-assigns-handle.test.ts b/scripts/__tests__/rn-compat-assigns-handle.test.ts new file mode 100644 index 0000000..889c0a6 --- /dev/null +++ b/scripts/__tests__/rn-compat-assigns-handle.test.ts @@ -0,0 +1,87 @@ +import { spawnSync } from 'node:child_process'; +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; + +const scriptPath = join(__dirname, '..', 'check-rn-compat.sh'); + +function assignsHandleSource(): string { + const src = readFileSync(scriptPath, 'utf8'); + const start = src.indexOf('assigns_handle() {'); + if (start < 0) { + throw new Error('assigns_handle missing'); + } + let depth = 0; + const open = src.indexOf('{', start); + for (let i = open; i < src.length; i += 1) { + if (src[i] === '{') { + depth += 1; + } else if (src[i] === '}') { + depth -= 1; + if (depth === 0) { + return src.slice(start, i + 1); + } + } + } + throw new Error('assigns_handle unclosed'); +} + +function runBash(script: string, file: string): number { + const result = spawnSync('bash', ['-c', script, 'bash', file], { encoding: 'utf8' }); + return result.status ?? 1; +} + +describe('assigns_handle under pipefail', () => { + const dir = mkdtempSync(join(tmpdir(), 'assigns-handle-')); + const fn = assignsHandleSource(); + + afterAll(() => { + rmSync(dir, { recursive: true, force: true }); + }); + + function write(name: string, body: string): string { + const file = join(dir, name); + writeFileSync(file, body); + return file; + } + + it('accepts an assignment at the start of a file large enough to SIGPIPE grep -q', () => { + const file = write( + 'early-assignment.js', + `this.__internalInstanceHandle = host;\n${'const unused = 1;\n'.repeat(80_000)}`, + ); + const broken = ` +set -euo pipefail +grep -v -E '^[[:space:]]*(//|\\*)' "$1" | grep -qE '\\.__internalInstanceHandle[[:space:]]*=([^=]|$)' +`; + const brokenStatus = runBash(broken, file); + expect(brokenStatus).toBeGreaterThan(0); + + const fixed = ` +set -euo pipefail +${fn} +assigns_handle "$1" +`; + expect(runBash(fixed, file)).toBe(0); + }); + + it('rejects a comparison', () => { + const file = write('comparison.js', 'if (this.__internalInstanceHandle === null) return;\n'); + const fixed = ` +set -euo pipefail +${fn} +assigns_handle "$1" +`; + expect(runBash(fixed, file)).toBeGreaterThan(0); + }); + + it('rejects a comment that mentions the assignment', () => { + const file = write('comment.js', '// this.__internalInstanceHandle = host;\n'); + const fixed = ` +set -euo pipefail +${fn} +assigns_handle "$1" +`; + expect(runBash(fixed, file)).toBeGreaterThan(0); + }); +}); diff --git a/scripts/check-rn-compat.sh b/scripts/check-rn-compat.sh index aec423f..56adc3f 100755 --- a/scripts/check-rn-compat.sh +++ b/scripts/check-rn-compat.sh @@ -76,7 +76,13 @@ echo " getPublicInstanceFromInternalInstanceHandle is defined and reachable t # non-space characters `//` or `*`, covering both `//` line comments and a # `/** … */`/JSDoc block's continuation lines) are filtered out first. assigns_handle() { - grep -v -E '^[[:space:]]*(//|\*)' "$1" | grep -qE '\.__internalInstanceHandle[[:space:]]*=([^=]|$)' + # Do not use grep -q on this pipe. It exits at the first match and closes + # the read end; under pipefail, grep -v then dies with SIGPIPE and a real + # assignment near the start of a large file is reported as a miss. Reading + # the filtered text to completion keeps the same pattern and the same + # comment-line filter. + grep -v -E '^[[:space:]]*(//|\*)' "$1" \ + | grep -E '\.__internalInstanceHandle[[:space:]]*=([^=]|$)' >/dev/null } ELEMENT_FILE="$RN_SRC/src/private/webapis/dom/nodes/ReactNativeElement.js"