@observerkit/metro 0.2.0
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 +118 -0
- package/dist/chunk-6RJOM2CO.cjs +199 -0
- package/dist/chunk-AUOVSTQX.cjs +7 -0
- package/dist/chunk-DFCKYXBG.js +199 -0
- package/dist/cli.cjs +156 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +155 -0
- package/dist/expo.cjs +92 -0
- package/dist/expo.d.cts +24 -0
- package/dist/expo.d.ts +22 -0
- package/dist/expo.js +88 -0
- package/dist/index.cjs +135 -0
- package/dist/index.d.cts +65 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +132 -0
- package/package.json +59 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
isJsonObject,
|
|
4
|
+
uploadSourceMaps
|
|
5
|
+
} from "./chunk-DFCKYXBG.js";
|
|
6
|
+
|
|
7
|
+
// src/cli.ts
|
|
8
|
+
import { parseArgs } from "util";
|
|
9
|
+
import { basename, dirname, resolve } from "path";
|
|
10
|
+
|
|
11
|
+
// src/repair.ts
|
|
12
|
+
import { readFile, writeFile } from "fs/promises";
|
|
13
|
+
var DEBUG_ID_COMMENT_PATTERN = /\/\/# debugId=([0-9a-f-]{36})/;
|
|
14
|
+
function defaultPackagerMapPath(mapPath) {
|
|
15
|
+
return mapPath.endsWith(".map") ? `${mapPath.slice(0, -".map".length)}.packager.map` : `${mapPath}.packager.map`;
|
|
16
|
+
}
|
|
17
|
+
function defaultBundlePath(mapPath) {
|
|
18
|
+
return mapPath.endsWith(".map") ? mapPath.slice(0, -".map".length) : mapPath;
|
|
19
|
+
}
|
|
20
|
+
async function readDebugIdFromMap(path) {
|
|
21
|
+
let content;
|
|
22
|
+
try {
|
|
23
|
+
content = await readFile(path, "utf-8");
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
let parsed;
|
|
28
|
+
try {
|
|
29
|
+
parsed = JSON.parse(content);
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
if (!isJsonObject(parsed)) return null;
|
|
34
|
+
return typeof parsed["debugId"] === "string" ? parsed["debugId"] : null;
|
|
35
|
+
}
|
|
36
|
+
async function readDebugIdFromBundle(path) {
|
|
37
|
+
let content;
|
|
38
|
+
try {
|
|
39
|
+
content = await readFile(path, "utf-8");
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const match = DEBUG_ID_COMMENT_PATTERN.exec(content);
|
|
44
|
+
return match?.[1] ?? null;
|
|
45
|
+
}
|
|
46
|
+
async function repairDebugId(mapPath, packagerMapPath, bundlePath) {
|
|
47
|
+
const content = await readFile(mapPath, "utf-8");
|
|
48
|
+
let parsed;
|
|
49
|
+
try {
|
|
50
|
+
parsed = JSON.parse(content);
|
|
51
|
+
} catch {
|
|
52
|
+
throw new Error(`[ObserverKit] ${mapPath} is not valid JSON`);
|
|
53
|
+
}
|
|
54
|
+
if (!isJsonObject(parsed)) {
|
|
55
|
+
throw new Error(`[ObserverKit] ${mapPath} is not a source map object`);
|
|
56
|
+
}
|
|
57
|
+
if (typeof parsed["debugId"] === "string") return;
|
|
58
|
+
const packagerCandidate = packagerMapPath ?? defaultPackagerMapPath(mapPath);
|
|
59
|
+
let debugId = await readDebugIdFromMap(packagerCandidate);
|
|
60
|
+
const bundleCandidate = bundlePath ?? defaultBundlePath(mapPath);
|
|
61
|
+
if (!debugId) {
|
|
62
|
+
debugId = await readDebugIdFromBundle(bundleCandidate);
|
|
63
|
+
}
|
|
64
|
+
if (!debugId) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`[ObserverKit] ${mapPath} has no debugId and none was found in ${packagerCandidate} or ${bundleCandidate}. Is withObserverkit applied in metro.config.js? For Hermes iOS builds, pass --bundle pointing at the pre-Hermes JS bundle (e.g. $CONFIGURATION_BUILD_DIR/main.jsbundle).`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
await writeFile(mapPath, JSON.stringify({ ...parsed, debugId }));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/cli.ts
|
|
73
|
+
var PLUGIN_VERSION = "0.2.0";
|
|
74
|
+
var USAGE = `Usage:
|
|
75
|
+
observerkit-upload --map <path> [--packager-map <path>] [--bundle <path>]
|
|
76
|
+
observerkit-upload --dir <path>
|
|
77
|
+
|
|
78
|
+
Options:
|
|
79
|
+
--map <path> Final source map to upload (repairs debugId first)
|
|
80
|
+
--packager-map <path> Pre-compose Metro map to copy the debugId from
|
|
81
|
+
--bundle <path> Pre-Hermes JS bundle to read a trailing
|
|
82
|
+
"//# debugId=<uuid>" comment from, used when no
|
|
83
|
+
packager map is available (Hermes iOS builds)
|
|
84
|
+
--dir <path> Upload every debug-id source map in a directory
|
|
85
|
+
(e.g. an expo export output)
|
|
86
|
+
--project-key <key> Defaults to $OBSERVERKIT_PROJECT_KEY
|
|
87
|
+
--endpoint <url> Defaults to $OBSERVERKIT_ENDPOINT or
|
|
88
|
+
https://ingest.observerkit.com`;
|
|
89
|
+
async function main() {
|
|
90
|
+
const { values } = parseArgs({
|
|
91
|
+
options: {
|
|
92
|
+
map: { type: "string" },
|
|
93
|
+
"packager-map": { type: "string" },
|
|
94
|
+
bundle: { type: "string" },
|
|
95
|
+
dir: { type: "string" },
|
|
96
|
+
"project-key": { type: "string" },
|
|
97
|
+
endpoint: { type: "string" }
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
const projectKey = values["project-key"] ?? process.env["OBSERVERKIT_PROJECT_KEY"];
|
|
101
|
+
if (!projectKey) {
|
|
102
|
+
console.error(
|
|
103
|
+
"[ObserverKit] Missing project key: pass --project-key or set OBSERVERKIT_PROJECT_KEY"
|
|
104
|
+
);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
const endpoint = values.endpoint ?? process.env["OBSERVERKIT_ENDPOINT"] ?? "https://ingest.observerkit.com";
|
|
108
|
+
if (!values.map && !values.dir) {
|
|
109
|
+
console.error(USAGE);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
if (values.dir && (values["packager-map"] || values.bundle)) {
|
|
113
|
+
console.error(
|
|
114
|
+
"[ObserverKit] --packager-map and --bundle are ignored when --dir is set"
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
if (values.map) {
|
|
118
|
+
if (!values.map.endsWith(".map")) {
|
|
119
|
+
console.error(`[ObserverKit] --map must point at a .map file, got "${values.map}"`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
const mapPath = resolve(values.map);
|
|
123
|
+
const packagerMap = values["packager-map"];
|
|
124
|
+
const bundle = values.bundle;
|
|
125
|
+
await repairDebugId(
|
|
126
|
+
mapPath,
|
|
127
|
+
packagerMap ? resolve(packagerMap) : void 0,
|
|
128
|
+
bundle ? resolve(bundle) : void 0
|
|
129
|
+
);
|
|
130
|
+
await uploadSourceMaps({
|
|
131
|
+
projectKey,
|
|
132
|
+
directory: dirname(mapPath),
|
|
133
|
+
endpoint,
|
|
134
|
+
deleteAfterUpload: false,
|
|
135
|
+
pluginVersion: PLUGIN_VERSION,
|
|
136
|
+
pluginName: "metro",
|
|
137
|
+
files: [basename(mapPath)]
|
|
138
|
+
});
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (values.dir) {
|
|
142
|
+
await uploadSourceMaps({
|
|
143
|
+
projectKey,
|
|
144
|
+
directory: resolve(values.dir),
|
|
145
|
+
endpoint,
|
|
146
|
+
deleteAfterUpload: false,
|
|
147
|
+
pluginVersion: PLUGIN_VERSION,
|
|
148
|
+
pluginName: "metro"
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
main().catch((err) => {
|
|
153
|
+
console.error(err instanceof Error ? err.message : err);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
});
|
package/dist/expo.cjs
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }require('./chunk-AUOVSTQX.cjs');
|
|
2
|
+
|
|
3
|
+
// src/expo.ts
|
|
4
|
+
var _configplugins = require('@expo/config-plugins');
|
|
5
|
+
|
|
6
|
+
// src/native-scripts.ts
|
|
7
|
+
var UPLOAD_MARKER = "observerkit-upload";
|
|
8
|
+
function escapeForDoubleQuoted(value) {
|
|
9
|
+
return value.replace(/[\\"]/g, "\\$&");
|
|
10
|
+
}
|
|
11
|
+
function escapeForPbxprojShell(value) {
|
|
12
|
+
return escapeForDoubleQuoted(escapeForDoubleQuoted(value));
|
|
13
|
+
}
|
|
14
|
+
function cliFlags(props) {
|
|
15
|
+
const key = props.projectKey ? ` --project-key \\"${escapeForPbxprojShell(props.projectKey)}\\"` : "";
|
|
16
|
+
const endpoint = props.endpoint ? ` --endpoint \\"${escapeForPbxprojShell(props.endpoint)}\\"` : "";
|
|
17
|
+
return `${key}${endpoint}`;
|
|
18
|
+
}
|
|
19
|
+
function patchIosShellScript(script, props) {
|
|
20
|
+
if (script.includes(UPLOAD_MARKER)) return script;
|
|
21
|
+
const hasQuotes = script.startsWith('"') && script.endsWith('"');
|
|
22
|
+
const inner = hasQuotes ? script.slice(1, -1) : script;
|
|
23
|
+
const exportLine = 'export SOURCEMAP_FILE=\\"$DERIVED_FILE_DIR/main.jsbundle.map\\"\\n';
|
|
24
|
+
const uploadBlock = `\\nif [ -f \\"$SOURCEMAP_FILE\\" ]; then\\n npx observerkit-upload --map \\"$SOURCEMAP_FILE\\" --bundle \\"$CONFIGURATION_BUILD_DIR/main.jsbundle\\"${cliFlags(props)} || echo \\"[ObserverKit] source map upload failed\\"\\nfi\\n`;
|
|
25
|
+
const patched = `${exportLine}${inner}${uploadBlock}`;
|
|
26
|
+
return hasQuotes ? `"${patched}"` : patched;
|
|
27
|
+
}
|
|
28
|
+
function buildGradleSnippet(props) {
|
|
29
|
+
const envLine = props.projectKey ? `
|
|
30
|
+
environment "OBSERVERKIT_PROJECT_KEY", "${escapeForDoubleQuoted(props.projectKey)}"` : "";
|
|
31
|
+
const endpointLine = props.endpoint ? `
|
|
32
|
+
environment "OBSERVERKIT_ENDPOINT", "${escapeForDoubleQuoted(props.endpoint)}"` : "";
|
|
33
|
+
return `
|
|
34
|
+
// ${UPLOAD_MARKER} (added by @observerkit/metro/expo; do not edit)
|
|
35
|
+
tasks.configureEach { task ->
|
|
36
|
+
def matcher = task.name =~ /^createBundle(\\w*)ReleaseJsAndAssets$/
|
|
37
|
+
if (matcher.matches()) {
|
|
38
|
+
task.doLast {
|
|
39
|
+
def flavor = matcher.group(1)
|
|
40
|
+
def variant = flavor.isEmpty()
|
|
41
|
+
? "release"
|
|
42
|
+
: flavor.substring(0, 1).toLowerCase() + flavor.substring(1) + "Release"
|
|
43
|
+
def mapFile = file("$buildDir/generated/sourcemaps/react/" + variant + "/index.android.bundle.map")
|
|
44
|
+
def packagerMapFile = file("$buildDir/intermediates/sourcemaps/react/" + variant + "/index.android.bundle.packager.map")
|
|
45
|
+
if (mapFile.exists()) {
|
|
46
|
+
def result = exec {
|
|
47
|
+
workingDir rootProject.projectDir.parentFile${envLine}${endpointLine}
|
|
48
|
+
commandLine "npx", "observerkit-upload", "--map", mapFile.absolutePath, "--packager-map", packagerMapFile.absolutePath
|
|
49
|
+
ignoreExitValue true
|
|
50
|
+
}
|
|
51
|
+
if (result.exitValue != 0) {
|
|
52
|
+
logger.warn("[ObserverKit] source map upload failed")
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
logger.warn("[ObserverKit] No source map found at " + mapFile + ", skipping upload")
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/expo.ts
|
|
64
|
+
var BUNDLE_PHASE_NAME = "Bundle React Native code and images";
|
|
65
|
+
var withObserverkitIos = (config, props) => _configplugins.withXcodeProject.call(void 0, config, (c) => {
|
|
66
|
+
const project = c.modResults;
|
|
67
|
+
const phases = _nullishCoalesce(project.hash.project.objects.PBXShellScriptBuildPhase, () => ( {}));
|
|
68
|
+
for (const key of Object.keys(phases)) {
|
|
69
|
+
const phase = phases[key];
|
|
70
|
+
if (!phase || typeof phase !== "object") continue;
|
|
71
|
+
if (typeof phase.shellScript !== "string") continue;
|
|
72
|
+
if (!String(_nullishCoalesce(phase.name, () => ( ""))).includes(BUNDLE_PHASE_NAME)) continue;
|
|
73
|
+
phase.shellScript = patchIosShellScript(phase.shellScript, props);
|
|
74
|
+
}
|
|
75
|
+
return c;
|
|
76
|
+
});
|
|
77
|
+
var withObserverkitAndroid = (config, props) => _configplugins.withAppBuildGradle.call(void 0, config, (c) => {
|
|
78
|
+
if (!c.modResults.contents.includes(UPLOAD_MARKER)) {
|
|
79
|
+
c.modResults.contents = c.modResults.contents + buildGradleSnippet(props);
|
|
80
|
+
}
|
|
81
|
+
return c;
|
|
82
|
+
});
|
|
83
|
+
var withObserverkitExpo = (config, props) => {
|
|
84
|
+
const resolved = _nullishCoalesce(props, () => ( {}));
|
|
85
|
+
return withObserverkitAndroid(withObserverkitIos(config, resolved), resolved);
|
|
86
|
+
};
|
|
87
|
+
var expo_default = withObserverkitExpo;
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
exports.default = expo_default;
|
|
91
|
+
|
|
92
|
+
module.exports = exports.default;
|
package/dist/expo.d.cts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
+
|
|
3
|
+
interface ObserverkitExpoProps {
|
|
4
|
+
/**
|
|
5
|
+
* ObserverKit project key baked into the generated build scripts. When
|
|
6
|
+
* omitted, the scripts rely on OBSERVERKIT_PROJECT_KEY being set in the
|
|
7
|
+
* build environment (e.g. EAS secrets).
|
|
8
|
+
*/
|
|
9
|
+
projectKey?: string;
|
|
10
|
+
endpoint?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Expo config plugin: add to app.json / app.config.js as
|
|
15
|
+
* "plugins": [["@observerkit/metro/expo", { "projectKey": "..." }]]
|
|
16
|
+
* so prebuild wires source map upload into both native builds. Also apply
|
|
17
|
+
* withObserverkit from "@observerkit/metro" in metro.config.js so debug IDs
|
|
18
|
+
* are injected into the bundle.
|
|
19
|
+
*/
|
|
20
|
+
declare const withObserverkitExpo: ConfigPlugin<ObserverkitExpoProps | undefined>;
|
|
21
|
+
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
export = withObserverkitExpo;
|
|
24
|
+
export type { ObserverkitExpoProps };
|
package/dist/expo.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
+
|
|
3
|
+
interface ObserverkitExpoProps {
|
|
4
|
+
/**
|
|
5
|
+
* ObserverKit project key baked into the generated build scripts. When
|
|
6
|
+
* omitted, the scripts rely on OBSERVERKIT_PROJECT_KEY being set in the
|
|
7
|
+
* build environment (e.g. EAS secrets).
|
|
8
|
+
*/
|
|
9
|
+
projectKey?: string;
|
|
10
|
+
endpoint?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Expo config plugin: add to app.json / app.config.js as
|
|
15
|
+
* "plugins": [["@observerkit/metro/expo", { "projectKey": "..." }]]
|
|
16
|
+
* so prebuild wires source map upload into both native builds. Also apply
|
|
17
|
+
* withObserverkit from "@observerkit/metro" in metro.config.js so debug IDs
|
|
18
|
+
* are injected into the bundle.
|
|
19
|
+
*/
|
|
20
|
+
declare const withObserverkitExpo: ConfigPlugin<ObserverkitExpoProps | undefined>;
|
|
21
|
+
|
|
22
|
+
export { type ObserverkitExpoProps, withObserverkitExpo as default };
|
package/dist/expo.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/expo.ts
|
|
2
|
+
import { withAppBuildGradle, withXcodeProject } from "@expo/config-plugins";
|
|
3
|
+
|
|
4
|
+
// src/native-scripts.ts
|
|
5
|
+
var UPLOAD_MARKER = "observerkit-upload";
|
|
6
|
+
function escapeForDoubleQuoted(value) {
|
|
7
|
+
return value.replace(/[\\"]/g, "\\$&");
|
|
8
|
+
}
|
|
9
|
+
function escapeForPbxprojShell(value) {
|
|
10
|
+
return escapeForDoubleQuoted(escapeForDoubleQuoted(value));
|
|
11
|
+
}
|
|
12
|
+
function cliFlags(props) {
|
|
13
|
+
const key = props.projectKey ? ` --project-key \\"${escapeForPbxprojShell(props.projectKey)}\\"` : "";
|
|
14
|
+
const endpoint = props.endpoint ? ` --endpoint \\"${escapeForPbxprojShell(props.endpoint)}\\"` : "";
|
|
15
|
+
return `${key}${endpoint}`;
|
|
16
|
+
}
|
|
17
|
+
function patchIosShellScript(script, props) {
|
|
18
|
+
if (script.includes(UPLOAD_MARKER)) return script;
|
|
19
|
+
const hasQuotes = script.startsWith('"') && script.endsWith('"');
|
|
20
|
+
const inner = hasQuotes ? script.slice(1, -1) : script;
|
|
21
|
+
const exportLine = 'export SOURCEMAP_FILE=\\"$DERIVED_FILE_DIR/main.jsbundle.map\\"\\n';
|
|
22
|
+
const uploadBlock = `\\nif [ -f \\"$SOURCEMAP_FILE\\" ]; then\\n npx observerkit-upload --map \\"$SOURCEMAP_FILE\\" --bundle \\"$CONFIGURATION_BUILD_DIR/main.jsbundle\\"${cliFlags(props)} || echo \\"[ObserverKit] source map upload failed\\"\\nfi\\n`;
|
|
23
|
+
const patched = `${exportLine}${inner}${uploadBlock}`;
|
|
24
|
+
return hasQuotes ? `"${patched}"` : patched;
|
|
25
|
+
}
|
|
26
|
+
function buildGradleSnippet(props) {
|
|
27
|
+
const envLine = props.projectKey ? `
|
|
28
|
+
environment "OBSERVERKIT_PROJECT_KEY", "${escapeForDoubleQuoted(props.projectKey)}"` : "";
|
|
29
|
+
const endpointLine = props.endpoint ? `
|
|
30
|
+
environment "OBSERVERKIT_ENDPOINT", "${escapeForDoubleQuoted(props.endpoint)}"` : "";
|
|
31
|
+
return `
|
|
32
|
+
// ${UPLOAD_MARKER} (added by @observerkit/metro/expo; do not edit)
|
|
33
|
+
tasks.configureEach { task ->
|
|
34
|
+
def matcher = task.name =~ /^createBundle(\\w*)ReleaseJsAndAssets$/
|
|
35
|
+
if (matcher.matches()) {
|
|
36
|
+
task.doLast {
|
|
37
|
+
def flavor = matcher.group(1)
|
|
38
|
+
def variant = flavor.isEmpty()
|
|
39
|
+
? "release"
|
|
40
|
+
: flavor.substring(0, 1).toLowerCase() + flavor.substring(1) + "Release"
|
|
41
|
+
def mapFile = file("$buildDir/generated/sourcemaps/react/" + variant + "/index.android.bundle.map")
|
|
42
|
+
def packagerMapFile = file("$buildDir/intermediates/sourcemaps/react/" + variant + "/index.android.bundle.packager.map")
|
|
43
|
+
if (mapFile.exists()) {
|
|
44
|
+
def result = exec {
|
|
45
|
+
workingDir rootProject.projectDir.parentFile${envLine}${endpointLine}
|
|
46
|
+
commandLine "npx", "observerkit-upload", "--map", mapFile.absolutePath, "--packager-map", packagerMapFile.absolutePath
|
|
47
|
+
ignoreExitValue true
|
|
48
|
+
}
|
|
49
|
+
if (result.exitValue != 0) {
|
|
50
|
+
logger.warn("[ObserverKit] source map upload failed")
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
logger.warn("[ObserverKit] No source map found at " + mapFile + ", skipping upload")
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/expo.ts
|
|
62
|
+
var BUNDLE_PHASE_NAME = "Bundle React Native code and images";
|
|
63
|
+
var withObserverkitIos = (config, props) => withXcodeProject(config, (c) => {
|
|
64
|
+
const project = c.modResults;
|
|
65
|
+
const phases = project.hash.project.objects.PBXShellScriptBuildPhase ?? {};
|
|
66
|
+
for (const key of Object.keys(phases)) {
|
|
67
|
+
const phase = phases[key];
|
|
68
|
+
if (!phase || typeof phase !== "object") continue;
|
|
69
|
+
if (typeof phase.shellScript !== "string") continue;
|
|
70
|
+
if (!String(phase.name ?? "").includes(BUNDLE_PHASE_NAME)) continue;
|
|
71
|
+
phase.shellScript = patchIosShellScript(phase.shellScript, props);
|
|
72
|
+
}
|
|
73
|
+
return c;
|
|
74
|
+
});
|
|
75
|
+
var withObserverkitAndroid = (config, props) => withAppBuildGradle(config, (c) => {
|
|
76
|
+
if (!c.modResults.contents.includes(UPLOAD_MARKER)) {
|
|
77
|
+
c.modResults.contents = c.modResults.contents + buildGradleSnippet(props);
|
|
78
|
+
}
|
|
79
|
+
return c;
|
|
80
|
+
});
|
|
81
|
+
var withObserverkitExpo = (config, props) => {
|
|
82
|
+
const resolved = props ?? {};
|
|
83
|
+
return withObserverkitAndroid(withObserverkitIos(config, resolved), resolved);
|
|
84
|
+
};
|
|
85
|
+
var expo_default = withObserverkitExpo;
|
|
86
|
+
export {
|
|
87
|
+
expo_default as default
|
|
88
|
+
};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); 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; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunk6RJOM2COcjs = require('./chunk-6RJOM2CO.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _chunkAUOVSTQXcjs = require('./chunk-AUOVSTQX.cjs');
|
|
9
|
+
|
|
10
|
+
// src/serializer.ts
|
|
11
|
+
var _module = require('module');
|
|
12
|
+
var DEBUG_ID_PLACEHOLDER = "00000000-0000-0000-0000-000000000000";
|
|
13
|
+
var DEBUG_ID_MODULE_PATH = "__observerkit-debug-id__";
|
|
14
|
+
function createDebugIdModule(code) {
|
|
15
|
+
return {
|
|
16
|
+
path: DEBUG_ID_MODULE_PATH,
|
|
17
|
+
dependencies: /* @__PURE__ */ new Map(),
|
|
18
|
+
getSource: () => Buffer.from(code),
|
|
19
|
+
inverseDependencies: /* @__PURE__ */ new Set(),
|
|
20
|
+
output: [
|
|
21
|
+
{
|
|
22
|
+
type: "js/script/virtual",
|
|
23
|
+
data: { code, lineCount: 1, map: [] }
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function injectDebugIdModule(preModules, debugIdModule) {
|
|
29
|
+
if (preModules.some((m) => m.path === DEBUG_ID_MODULE_PATH)) return preModules;
|
|
30
|
+
const preludeIndex = preModules.findIndex((m) => m.path === "__prelude__");
|
|
31
|
+
if (preludeIndex === -1) return [debugIdModule, ...preModules];
|
|
32
|
+
return [
|
|
33
|
+
...preModules.slice(0, preludeIndex + 1),
|
|
34
|
+
debugIdModule,
|
|
35
|
+
...preModules.slice(preludeIndex + 1)
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
function addDebugIdToMap(map, debugId) {
|
|
39
|
+
let parsed;
|
|
40
|
+
try {
|
|
41
|
+
parsed = JSON.parse(map);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
return map;
|
|
44
|
+
}
|
|
45
|
+
if (!_chunk6RJOM2COcjs.isJsonObject.call(void 0, parsed)) return map;
|
|
46
|
+
return JSON.stringify({ ...parsed, debugId });
|
|
47
|
+
}
|
|
48
|
+
function unwrapModuleExport(mod, exportName) {
|
|
49
|
+
if (exportName) {
|
|
50
|
+
const named = _chunk6RJOM2COcjs.isJsonObject.call(void 0, mod) ? mod[exportName] : void 0;
|
|
51
|
+
if (typeof named === "function") return named;
|
|
52
|
+
}
|
|
53
|
+
const defaultExport = _chunk6RJOM2COcjs.isJsonObject.call(void 0, mod) ? mod["default"] : void 0;
|
|
54
|
+
if (typeof defaultExport === "function") return defaultExport;
|
|
55
|
+
if (typeof mod === "function") return mod;
|
|
56
|
+
throw new Error(
|
|
57
|
+
`[ObserverKit] Could not resolve${exportName ? ` a "${exportName}" or` : ""} a default export from a Metro internal module.`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
function loadDefaultSerializer() {
|
|
61
|
+
const require2 = _module.createRequire.call(void 0, _chunkAUOVSTQXcjs.importMetaUrl);
|
|
62
|
+
const load = (id, exportName) => {
|
|
63
|
+
const mod = require2(id);
|
|
64
|
+
return unwrapModuleExport(mod, exportName);
|
|
65
|
+
};
|
|
66
|
+
let baseJSBundle;
|
|
67
|
+
let bundleToString;
|
|
68
|
+
let sourceMapString;
|
|
69
|
+
try {
|
|
70
|
+
baseJSBundle = load("metro/src/DeltaBundler/Serializers/baseJSBundle");
|
|
71
|
+
bundleToString = load("metro/src/lib/bundleToString");
|
|
72
|
+
sourceMapString = load(
|
|
73
|
+
"metro/src/DeltaBundler/Serializers/sourceMapString",
|
|
74
|
+
"sourceMapString"
|
|
75
|
+
);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
"[ObserverKit] Could not load Metro's serializer internals. Add metro as a devDependency of your app (pnpm add -D metro) or set a customSerializer in metro.config.js before withObserverkit.",
|
|
79
|
+
{ cause: err }
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
return (entryPoint, preModules, graph, options) => {
|
|
83
|
+
const bundle = baseJSBundle.apply(void 0, [entryPoint, preModules, graph, options]);
|
|
84
|
+
const { code } = bundleToString.apply(void 0, [bundle]);
|
|
85
|
+
if (options.dev) return code;
|
|
86
|
+
const sortedModules = [...graph.dependencies.values()].sort(
|
|
87
|
+
(a, b) => options.createModuleId(a.path) - options.createModuleId(b.path)
|
|
88
|
+
);
|
|
89
|
+
const map = sourceMapString.apply(void 0, [
|
|
90
|
+
[...preModules, ...sortedModules],
|
|
91
|
+
{
|
|
92
|
+
excludeSource: false,
|
|
93
|
+
processModuleFilter: options.processModuleFilter,
|
|
94
|
+
shouldAddToIgnoreList: options.shouldAddToIgnoreList
|
|
95
|
+
}
|
|
96
|
+
]);
|
|
97
|
+
return { code, map };
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function createObserverkitSerializer(wrapped) {
|
|
101
|
+
return async (entryPoint, preModules, graph, options) => {
|
|
102
|
+
const serializer = _nullishCoalesce(wrapped, () => ( loadDefaultSerializer()));
|
|
103
|
+
if (options.dev) {
|
|
104
|
+
return serializer(entryPoint, preModules, graph, options);
|
|
105
|
+
}
|
|
106
|
+
const { snippet } = _chunk6RJOM2COcjs.buildStackKeyedDebugIdSnippet.call(void 0, DEBUG_ID_PLACEHOLDER);
|
|
107
|
+
const withDebugId = injectDebugIdModule(preModules, createDebugIdModule(snippet));
|
|
108
|
+
const result = await serializer(entryPoint, withDebugId, graph, options);
|
|
109
|
+
const code = typeof result === "string" ? result : result.code;
|
|
110
|
+
const map = typeof result === "string" ? null : result.map;
|
|
111
|
+
const debugId = _chunk6RJOM2COcjs.generateDebugId.call(void 0, code);
|
|
112
|
+
const finalCode = `${code.split(DEBUG_ID_PLACEHOLDER).join(debugId)}
|
|
113
|
+
//# debugId=${debugId}`;
|
|
114
|
+
if (map === null) return finalCode;
|
|
115
|
+
return { code: finalCode, map: addDebugIdToMap(map, debugId) };
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/index.ts
|
|
120
|
+
function withObserverkit(config) {
|
|
121
|
+
return {
|
|
122
|
+
...config,
|
|
123
|
+
serializer: {
|
|
124
|
+
...config.serializer,
|
|
125
|
+
customSerializer: createObserverkitSerializer(
|
|
126
|
+
_optionalChain([config, 'access', _ => _.serializer, 'optionalAccess', _2 => _2.customSerializer])
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
exports.DEBUG_ID_PLACEHOLDER = DEBUG_ID_PLACEHOLDER; exports.createObserverkitSerializer = createObserverkitSerializer; exports.default = withObserverkit;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
interface MetroModuleOutputData {
|
|
2
|
+
code: string;
|
|
3
|
+
lineCount: number;
|
|
4
|
+
map: ReadonlyArray<unknown>;
|
|
5
|
+
}
|
|
6
|
+
interface MetroModuleOutput {
|
|
7
|
+
type: string;
|
|
8
|
+
data: MetroModuleOutputData;
|
|
9
|
+
}
|
|
10
|
+
interface MetroModule {
|
|
11
|
+
path: string;
|
|
12
|
+
dependencies: ReadonlyMap<string, unknown>;
|
|
13
|
+
getSource: () => Buffer;
|
|
14
|
+
inverseDependencies: Iterable<string>;
|
|
15
|
+
output: ReadonlyArray<MetroModuleOutput>;
|
|
16
|
+
}
|
|
17
|
+
interface MetroGraph {
|
|
18
|
+
dependencies: ReadonlyMap<string, MetroModule>;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
interface MetroSerializerOptions {
|
|
22
|
+
dev: boolean;
|
|
23
|
+
createModuleId: (filePath: string) => number;
|
|
24
|
+
processModuleFilter?: (module: MetroModule) => boolean;
|
|
25
|
+
shouldAddToIgnoreList?: (module: MetroModule) => boolean;
|
|
26
|
+
sourceMapUrl?: string | null;
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
type MetroSerializerResult = string | {
|
|
30
|
+
code: string;
|
|
31
|
+
map: string;
|
|
32
|
+
};
|
|
33
|
+
type MetroSerializer = (entryPoint: string, preModules: ReadonlyArray<MetroModule>, graph: MetroGraph, options: MetroSerializerOptions) => MetroSerializerResult | Promise<MetroSerializerResult>;
|
|
34
|
+
interface MetroConfigLike {
|
|
35
|
+
serializer?: {
|
|
36
|
+
customSerializer?: MetroSerializer;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Fixed-length placeholder baked into the injected snippet before
|
|
44
|
+
* serialization. The real debug id (uuid v5 of the serialized bundle) is the
|
|
45
|
+
* same length, so the post-serialization string replacement never shifts
|
|
46
|
+
* source map positions.
|
|
47
|
+
*/
|
|
48
|
+
declare const DEBUG_ID_PLACEHOLDER = "00000000-0000-0000-0000-000000000000";
|
|
49
|
+
declare function createObserverkitSerializer(wrapped?: MetroSerializer): MetroSerializer;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Wire ObserverKit debug-id injection into a Metro config:
|
|
53
|
+
*
|
|
54
|
+
* const { getDefaultConfig } = require("@react-native/metro-config")
|
|
55
|
+
* const withObserverkit = require("@observerkit/metro")
|
|
56
|
+
* module.exports = withObserverkit(getDefaultConfig(__dirname))
|
|
57
|
+
*
|
|
58
|
+
* Source map upload happens separately via the observerkit-upload CLI in the
|
|
59
|
+
* native build (Xcode build phase / Gradle task / Expo config plugin).
|
|
60
|
+
*/
|
|
61
|
+
declare function withObserverkit(config: MetroConfigLike): MetroConfigLike;
|
|
62
|
+
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
export = withObserverkit;
|
|
65
|
+
export { DEBUG_ID_PLACEHOLDER, type MetroConfigLike, type MetroGraph, type MetroModule, type MetroSerializer, type MetroSerializerOptions, type MetroSerializerResult, createObserverkitSerializer };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
interface MetroModuleOutputData {
|
|
2
|
+
code: string;
|
|
3
|
+
lineCount: number;
|
|
4
|
+
map: ReadonlyArray<unknown>;
|
|
5
|
+
}
|
|
6
|
+
interface MetroModuleOutput {
|
|
7
|
+
type: string;
|
|
8
|
+
data: MetroModuleOutputData;
|
|
9
|
+
}
|
|
10
|
+
interface MetroModule {
|
|
11
|
+
path: string;
|
|
12
|
+
dependencies: ReadonlyMap<string, unknown>;
|
|
13
|
+
getSource: () => Buffer;
|
|
14
|
+
inverseDependencies: Iterable<string>;
|
|
15
|
+
output: ReadonlyArray<MetroModuleOutput>;
|
|
16
|
+
}
|
|
17
|
+
interface MetroGraph {
|
|
18
|
+
dependencies: ReadonlyMap<string, MetroModule>;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
interface MetroSerializerOptions {
|
|
22
|
+
dev: boolean;
|
|
23
|
+
createModuleId: (filePath: string) => number;
|
|
24
|
+
processModuleFilter?: (module: MetroModule) => boolean;
|
|
25
|
+
shouldAddToIgnoreList?: (module: MetroModule) => boolean;
|
|
26
|
+
sourceMapUrl?: string | null;
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
type MetroSerializerResult = string | {
|
|
30
|
+
code: string;
|
|
31
|
+
map: string;
|
|
32
|
+
};
|
|
33
|
+
type MetroSerializer = (entryPoint: string, preModules: ReadonlyArray<MetroModule>, graph: MetroGraph, options: MetroSerializerOptions) => MetroSerializerResult | Promise<MetroSerializerResult>;
|
|
34
|
+
interface MetroConfigLike {
|
|
35
|
+
serializer?: {
|
|
36
|
+
customSerializer?: MetroSerializer;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Fixed-length placeholder baked into the injected snippet before
|
|
44
|
+
* serialization. The real debug id (uuid v5 of the serialized bundle) is the
|
|
45
|
+
* same length, so the post-serialization string replacement never shifts
|
|
46
|
+
* source map positions.
|
|
47
|
+
*/
|
|
48
|
+
declare const DEBUG_ID_PLACEHOLDER = "00000000-0000-0000-0000-000000000000";
|
|
49
|
+
declare function createObserverkitSerializer(wrapped?: MetroSerializer): MetroSerializer;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Wire ObserverKit debug-id injection into a Metro config:
|
|
53
|
+
*
|
|
54
|
+
* const { getDefaultConfig } = require("@react-native/metro-config")
|
|
55
|
+
* const withObserverkit = require("@observerkit/metro")
|
|
56
|
+
* module.exports = withObserverkit(getDefaultConfig(__dirname))
|
|
57
|
+
*
|
|
58
|
+
* Source map upload happens separately via the observerkit-upload CLI in the
|
|
59
|
+
* native build (Xcode build phase / Gradle task / Expo config plugin).
|
|
60
|
+
*/
|
|
61
|
+
declare function withObserverkit(config: MetroConfigLike): MetroConfigLike;
|
|
62
|
+
|
|
63
|
+
export { DEBUG_ID_PLACEHOLDER, type MetroConfigLike, type MetroGraph, type MetroModule, type MetroSerializer, type MetroSerializerOptions, type MetroSerializerResult, createObserverkitSerializer, withObserverkit as default };
|