txlemetry-react-native 4.55.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +353 -0
- package/README.md +13 -0
- package/dist/PostHogContext.d.ts +5 -0
- package/dist/PostHogContext.js +1 -0
- package/dist/PostHogErrorBoundary.d.ts +27 -0
- package/dist/PostHogErrorBoundary.js +1 -0
- package/dist/PostHogMaskView.d.ts +39 -0
- package/dist/PostHogMaskView.js +1 -0
- package/dist/PostHogProvider.d.ts +100 -0
- package/dist/PostHogProvider.js +1 -0
- package/dist/autocapture.d.ts +4 -0
- package/dist/autocapture.js +1 -0
- package/dist/error-tracking/index.d.ts +98 -0
- package/dist/error-tracking/index.js +1 -0
- package/dist/error-tracking/utils.d.ts +5 -0
- package/dist/error-tracking/utils.js +1 -0
- package/dist/frameworks/wix-navigation.d.ts +3 -0
- package/dist/frameworks/wix-navigation.js +1 -0
- package/dist/hooks/useFeatureFlag.d.ts +5 -0
- package/dist/hooks/useFeatureFlag.js +1 -0
- package/dist/hooks/useFeatureFlagResult.d.ts +3 -0
- package/dist/hooks/useFeatureFlagResult.js +1 -0
- package/dist/hooks/useFeatureFlags.d.ts +3 -0
- package/dist/hooks/useFeatureFlags.js +1 -0
- package/dist/hooks/useNavigationTracker.d.ts +6 -0
- package/dist/hooks/useNavigationTracker.js +1 -0
- package/dist/hooks/usePostHog.d.ts +2 -0
- package/dist/hooks/usePostHog.js +1 -0
- package/dist/hooks/utils.d.ts +14 -0
- package/dist/hooks/utils.js +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +1 -0
- package/dist/index.txlemetry.d.ts +36 -0
- package/dist/index.txlemetry.js +21 -0
- package/dist/logs-defaults.d.ts +9 -0
- package/dist/logs-defaults.js +1 -0
- package/dist/native-deps.d.ts +4 -0
- package/dist/native-deps.js +1 -0
- package/dist/optional/OptionalAsyncStorage.d.ts +2 -0
- package/dist/optional/OptionalAsyncStorage.js +1 -0
- package/dist/optional/OptionalExpoApplication.d.ts +2 -0
- package/dist/optional/OptionalExpoApplication.js +1 -0
- package/dist/optional/OptionalExpoDevice.d.ts +2 -0
- package/dist/optional/OptionalExpoDevice.js +1 -0
- package/dist/optional/OptionalExpoFileSystem.d.ts +2 -0
- package/dist/optional/OptionalExpoFileSystem.js +1 -0
- package/dist/optional/OptionalExpoFileSystemLegacy.d.ts +2 -0
- package/dist/optional/OptionalExpoFileSystemLegacy.js +1 -0
- package/dist/optional/OptionalExpoLocalization.d.ts +2 -0
- package/dist/optional/OptionalExpoLocalization.js +1 -0
- package/dist/optional/OptionalPlugin.d.ts +20 -0
- package/dist/optional/OptionalPlugin.js +1 -0
- package/dist/optional/OptionalReactNativeDeviceInfo.d.ts +2 -0
- package/dist/optional/OptionalReactNativeDeviceInfo.js +1 -0
- package/dist/optional/OptionalReactNativeLocalize.d.ts +13 -0
- package/dist/optional/OptionalReactNativeLocalize.js +1 -0
- package/dist/optional/OptionalReactNativeNavigation.d.ts +2 -0
- package/dist/optional/OptionalReactNativeNavigation.js +1 -0
- package/dist/optional/OptionalReactNativeNavigationWix.d.ts +2 -0
- package/dist/optional/OptionalReactNativeNavigationWix.js +1 -0
- package/dist/optional/OptionalReactNativeSafeArea.d.ts +2 -0
- package/dist/optional/OptionalReactNativeSafeArea.js +1 -0
- package/dist/optional/OptionalReactNativeSvg.d.ts +2 -0
- package/dist/optional/OptionalReactNativeSvg.js +1 -0
- package/dist/posthog-rn.d.ts +1096 -0
- package/dist/posthog-rn.js +1 -0
- package/dist/storage.d.ts +41 -0
- package/dist/storage.js +1 -0
- package/dist/surveys/PostHogSurveyProvider.d.ts +23 -0
- package/dist/surveys/PostHogSurveyProvider.js +1 -0
- package/dist/surveys/components/BottomSection.d.ts +9 -0
- package/dist/surveys/components/BottomSection.js +1 -0
- package/dist/surveys/components/Cancel.d.ts +5 -0
- package/dist/surveys/components/Cancel.js +1 -0
- package/dist/surveys/components/ConfirmationMessage.d.ts +12 -0
- package/dist/surveys/components/ConfirmationMessage.js +1 -0
- package/dist/surveys/components/QuestionHeader.d.ts +8 -0
- package/dist/surveys/components/QuestionHeader.js +1 -0
- package/dist/surveys/components/QuestionTypes.d.ts +26 -0
- package/dist/surveys/components/QuestionTypes.js +1 -0
- package/dist/surveys/components/SurveyModal.d.ts +11 -0
- package/dist/surveys/components/SurveyModal.js +1 -0
- package/dist/surveys/components/Surveys.d.ts +16 -0
- package/dist/surveys/components/Surveys.js +1 -0
- package/dist/surveys/getActiveMatchingSurveys.d.ts +2 -0
- package/dist/surveys/getActiveMatchingSurveys.js +1 -0
- package/dist/surveys/icons.d.ts +11 -0
- package/dist/surveys/icons.js +1 -0
- package/dist/surveys/index.d.ts +6 -0
- package/dist/surveys/index.js +1 -0
- package/dist/surveys/safeStyleSheet.d.ts +8 -0
- package/dist/surveys/safeStyleSheet.js +1 -0
- package/dist/surveys/survey-translations.d.ts +7 -0
- package/dist/surveys/survey-translations.js +1 -0
- package/dist/surveys/surveys-utils.d.ts +54 -0
- package/dist/surveys/surveys-utils.js +1 -0
- package/dist/surveys/useActivatedSurveys.d.ts +3 -0
- package/dist/surveys/useActivatedSurveys.js +1 -0
- package/dist/surveys/useSurveyStorage.d.ts +8 -0
- package/dist/surveys/useSurveyStorage.js +1 -0
- package/dist/tooling/expoconfig.d.ts +64 -0
- package/dist/tooling/expoconfig.js +1 -0
- package/dist/tooling/metroconfig.d.ts +21 -0
- package/dist/tooling/metroconfig.js +1 -0
- package/dist/tooling/posthogMetroSerializer.d.ts +17 -0
- package/dist/tooling/posthogMetroSerializer.js +1 -0
- package/dist/tooling/utils.d.ts +58 -0
- package/dist/tooling/utils.js +1 -0
- package/dist/tooling/vendor/expo/expoconfig.d.ts +23 -0
- package/dist/tooling/vendor/expo/expoconfig.js +1 -0
- package/dist/tooling/vendor/metro/countLines.d.ts +2 -0
- package/dist/tooling/vendor/metro/countLines.js +1 -0
- package/dist/tooling/vendor/metro/utils.d.ts +22 -0
- package/dist/tooling/vendor/metro/utils.js +1 -0
- package/dist/types.d.ts +205 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +25 -0
- package/dist/utils.js +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +1 -0
- package/package.json +149 -0
- package/tooling/txlemetry-xcode.sh +222 -0
- package/tooling/txlemetry.gradle +407 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
// Portions of this file are derived from getsentry/sentry-react-native
|
|
2
|
+
// Copyright (c) 2017 Sentry
|
|
3
|
+
// Licensed under the MIT License: https://github.com/getsentry/sentry-react-native/blob/main/LICENSE.md
|
|
4
|
+
|
|
5
|
+
import org.apache.tools.ant.taskdefs.condition.Os
|
|
6
|
+
|
|
7
|
+
import java.util.regex.Matcher
|
|
8
|
+
import java.util.regex.Pattern
|
|
9
|
+
|
|
10
|
+
import org.gradle.api.logging.Logging
|
|
11
|
+
|
|
12
|
+
interface InjectedExecOps {
|
|
13
|
+
@Inject //@javax.inject.Inject
|
|
14
|
+
ExecOperations getExecOps()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
plugins.withId('com.android.application') {
|
|
18
|
+
def androidComponents = extensions.getByName("androidComponents")
|
|
19
|
+
|
|
20
|
+
androidComponents.onVariants(androidComponents.selector().all()) { v ->
|
|
21
|
+
if (!v.name.toLowerCase().contains("debug")) {
|
|
22
|
+
// separately we then hook into the bundle task of react native to inject
|
|
23
|
+
// sourcemap generation parameters. In case for whatever reason no release
|
|
24
|
+
// was found for the asset folder we just bail.
|
|
25
|
+
def bundleTasks = tasks.findAll { task -> (task.name.startsWith("createBundle") || task.name.startsWith("bundle")) && task.name.endsWith("JsAndAssets") && !task.name.contains("Debug") && task.enabled }
|
|
26
|
+
// this is the task that calls react-native bundle {params}
|
|
27
|
+
bundleTasks.each { bundleTask ->
|
|
28
|
+
def shouldCleanUp
|
|
29
|
+
def sourcemapOutput
|
|
30
|
+
def bundleOutput
|
|
31
|
+
def packagerSourcemapOutput
|
|
32
|
+
def bundleCommand
|
|
33
|
+
def props = bundleTask.getProperties()
|
|
34
|
+
def reactRoot = props.get("workingDir")
|
|
35
|
+
if (reactRoot == null) {
|
|
36
|
+
reactRoot = props.get("root").get() // RN 0.71 and above
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
(shouldCleanUp, bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand) = forceSourceMapOutputFromBundleTask(bundleTask)
|
|
40
|
+
|
|
41
|
+
// Lets leave this here if we need to debug
|
|
42
|
+
// println bundleTask.properties
|
|
43
|
+
// .sort{it.key}
|
|
44
|
+
// .collect{it}
|
|
45
|
+
// .findAll{!['class', 'active'].contains(it.key)}
|
|
46
|
+
// .join('\n')
|
|
47
|
+
|
|
48
|
+
def currentVariants = extractCurrentVariants(bundleTask, v)
|
|
49
|
+
if (currentVariants == null) return
|
|
50
|
+
|
|
51
|
+
def previousCliTask = null
|
|
52
|
+
def applicationVariant = null
|
|
53
|
+
|
|
54
|
+
def nameCleanup = "${bundleTask.name}_TxlemetryUploadCleanUp"
|
|
55
|
+
// Upload the source map several times if necessary: once for each release and versionCode.
|
|
56
|
+
currentVariants.each { key, currentVariant ->
|
|
57
|
+
def variant = currentVariant[0]
|
|
58
|
+
def releaseName = currentVariant[1]
|
|
59
|
+
def versionCode = currentVariant[2]
|
|
60
|
+
applicationVariant = currentVariant[3]
|
|
61
|
+
def appId = currentVariant[4]
|
|
62
|
+
def versionName = currentVariant[5]
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
if (versionCode instanceof String) {
|
|
66
|
+
versionCode = Integer.parseInt(versionCode)
|
|
67
|
+
versionCode = Math.abs(versionCode)
|
|
68
|
+
}
|
|
69
|
+
} catch (NumberFormatException e) {
|
|
70
|
+
project.logger.info("versionCode: '$versionCode' isn't an Integer, using the plain value.")
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
def nameCliTask = "${bundleTask.name}_TxlemetryUpload_${releaseName}_${versionCode}"
|
|
74
|
+
|
|
75
|
+
// If several outputs have the same releaseName and versionCode, we'd do the exact same
|
|
76
|
+
// upload for each of them. No need to repeat.
|
|
77
|
+
try { tasks.named(nameCliTask); return } catch (Exception e) {}
|
|
78
|
+
|
|
79
|
+
/** Upload source map file to the Txlemetry server via CLI call. */
|
|
80
|
+
def cliTask = tasks.register(nameCliTask) {
|
|
81
|
+
description = "upload sourcemaps to Txlemetry"
|
|
82
|
+
group = 'txlemetry.com'
|
|
83
|
+
|
|
84
|
+
def extraArgs = []
|
|
85
|
+
if (appId != null && !appId.isEmpty()) {
|
|
86
|
+
extraArgs.addAll(["--release-name", appId.toString()])
|
|
87
|
+
}
|
|
88
|
+
if (versionName != null && !versionName.toString().isEmpty()) {
|
|
89
|
+
extraArgs.addAll(["--release-version", versionName.toString()])
|
|
90
|
+
}
|
|
91
|
+
if (versionCode != null) {
|
|
92
|
+
extraArgs.addAll(["--build", versionCode.toString()])
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
def txlemetryUploadArgs = []
|
|
96
|
+
if ((project.ext.has("txlemetryReactNativeSkipOnConflict") && project.ext.get("txlemetryReactNativeSkipOnConflict") == true) ||
|
|
97
|
+
(project.ext.has("posthogReactNativeSkipOnConflict") && project.ext.get("posthogReactNativeSkipOnConflict") == true)) {
|
|
98
|
+
txlemetryUploadArgs.add("--skip-on-conflict")
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
def injected = project.objects.newInstance(InjectedExecOps)
|
|
102
|
+
|
|
103
|
+
// Resolve the txlemetry-cli path at execution time, not during
|
|
104
|
+
// configuration. The resolver starts node/npm via Groovy's `.execute()`,
|
|
105
|
+
// and Gradle's configuration cache forbids starting external processes at
|
|
106
|
+
// configuration time. Resolution lives in the static
|
|
107
|
+
// TxlemetryCli.resolveCliPackagePath() so these serialized task actions can
|
|
108
|
+
// call it without relying on the apply-from script's owner chain — a
|
|
109
|
+
// script-level method fails under the configuration cache with "Could not
|
|
110
|
+
// find method ... on object of type DefaultExecAction_Decorated". rootDir
|
|
111
|
+
// is captured as plain serializable state; `Task.project` must not be read
|
|
112
|
+
// at execution time, so logging uses the task's own `logger`.
|
|
113
|
+
def rootDirFile = rootDir
|
|
114
|
+
def osCompatibility = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c', 'node'] : []
|
|
115
|
+
|
|
116
|
+
doFirst {
|
|
117
|
+
def cliPackage = TxlemetryCli.resolveCliPackagePath(rootDirFile, reactRoot)
|
|
118
|
+
def args = [cliPackage]
|
|
119
|
+
args.addAll(["hermes", "clone",
|
|
120
|
+
"--minified-map-path", packagerSourcemapOutput, // The path to a sourcemap
|
|
121
|
+
"--composed-map-path", sourcemapOutput // The path of the composed source map
|
|
122
|
+
])
|
|
123
|
+
args.addAll(extraArgs)
|
|
124
|
+
logger.info("txlemetry-cli clone arguments: ${args}")
|
|
125
|
+
|
|
126
|
+
injected.execOps.exec {
|
|
127
|
+
workingDir reactRoot
|
|
128
|
+
commandLine(*osCompatibility, *args)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
doLast {
|
|
133
|
+
def cliPackage = TxlemetryCli.resolveCliPackagePath(rootDirFile, reactRoot)
|
|
134
|
+
def args = [cliPackage]
|
|
135
|
+
args.addAll(["hermes", "upload",
|
|
136
|
+
"--directory", sourcemapOutput.getParent() // The path to a sourcemap that should be uploaded.
|
|
137
|
+
])
|
|
138
|
+
args.addAll(extraArgs)
|
|
139
|
+
args.addAll(txlemetryUploadArgs)
|
|
140
|
+
logger.info("txlemetry-cli upload arguments: ${args}")
|
|
141
|
+
|
|
142
|
+
injected.execOps.exec {
|
|
143
|
+
workingDir reactRoot
|
|
144
|
+
commandLine(*osCompatibility, *args)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
enabled true
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// chain the upload tasks so they run sequentially in order to run
|
|
152
|
+
// the cliCleanUpTask after the final upload task is run
|
|
153
|
+
if (previousCliTask != null) {
|
|
154
|
+
previousCliTask.configure { finalizedBy cliTask }
|
|
155
|
+
} else {
|
|
156
|
+
bundleTask.configure { finalizedBy cliTask }
|
|
157
|
+
}
|
|
158
|
+
previousCliTask = cliTask
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Delete sourcemap files */
|
|
162
|
+
def cliCleanUpTask = tasks.register(nameCleanup, Delete) {
|
|
163
|
+
description = "clean up extra sourcemap"
|
|
164
|
+
group = 'txlemetry.com'
|
|
165
|
+
|
|
166
|
+
delete sourcemapOutput
|
|
167
|
+
delete "$buildDir/intermediates/assets/release/index.android.bundle.map"
|
|
168
|
+
// react native default bundle dir
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// register clean task extension
|
|
172
|
+
cliCleanUpTask.configure { onlyIf { shouldCleanUp } }
|
|
173
|
+
// due to chaining the last value of previousCliTask will be the final
|
|
174
|
+
// upload task, after which the cleanup can be done
|
|
175
|
+
previousCliTask.configure { finalizedBy cliCleanUpTask }
|
|
176
|
+
|
|
177
|
+
def packageTasks = tasks.matching {
|
|
178
|
+
task -> ("package${applicationVariant}".equalsIgnoreCase(task.name) || "package${applicationVariant}Bundle".equalsIgnoreCase(task.name)) && task.enabled
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Static so the serialized sourcemap-upload task actions can call it under the
|
|
186
|
+
// Gradle configuration cache. It starts node/npm, so it must run at execution
|
|
187
|
+
// time — starting external processes at configuration time is rejected by the
|
|
188
|
+
// configuration cache. Uses its own logger (not `project.logger`) and takes
|
|
189
|
+
// rootDir as a parameter so it never touches `Task.project` at execution time.
|
|
190
|
+
abstract class TxlemetryCli {
|
|
191
|
+
static String resolveCliPackagePath(File rootDir, reactRoot) {
|
|
192
|
+
def logger = Logging.getLogger(TxlemetryCli)
|
|
193
|
+
|
|
194
|
+
// First, try to find @txlemetry/cli folder from require.resolve
|
|
195
|
+
try {
|
|
196
|
+
def resolvedPath = new File(["node", "--print", "require.resolve('@txlemetry/cli/package.json')"].execute(null, rootDir).text.trim()).getParentFile()
|
|
197
|
+
if (resolvedPath != null && resolvedPath.exists()) {
|
|
198
|
+
def runTxlemetryCliFile = new File(resolvedPath, "run-txlemetry-cli.js")
|
|
199
|
+
if (runTxlemetryCliFile.exists()) {
|
|
200
|
+
logger.info("resolved txlemetry-cli dynamically: `${runTxlemetryCliFile.getAbsolutePath()}`")
|
|
201
|
+
return runTxlemetryCliFile.getAbsolutePath()
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
} catch (Throwable ignored) {}
|
|
205
|
+
|
|
206
|
+
// Second, check if @txlemetry/cli exists in $reactRoot/node_modules
|
|
207
|
+
def nodeModulesPath = new File("$reactRoot/node_modules/@txlemetry/cli")
|
|
208
|
+
if (nodeModulesPath.exists()) {
|
|
209
|
+
def runTxlemetryCliFile = new File(nodeModulesPath, "run-txlemetry-cli.js")
|
|
210
|
+
if (runTxlemetryCliFile.exists()) {
|
|
211
|
+
logger.info("resolved txlemetry-cli hard-coded path (yarn or npm): `${runTxlemetryCliFile.getAbsolutePath()}`")
|
|
212
|
+
return runTxlemetryCliFile.getAbsolutePath()
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Third, check for pnpm installation with node_modules/.bin/txlemetry-cli
|
|
217
|
+
def pnpmBinPath = new File("$reactRoot/node_modules/.bin/txlemetry-cli")
|
|
218
|
+
if (pnpmBinPath.exists()) {
|
|
219
|
+
logger.info("resolved txlemetry-cli hard-coded path (pnpm): `${pnpmBinPath.getAbsolutePath()}`")
|
|
220
|
+
return pnpmBinPath.getAbsolutePath()
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Fourth, check using npm root for local installation
|
|
224
|
+
try {
|
|
225
|
+
def npmRoot = ["npm", "root"].execute(null, rootDir).text.trim()
|
|
226
|
+
def npmTxlemetryCliPath = new File(npmRoot, "@txlemetry/cli")
|
|
227
|
+
if (npmTxlemetryCliPath.exists()) {
|
|
228
|
+
def runTxlemetryCliFile = new File(npmTxlemetryCliPath, "run-txlemetry-cli.js")
|
|
229
|
+
if (runTxlemetryCliFile.exists()) {
|
|
230
|
+
logger.info("resolved txlemetry-cli via npm root: `${runTxlemetryCliFile.getAbsolutePath()}`")
|
|
231
|
+
return runTxlemetryCliFile.getAbsolutePath()
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} catch (Throwable ignored) {}
|
|
235
|
+
|
|
236
|
+
// Fifth, check for global npm installation of @txlemetry/cli
|
|
237
|
+
try {
|
|
238
|
+
def globalPrefix = ["npm", "prefix", "-g"].execute().text.trim()
|
|
239
|
+
def globalTxlemetryCliPath = new File(globalPrefix, "lib/node_modules/@txlemetry/cli")
|
|
240
|
+
if (globalTxlemetryCliPath.exists()) {
|
|
241
|
+
def runTxlemetryCliFile = new File(globalTxlemetryCliPath, "run-txlemetry-cli.js")
|
|
242
|
+
if (runTxlemetryCliFile.exists()) {
|
|
243
|
+
logger.info("resolved txlemetry-cli from global npm installation: `${runTxlemetryCliFile.getAbsolutePath()}`")
|
|
244
|
+
return runTxlemetryCliFile.getAbsolutePath()
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
} catch (Throwable ignored) {}
|
|
248
|
+
|
|
249
|
+
// Finally, fallback to global install
|
|
250
|
+
logger.info("falling back to global txlemetry-cli")
|
|
251
|
+
return "txlemetry-cli"
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
def resolveTxlemetryReactNativeSDKPath(reactRoot) {
|
|
256
|
+
def resolvedPath = null
|
|
257
|
+
try {
|
|
258
|
+
resolvedPath = new File(["node", "--print", "require.resolve('txlemetry-react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile();
|
|
259
|
+
} catch (Throwable ignored) {} // if the resolve fails we fallback to the default path
|
|
260
|
+
def packagePath = resolvedPath != null && resolvedPath.exists() ? resolvedPath.getAbsolutePath() : "$reactRoot/node_modules/txlemetry-react-native"
|
|
261
|
+
return packagePath
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** Extract from arguments collection bundle and sourcemap files output names. */
|
|
265
|
+
static extractBundleTaskArgumentsLegacy(cmdArgs, Project project) {
|
|
266
|
+
def bundleOutput = null
|
|
267
|
+
def sourcemapOutput = null
|
|
268
|
+
def packagerSourcemapOutput = null
|
|
269
|
+
// packagerBundleOutput doesn't exist, because packager output is overwritten by Hermes
|
|
270
|
+
|
|
271
|
+
cmdArgs.eachWithIndex { String arg, int i ->
|
|
272
|
+
if (arg == "--bundle-output") {
|
|
273
|
+
bundleOutput = cmdArgs[i + 1]
|
|
274
|
+
project.logger.info("--bundle-output: `${bundleOutput}`")
|
|
275
|
+
} else if (arg == "--sourcemap-output") {
|
|
276
|
+
sourcemapOutput = cmdArgs[i + 1]
|
|
277
|
+
packagerSourcemapOutput = sourcemapOutput
|
|
278
|
+
project.logger.info("--sourcemap-output param: `${sourcemapOutput}`")
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Best thing would be if we just had access to the local gradle variables here:
|
|
283
|
+
// https://github.com/facebook/react-native/blob/ff3b839e9a5a6c9e398a1327cde6dd49a3593092/react.gradle#L89-L97
|
|
284
|
+
// Now, the issue is that hermes builds have a different pipeline:
|
|
285
|
+
// `metro -> hermes -> compose-source-maps`, which then combines both intermediate sourcemaps into the final one.
|
|
286
|
+
// In this function here, we only grep through the first `metro` step, which only generates an intermediate sourcemap,
|
|
287
|
+
// which is wrong. We need the final one. Luckily, we can just generate the path from the `bundleOutput`, since
|
|
288
|
+
// the paths seem to be well defined.
|
|
289
|
+
|
|
290
|
+
// if sourcemapOutput is null, it means there's no source maps at all
|
|
291
|
+
// if hermes is enabled and has intermediates folder, we need to fix paths
|
|
292
|
+
// if hermes is disabled, sourcemapOutput is already ok
|
|
293
|
+
def enableHermes = project.ext.react.get("enableHermes", false);
|
|
294
|
+
project.logger.info("enableHermes: `${enableHermes}`")
|
|
295
|
+
|
|
296
|
+
if (bundleOutput != null && sourcemapOutput != null && enableHermes) {
|
|
297
|
+
// react-native < 0.60.1
|
|
298
|
+
def pattern = Pattern.compile("(/|\\\\)intermediates\\1sourcemaps\\1react\\1")
|
|
299
|
+
Matcher matcher = pattern.matcher(sourcemapOutput)
|
|
300
|
+
// if its intermediates/sourcemaps/react then it should be generated/sourcemaps/react
|
|
301
|
+
if (matcher.find()) {
|
|
302
|
+
project.logger.info("sourcemapOutput has the wrong path, let's fix it.")
|
|
303
|
+
// replacing from bundleOutput which is more reliable
|
|
304
|
+
sourcemapOutput = bundleOutput.replaceAll("(/|\\\\)generated\\1assets\\1react\\1", "\$1generated\$1sourcemaps\$1react\$1") + ".map"
|
|
305
|
+
project.logger.info("sourcemapOutput new path: `${sourcemapOutput}`")
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// get the current bundle command, if not peresent use default plain "bundle"
|
|
310
|
+
// we use this later to decide how to upload source maps
|
|
311
|
+
def bundleCommand = project.ext.react.get("bundleCommand", "bundle")
|
|
312
|
+
|
|
313
|
+
return [bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand]
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** Extract bundle and sourcemap paths from bundle task props.
|
|
317
|
+
* Based on https://github.com/facebook/react-native/blob/93c17cd0c43ba7fe3bc09f547b64771984992fbb/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt
|
|
318
|
+
* Output source map path is the same for both Hermes and JSC.
|
|
319
|
+
*/
|
|
320
|
+
static extractBundleTaskArgumentsRN71AndAbove(bundleTask, logger) {
|
|
321
|
+
def props = bundleTask.getProperties()
|
|
322
|
+
def bundleAssetName = props.bundleAssetName?.get()
|
|
323
|
+
|
|
324
|
+
if (bundleAssetName == null) {
|
|
325
|
+
return [null, null]
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
def bundleCommand = props.bundleCommand.get()
|
|
329
|
+
def bundleFile = new File(props.jsBundleDir.get().asFile.absolutePath, bundleAssetName)
|
|
330
|
+
def outputSourceMap = new File(props.jsSourceMapsDir.get().asFile.absolutePath, "${bundleAssetName}.map")
|
|
331
|
+
def packagerOutputSourceMap = new File(props.jsIntermediateSourceMapsDir.get().asFile.absolutePath, "${bundleAssetName}.packager.map")
|
|
332
|
+
|
|
333
|
+
logger.info("bundleFile: `${bundleFile}`")
|
|
334
|
+
logger.info("outputSourceMap: `${outputSourceMap}`")
|
|
335
|
+
logger.info("packagerOutputSourceMap: `${packagerOutputSourceMap}`")
|
|
336
|
+
return [bundleFile, outputSourceMap, packagerOutputSourceMap, bundleCommand]
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** Force Bundle task to produce sourcemap files if they are not pre-configured by user yet. */
|
|
340
|
+
def forceSourceMapOutputFromBundleTask(bundleTask) {
|
|
341
|
+
def props = bundleTask.getProperties()
|
|
342
|
+
def cmd = props.get("commandLine") as List<String>
|
|
343
|
+
def cmdArgs = props.get("args") as List<String>
|
|
344
|
+
def shouldCleanUp = false
|
|
345
|
+
def bundleOutput = null
|
|
346
|
+
def sourcemapOutput = null
|
|
347
|
+
def packagerSourcemapOutput = null
|
|
348
|
+
def bundleCommand = null
|
|
349
|
+
|
|
350
|
+
(bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand) = extractBundleTaskArgumentsRN71AndAbove(bundleTask, logger)
|
|
351
|
+
if (bundleOutput == null) {
|
|
352
|
+
(bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand) = extractBundleTaskArgumentsLegacy(cmdArgs, project)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (sourcemapOutput == null) {
|
|
356
|
+
sourcemapOutput = bundleOutput + ".map"
|
|
357
|
+
|
|
358
|
+
cmd.addAll(["--sourcemap-output", sourcemapOutput])
|
|
359
|
+
cmdArgs.addAll(["--sourcemap-output", sourcemapOutput])
|
|
360
|
+
|
|
361
|
+
shouldCleanUp = true
|
|
362
|
+
|
|
363
|
+
bundleTask.setProperty("commandLine", cmd)
|
|
364
|
+
bundleTask.setProperty("args", cmdArgs)
|
|
365
|
+
|
|
366
|
+
project.logger.info("forced sourcemap file output for `${bundleTask.name}` task")
|
|
367
|
+
} else {
|
|
368
|
+
project.logger.info("Info: used pre-configured source map files: ${sourcemapOutput}")
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return [shouldCleanUp, bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand]
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** compose array with one item - current build flavor name */
|
|
375
|
+
static extractCurrentVariants(bundleTask, variant) {
|
|
376
|
+
// examples: bundleLocalReleaseJsAndAssets, createBundleYellowDebugJsAndAssets
|
|
377
|
+
def pattern = Pattern.compile("(?:create)?(?:B|b)undle([A-Z][A-Za-z0-9_]+)JsAndAssets")
|
|
378
|
+
|
|
379
|
+
def currentRelease = ""
|
|
380
|
+
|
|
381
|
+
Matcher matcher = pattern.matcher(bundleTask.name)
|
|
382
|
+
if (matcher.find()) {
|
|
383
|
+
def match = matcher.group(1)
|
|
384
|
+
currentRelease = match.substring(0, 1).toLowerCase() + match.substring(1)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
def currentVariants = null
|
|
388
|
+
if (variant.name.equalsIgnoreCase(currentRelease)) {
|
|
389
|
+
currentVariants = [:]
|
|
390
|
+
def variantName = variant.name
|
|
391
|
+
variant.outputs.each { output ->
|
|
392
|
+
def defaultVersionCode = output.versionCode.getOrElse(0)
|
|
393
|
+
def versionCode = defaultVersionCode
|
|
394
|
+
def appId = variant.applicationId.get()
|
|
395
|
+
def versionName = output.versionName.getOrElse('') // may be empty if not set
|
|
396
|
+
def defaultReleaseName = "${appId}@${versionName}+${versionCode}"
|
|
397
|
+
def releaseName = defaultReleaseName
|
|
398
|
+
|
|
399
|
+
def outputName = output.baseName
|
|
400
|
+
|
|
401
|
+
if (currentVariants[outputName] == null) currentVariants[outputName] = []
|
|
402
|
+
currentVariants[outputName] = [outputName, releaseName, versionCode, variantName, appId, versionName]
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return currentVariants
|
|
407
|
+
}
|