peachsim 0.1.628 → 0.1.630
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 +8 -4
- package/cli/bridge-flow-runner.ts +10 -3
- package/cli/cli-update.ts +2 -7
- package/cli/cloud-test-tunnel.ts +16 -3
- package/cli/commands/config.ts +1 -1
- package/cli/commands/control.ts +28 -3
- package/cli/commands/daemon-mac-app.ts +4 -2
- package/cli/commands/daemon.ts +4 -4
- package/cli/commands/device.ts +2 -3
- package/cli/commands/inspect/actions.ts +125 -90
- package/cli/commands/inspect/core.ts +5 -0
- package/cli/commands/inspect.ts +27 -13
- package/cli/commands/platform.ts +1 -1
- package/cli/commands/screenshot-layers.ts +1 -1
- package/cli/commands/screenshot.ts +1 -1
- package/cli/commands/skills.ts +0 -31
- package/cli/drivers/playwright-provisioning.ts +3 -2
- package/cli/drivers/playwright-sim-host.ts +25 -9
- package/cli/main.ts +8 -2
- package/cli/outbound-endpoints.ts +0 -4
- package/detox/index.ts +74 -43
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +129 -27
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +290 -315
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +253 -121
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/{vite-kotlin.cjs → kotlin-host.cjs} +130 -19
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +132 -9
- package/dist-lib/native-app-identity.cjs +278 -0
- package/dist-lib/native-app-identity.mjs +245 -0
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +110 -87
- package/dist-lib/sdk.mjs +110 -87
- package/dist-lib/skills.cjs +841 -643
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +282 -177
- package/dist-lib/vite-swift.cjs +1 -1
- package/dist-lib/vite.cjs +11 -28
- package/kotlin/README.md +32 -4
- package/kotlin/fixtures/counter/Counter.kt +26 -0
- package/kotlin/fixtures/counter/CounterScreen.kt +40 -0
- package/kotlin/fixtures/headless-counter/Headless.kt +228 -0
- package/kotlin/fixtures/runtime-state/RuntimeState.kt +200 -0
- package/kotlin/fork/LICENSE +178 -0
- package/kotlin/fork/NOTICE +25 -0
- package/kotlin/fork/README.md +59 -0
- package/kotlin/fork/build.sh +128 -0
- package/kotlin/fork/compose-worker-globals.patch +96 -0
- package/kotlin/fork/fork.json +33 -0
- package/kotlin/fork/publish.ts +77 -0
- package/kotlin/fork/skiko-worker-clock.patch +33 -0
- package/kotlin/toolchain.json +288 -0
- package/package.json +12 -5
- package/src/automatic-update-policy.ts +17 -0
- package/src/host/bridge-host.ts +3 -1
- package/src/{vite-plugin-kotlin.ts → kotlin-host.ts} +155 -12
- package/src/metro-plugin.ts +18 -0
- package/src/native-app-identity.ts +376 -0
- package/src/native-firebase-config.ts +90 -0
- package/src/screenshots/frame-compose.ts +5 -2
- package/src/screenshots/registry.ts +1 -1
- package/src/screenshots/schema.ts +2 -2
- package/src/vite-plugin-one.ts +11 -28
- package/src/vite-plugin.ts +6 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -29,15 +29,18 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
));
|
|
30
30
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
31
|
|
|
32
|
-
// src/
|
|
33
|
-
var
|
|
34
|
-
__export(
|
|
32
|
+
// src/kotlin-host.ts
|
|
33
|
+
var kotlin_host_exports = {};
|
|
34
|
+
__export(kotlin_host_exports, {
|
|
35
35
|
KOTLIN_ARTIFACT_PREFIX: () => KOTLIN_ARTIFACT_PREFIX,
|
|
36
|
+
KOTLIN_PACKAGE_PATH: () => KOTLIN_PACKAGE_PATH,
|
|
36
37
|
kotlinArtifact: () => kotlinArtifact,
|
|
37
38
|
kotlinSources: () => kotlinSources,
|
|
38
|
-
|
|
39
|
+
peachKotlinModuleRoot: () => peachKotlinModuleRoot,
|
|
40
|
+
serveKotlinArtifact: () => serveKotlinArtifact,
|
|
41
|
+
serveKotlinRequest: () => serveKotlinRequest
|
|
39
42
|
});
|
|
40
|
-
module.exports = __toCommonJS(
|
|
43
|
+
module.exports = __toCommonJS(kotlin_host_exports);
|
|
41
44
|
var import_node_child_process = require("node:child_process");
|
|
42
45
|
var import_node_crypto = require("node:crypto");
|
|
43
46
|
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
@@ -61,7 +64,7 @@ function isRecord(value) {
|
|
|
61
64
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62
65
|
}
|
|
63
66
|
|
|
64
|
-
// src/
|
|
67
|
+
// src/kotlin-host.ts
|
|
65
68
|
var run = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
66
69
|
var KOTLIN_ARTIFACT_PREFIX = "/__peach/kotlin-artifact/";
|
|
67
70
|
function readToolchain(moduleRoot) {
|
|
@@ -75,17 +78,34 @@ function readToolchain(moduleRoot) {
|
|
|
75
78
|
);
|
|
76
79
|
return { url: value.url, sha256: value.sha256 };
|
|
77
80
|
};
|
|
78
|
-
if (!isRecord(parsed) || !isRecord(parsed.compiler) || !Array.isArray(parsed.libraries))
|
|
81
|
+
if (!isRecord(parsed) || !isRecord(parsed.compiler) || !Array.isArray(parsed.libraries) || !Array.isArray(parsed.composeLibraries) || !Array.isArray(parsed.composeJsLibraries) || !isRecord(parsed.composeRuntime) || typeof parsed.composeRuntime.name !== "string")
|
|
79
82
|
throw new Error("peachsim kotlin/toolchain.json has no compiler and libraries");
|
|
80
83
|
const version = parsed.compiler.version;
|
|
81
84
|
if (typeof version !== "string")
|
|
82
85
|
throw new Error("peachsim kotlin/toolchain.json has no compiler version");
|
|
86
|
+
const libraries = (values) => values.map((library) => {
|
|
87
|
+
if (!isRecord(library) || typeof library.name !== "string")
|
|
88
|
+
throw new Error("peachsim kotlin/toolchain.json names a library without a name");
|
|
89
|
+
return { ...download(library), name: library.name };
|
|
90
|
+
});
|
|
83
91
|
return {
|
|
84
92
|
compiler: { ...download(parsed.compiler), version },
|
|
85
|
-
libraries: parsed.libraries
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
93
|
+
libraries: libraries(parsed.libraries),
|
|
94
|
+
composeLibraries: libraries(parsed.composeLibraries),
|
|
95
|
+
composeRuntime: {
|
|
96
|
+
...download(parsed.composeRuntime),
|
|
97
|
+
name: parsed.composeRuntime.name
|
|
98
|
+
},
|
|
99
|
+
composeJsLibraries: parsed.composeJsLibraries.map((library) => {
|
|
100
|
+
if (!isRecord(library) || typeof library.name !== "string" || typeof library.module !== "string" || typeof library.file !== "string" || typeof library.archiveEntry !== "string")
|
|
101
|
+
throw new Error("peachsim kotlin/toolchain.json has an incomplete JS library");
|
|
102
|
+
return {
|
|
103
|
+
...download(library),
|
|
104
|
+
name: library.name,
|
|
105
|
+
module: library.module,
|
|
106
|
+
file: library.file,
|
|
107
|
+
archiveEntry: library.archiveEntry
|
|
108
|
+
};
|
|
89
109
|
})
|
|
90
110
|
};
|
|
91
111
|
}
|
|
@@ -207,7 +227,7 @@ function entrySource(ids) {
|
|
|
207
227
|
" } else {",
|
|
208
228
|
' reply.put("ok", true).put("value", dispatch.call(module, method, argsJson))',
|
|
209
229
|
" }",
|
|
210
|
-
" } catch (error:
|
|
230
|
+
" } catch (error: Throwable) {",
|
|
211
231
|
' reply.put("ok", false).put("code", "E_NATIVE_SOURCE").put("error", "$module.$method: ${error.message}")',
|
|
212
232
|
" }",
|
|
213
233
|
" reply.toString().toJsString()",
|
|
@@ -215,7 +235,7 @@ function entrySource(ids) {
|
|
|
215
235
|
""
|
|
216
236
|
].join("\n");
|
|
217
237
|
}
|
|
218
|
-
var BUILD_FORMAT =
|
|
238
|
+
var BUILD_FORMAT = 4;
|
|
219
239
|
var builds = /* @__PURE__ */ new Map();
|
|
220
240
|
function buildsDir() {
|
|
221
241
|
return import_node_path2.default.join(kotlinHome(), "builds");
|
|
@@ -228,8 +248,11 @@ async function kotlinArtifact(root, moduleRoot, origin) {
|
|
|
228
248
|
if (sources.length === 0) throw new Error(`${root} holds no Kotlin sources`);
|
|
229
249
|
const generated = {};
|
|
230
250
|
const ids = [];
|
|
251
|
+
let usesCompose = false;
|
|
231
252
|
for (const file of sources) {
|
|
232
|
-
const
|
|
253
|
+
const source = import_node_fs.default.readFileSync(file, "utf8");
|
|
254
|
+
if (/\bandroidx\.compose\./.test(source)) usesCompose = true;
|
|
255
|
+
const contract = nativeSourceContract(file, source);
|
|
233
256
|
if (contract.modules.length === 0) continue;
|
|
234
257
|
const id = kotlinSourceId(root, file);
|
|
235
258
|
ids.push(id);
|
|
@@ -244,25 +267,52 @@ async function kotlinArtifact(root, moduleRoot, origin) {
|
|
|
244
267
|
for (const [name, text] of Object.entries(generated))
|
|
245
268
|
digest.update(`${name}\0${text}\0`);
|
|
246
269
|
const hash = digest.digest("hex").slice(0, 24);
|
|
247
|
-
const artifact = {
|
|
270
|
+
const artifact = {
|
|
271
|
+
url: `${origin}${KOTLIN_ARTIFACT_PREFIX}${hash}/app.mjs`,
|
|
272
|
+
hash
|
|
273
|
+
};
|
|
248
274
|
const out = import_node_path2.default.join(buildsDir(), hash);
|
|
249
275
|
if (import_node_fs.default.existsSync(import_node_path2.default.join(out, "js", "app.wasm"))) return artifact;
|
|
250
276
|
const pending = builds.get(hash);
|
|
251
277
|
if (pending) return pending;
|
|
252
278
|
const build = (async () => {
|
|
253
|
-
const
|
|
279
|
+
const ready = await ensureToolchain(toolchain);
|
|
280
|
+
const { kotlinc } = ready;
|
|
281
|
+
const libraries = [...ready.libraries];
|
|
282
|
+
const composeRuntime = import_node_path2.default.join(
|
|
283
|
+
kotlinHome(),
|
|
284
|
+
toolchain.compiler.version,
|
|
285
|
+
toolchain.composeRuntime.name
|
|
286
|
+
);
|
|
287
|
+
if (usesCompose) {
|
|
288
|
+
for (const library of toolchain.composeLibraries) {
|
|
289
|
+
const target = import_node_path2.default.join(kotlinHome(), toolchain.compiler.version, library.name);
|
|
290
|
+
await fetchVerified(library, target);
|
|
291
|
+
libraries.push(target);
|
|
292
|
+
}
|
|
293
|
+
await fetchVerified(toolchain.composeRuntime, composeRuntime);
|
|
294
|
+
}
|
|
254
295
|
import_node_fs.default.mkdirSync(buildsDir(), { recursive: true });
|
|
255
296
|
const work = import_node_fs.default.mkdtempSync(import_node_path2.default.join(buildsDir(), `${hash}-`));
|
|
256
297
|
const generatedDir = import_node_path2.default.join(work, "generated");
|
|
257
298
|
import_node_fs.default.mkdirSync(generatedDir);
|
|
258
299
|
for (const [name, text] of Object.entries(generated))
|
|
259
300
|
import_node_fs.default.writeFileSync(import_node_path2.default.join(generatedDir, name), text);
|
|
260
|
-
const common = [
|
|
301
|
+
const common = [
|
|
302
|
+
// the full upstream Compose graph exceeds kotlinc's 512 mib default heap.
|
|
303
|
+
"-J-Xmx2g",
|
|
304
|
+
"-Xwasm-target=js",
|
|
305
|
+
"-libraries",
|
|
306
|
+
libraries.join(import_node_path2.default.delimiter)
|
|
307
|
+
];
|
|
261
308
|
try {
|
|
262
309
|
await run(
|
|
263
310
|
kotlinc,
|
|
264
311
|
[
|
|
265
312
|
...common,
|
|
313
|
+
...usesCompose ? [
|
|
314
|
+
`-Xplugin=${import_node_path2.default.resolve(import_node_path2.default.dirname(kotlinc), "../lib/compose-compiler-plugin.jar")}`
|
|
315
|
+
] : [],
|
|
266
316
|
"-language-version",
|
|
267
317
|
language,
|
|
268
318
|
"-api-version",
|
|
@@ -293,6 +343,43 @@ async function kotlinArtifact(root, moduleRoot, origin) {
|
|
|
293
343
|
],
|
|
294
344
|
{ maxBuffer: 16 * 1024 * 1024 }
|
|
295
345
|
);
|
|
346
|
+
if (usesCompose)
|
|
347
|
+
await run("unzip", [
|
|
348
|
+
"-q",
|
|
349
|
+
"-j",
|
|
350
|
+
composeRuntime,
|
|
351
|
+
"skiko.mjs",
|
|
352
|
+
"skiko.wasm",
|
|
353
|
+
"-d",
|
|
354
|
+
import_node_path2.default.join(work, "js")
|
|
355
|
+
]);
|
|
356
|
+
if (usesCompose) {
|
|
357
|
+
for (const library of toolchain.composeJsLibraries) {
|
|
358
|
+
for (const file of import_node_fs.default.readdirSync(import_node_path2.default.join(work, "js"))) {
|
|
359
|
+
if (!file.endsWith(".mjs")) continue;
|
|
360
|
+
const target = import_node_path2.default.join(work, "js", file);
|
|
361
|
+
const source = import_node_fs.default.readFileSync(target, "utf8");
|
|
362
|
+
let next = source;
|
|
363
|
+
for (const quote of ["'", '"'])
|
|
364
|
+
next = next.replaceAll(
|
|
365
|
+
`from ${quote}${library.module}${quote}`,
|
|
366
|
+
`from ${quote}./${library.file}${quote}`
|
|
367
|
+
);
|
|
368
|
+
if (next === source) continue;
|
|
369
|
+
const archive = import_node_path2.default.join(
|
|
370
|
+
kotlinHome(),
|
|
371
|
+
toolchain.compiler.version,
|
|
372
|
+
library.name
|
|
373
|
+
);
|
|
374
|
+
await fetchVerified(library, archive);
|
|
375
|
+
const { stdout } = await run("tar", ["-xOf", archive, library.archiveEntry], {
|
|
376
|
+
maxBuffer: 16 * 1024 * 1024
|
|
377
|
+
});
|
|
378
|
+
import_node_fs.default.writeFileSync(import_node_path2.default.join(work, "js", library.file), stdout);
|
|
379
|
+
import_node_fs.default.writeFileSync(target, next);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
296
383
|
} catch (error) {
|
|
297
384
|
import_node_fs.default.rmSync(work, { recursive: true, force: true });
|
|
298
385
|
const output = isRecord(error) ? `${String(error.stderr ?? "")}${String(error.stdout ?? "")}` : "";
|
|
@@ -347,10 +434,34 @@ function serveKotlinArtifact(pathname, res) {
|
|
|
347
434
|
res.end(import_node_fs.default.readFileSync(target));
|
|
348
435
|
return true;
|
|
349
436
|
}
|
|
437
|
+
var KOTLIN_PACKAGE_PATH = "/__peach/kotlin-package";
|
|
438
|
+
function peachKotlinModuleRoot(root) {
|
|
439
|
+
const peachsimPackage = (0, import_node_module.createRequire)(import_node_path2.default.join(root, "package.json")).resolve(
|
|
440
|
+
"peachsim/package.json"
|
|
441
|
+
);
|
|
442
|
+
return import_node_path2.default.join(import_node_path2.default.dirname(peachsimPackage), "kotlin");
|
|
443
|
+
}
|
|
444
|
+
async function serveKotlinRequest(pathname, res, app) {
|
|
445
|
+
if (serveKotlinArtifact(pathname, res)) return true;
|
|
446
|
+
if (pathname !== KOTLIN_PACKAGE_PATH) return false;
|
|
447
|
+
res.setHeader("access-control-allow-origin", "*");
|
|
448
|
+
try {
|
|
449
|
+
const artifact = await kotlinArtifact(app.root, app.moduleRoot, app.origin);
|
|
450
|
+
res.setHeader("content-type", "application/json");
|
|
451
|
+
res.end(JSON.stringify({ ...artifact, hmrPath: app.hmrPath }));
|
|
452
|
+
} catch (error) {
|
|
453
|
+
res.statusCode = 500;
|
|
454
|
+
res.end(error instanceof Error ? error.message : String(error));
|
|
455
|
+
}
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
350
458
|
// Annotate the CommonJS export names for ESM import in node:
|
|
351
459
|
0 && (module.exports = {
|
|
352
460
|
KOTLIN_ARTIFACT_PREFIX,
|
|
461
|
+
KOTLIN_PACKAGE_PATH,
|
|
353
462
|
kotlinArtifact,
|
|
354
463
|
kotlinSources,
|
|
355
|
-
|
|
464
|
+
peachKotlinModuleRoot,
|
|
465
|
+
serveKotlinArtifact,
|
|
466
|
+
serveKotlinRequest
|
|
356
467
|
});
|
package/dist-lib/menu.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/menu.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/metro.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -528,6 +528,113 @@ function appendRNXMetroModuleIdentityFooter(bundleText, identity) {
|
|
|
528
528
|
${RNXSIM_METRO_SOURCE_MAP_COMMENT}${detached.sourceMappingUrl}`;
|
|
529
529
|
}
|
|
530
530
|
|
|
531
|
+
// src/native-firebase-config.ts
|
|
532
|
+
var import_node_fs2 = __toESM(require("node:fs"), 1);
|
|
533
|
+
var import_node_module = require("node:module");
|
|
534
|
+
var import_node_path2 = __toESM(require("node:path"), 1);
|
|
535
|
+
|
|
536
|
+
// src/is-record.ts
|
|
537
|
+
function isRecord(value) {
|
|
538
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// src/plist.ts
|
|
542
|
+
var import_plist = __toESM(require("@expo/plist"), 1);
|
|
543
|
+
function resolvePlistParser(value) {
|
|
544
|
+
if (!isRecord(value)) return null;
|
|
545
|
+
const direct = value.parse;
|
|
546
|
+
if (typeof direct === "function") {
|
|
547
|
+
return (source) => Reflect.apply(direct, value, [source]);
|
|
548
|
+
}
|
|
549
|
+
const nested = value.default;
|
|
550
|
+
if (!isRecord(nested)) return null;
|
|
551
|
+
const nestedParse = nested.parse;
|
|
552
|
+
return typeof nestedParse === "function" ? (source) => Reflect.apply(nestedParse, nested, [source]) : null;
|
|
553
|
+
}
|
|
554
|
+
var parsePlist = resolvePlistParser(import_plist.default);
|
|
555
|
+
function parsePlistSource(source) {
|
|
556
|
+
return parsePlist?.(source) ?? null;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/native-firebase-config.ts
|
|
560
|
+
function readNativeFirebaseConfig(projectRoot) {
|
|
561
|
+
const result = {};
|
|
562
|
+
if (![
|
|
563
|
+
"app.json",
|
|
564
|
+
"app.config.js",
|
|
565
|
+
"app.config.ts",
|
|
566
|
+
"app.config.cjs",
|
|
567
|
+
"app.config.mjs"
|
|
568
|
+
].some((name) => import_node_fs2.default.existsSync(import_node_path2.default.join(projectRoot, name))))
|
|
569
|
+
return result;
|
|
570
|
+
const require2 = (0, import_node_module.createRequire)(import_node_path2.default.join(projectRoot, "package.json"));
|
|
571
|
+
const configModule = require2("@expo/config");
|
|
572
|
+
if (!isRecord(configModule) || typeof configModule.getConfig !== "function") {
|
|
573
|
+
throw new Error("Expo native configuration is unavailable.");
|
|
574
|
+
}
|
|
575
|
+
const resolved = Reflect.apply(configModule.getConfig, configModule, [
|
|
576
|
+
projectRoot,
|
|
577
|
+
{ skipSDKVersionRequirement: true }
|
|
578
|
+
]);
|
|
579
|
+
const config = isRecord(resolved) && isRecord(resolved.exp) ? resolved.exp : {};
|
|
580
|
+
for (const platform of ["ios", "android"]) {
|
|
581
|
+
const native = config[platform];
|
|
582
|
+
if (!isRecord(native) || typeof native.googleServicesFile !== "string") continue;
|
|
583
|
+
try {
|
|
584
|
+
const source = import_node_fs2.default.readFileSync(
|
|
585
|
+
import_node_path2.default.resolve(projectRoot, native.googleServicesFile),
|
|
586
|
+
"utf8"
|
|
587
|
+
);
|
|
588
|
+
const parsed = platform === "ios" ? parsePlistSource(source) : JSON.parse(source);
|
|
589
|
+
if (!isRecord(parsed)) throw new Error("Invalid Google services file.");
|
|
590
|
+
if (platform === "ios") {
|
|
591
|
+
result[platform] = {
|
|
592
|
+
apiKey: parsed.API_KEY,
|
|
593
|
+
appId: parsed.GOOGLE_APP_ID,
|
|
594
|
+
projectId: parsed.PROJECT_ID,
|
|
595
|
+
databaseURL: parsed.DATABASE_URL,
|
|
596
|
+
gaTrackingId: parsed.TRACKING_ID,
|
|
597
|
+
storageBucket: parsed.STORAGE_BUCKET,
|
|
598
|
+
messagingSenderId: parsed.GCM_SENDER_ID,
|
|
599
|
+
clientId: parsed.CLIENT_ID,
|
|
600
|
+
androidClientID: parsed.ANDROID_CLIENT_ID,
|
|
601
|
+
deepLinkUrlScheme: parsed.REVERSED_CLIENT_ID
|
|
602
|
+
};
|
|
603
|
+
} else {
|
|
604
|
+
const project = isRecord(parsed.project_info) ? parsed.project_info : {};
|
|
605
|
+
const clients = Array.isArray(parsed.client) ? parsed.client : [];
|
|
606
|
+
const client = clients.find((value) => {
|
|
607
|
+
if (!isRecord(value) || !isRecord(value.client_info)) return false;
|
|
608
|
+
const android = value.client_info.android_client_info;
|
|
609
|
+
return isRecord(android) && android.package_name === native.package;
|
|
610
|
+
});
|
|
611
|
+
if (!isRecord(client) || !isRecord(client.client_info))
|
|
612
|
+
throw new Error("No Google services client matches the Android package.");
|
|
613
|
+
const apiKeys = Array.isArray(client.api_key) ? client.api_key : [];
|
|
614
|
+
const apiKey = apiKeys.find(
|
|
615
|
+
(value) => isRecord(value) && typeof value.current_key === "string"
|
|
616
|
+
);
|
|
617
|
+
const oauthClients = Array.isArray(client.oauth_client) ? client.oauth_client : [];
|
|
618
|
+
const oauth = oauthClients.find(
|
|
619
|
+
(value) => isRecord(value) && value.client_type === 3
|
|
620
|
+
);
|
|
621
|
+
result[platform] = {
|
|
622
|
+
apiKey: isRecord(apiKey) ? apiKey.current_key : void 0,
|
|
623
|
+
appId: client.client_info.mobilesdk_app_id,
|
|
624
|
+
projectId: project.project_id,
|
|
625
|
+
databaseURL: project.firebase_url,
|
|
626
|
+
storageBucket: project.storage_bucket,
|
|
627
|
+
messagingSenderId: project.project_number,
|
|
628
|
+
clientId: isRecord(oauth) ? oauth.client_id : void 0
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
} catch (error) {
|
|
632
|
+
result[platform] = { error: error instanceof Error ? error.message : String(error) };
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return result;
|
|
636
|
+
}
|
|
637
|
+
|
|
531
638
|
// src/runtime-assets.ts
|
|
532
639
|
var import_fs = __toESM(require("fs"), 1);
|
|
533
640
|
var import_path = __toESM(require("path"), 1);
|
|
@@ -539,28 +646,28 @@ function isValidRuntimeVersion(value) {
|
|
|
539
646
|
}
|
|
540
647
|
|
|
541
648
|
// src/home-paths.ts
|
|
542
|
-
var
|
|
649
|
+
var import_node_fs3 = __toESM(require("node:fs"), 1);
|
|
543
650
|
var import_node_os = require("node:os");
|
|
544
|
-
var
|
|
651
|
+
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
545
652
|
var PEACH_HOME_ENV = "PEACH_HOME";
|
|
546
653
|
var ACTIVE_RUNTIME_FILE = "active";
|
|
547
654
|
function rnxHomeDir() {
|
|
548
655
|
const override = process.env[PEACH_HOME_ENV];
|
|
549
|
-
if (override && override.length > 0) return
|
|
550
|
-
return
|
|
656
|
+
if (override && override.length > 0) return import_node_path3.default.resolve(override);
|
|
657
|
+
return import_node_path3.default.join((0, import_node_os.homedir)(), ".peach");
|
|
551
658
|
}
|
|
552
659
|
function runtimesDir() {
|
|
553
|
-
return
|
|
660
|
+
return import_node_path3.default.join(rnxHomeDir(), "runtimes");
|
|
554
661
|
}
|
|
555
662
|
function runtimeDir(version) {
|
|
556
|
-
return
|
|
663
|
+
return import_node_path3.default.join(runtimesDir(), version);
|
|
557
664
|
}
|
|
558
665
|
function activeRuntimeFile() {
|
|
559
|
-
return
|
|
666
|
+
return import_node_path3.default.join(runtimesDir(), ACTIVE_RUNTIME_FILE);
|
|
560
667
|
}
|
|
561
668
|
function readActiveRuntime() {
|
|
562
669
|
try {
|
|
563
|
-
const value =
|
|
670
|
+
const value = import_node_fs3.default.readFileSync(activeRuntimeFile(), "utf8").trim();
|
|
564
671
|
return value.length > 0 ? value : null;
|
|
565
672
|
} catch {
|
|
566
673
|
return null;
|
|
@@ -873,6 +980,22 @@ function withRNX(config) {
|
|
|
873
980
|
});
|
|
874
981
|
return;
|
|
875
982
|
}
|
|
983
|
+
if ((req.url || "").split("?")[0] === "/__peach-native-firebase-config") {
|
|
984
|
+
try {
|
|
985
|
+
res.setHeader("Content-Type", "application/json");
|
|
986
|
+
res.setHeader("Cache-Control", "no-store");
|
|
987
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
988
|
+
res.end(JSON.stringify(readNativeFirebaseConfig(cfgProjectRoot)));
|
|
989
|
+
} catch (error) {
|
|
990
|
+
res.statusCode = 400;
|
|
991
|
+
res.end(
|
|
992
|
+
JSON.stringify({
|
|
993
|
+
error: error instanceof Error ? error.message : String(error)
|
|
994
|
+
})
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
876
999
|
const url = req.url || "";
|
|
877
1000
|
const pathname = url.split("?")[0];
|
|
878
1001
|
const runtimeRoot = resolveRuntimeRootForRequestHost(req.headers?.host);
|