Skip to content

Commit 5fc84a1

Browse files
feat: expo-sourcemap-support (#1392)
* feat: add expo sourcemap support * feat: add expo sourcemap support * feat: add expo sourcemap support * feat: add expo sourcemap support * feat: add expo sourcemap support * feat: add expo sourcemap support * feat: add expo sourcemap support * feat: add expo sourcemap support * feat: add expo sourcemap support * feat: update sourcemaps.gradle * feat: update sourcemaps.gradle * feat: update sourcemaps.gradle * feat: update sourcemaps.gradle * feat: update sourcemaps.gradle * feat: update sourcemaps.gradle * feat: add permissions * feat support sourcemap expo * feat support sourcemap expo * feat: add manifest permissions * feat: add manifest permissions * feat: add manifest permissions * fix: upload command * fix: upload command * fix: upload command * fix: upload command * fix: upload command * fix: upload command * fix: upload command * fix: upload command * fix: upload command * fix: upload command * feat: expo sourcemap support * fix: CHANGELOG.md * fix: CHANGELOG.md
1 parent 775f1d2 commit 5fc84a1

21 files changed

+570
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
- Add Support Eas updates. ([#1391](https://github.com/Instabug/Instabug-React-Native/pull/1391))
1212

13+
- Add support for uploading sourcemap files in expo apps. ([#1392](https://github.com/Instabug/Instabug-React-Native/pull/1392))
14+
1315
### Changed
1416

1517
- **BREAKING** Remove deprecated APIs ([#1424](https://github.com/Instabug/Instabug-React-Native/pull/1424)). See migration guide for more details.
@@ -36,8 +38,6 @@
3638

3739
### Added
3840

39-
- Add support for expo updates versioning ([#1391](https://github.com/Instabug/Instabug-React-Native/pull/1391))
40-
4141
- Add support enable/disable screenshot auto masking. ([#1389](https://github.com/Instabug/Instabug-React-Native/pull/1389))
4242

4343
- Add support for BugReporting user consents. ([#1383](https://github.com/Instabug/Instabug-React-Native/pull/1383))

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,21 @@ For more info, visit [Instabug.com](https://www.instabug.com).
2626
yarn add instabug-reactnative
2727
```
2828

29-
2. CocoaPods on iOS needs this extra step:
29+
2. if you are using expo you need to add `instabug-reactnative` plugin to `app.json`:
30+
31+
```json
32+
"plugins" : [
33+
[
34+
"instabug-reactnative",
35+
{
36+
// optional that add Mic,Photo permission on iOS and FOREGROUND_SERVICE_MEDIA_PROJECTION on android
37+
"addScreenRecordingBugReportingPermission": true
38+
}
39+
]
40+
]
41+
```
42+
43+
3. CocoaPods on iOS needs this extra step:
3044

3145
```bash
3246
cd ios && pod install && cd ..

android/sourcemaps.gradle

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ project.afterEvaluate {
1515
def flavor = name.substring(start, end).uncapitalize()
1616
def defaultVersion = getDefaultVersion(flavor)
1717

18-
task.finalizedBy createUploadSourcemapsTask(flavor, defaultVersion.name, defaultVersion.code)
18+
19+
20+
task.finalizedBy createUploadSourcemapsTask(flavor, defaultVersion.name, defaultVersion.code,task)
1921
}
2022
}
2123

22-
Task createUploadSourcemapsTask(String flavor, String defaultVersionName, String defaultVersionCode) {
24+
Task createUploadSourcemapsTask(String flavor, String defaultVersionName, String defaultVersionCode, Task task) {
2325
def name = 'uploadSourcemaps' + flavor.capitalize()
2426

2527
// Don't recreate the task if it already exists.
@@ -39,18 +41,26 @@ Task createUploadSourcemapsTask(String flavor, String defaultVersionName, String
3941
try {
4042
def appProject = project(':app')
4143
def appDir = appProject.projectDir
42-
def sourceMapFile = getSourceMapFile(appDir, flavor)
44+
def sourceMapFile = getSourceMapFile(appDir, flavor,task)
45+
println "✅ Resolved sourcemap file path: ${sourceMapFile.absolutePath}"
4346

4447
def jsProjectDir = rootDir.parentFile
4548
def instabugDir = new File(['node', '-p', 'require.resolve("instabug-reactnative/package.json")'].execute(null, rootDir).text.trim()).getParentFile()
4649

47-
def tokenShellFile = new File(instabugDir, 'scripts/find-token.sh')
48-
def inferredToken = executeShellScript(tokenShellFile, jsProjectDir)
50+
def tokenJsFile = new File(instabugDir, 'scripts/find-token.js')
51+
def inferredToken = executeNodeScript(tokenJsFile, jsProjectDir)
52+
53+
if (!inferredToken) {
54+
throw new GradleException("❌ Unable to infer Instabug token from script: ${tokenShellFile.absolutePath}")
55+
}
56+
4957
def appToken = resolveVar('App Token', 'INSTABUG_APP_TOKEN', inferredToken)
5058

5159
def versionName = resolveVar('Version Name', 'INSTABUG_VERSION_NAME', defaultVersionName)
5260
def versionCode = resolveVar('Version Code', 'INSTABUG_VERSION_CODE', defaultVersionCode)
5361

62+
println "📦 Uploading with versionName=${versionName}, versionCode=${versionCode}, appToken=${appToken.take(5)}..."
63+
5464
exec {
5565
def osCompatibility = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c'] : []
5666
def args = [
@@ -67,34 +77,57 @@ Task createUploadSourcemapsTask(String flavor, String defaultVersionName, String
6777
} catch (exception) {
6878
project.logger.error "Failed to upload source map file.\n" +
6979
"Reason: ${exception.message}"
80+
throw exception
81+
7082
}
7183
}
7284
}
7385

7486
return provider.get()
7587
}
7688

77-
File getSourceMapFile(File appDir, String flavor) {
89+
File getSourceMapFile(File appDir, String flavor, Task task) {
7890
def defaultFlavorPath = flavor.empty ? 'release' : "${flavor}Release"
7991
def defaultSourceMapDest = "build/generated/sourcemaps/react/${defaultFlavorPath}/index.android.bundle.map"
8092
def defaultSourceMapFile = new File(appDir, defaultSourceMapDest)
93+
def props = task.getProperties()
94+
95+
def bundleAssetName = props.containsKey("bundleAssetName") ? props.bundleAssetName?.getOrNull() : null
96+
def jsSourceMapsDir = props.containsKey("jsSourceMapsDir") ? props.jsSourceMapsDir?.getOrNull() : null
97+
def jsIntermediateSourceMapsDir = props.containsKey("jsIntermediateSourceMapsDir") ? props.jsIntermediateSourceMapsDir?.getOrNull() : null
98+
99+
if (bundleAssetName && jsSourceMapsDir) {
100+
def outputSourceMap = new File(jsSourceMapsDir.asFile.absolutePath, "${bundleAssetName}.map")
101+
if (outputSourceMap.exists()) {
102+
return outputSourceMap
103+
}
104+
}
105+
106+
if (bundleAssetName && jsIntermediateSourceMapsDir) {
107+
def packagerOutputSourceMap = new File(jsIntermediateSourceMapsDir.asFile.absolutePath, "${bundleAssetName}.packager.map")
108+
if (packagerOutputSourceMap.exists()) {
109+
return packagerOutputSourceMap
110+
}
111+
}
81112

82113
if (defaultSourceMapFile.exists()) {
83114
return defaultSourceMapFile
84115
}
85116

86117
if (flavor.empty) {
87-
throw new InvalidUserDataException("Unable to find source map file at: ${defaultSourceMapFile.absolutePath}.")
118+
println"Source map file not found at: ${defaultSourceMapFile.absolutePath}. Skipping."
119+
return null
88120
}
89121

90122
def fallbackSourceMapDest = "build/generated/sourcemaps/react/${flavor}/release/index.android.bundle.map"
91123
def fallbackSourceMapFile = new File(appDir, fallbackSourceMapDest)
92124

93-
project.logger.info "Unable to find source map file at: ${defaultSourceMapFile.absolutePath}.\n" +
125+
println "Unable to find source map file at: ${defaultSourceMapFile.absolutePath}.\n" +
94126
"Falling back to ${fallbackSourceMapFile.absolutePath}."
95127

96128
if (!fallbackSourceMapFile.exists()) {
97-
throw new InvalidUserDataException("Unable to find source map file at: ${fallbackSourceMapFile.absolutePath} either.")
129+
println "Fallback source map file not found at: ${fallbackSourceMapFile.absolutePath}. Skipping."
130+
return null
98131
}
99132

100133
return fallbackSourceMapFile
@@ -155,14 +188,56 @@ String resolveVar(String name, String envKey, String defaultValue) {
155188
return value
156189
}
157190

191+
static String executeNodeScript(File script, File workingDir) {
192+
if (!script.exists()) {
193+
println "Script not found: ${script.absolutePath}"
194+
return null
195+
}
196+
197+
def output = new StringBuffer()
198+
def error = new StringBuffer()
199+
200+
try {
201+
def process = ['node', script.getAbsolutePath()].execute(null, workingDir)
202+
process.waitForProcessOutput(output, error)
203+
204+
if (process.exitValue() != 0) {
205+
println "Script failed with exit code ${process.exitValue()}"
206+
println "Standard Error:\n${error.toString().trim()}"
207+
println "Standard Output:\n${output.toString().trim()}"
208+
return null
209+
}
210+
211+
return output.toString().trim()
212+
213+
} catch (Exception e) {
214+
println "Exception while executing Node.js script: ${e.message}"
215+
e.printStackTrace()
216+
return null
217+
}
218+
}
219+
158220
static String executeShellScript(File script, File workingDir) {
159221
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
160222
return null
161223
}
162224

225+
if (!script.canExecute()) {
226+
// Try to set executable permission
227+
script.setExecutable(true)
228+
}
229+
163230
def output = new StringBuffer()
231+
def error = new StringBuffer()
232+
233+
// Using 'sh' instead of './' to avoid needing exec permission, but keeping chmod above just in case
164234
def process = ['sh', script.getAbsolutePath()].execute(null, workingDir)
165-
process?.waitForProcessOutput(output, new StringBuffer())
235+
process?.waitForProcessOutput(output, error)
236+
237+
if (process.exitValue() != 0) {
238+
println "Error running script: ${error.toString().trim()}"
239+
return null
240+
}
166241

167-
return process?.exitValue() == 0 ? output.toString().trim() : null
242+
return output.toString().trim()
168243
}

app.plugin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./expo');
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Command, Option } from 'commander';
2+
import { UploadEasUpdatesSourcemaps, UploadEasUpdatesSourcemapsOptions } from '../upload';
3+
4+
export const uploadEasUpdatesSourcemapsCommand = new Command();
5+
6+
uploadEasUpdatesSourcemapsCommand
7+
.name('upload-eas-updates-sourcemaps')
8+
.addOption(
9+
new Option('-f, --file <path>', 'The path of eas update folder')
10+
.makeOptionMandatory()
11+
.default('dist'),
12+
)
13+
.addOption(
14+
new Option('-t, --token <value>', 'Your App Token')
15+
.env('INSTABUG_APP_TOKEN')
16+
.makeOptionMandatory(),
17+
)
18+
.addOption(
19+
new Option('-n, --name <value>', 'The app version name')
20+
.env('INSTABUG_APP_VERSION_NAME')
21+
.makeOptionMandatory(),
22+
)
23+
.addOption(
24+
new Option('-c, --code <value>', 'The app version code')
25+
.env('INSTABUG_APP_VERSION_CODE')
26+
.makeOptionMandatory(),
27+
)
28+
.addOption(
29+
new Option('--androidUpdateId <value>', "The CodePush label if it's a CodePush release"),
30+
)
31+
.addOption(new Option('--iosUpdateId <value>', "The CodePush label if it's a CodePush release"))
32+
.action(function (this: Command) {
33+
const options = this.opts<UploadEasUpdatesSourcemapsOptions>();
34+
UploadEasUpdatesSourcemaps(options);
35+
})
36+
.showHelpAfterError();

cli/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Command } from 'commander';
33

44
import { uploadSourcemapsCommand } from './commands/UploadSourcemaps';
55
import { UploadSoFilesCommand } from './commands/UploadSoFiles';
6+
import { uploadEasUpdatesSourcemapsCommand } from './commands/UploadEasUpdatesSourcemaps';
67

78
const program = new Command();
89

@@ -12,6 +13,7 @@ program
1213
.description('A CLI for uploading source maps to Instabug dashboard.')
1314
.usage('[command]')
1415
.addCommand(uploadSourcemapsCommand)
15-
.addCommand(UploadSoFilesCommand);
16+
.addCommand(UploadSoFilesCommand)
17+
.addCommand(uploadEasUpdatesSourcemapsCommand);
1618

1719
program.parse(process.argv);

cli/upload/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './uploadSourcemaps';
22
export * from './uploadSoFiles';
3+
export * from './uploadEasUpdatesSourcemaps';
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import fs from 'fs';
2+
import { uploadSourcemaps } from './uploadSourcemaps';
3+
import * as path from 'path';
4+
5+
export interface UploadEasUpdatesSourcemapsOptions {
6+
file: string;
7+
token: string;
8+
name: string;
9+
code: string;
10+
androidUpdateId?: string;
11+
iosUpdateId?: string;
12+
/**
13+
* Disables logging to the console and prevents process exit on error.
14+
*
15+
* @default false
16+
* */
17+
silent?: boolean;
18+
}
19+
20+
function getMapFile(folderPath: string): string | null {
21+
try {
22+
if (fs.existsSync(folderPath)) {
23+
const files = fs.readdirSync(folderPath);
24+
const mapFile = files.find((file) => file.endsWith('.map'));
25+
if (!mapFile) {
26+
return null;
27+
}
28+
return path.join(folderPath, mapFile);
29+
}
30+
return null;
31+
} catch (err) {
32+
console.error('Failed to read folder:', err);
33+
return null;
34+
}
35+
}
36+
37+
/**
38+
* Uploads JavaScript sourcemaps to Instabug.
39+
*
40+
* @param opts Options for the sourcemaps upload process.
41+
* @returns A promise that resolves to a boolean indicating whether the upload was successful.
42+
*/
43+
export const UploadEasUpdatesSourcemaps = async (
44+
opts: UploadEasUpdatesSourcemapsOptions,
45+
): Promise<boolean> => {
46+
const jsFolderPath = path.join(opts.file, '_expo', 'static', 'js');
47+
48+
const androidFile = getMapFile(path.join(jsFolderPath, 'android'));
49+
const iosFile = getMapFile(path.join(jsFolderPath, 'ios'));
50+
if (androidFile && fs.existsSync(androidFile)) {
51+
await uploadSourcemaps({
52+
platform: 'android',
53+
name: opts.name,
54+
code: opts.code,
55+
token: opts.token,
56+
label: opts.androidUpdateId,
57+
file: androidFile,
58+
silent: opts.silent,
59+
});
60+
}
61+
62+
if (iosFile && fs.existsSync(iosFile)) {
63+
await uploadSourcemaps({
64+
platform: 'ios',
65+
name: opts.name,
66+
code: opts.code,
67+
token: opts.token,
68+
label: opts.iosUpdateId,
69+
file: iosFile,
70+
silent: opts.silent,
71+
});
72+
}
73+
return true;
74+
};

examples/default/ios/InstabugExample.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@
430430
name = "[CP-User] [instabug-reactnative] Upload Sourcemap";
431431
runOnlyForDeploymentPostprocessing = 0;
432432
shellPath = /bin/sh;
433-
shellScript = "#!/bin/sh\n\n\nexport SOURCEMAP_FILE=\"$DERIVED_FILE_DIR/main.jsbundle.map\"\n\nmain() {\n # Read environment variables from ios/.xcode.env if it exists\n env_path=\"$PODS_ROOT/../.xcode.env\"\n if [ -f \"$env_path\" ]; then\n source \"$env_path\"\n fi\n\n # Read environment variables from ios/.xcode.env.local if it exists\n local_env_path=\"${ENV_PATH}.local\"\n if [ -f \"$local_env_path\" ]; then\n source \"$local_env_path\"\n fi\n\n if [[ \"$INSTABUG_SOURCEMAPS_UPLOAD_DISABLE\" = true ]]; then\n echo \"[Info] \\`INSTABUG_SOURCEMAPS_UPLOAD_DISABLE\\` was set to true, skipping sourcemaps upload...\"\n exit 0\n fi\n\n if [[ \"$CONFIGURATION\" = \"Debug\" ]]; then\n echo \"[Info] Building in debug mode, skipping sourcemaps upload...\"\n exit 0\n fi\n\n if [[ -z \"$INFOPLIST_FILE\" ]] || [[ -z \"$PROJECT_DIR\" ]]; then\n echo \"[Error] Instabug sourcemaps script must be invoked by Xcode\"\n exit 0\n fi\n\n\nlocal sourcemap_file=\"\"\n # Use existing sourcemap if available\n if [[ -f \"$SOURCEMAP_FILE\" ]]; then\n sourcemap_file=\"$SOURCEMAP_FILE\"\n else\n sourcemap_file=$(generate_sourcemaps | tail -n 1)\nfi\n\n local js_project_dir=\"$PROJECT_DIR/..\"\n local instabug_dir=$(dirname $(node -p \"require.resolve('instabug-reactnative/package.json')\"))\n local inferred_token=$(cd $js_project_dir && source $instabug_dir/scripts/find-token.sh)\n local app_token=$(resolve_var \"App Token\" \"INSTABUG_APP_TOKEN\" \"$inferred_token\" | tail -n 1)\n\n local inferred_name=$(/usr/libexec/PlistBuddy -c 'print CFBundleShortVersionString' \"$PROJECT_DIR/$INFOPLIST_FILE\")\n local version_name=$(resolve_var \"Version Name\" \"INSTABUG_APP_VERSION_NAME\" \"$inferred_name\" | tail -n 1)\n\n local inferred_code=$(/usr/libexec/PlistBuddy -c 'print CFBundleVersion' \"$PROJECT_DIR/$INFOPLIST_FILE\")\n local version_code=$(resolve_var \"Version Code\" \"INSTABUG_APP_VERSION_CODE\" \"$inferred_code\" | tail -n 1)\n\nif [ -n \"$sourcemap_file\" ]; then\n node $instabug_dir/bin/index.js upload-sourcemaps \\\n --platform ios \\\n --file $sourcemap_file \\\n --token $app_token \\\n --name $version_name \\\n --code $version_code\n fi\n}\n\ngenerate_sourcemaps() {\n local react_native_dir=$(dirname $(node -p \"require.resolve('react-native/package.json')\"))\n\n # Fixes an issue with react-native prior to v0.67.0\n # For more info: https://github.com/facebook/react-native/issues/32168\n export RN_DIR=$react_native_dir\n\n # Used withing `react-native-xcode.sh` to generate sourcemap file\n export SOURCEMAP_FILE=\"$(pwd)/main.jsbundle.map\";\n\n source \"$react_native_dir/scripts/react-native-xcode.sh\"\n\n if [[ ! -f \"$SOURCEMAP_FILE\" ]]; then\n echo \"[Error] Unable to find source map file at: $SOURCEMAP_FILE\"\n exit 0\n fi\n\n echo $SOURCEMAP_FILE\n}\n\nresolve_var() {\n local name=$1\n local env_key=$2\n local default_value=$3\n\n local env_value=\"${!env_key}\"\n\n if [[ -n \"$env_value\" ]] && [[ -n \"$default_value\" ]] && [[ \"$env_value\" != default_value ]]; then\n echo \"[Warning] Environment variable \\`$env_key\\` might have incorrect value, make sure this was intentional:\"\n echo \" Environment Value: $env_value\"\n echo \" Default Value: $default_value\"\n fi\n\n local value=\"${env_value:-$default_value}\"\n\n if [[ -z \"$value\" ]]; then\n echo \"[Error] Unable to find $name! Set the environment variable \\`$env_key\\` and try again.\"\n exit 0\n fi\n\n echo $value\n}\n\nmain \"$@\"; exit\n";
433+
shellScript = "#!/bin/sh\n\n\nexport SOURCEMAP_FILE=\"$DERIVED_FILE_DIR/main.jsbundle.map\"\n\nmain() {\n # Read environment variables from ios/.xcode.env if it exists\n env_path=\"$PODS_ROOT/../.xcode.env\"\n if [ -f \"$env_path\" ]; then\n source \"$env_path\"\n fi\n\n # Read environment variables from ios/.xcode.env.local if it exists\n local_env_path=\"${ENV_PATH}.local\"\n if [ -f \"$local_env_path\" ]; then\n source \"$local_env_path\"\n fi\n\n if [[ \"$INSTABUG_SOURCEMAPS_UPLOAD_DISABLE\" = true ]]; then\n echo \"[Info] \\`INSTABUG_SOURCEMAPS_UPLOAD_DISABLE\\` was set to true, skipping sourcemaps upload...\"\n exit 0\n fi\n\n if [[ \"$CONFIGURATION\" = \"Debug\" ]]; then\n echo \"[Info] Building in debug mode, skipping sourcemaps upload...\"\n exit 0\n fi\n\n if [[ -z \"$INFOPLIST_FILE\" ]] || [[ -z \"$PROJECT_DIR\" ]]; then\n echo \"[Error] Instabug sourcemaps script must be invoked by Xcode\"\n exit 0\n fi\n\n\nlocal sourcemap_file=\"\"\n # Use existing sourcemap if available\n if [[ -f \"$SOURCEMAP_FILE\" ]]; then\n sourcemap_file=\"$SOURCEMAP_FILE\"\n else\n sourcemap_file=$(generate_sourcemaps | tail -n 1)\nfi\n\n local js_project_dir=\"$PROJECT_DIR/..\"\n local instabug_dir=$(dirname $(node -p \"require.resolve('instabug-reactnative/package.json')\"))\n local inferred_token=$(cd $js_project_dir && node $instabug_dir/scripts/find-token.js)\n local app_token=$(resolve_var \"App Token\" \"INSTABUG_APP_TOKEN\" \"$inferred_token\" | tail -n 1)\n\n local inferred_name=$(/usr/libexec/PlistBuddy -c 'print CFBundleShortVersionString' \"$PROJECT_DIR/$INFOPLIST_FILE\")\n local version_name=$(resolve_var \"Version Name\" \"INSTABUG_APP_VERSION_NAME\" \"$inferred_name\" | tail -n 1)\n\n local inferred_code=$(/usr/libexec/PlistBuddy -c 'print CFBundleVersion' \"$PROJECT_DIR/$INFOPLIST_FILE\")\n local version_code=$(resolve_var \"Version Code\" \"INSTABUG_APP_VERSION_CODE\" \"$inferred_code\" | tail -n 1)\n\nif [ -n \"$sourcemap_file\" ]; then\n node $instabug_dir/bin/index.js upload-sourcemaps \\\n --platform ios \\\n --file $sourcemap_file \\\n --token $app_token \\\n --name $version_name \\\n --code $version_code\n fi\n}\n\ngenerate_sourcemaps() {\n local react_native_dir=$(dirname $(node -p \"require.resolve('react-native/package.json')\"))\n\n # Fixes an issue with react-native prior to v0.67.0\n # For more info: https://github.com/facebook/react-native/issues/32168\n export RN_DIR=$react_native_dir\n\n # Used withing `react-native-xcode.sh` to generate sourcemap file\n export SOURCEMAP_FILE=\"$(pwd)/main.jsbundle.map\";\n\n source \"$react_native_dir/scripts/react-native-xcode.sh\"\n\n if [[ ! -f \"$SOURCEMAP_FILE\" ]]; then\n echo \"[Error] Unable to find source map file at: $SOURCEMAP_FILE\"\n exit 0\n fi\n\n echo $SOURCEMAP_FILE\n}\n\nresolve_var() {\n local name=$1\n local env_key=$2\n local default_value=$3\n\n local env_value=\"${!env_key}\"\n\n if [[ -n \"$env_value\" ]] && [[ -n \"$default_value\" ]] && [[ \"$env_value\" != default_value ]]; then\n echo \"[Warning] Environment variable \\`$env_key\\` might have incorrect value, make sure this was intentional:\"\n echo \" Environment Value: $env_value\"\n echo \" Default Value: $default_value\"\n fi\n\n local value=\"${env_value:-$default_value}\"\n\n if [[ -z \"$value\" ]]; then\n echo \"[Error] Unable to find $name! Set the environment variable \\`$env_key\\` and try again.\"\n exit 0\n fi\n\n echo $value\n}\n\nmain \"$@\"; exit\n";
434434
};
435435
B77A7BA143DBD17E8AAFD0B4 /* [CP] Embed Pods Frameworks */ = {
436436
isa = PBXShellScriptBuildPhase;

expo.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './plugin/build';

0 commit comments

Comments
 (0)