@observerkit/metro 0.2.0 → 0.2.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/README.md +21 -4
- package/dist/{chunk-DFCKYXBG.js → chunk-3IIVAXY2.js} +115 -9
- package/dist/{chunk-6RJOM2CO.cjs → chunk-DFKRMIQJ.cjs} +115 -9
- package/dist/cli.cjs +45 -7
- package/dist/cli.js +41 -3
- package/dist/expo.cjs +44 -3
- package/dist/expo.js +44 -3
- package/dist/index.cjs +6 -6
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ The `observerkit-upload` CLI reads the project key from `--project-key` or the `
|
|
|
26
26
|
|
|
27
27
|
### Expo
|
|
28
28
|
|
|
29
|
-
Add the config plugin; prebuild wires both native builds automatically:
|
|
29
|
+
Add the config plugin; prebuild wires both native builds automatically, including the Android R8 mapping upload described below:
|
|
30
30
|
|
|
31
31
|
```json
|
|
32
32
|
{
|
|
@@ -94,6 +94,18 @@ tasks.configureEach { task ->
|
|
|
94
94
|
|
|
95
95
|
The composed map lands in `generated/sourcemaps/react/<variant>/`, while the pre-compose packager map (needed to restore the `debugId`, see Hermes below) stays behind in `intermediates/sourcemaps/react/<variant>/`. `ignoreExitValue` plus the logged warning make sure a failed upload never fails `assembleRelease`.
|
|
96
96
|
|
|
97
|
+
## Android R8/ProGuard mapping upload
|
|
98
|
+
|
|
99
|
+
Release Android builds run through R8/ProGuard, so JVM crash and ANR stack traces are obfuscated unless a mapping file is uploaded. The Expo config plugin wires this automatically: a Gradle hook runs after the release R8 minify task (`minify<Flavor>ReleaseWithR8`) and uploads `mapping.txt`, keyed by `versionName` and `versionCode` read from `android.defaultConfig`. The hook is release-only, mirroring the source map hook above: every variant shares `defaultConfig`'s version pair, and the server stores mappings last-upload-wins, so a minified debug or staging build would otherwise clobber the release mapping for the same version. Rebuilding the same version overwrites the stored mapping, so re-upload happens naturally on every release build.
|
|
100
|
+
|
|
101
|
+
For bare React Native, or apps that override the version per flavor, upload the mapping manually with the CLI:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
observerkit-upload --mapping android/app/build/outputs/mapping/release/mapping.txt --version-name 1.2.0 --version-code 42
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The server retraces JVM crash and ANR frames with the uploaded mapping before grouping, so deobfuscated frames stay grouped consistently across releases.
|
|
108
|
+
|
|
97
109
|
## Hermes
|
|
98
110
|
|
|
99
111
|
Symbolication support targets Hermes, the React Native default JS engine; JSC is not supported.
|
|
@@ -108,9 +120,14 @@ Hermes release builds compose the Metro source map with the bytecode map, which
|
|
|
108
120
|
```
|
|
109
121
|
observerkit-upload --map <path> [--packager-map <path>] [--bundle <path>]
|
|
110
122
|
observerkit-upload --dir <path>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
--
|
|
123
|
+
observerkit-upload --mapping <path> --version-name <name> --version-code <code>
|
|
124
|
+
|
|
125
|
+
--project-key <key> Defaults to $OBSERVERKIT_PROJECT_KEY
|
|
126
|
+
--endpoint <url> Defaults to $OBSERVERKIT_ENDPOINT or https://ingest.observerkit.com
|
|
127
|
+
--mapping <path> R8/ProGuard mapping.txt to upload, keyed by
|
|
128
|
+
--version-name and --version-code
|
|
129
|
+
--version-name <name> App versionName, required with --mapping
|
|
130
|
+
--version-code <code> App versionCode (digits only), required with --mapping
|
|
114
131
|
```
|
|
115
132
|
|
|
116
133
|
## pnpm note
|
|
@@ -10,6 +10,14 @@ function isJsonObject(value) {
|
|
|
10
10
|
// ../plugin-core/src/upload.ts
|
|
11
11
|
var DEFAULT_MAX_FILE_BYTES = 50 * 1024 * 1024;
|
|
12
12
|
var DEFAULT_MAX_BATCH_BYTES = 100 * 1024 * 1024;
|
|
13
|
+
var RETRY_DELAYS_MS = [1e3, 4e3];
|
|
14
|
+
var sleep = (ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
15
|
+
function isDirectoryMissing(error) {
|
|
16
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
17
|
+
}
|
|
18
|
+
function isCssMap(mapFile) {
|
|
19
|
+
return mapFile.endsWith(".css.map");
|
|
20
|
+
}
|
|
13
21
|
function hasDebugId(content) {
|
|
14
22
|
if (!content.includes('"debugId"')) return false;
|
|
15
23
|
try {
|
|
@@ -49,6 +57,18 @@ async function deleteMapFiles(directory, mapFiles) {
|
|
|
49
57
|
`[ObserverKit] Deleted ${mapFiles.length - failures.length} .map files from output`
|
|
50
58
|
);
|
|
51
59
|
}
|
|
60
|
+
var UploadResponseError = class extends Error {
|
|
61
|
+
status;
|
|
62
|
+
constructor(status, message) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = "UploadResponseError";
|
|
65
|
+
this.status = status;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function isTransient(error) {
|
|
69
|
+
if (error instanceof UploadResponseError) return error.status >= 500;
|
|
70
|
+
return error instanceof TypeError;
|
|
71
|
+
}
|
|
52
72
|
async function uploadBatch(batch, options) {
|
|
53
73
|
const formData = new FormData();
|
|
54
74
|
for (const [index, entry] of batch.entries()) {
|
|
@@ -70,11 +90,28 @@ async function uploadBatch(batch, options) {
|
|
|
70
90
|
});
|
|
71
91
|
if (!response.ok) {
|
|
72
92
|
const text = await response.text();
|
|
73
|
-
throw new
|
|
93
|
+
throw new UploadResponseError(
|
|
94
|
+
response.status,
|
|
74
95
|
`[ObserverKit] Source map upload failed: ${response.status} ${text}`
|
|
75
96
|
);
|
|
76
97
|
}
|
|
77
98
|
}
|
|
99
|
+
async function uploadBatchWithRetry(batch, options) {
|
|
100
|
+
for (let attempt = 0; ; attempt++) {
|
|
101
|
+
try {
|
|
102
|
+
await uploadBatch(batch, options);
|
|
103
|
+
return;
|
|
104
|
+
} catch (err) {
|
|
105
|
+
const wait = RETRY_DELAYS_MS[attempt];
|
|
106
|
+
if (wait === void 0 || !isTransient(err)) throw err;
|
|
107
|
+
const reason = err instanceof UploadResponseError ? `(${err.status})` : "(network error)";
|
|
108
|
+
console.warn(
|
|
109
|
+
`[ObserverKit] Upload failed ${reason}, retrying in ${wait / 1e3}s (attempt ${attempt + 2}/${RETRY_DELAYS_MS.length + 1})`
|
|
110
|
+
);
|
|
111
|
+
await options.delay(wait);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
78
115
|
var JS_SOURCE_MAPPING_URL = /^\/\/[#@] sourceMappingURL=\S+[ \t]*$/gm;
|
|
79
116
|
var CSS_SOURCE_MAPPING_URL = /^\/\*# sourceMappingURL=\S+[ \t]*\*\/[ \t]*$/gm;
|
|
80
117
|
function isChunkFile(name) {
|
|
@@ -105,10 +142,28 @@ async function uploadSourceMaps(options) {
|
|
|
105
142
|
const { projectKey, directory, endpoint, deleteAfterUpload, pluginVersion, pluginName } = options;
|
|
106
143
|
const maxFileBytes = options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES;
|
|
107
144
|
const maxBatchBytes = options.maxBatchBytes ?? DEFAULT_MAX_BATCH_BYTES;
|
|
108
|
-
const
|
|
145
|
+
const delay = options.delay ?? sleep;
|
|
146
|
+
let allFiles;
|
|
147
|
+
if (options.files) {
|
|
148
|
+
allFiles = [...options.files];
|
|
149
|
+
} else {
|
|
150
|
+
try {
|
|
151
|
+
allFiles = await readdir(directory, { recursive: true, encoding: "utf-8" });
|
|
152
|
+
} catch (err) {
|
|
153
|
+
if (isDirectoryMissing(err)) {
|
|
154
|
+
console.error(
|
|
155
|
+
`[ObserverKit] Output directory not found: ${directory}. No source maps were uploaded. Check that this is where your build writes its output.`
|
|
156
|
+
);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
throw err;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
109
162
|
const allMapFiles = allFiles.filter((f) => f.endsWith(".map"));
|
|
110
163
|
if (allMapFiles.length === 0) {
|
|
111
|
-
console.
|
|
164
|
+
console.warn(
|
|
165
|
+
`[ObserverKit] No .map files found in ${directory}, skipping source map upload. Source map emission is enabled by this plugin, so an empty scan usually means the build wrote its output elsewhere.`
|
|
166
|
+
);
|
|
112
167
|
return;
|
|
113
168
|
}
|
|
114
169
|
try {
|
|
@@ -125,7 +180,7 @@ async function uploadSourceMaps(options) {
|
|
|
125
180
|
continue;
|
|
126
181
|
}
|
|
127
182
|
if (!hasDebugId(content)) {
|
|
128
|
-
skippedNoDebugId += 1;
|
|
183
|
+
if (!isCssMap(mapFile)) skippedNoDebugId += 1;
|
|
129
184
|
continue;
|
|
130
185
|
}
|
|
131
186
|
if (content.byteLength > maxFileBytes) {
|
|
@@ -158,11 +213,23 @@ async function uploadSourceMaps(options) {
|
|
|
158
213
|
const url = `${endpoint.replace(/\/+$/, "")}/v1/sourcemaps`;
|
|
159
214
|
const batches = batchBySize(uploadable, maxBatchBytes);
|
|
160
215
|
for (const [index, batch] of batches.entries()) {
|
|
161
|
-
await
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
216
|
+
await uploadBatchWithRetry(batch, {
|
|
217
|
+
directory,
|
|
218
|
+
url,
|
|
219
|
+
projectKey,
|
|
220
|
+
pluginVersion,
|
|
221
|
+
pluginName,
|
|
222
|
+
delay
|
|
223
|
+
});
|
|
224
|
+
if (batches.length > 1) {
|
|
225
|
+
console.log(
|
|
226
|
+
`[ObserverKit] Uploaded batch ${index + 1}/${batches.length} (${batch.length} source maps)`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
165
229
|
}
|
|
230
|
+
console.log(
|
|
231
|
+
`[ObserverKit] Uploaded ${uploadable.length} source map(s) from ${directory}`
|
|
232
|
+
);
|
|
166
233
|
} catch (err) {
|
|
167
234
|
if (deleteAfterUpload) {
|
|
168
235
|
console.warn(
|
|
@@ -178,6 +245,44 @@ async function uploadSourceMaps(options) {
|
|
|
178
245
|
}
|
|
179
246
|
}
|
|
180
247
|
|
|
248
|
+
// ../plugin-core/src/upload-mapping.ts
|
|
249
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
250
|
+
var DEFAULT_MAX_MAPPING_BYTES = 50 * 1024 * 1024;
|
|
251
|
+
async function uploadProguardMapping(options) {
|
|
252
|
+
const maxFileBytes = options.maxFileBytes ?? DEFAULT_MAX_MAPPING_BYTES;
|
|
253
|
+
const content = await readFile2(options.mappingPath);
|
|
254
|
+
if (content.byteLength > maxFileBytes) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
`[ObserverKit] Mapping file exceeds the per-file ingest limit (${maxFileBytes} bytes)`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
const formData = new FormData();
|
|
260
|
+
formData.append("versionName", options.versionName);
|
|
261
|
+
formData.append("versionCode", options.versionCode);
|
|
262
|
+
formData.append(
|
|
263
|
+
"file",
|
|
264
|
+
new Blob([new Uint8Array(content)], { type: "text/plain" }),
|
|
265
|
+
"mapping.txt"
|
|
266
|
+
);
|
|
267
|
+
const url = `${options.endpoint.replace(/\/+$/, "")}/v1/mappings`;
|
|
268
|
+
const response = await fetch(url, {
|
|
269
|
+
method: "POST",
|
|
270
|
+
headers: {
|
|
271
|
+
"X-ObserverKit-Key": options.projectKey,
|
|
272
|
+
"X-ObserverKit-Plugin-Version": options.pluginVersion,
|
|
273
|
+
"X-ObserverKit-Plugin-Name": options.pluginName
|
|
274
|
+
},
|
|
275
|
+
body: formData
|
|
276
|
+
});
|
|
277
|
+
if (!response.ok) {
|
|
278
|
+
const text = await response.text();
|
|
279
|
+
throw new Error(`[ObserverKit] Mapping upload failed: ${response.status} ${text}`);
|
|
280
|
+
}
|
|
281
|
+
console.log(
|
|
282
|
+
`[ObserverKit] Uploaded R8 mapping for version ${options.versionName} (${options.versionCode})`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
181
286
|
// ../plugin-core/src/debug-id.ts
|
|
182
287
|
import { v5 } from "uuid";
|
|
183
288
|
var OBSERVERKIT_NAMESPACE = "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d";
|
|
@@ -195,5 +300,6 @@ export {
|
|
|
195
300
|
generateDebugId,
|
|
196
301
|
isJsonObject,
|
|
197
302
|
buildStackKeyedDebugIdSnippet,
|
|
198
|
-
uploadSourceMaps
|
|
303
|
+
uploadSourceMaps,
|
|
304
|
+
uploadProguardMapping
|
|
199
305
|
};
|
|
@@ -10,6 +10,14 @@ function isJsonObject(value) {
|
|
|
10
10
|
// ../plugin-core/src/upload.ts
|
|
11
11
|
var DEFAULT_MAX_FILE_BYTES = 50 * 1024 * 1024;
|
|
12
12
|
var DEFAULT_MAX_BATCH_BYTES = 100 * 1024 * 1024;
|
|
13
|
+
var RETRY_DELAYS_MS = [1e3, 4e3];
|
|
14
|
+
var sleep = (ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
15
|
+
function isDirectoryMissing(error) {
|
|
16
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
17
|
+
}
|
|
18
|
+
function isCssMap(mapFile) {
|
|
19
|
+
return mapFile.endsWith(".css.map");
|
|
20
|
+
}
|
|
13
21
|
function hasDebugId(content) {
|
|
14
22
|
if (!content.includes('"debugId"')) return false;
|
|
15
23
|
try {
|
|
@@ -49,6 +57,18 @@ async function deleteMapFiles(directory, mapFiles) {
|
|
|
49
57
|
`[ObserverKit] Deleted ${mapFiles.length - failures.length} .map files from output`
|
|
50
58
|
);
|
|
51
59
|
}
|
|
60
|
+
var UploadResponseError = class extends Error {
|
|
61
|
+
|
|
62
|
+
constructor(status, message) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = "UploadResponseError";
|
|
65
|
+
this.status = status;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function isTransient(error) {
|
|
69
|
+
if (error instanceof UploadResponseError) return error.status >= 500;
|
|
70
|
+
return error instanceof TypeError;
|
|
71
|
+
}
|
|
52
72
|
async function uploadBatch(batch, options) {
|
|
53
73
|
const formData = new FormData();
|
|
54
74
|
for (const [index, entry] of batch.entries()) {
|
|
@@ -70,11 +90,28 @@ async function uploadBatch(batch, options) {
|
|
|
70
90
|
});
|
|
71
91
|
if (!response.ok) {
|
|
72
92
|
const text = await response.text();
|
|
73
|
-
throw new
|
|
93
|
+
throw new UploadResponseError(
|
|
94
|
+
response.status,
|
|
74
95
|
`[ObserverKit] Source map upload failed: ${response.status} ${text}`
|
|
75
96
|
);
|
|
76
97
|
}
|
|
77
98
|
}
|
|
99
|
+
async function uploadBatchWithRetry(batch, options) {
|
|
100
|
+
for (let attempt = 0; ; attempt++) {
|
|
101
|
+
try {
|
|
102
|
+
await uploadBatch(batch, options);
|
|
103
|
+
return;
|
|
104
|
+
} catch (err) {
|
|
105
|
+
const wait = RETRY_DELAYS_MS[attempt];
|
|
106
|
+
if (wait === void 0 || !isTransient(err)) throw err;
|
|
107
|
+
const reason = err instanceof UploadResponseError ? `(${err.status})` : "(network error)";
|
|
108
|
+
console.warn(
|
|
109
|
+
`[ObserverKit] Upload failed ${reason}, retrying in ${wait / 1e3}s (attempt ${attempt + 2}/${RETRY_DELAYS_MS.length + 1})`
|
|
110
|
+
);
|
|
111
|
+
await options.delay(wait);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
78
115
|
var JS_SOURCE_MAPPING_URL = /^\/\/[#@] sourceMappingURL=\S+[ \t]*$/gm;
|
|
79
116
|
var CSS_SOURCE_MAPPING_URL = /^\/\*# sourceMappingURL=\S+[ \t]*\*\/[ \t]*$/gm;
|
|
80
117
|
function isChunkFile(name) {
|
|
@@ -105,10 +142,28 @@ async function uploadSourceMaps(options) {
|
|
|
105
142
|
const { projectKey, directory, endpoint, deleteAfterUpload, pluginVersion, pluginName } = options;
|
|
106
143
|
const maxFileBytes = _nullishCoalesce(options.maxFileBytes, () => ( DEFAULT_MAX_FILE_BYTES));
|
|
107
144
|
const maxBatchBytes = _nullishCoalesce(options.maxBatchBytes, () => ( DEFAULT_MAX_BATCH_BYTES));
|
|
108
|
-
const
|
|
145
|
+
const delay = _nullishCoalesce(options.delay, () => ( sleep));
|
|
146
|
+
let allFiles;
|
|
147
|
+
if (options.files) {
|
|
148
|
+
allFiles = [...options.files];
|
|
149
|
+
} else {
|
|
150
|
+
try {
|
|
151
|
+
allFiles = await _promises.readdir.call(void 0, directory, { recursive: true, encoding: "utf-8" });
|
|
152
|
+
} catch (err) {
|
|
153
|
+
if (isDirectoryMissing(err)) {
|
|
154
|
+
console.error(
|
|
155
|
+
`[ObserverKit] Output directory not found: ${directory}. No source maps were uploaded. Check that this is where your build writes its output.`
|
|
156
|
+
);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
throw err;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
109
162
|
const allMapFiles = allFiles.filter((f) => f.endsWith(".map"));
|
|
110
163
|
if (allMapFiles.length === 0) {
|
|
111
|
-
console.
|
|
164
|
+
console.warn(
|
|
165
|
+
`[ObserverKit] No .map files found in ${directory}, skipping source map upload. Source map emission is enabled by this plugin, so an empty scan usually means the build wrote its output elsewhere.`
|
|
166
|
+
);
|
|
112
167
|
return;
|
|
113
168
|
}
|
|
114
169
|
try {
|
|
@@ -125,7 +180,7 @@ async function uploadSourceMaps(options) {
|
|
|
125
180
|
continue;
|
|
126
181
|
}
|
|
127
182
|
if (!hasDebugId(content)) {
|
|
128
|
-
skippedNoDebugId += 1;
|
|
183
|
+
if (!isCssMap(mapFile)) skippedNoDebugId += 1;
|
|
129
184
|
continue;
|
|
130
185
|
}
|
|
131
186
|
if (content.byteLength > maxFileBytes) {
|
|
@@ -158,11 +213,23 @@ async function uploadSourceMaps(options) {
|
|
|
158
213
|
const url = `${endpoint.replace(/\/+$/, "")}/v1/sourcemaps`;
|
|
159
214
|
const batches = batchBySize(uploadable, maxBatchBytes);
|
|
160
215
|
for (const [index, batch] of batches.entries()) {
|
|
161
|
-
await
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
216
|
+
await uploadBatchWithRetry(batch, {
|
|
217
|
+
directory,
|
|
218
|
+
url,
|
|
219
|
+
projectKey,
|
|
220
|
+
pluginVersion,
|
|
221
|
+
pluginName,
|
|
222
|
+
delay
|
|
223
|
+
});
|
|
224
|
+
if (batches.length > 1) {
|
|
225
|
+
console.log(
|
|
226
|
+
`[ObserverKit] Uploaded batch ${index + 1}/${batches.length} (${batch.length} source maps)`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
165
229
|
}
|
|
230
|
+
console.log(
|
|
231
|
+
`[ObserverKit] Uploaded ${uploadable.length} source map(s) from ${directory}`
|
|
232
|
+
);
|
|
166
233
|
} catch (err) {
|
|
167
234
|
if (deleteAfterUpload) {
|
|
168
235
|
console.warn(
|
|
@@ -178,6 +245,44 @@ async function uploadSourceMaps(options) {
|
|
|
178
245
|
}
|
|
179
246
|
}
|
|
180
247
|
|
|
248
|
+
// ../plugin-core/src/upload-mapping.ts
|
|
249
|
+
|
|
250
|
+
var DEFAULT_MAX_MAPPING_BYTES = 50 * 1024 * 1024;
|
|
251
|
+
async function uploadProguardMapping(options) {
|
|
252
|
+
const maxFileBytes = _nullishCoalesce(options.maxFileBytes, () => ( DEFAULT_MAX_MAPPING_BYTES));
|
|
253
|
+
const content = await _promises.readFile.call(void 0, options.mappingPath);
|
|
254
|
+
if (content.byteLength > maxFileBytes) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
`[ObserverKit] Mapping file exceeds the per-file ingest limit (${maxFileBytes} bytes)`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
const formData = new FormData();
|
|
260
|
+
formData.append("versionName", options.versionName);
|
|
261
|
+
formData.append("versionCode", options.versionCode);
|
|
262
|
+
formData.append(
|
|
263
|
+
"file",
|
|
264
|
+
new Blob([new Uint8Array(content)], { type: "text/plain" }),
|
|
265
|
+
"mapping.txt"
|
|
266
|
+
);
|
|
267
|
+
const url = `${options.endpoint.replace(/\/+$/, "")}/v1/mappings`;
|
|
268
|
+
const response = await fetch(url, {
|
|
269
|
+
method: "POST",
|
|
270
|
+
headers: {
|
|
271
|
+
"X-ObserverKit-Key": options.projectKey,
|
|
272
|
+
"X-ObserverKit-Plugin-Version": options.pluginVersion,
|
|
273
|
+
"X-ObserverKit-Plugin-Name": options.pluginName
|
|
274
|
+
},
|
|
275
|
+
body: formData
|
|
276
|
+
});
|
|
277
|
+
if (!response.ok) {
|
|
278
|
+
const text = await response.text();
|
|
279
|
+
throw new Error(`[ObserverKit] Mapping upload failed: ${response.status} ${text}`);
|
|
280
|
+
}
|
|
281
|
+
console.log(
|
|
282
|
+
`[ObserverKit] Uploaded R8 mapping for version ${options.versionName} (${options.versionCode})`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
181
286
|
// ../plugin-core/src/debug-id.ts
|
|
182
287
|
var _uuid = require('uuid');
|
|
183
288
|
var OBSERVERKIT_NAMESPACE = "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d";
|
|
@@ -196,4 +301,5 @@ function buildStackKeyedDebugIdSnippet(debugId) {
|
|
|
196
301
|
|
|
197
302
|
|
|
198
303
|
|
|
199
|
-
|
|
304
|
+
|
|
305
|
+
exports.generateDebugId = generateDebugId; exports.isJsonObject = isJsonObject; exports.buildStackKeyedDebugIdSnippet = buildStackKeyedDebugIdSnippet; exports.uploadSourceMaps = uploadSourceMaps; exports.uploadProguardMapping = uploadProguardMapping;
|
package/dist/cli.cjs
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
"use strict"; function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
var _chunkDFKRMIQJcjs = require('./chunk-DFKRMIQJ.cjs');
|
|
6
7
|
require('./chunk-AUOVSTQX.cjs');
|
|
7
8
|
|
|
8
9
|
// src/cli.ts
|
|
@@ -31,7 +32,7 @@ async function readDebugIdFromMap(path) {
|
|
|
31
32
|
} catch (e2) {
|
|
32
33
|
return null;
|
|
33
34
|
}
|
|
34
|
-
if (!
|
|
35
|
+
if (!_chunkDFKRMIQJcjs.isJsonObject.call(void 0, parsed)) return null;
|
|
35
36
|
return typeof parsed["debugId"] === "string" ? parsed["debugId"] : null;
|
|
36
37
|
}
|
|
37
38
|
async function readDebugIdFromBundle(path) {
|
|
@@ -52,7 +53,7 @@ async function repairDebugId(mapPath, packagerMapPath, bundlePath) {
|
|
|
52
53
|
} catch (e4) {
|
|
53
54
|
throw new Error(`[ObserverKit] ${mapPath} is not valid JSON`);
|
|
54
55
|
}
|
|
55
|
-
if (!
|
|
56
|
+
if (!_chunkDFKRMIQJcjs.isJsonObject.call(void 0, parsed)) {
|
|
56
57
|
throw new Error(`[ObserverKit] ${mapPath} is not a source map object`);
|
|
57
58
|
}
|
|
58
59
|
if (typeof parsed["debugId"] === "string") return;
|
|
@@ -71,10 +72,11 @@ async function repairDebugId(mapPath, packagerMapPath, bundlePath) {
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
// src/cli.ts
|
|
74
|
-
var PLUGIN_VERSION = "0.2.
|
|
75
|
+
var PLUGIN_VERSION = "0.2.1";
|
|
75
76
|
var USAGE = `Usage:
|
|
76
77
|
observerkit-upload --map <path> [--packager-map <path>] [--bundle <path>]
|
|
77
78
|
observerkit-upload --dir <path>
|
|
79
|
+
observerkit-upload --mapping <path> --version-name <name> --version-code <code>
|
|
78
80
|
|
|
79
81
|
Options:
|
|
80
82
|
--map <path> Final source map to upload (repairs debugId first)
|
|
@@ -84,6 +86,11 @@ Options:
|
|
|
84
86
|
packager map is available (Hermes iOS builds)
|
|
85
87
|
--dir <path> Upload every debug-id source map in a directory
|
|
86
88
|
(e.g. an expo export output)
|
|
89
|
+
--mapping <path> R8/ProGuard mapping.txt to upload, keyed by
|
|
90
|
+
--version-name and --version-code
|
|
91
|
+
--version-name <name> App versionName, required with --mapping
|
|
92
|
+
--version-code <code> App versionCode (digits only), required with
|
|
93
|
+
--mapping
|
|
87
94
|
--project-key <key> Defaults to $OBSERVERKIT_PROJECT_KEY
|
|
88
95
|
--endpoint <url> Defaults to $OBSERVERKIT_ENDPOINT or
|
|
89
96
|
https://ingest.observerkit.com`;
|
|
@@ -94,6 +101,9 @@ async function main() {
|
|
|
94
101
|
"packager-map": { type: "string" },
|
|
95
102
|
bundle: { type: "string" },
|
|
96
103
|
dir: { type: "string" },
|
|
104
|
+
mapping: { type: "string" },
|
|
105
|
+
"version-name": { type: "string" },
|
|
106
|
+
"version-code": { type: "string" },
|
|
97
107
|
"project-key": { type: "string" },
|
|
98
108
|
endpoint: { type: "string" }
|
|
99
109
|
}
|
|
@@ -106,7 +116,7 @@ async function main() {
|
|
|
106
116
|
process.exit(1);
|
|
107
117
|
}
|
|
108
118
|
const endpoint = _nullishCoalesce(_nullishCoalesce(values.endpoint, () => ( process.env["OBSERVERKIT_ENDPOINT"])), () => ( "https://ingest.observerkit.com"));
|
|
109
|
-
if (!values.map && !values.dir) {
|
|
119
|
+
if (!values.map && !values.dir && !values.mapping) {
|
|
110
120
|
console.error(USAGE);
|
|
111
121
|
process.exit(1);
|
|
112
122
|
}
|
|
@@ -115,6 +125,34 @@ async function main() {
|
|
|
115
125
|
"[ObserverKit] --packager-map and --bundle are ignored when --dir is set"
|
|
116
126
|
);
|
|
117
127
|
}
|
|
128
|
+
if (values.mapping) {
|
|
129
|
+
if (values.map || values.dir) {
|
|
130
|
+
console.error("[ObserverKit] --mapping cannot be combined with --map or --dir");
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
const versionName = values["version-name"];
|
|
134
|
+
const versionCode = values["version-code"];
|
|
135
|
+
if (!versionName || !versionCode) {
|
|
136
|
+
console.error("[ObserverKit] --mapping requires --version-name and --version-code");
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
if (!/^\d+$/.test(versionCode)) {
|
|
140
|
+
console.error(
|
|
141
|
+
`[ObserverKit] --version-code must be a string of digits, got "${versionCode}"`
|
|
142
|
+
);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
await _chunkDFKRMIQJcjs.uploadProguardMapping.call(void 0, {
|
|
146
|
+
projectKey,
|
|
147
|
+
endpoint,
|
|
148
|
+
mappingPath: _path.resolve.call(void 0, values.mapping),
|
|
149
|
+
versionName,
|
|
150
|
+
versionCode,
|
|
151
|
+
pluginVersion: PLUGIN_VERSION,
|
|
152
|
+
pluginName: "metro"
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
118
156
|
if (values.map) {
|
|
119
157
|
if (!values.map.endsWith(".map")) {
|
|
120
158
|
console.error(`[ObserverKit] --map must point at a .map file, got "${values.map}"`);
|
|
@@ -128,7 +166,7 @@ async function main() {
|
|
|
128
166
|
packagerMap ? _path.resolve.call(void 0, packagerMap) : void 0,
|
|
129
167
|
bundle ? _path.resolve.call(void 0, bundle) : void 0
|
|
130
168
|
);
|
|
131
|
-
await
|
|
169
|
+
await _chunkDFKRMIQJcjs.uploadSourceMaps.call(void 0, {
|
|
132
170
|
projectKey,
|
|
133
171
|
directory: _path.dirname.call(void 0, mapPath),
|
|
134
172
|
endpoint,
|
|
@@ -140,7 +178,7 @@ async function main() {
|
|
|
140
178
|
return;
|
|
141
179
|
}
|
|
142
180
|
if (values.dir) {
|
|
143
|
-
await
|
|
181
|
+
await _chunkDFKRMIQJcjs.uploadSourceMaps.call(void 0, {
|
|
144
182
|
projectKey,
|
|
145
183
|
directory: _path.resolve.call(void 0, values.dir),
|
|
146
184
|
endpoint,
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
isJsonObject,
|
|
4
|
+
uploadProguardMapping,
|
|
4
5
|
uploadSourceMaps
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3IIVAXY2.js";
|
|
6
7
|
|
|
7
8
|
// src/cli.ts
|
|
8
9
|
import { parseArgs } from "util";
|
|
@@ -70,10 +71,11 @@ async function repairDebugId(mapPath, packagerMapPath, bundlePath) {
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
// src/cli.ts
|
|
73
|
-
var PLUGIN_VERSION = "0.2.
|
|
74
|
+
var PLUGIN_VERSION = "0.2.1";
|
|
74
75
|
var USAGE = `Usage:
|
|
75
76
|
observerkit-upload --map <path> [--packager-map <path>] [--bundle <path>]
|
|
76
77
|
observerkit-upload --dir <path>
|
|
78
|
+
observerkit-upload --mapping <path> --version-name <name> --version-code <code>
|
|
77
79
|
|
|
78
80
|
Options:
|
|
79
81
|
--map <path> Final source map to upload (repairs debugId first)
|
|
@@ -83,6 +85,11 @@ Options:
|
|
|
83
85
|
packager map is available (Hermes iOS builds)
|
|
84
86
|
--dir <path> Upload every debug-id source map in a directory
|
|
85
87
|
(e.g. an expo export output)
|
|
88
|
+
--mapping <path> R8/ProGuard mapping.txt to upload, keyed by
|
|
89
|
+
--version-name and --version-code
|
|
90
|
+
--version-name <name> App versionName, required with --mapping
|
|
91
|
+
--version-code <code> App versionCode (digits only), required with
|
|
92
|
+
--mapping
|
|
86
93
|
--project-key <key> Defaults to $OBSERVERKIT_PROJECT_KEY
|
|
87
94
|
--endpoint <url> Defaults to $OBSERVERKIT_ENDPOINT or
|
|
88
95
|
https://ingest.observerkit.com`;
|
|
@@ -93,6 +100,9 @@ async function main() {
|
|
|
93
100
|
"packager-map": { type: "string" },
|
|
94
101
|
bundle: { type: "string" },
|
|
95
102
|
dir: { type: "string" },
|
|
103
|
+
mapping: { type: "string" },
|
|
104
|
+
"version-name": { type: "string" },
|
|
105
|
+
"version-code": { type: "string" },
|
|
96
106
|
"project-key": { type: "string" },
|
|
97
107
|
endpoint: { type: "string" }
|
|
98
108
|
}
|
|
@@ -105,7 +115,7 @@ async function main() {
|
|
|
105
115
|
process.exit(1);
|
|
106
116
|
}
|
|
107
117
|
const endpoint = values.endpoint ?? process.env["OBSERVERKIT_ENDPOINT"] ?? "https://ingest.observerkit.com";
|
|
108
|
-
if (!values.map && !values.dir) {
|
|
118
|
+
if (!values.map && !values.dir && !values.mapping) {
|
|
109
119
|
console.error(USAGE);
|
|
110
120
|
process.exit(1);
|
|
111
121
|
}
|
|
@@ -114,6 +124,34 @@ async function main() {
|
|
|
114
124
|
"[ObserverKit] --packager-map and --bundle are ignored when --dir is set"
|
|
115
125
|
);
|
|
116
126
|
}
|
|
127
|
+
if (values.mapping) {
|
|
128
|
+
if (values.map || values.dir) {
|
|
129
|
+
console.error("[ObserverKit] --mapping cannot be combined with --map or --dir");
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
const versionName = values["version-name"];
|
|
133
|
+
const versionCode = values["version-code"];
|
|
134
|
+
if (!versionName || !versionCode) {
|
|
135
|
+
console.error("[ObserverKit] --mapping requires --version-name and --version-code");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
if (!/^\d+$/.test(versionCode)) {
|
|
139
|
+
console.error(
|
|
140
|
+
`[ObserverKit] --version-code must be a string of digits, got "${versionCode}"`
|
|
141
|
+
);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
await uploadProguardMapping({
|
|
145
|
+
projectKey,
|
|
146
|
+
endpoint,
|
|
147
|
+
mappingPath: resolve(values.mapping),
|
|
148
|
+
versionName,
|
|
149
|
+
versionCode,
|
|
150
|
+
pluginVersion: PLUGIN_VERSION,
|
|
151
|
+
pluginName: "metro"
|
|
152
|
+
});
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
117
155
|
if (values.map) {
|
|
118
156
|
if (!values.map.endsWith(".map")) {
|
|
119
157
|
console.error(`[ObserverKit] --map must point at a .map file, got "${values.map}"`);
|
package/dist/expo.cjs
CHANGED
|
@@ -5,6 +5,9 @@ var _configplugins = require('@expo/config-plugins');
|
|
|
5
5
|
|
|
6
6
|
// src/native-scripts.ts
|
|
7
7
|
var UPLOAD_MARKER = "observerkit-upload";
|
|
8
|
+
var MAPPING_UPLOAD_MARKER = "observerkit-mapping-upload";
|
|
9
|
+
var UPLOAD_MARKER_COMMENT = `// ${UPLOAD_MARKER} (added`;
|
|
10
|
+
var MAPPING_UPLOAD_MARKER_COMMENT = `// ${MAPPING_UPLOAD_MARKER} (added`;
|
|
8
11
|
function escapeForDoubleQuoted(value) {
|
|
9
12
|
return value.replace(/[\\"]/g, "\\$&");
|
|
10
13
|
}
|
|
@@ -25,11 +28,14 @@ function patchIosShellScript(script, props) {
|
|
|
25
28
|
const patched = `${exportLine}${inner}${uploadBlock}`;
|
|
26
29
|
return hasQuotes ? `"${patched}"` : patched;
|
|
27
30
|
}
|
|
28
|
-
function
|
|
31
|
+
function gradleEnvLines(props) {
|
|
29
32
|
const envLine = props.projectKey ? `
|
|
30
33
|
environment "OBSERVERKIT_PROJECT_KEY", "${escapeForDoubleQuoted(props.projectKey)}"` : "";
|
|
31
34
|
const endpointLine = props.endpoint ? `
|
|
32
35
|
environment "OBSERVERKIT_ENDPOINT", "${escapeForDoubleQuoted(props.endpoint)}"` : "";
|
|
36
|
+
return `${envLine}${endpointLine}`;
|
|
37
|
+
}
|
|
38
|
+
function buildGradleSnippet(props) {
|
|
33
39
|
return `
|
|
34
40
|
// ${UPLOAD_MARKER} (added by @observerkit/metro/expo; do not edit)
|
|
35
41
|
tasks.configureEach { task ->
|
|
@@ -44,7 +50,7 @@ tasks.configureEach { task ->
|
|
|
44
50
|
def packagerMapFile = file("$buildDir/intermediates/sourcemaps/react/" + variant + "/index.android.bundle.packager.map")
|
|
45
51
|
if (mapFile.exists()) {
|
|
46
52
|
def result = exec {
|
|
47
|
-
workingDir rootProject.projectDir.parentFile${
|
|
53
|
+
workingDir rootProject.projectDir.parentFile${gradleEnvLines(props)}
|
|
48
54
|
commandLine "npx", "observerkit-upload", "--map", mapFile.absolutePath, "--packager-map", packagerMapFile.absolutePath
|
|
49
55
|
ignoreExitValue true
|
|
50
56
|
}
|
|
@@ -59,6 +65,38 @@ tasks.configureEach { task ->
|
|
|
59
65
|
}
|
|
60
66
|
`;
|
|
61
67
|
}
|
|
68
|
+
function mappingGradleSnippet(props) {
|
|
69
|
+
return `
|
|
70
|
+
// ${MAPPING_UPLOAD_MARKER} (added by @observerkit/metro/expo; do not edit)
|
|
71
|
+
tasks.configureEach { task ->
|
|
72
|
+
def matcher = task.name =~ /^minify(\\w*)ReleaseWithR8$/
|
|
73
|
+
if (matcher.matches()) {
|
|
74
|
+
task.doLast {
|
|
75
|
+
def flavor = matcher.group(1)
|
|
76
|
+
def variant = flavor.isEmpty()
|
|
77
|
+
? "release"
|
|
78
|
+
: flavor.substring(0, 1).toLowerCase() + flavor.substring(1) + "Release"
|
|
79
|
+
def mappingFile = file("$buildDir/outputs/mapping/" + variant + "/mapping.txt")
|
|
80
|
+
def androidExt = project.extensions.getByName("android")
|
|
81
|
+
def versionName = androidExt.defaultConfig.versionName
|
|
82
|
+
def versionCode = androidExt.defaultConfig.versionCode
|
|
83
|
+
if (mappingFile.exists() && versionName != null && versionCode != null) {
|
|
84
|
+
def result = exec {
|
|
85
|
+
workingDir rootProject.projectDir.parentFile${gradleEnvLines(props)}
|
|
86
|
+
commandLine "npx", "observerkit-upload", "--mapping", mappingFile.absolutePath, "--version-name", versionName.toString(), "--version-code", versionCode.toString()
|
|
87
|
+
ignoreExitValue true
|
|
88
|
+
}
|
|
89
|
+
if (result.exitValue != 0) {
|
|
90
|
+
logger.warn("[ObserverKit] R8 mapping upload failed")
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
logger.warn("[ObserverKit] No R8 mapping found at " + mappingFile + ", skipping upload")
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
62
100
|
|
|
63
101
|
// src/expo.ts
|
|
64
102
|
var BUNDLE_PHASE_NAME = "Bundle React Native code and images";
|
|
@@ -75,9 +113,12 @@ var withObserverkitIos = (config, props) => _configplugins.withXcodeProject.call
|
|
|
75
113
|
return c;
|
|
76
114
|
});
|
|
77
115
|
var withObserverkitAndroid = (config, props) => _configplugins.withAppBuildGradle.call(void 0, config, (c) => {
|
|
78
|
-
if (!c.modResults.contents.includes(
|
|
116
|
+
if (!c.modResults.contents.includes(UPLOAD_MARKER_COMMENT)) {
|
|
79
117
|
c.modResults.contents = c.modResults.contents + buildGradleSnippet(props);
|
|
80
118
|
}
|
|
119
|
+
if (!c.modResults.contents.includes(MAPPING_UPLOAD_MARKER_COMMENT)) {
|
|
120
|
+
c.modResults.contents = c.modResults.contents + mappingGradleSnippet(props);
|
|
121
|
+
}
|
|
81
122
|
return c;
|
|
82
123
|
});
|
|
83
124
|
var withObserverkitExpo = (config, props) => {
|
package/dist/expo.js
CHANGED
|
@@ -3,6 +3,9 @@ import { withAppBuildGradle, withXcodeProject } from "@expo/config-plugins";
|
|
|
3
3
|
|
|
4
4
|
// src/native-scripts.ts
|
|
5
5
|
var UPLOAD_MARKER = "observerkit-upload";
|
|
6
|
+
var MAPPING_UPLOAD_MARKER = "observerkit-mapping-upload";
|
|
7
|
+
var UPLOAD_MARKER_COMMENT = `// ${UPLOAD_MARKER} (added`;
|
|
8
|
+
var MAPPING_UPLOAD_MARKER_COMMENT = `// ${MAPPING_UPLOAD_MARKER} (added`;
|
|
6
9
|
function escapeForDoubleQuoted(value) {
|
|
7
10
|
return value.replace(/[\\"]/g, "\\$&");
|
|
8
11
|
}
|
|
@@ -23,11 +26,14 @@ function patchIosShellScript(script, props) {
|
|
|
23
26
|
const patched = `${exportLine}${inner}${uploadBlock}`;
|
|
24
27
|
return hasQuotes ? `"${patched}"` : patched;
|
|
25
28
|
}
|
|
26
|
-
function
|
|
29
|
+
function gradleEnvLines(props) {
|
|
27
30
|
const envLine = props.projectKey ? `
|
|
28
31
|
environment "OBSERVERKIT_PROJECT_KEY", "${escapeForDoubleQuoted(props.projectKey)}"` : "";
|
|
29
32
|
const endpointLine = props.endpoint ? `
|
|
30
33
|
environment "OBSERVERKIT_ENDPOINT", "${escapeForDoubleQuoted(props.endpoint)}"` : "";
|
|
34
|
+
return `${envLine}${endpointLine}`;
|
|
35
|
+
}
|
|
36
|
+
function buildGradleSnippet(props) {
|
|
31
37
|
return `
|
|
32
38
|
// ${UPLOAD_MARKER} (added by @observerkit/metro/expo; do not edit)
|
|
33
39
|
tasks.configureEach { task ->
|
|
@@ -42,7 +48,7 @@ tasks.configureEach { task ->
|
|
|
42
48
|
def packagerMapFile = file("$buildDir/intermediates/sourcemaps/react/" + variant + "/index.android.bundle.packager.map")
|
|
43
49
|
if (mapFile.exists()) {
|
|
44
50
|
def result = exec {
|
|
45
|
-
workingDir rootProject.projectDir.parentFile${
|
|
51
|
+
workingDir rootProject.projectDir.parentFile${gradleEnvLines(props)}
|
|
46
52
|
commandLine "npx", "observerkit-upload", "--map", mapFile.absolutePath, "--packager-map", packagerMapFile.absolutePath
|
|
47
53
|
ignoreExitValue true
|
|
48
54
|
}
|
|
@@ -57,6 +63,38 @@ tasks.configureEach { task ->
|
|
|
57
63
|
}
|
|
58
64
|
`;
|
|
59
65
|
}
|
|
66
|
+
function mappingGradleSnippet(props) {
|
|
67
|
+
return `
|
|
68
|
+
// ${MAPPING_UPLOAD_MARKER} (added by @observerkit/metro/expo; do not edit)
|
|
69
|
+
tasks.configureEach { task ->
|
|
70
|
+
def matcher = task.name =~ /^minify(\\w*)ReleaseWithR8$/
|
|
71
|
+
if (matcher.matches()) {
|
|
72
|
+
task.doLast {
|
|
73
|
+
def flavor = matcher.group(1)
|
|
74
|
+
def variant = flavor.isEmpty()
|
|
75
|
+
? "release"
|
|
76
|
+
: flavor.substring(0, 1).toLowerCase() + flavor.substring(1) + "Release"
|
|
77
|
+
def mappingFile = file("$buildDir/outputs/mapping/" + variant + "/mapping.txt")
|
|
78
|
+
def androidExt = project.extensions.getByName("android")
|
|
79
|
+
def versionName = androidExt.defaultConfig.versionName
|
|
80
|
+
def versionCode = androidExt.defaultConfig.versionCode
|
|
81
|
+
if (mappingFile.exists() && versionName != null && versionCode != null) {
|
|
82
|
+
def result = exec {
|
|
83
|
+
workingDir rootProject.projectDir.parentFile${gradleEnvLines(props)}
|
|
84
|
+
commandLine "npx", "observerkit-upload", "--mapping", mappingFile.absolutePath, "--version-name", versionName.toString(), "--version-code", versionCode.toString()
|
|
85
|
+
ignoreExitValue true
|
|
86
|
+
}
|
|
87
|
+
if (result.exitValue != 0) {
|
|
88
|
+
logger.warn("[ObserverKit] R8 mapping upload failed")
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
logger.warn("[ObserverKit] No R8 mapping found at " + mappingFile + ", skipping upload")
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
60
98
|
|
|
61
99
|
// src/expo.ts
|
|
62
100
|
var BUNDLE_PHASE_NAME = "Bundle React Native code and images";
|
|
@@ -73,9 +111,12 @@ var withObserverkitIos = (config, props) => withXcodeProject(config, (c) => {
|
|
|
73
111
|
return c;
|
|
74
112
|
});
|
|
75
113
|
var withObserverkitAndroid = (config, props) => withAppBuildGradle(config, (c) => {
|
|
76
|
-
if (!c.modResults.contents.includes(
|
|
114
|
+
if (!c.modResults.contents.includes(UPLOAD_MARKER_COMMENT)) {
|
|
77
115
|
c.modResults.contents = c.modResults.contents + buildGradleSnippet(props);
|
|
78
116
|
}
|
|
117
|
+
if (!c.modResults.contents.includes(MAPPING_UPLOAD_MARKER_COMMENT)) {
|
|
118
|
+
c.modResults.contents = c.modResults.contents + mappingGradleSnippet(props);
|
|
119
|
+
}
|
|
79
120
|
return c;
|
|
80
121
|
});
|
|
81
122
|
var withObserverkitExpo = (config, props) => {
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkDFKRMIQJcjs = require('./chunk-DFKRMIQJ.cjs');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
var _chunkAUOVSTQXcjs = require('./chunk-AUOVSTQX.cjs');
|
|
@@ -42,15 +42,15 @@ function addDebugIdToMap(map, debugId) {
|
|
|
42
42
|
} catch (e) {
|
|
43
43
|
return map;
|
|
44
44
|
}
|
|
45
|
-
if (!
|
|
45
|
+
if (!_chunkDFKRMIQJcjs.isJsonObject.call(void 0, parsed)) return map;
|
|
46
46
|
return JSON.stringify({ ...parsed, debugId });
|
|
47
47
|
}
|
|
48
48
|
function unwrapModuleExport(mod, exportName) {
|
|
49
49
|
if (exportName) {
|
|
50
|
-
const named =
|
|
50
|
+
const named = _chunkDFKRMIQJcjs.isJsonObject.call(void 0, mod) ? mod[exportName] : void 0;
|
|
51
51
|
if (typeof named === "function") return named;
|
|
52
52
|
}
|
|
53
|
-
const defaultExport =
|
|
53
|
+
const defaultExport = _chunkDFKRMIQJcjs.isJsonObject.call(void 0, mod) ? mod["default"] : void 0;
|
|
54
54
|
if (typeof defaultExport === "function") return defaultExport;
|
|
55
55
|
if (typeof mod === "function") return mod;
|
|
56
56
|
throw new Error(
|
|
@@ -103,12 +103,12 @@ function createObserverkitSerializer(wrapped) {
|
|
|
103
103
|
if (options.dev) {
|
|
104
104
|
return serializer(entryPoint, preModules, graph, options);
|
|
105
105
|
}
|
|
106
|
-
const { snippet } =
|
|
106
|
+
const { snippet } = _chunkDFKRMIQJcjs.buildStackKeyedDebugIdSnippet.call(void 0, DEBUG_ID_PLACEHOLDER);
|
|
107
107
|
const withDebugId = injectDebugIdModule(preModules, createDebugIdModule(snippet));
|
|
108
108
|
const result = await serializer(entryPoint, withDebugId, graph, options);
|
|
109
109
|
const code = typeof result === "string" ? result : result.code;
|
|
110
110
|
const map = typeof result === "string" ? null : result.map;
|
|
111
|
-
const debugId =
|
|
111
|
+
const debugId = _chunkDFKRMIQJcjs.generateDebugId.call(void 0, code);
|
|
112
112
|
const finalCode = `${code.split(DEBUG_ID_PLACEHOLDER).join(debugId)}
|
|
113
113
|
//# debugId=${debugId}`;
|
|
114
114
|
if (map === null) return finalCode;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@observerkit/metro",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Metro plugin for ObserverKit: injects debug IDs and uploads React Native source maps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"tsup": "^8.3.5",
|
|
46
46
|
"typescript": "5.9.2",
|
|
47
47
|
"vitest": "^3.2.4",
|
|
48
|
-
"@repo/plugin-core": "0.0.
|
|
48
|
+
"@repo/plugin-core": "0.0.1"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"uuid": "^13.0.0"
|