peachsim 0.1.2186 → 0.1.2187
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/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.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/bundle-channel.cjs +2706 -2381
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +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/config.mjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +3227 -3220
- package/dist-lib/expo-swift-metadata.cjs +1 -1
- package/dist-lib/expo-swift-metadata.mjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +4538 -4213
- package/dist-lib/host/fetch-proxy-handler.cjs +6 -5
- 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 +429 -279
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +645 -284
- 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 +730 -580
- package/dist-lib/native-app-identity-project.cjs +2 -2
- package/dist-lib/native-app-identity-project.mjs +2 -2
- package/dist-lib/native-app-identity.cjs +1 -1
- package/dist-lib/native-app-identity.mjs +1 -1
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/pdfium-raster.cjs +1 -1
- package/dist-lib/pdfium-raster.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/public-origins-lib-esm.json +24 -24
- package/dist-lib/public-origins-lib.json +99 -59
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/reap-browser.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +5196 -4871
- package/dist-lib/swift-compile.cjs +2 -2
- package/dist-lib/swift-compile.mjs +2 -2
- 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-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +2 -2
- package/dist-lib/vite.cjs +6 -5
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/kotlin/sdk.tar.gz +0 -0
- package/package.json +1 -1
- package/sdk/ios/System/Library/Frameworks/CFNetwork.framework/Headers/CFNetwork.h +10 -0
- package/src/android-autolinking.ts +45 -4
- package/src/android-bridge-packages.ts +2 -2
- package/src/android-gradle-sources.ts +143 -0
- package/src/androidAutolinkingContract.ts +8 -0
- package/src/androidGradleContract.ts +14 -0
- package/src/expo-kotlin-host.ts +3 -0
- package/src/java-module-abi.ts +145 -0
- package/src/javaAbiContract.ts +14 -0
- package/src/kotlin-host.ts +55 -3
- package/src/nitro-source.ts +2 -167
- package/src/react-native-autolinking.ts +153 -0
package/dist-lib/kotlin-host.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2187 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -7,6 +7,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
7
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
8
|
var __getProtoOf = Object.getPrototypeOf;
|
|
9
9
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __esm = (fn, res) => function __init() {
|
|
11
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
|
+
};
|
|
10
13
|
var __export = (target, all) => {
|
|
11
14
|
for (var name in all)
|
|
12
15
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -29,6 +32,312 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
32
|
));
|
|
30
33
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
34
|
|
|
35
|
+
// <define:__SWIFT_COVERAGE_SOURCE_DIGESTS__>
|
|
36
|
+
var init_define_SWIFT_COVERAGE_SOURCE_DIGESTS = __esm({
|
|
37
|
+
"<define:__SWIFT_COVERAGE_SOURCE_DIGESTS__>"() {
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// src/is-record.ts
|
|
42
|
+
function isRecord(value) {
|
|
43
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44
|
+
}
|
|
45
|
+
var init_is_record = __esm({
|
|
46
|
+
"src/is-record.ts"() {
|
|
47
|
+
"use strict";
|
|
48
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// src/home-paths.ts
|
|
53
|
+
function ambientHomeDir() {
|
|
54
|
+
return import_node_path.default.join((0, import_node_os.homedir)(), ".peach");
|
|
55
|
+
}
|
|
56
|
+
function rnxHomeDir() {
|
|
57
|
+
const override = process.env[PEACH_HOME_ENV];
|
|
58
|
+
return override && override.length > 0 ? import_node_path.default.resolve(override) : ambientHomeDir();
|
|
59
|
+
}
|
|
60
|
+
var import_node_os, import_node_path, PEACH_HOME_ENV, DAEMON_LOCKFILE_MAX_BYTES;
|
|
61
|
+
var init_home_paths = __esm({
|
|
62
|
+
"src/home-paths.ts"() {
|
|
63
|
+
"use strict";
|
|
64
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
65
|
+
import_node_os = require("node:os");
|
|
66
|
+
import_node_path = __toESM(require("node:path"), 1);
|
|
67
|
+
PEACH_HOME_ENV = "PEACH_HOME";
|
|
68
|
+
DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// src/kotlin-toolchain.ts
|
|
73
|
+
function readToolchain(moduleRoot) {
|
|
74
|
+
const parsed = JSON.parse(
|
|
75
|
+
import_node_fs.default.readFileSync(import_node_path2.default.join(moduleRoot, "toolchain.json"), "utf8")
|
|
76
|
+
);
|
|
77
|
+
const download = (value) => {
|
|
78
|
+
if (!isRecord(value) || typeof value.url !== "string" || typeof value.sha256 !== "string")
|
|
79
|
+
throw new Error(
|
|
80
|
+
"peachsim kotlin/toolchain.json names a download without url and sha256"
|
|
81
|
+
);
|
|
82
|
+
return { url: value.url, sha256: value.sha256 };
|
|
83
|
+
};
|
|
84
|
+
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")
|
|
85
|
+
throw new Error("peachsim kotlin/toolchain.json has no compiler and libraries");
|
|
86
|
+
const version = parsed.compiler.version;
|
|
87
|
+
if (typeof version !== "string")
|
|
88
|
+
throw new Error("peachsim kotlin/toolchain.json has no compiler version");
|
|
89
|
+
const libraries = (values) => values.map((library) => {
|
|
90
|
+
if (!isRecord(library) || typeof library.name !== "string")
|
|
91
|
+
throw new Error("peachsim kotlin/toolchain.json names a library without a name");
|
|
92
|
+
return { ...download(library), name: library.name };
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
compiler: { ...download(parsed.compiler), version },
|
|
96
|
+
libraries: libraries(parsed.libraries),
|
|
97
|
+
composeLibraries: libraries(parsed.composeLibraries),
|
|
98
|
+
composeRuntime: {
|
|
99
|
+
...download(parsed.composeRuntime),
|
|
100
|
+
name: parsed.composeRuntime.name
|
|
101
|
+
},
|
|
102
|
+
composeJsLibraries: parsed.composeJsLibraries.map((library) => {
|
|
103
|
+
if (!isRecord(library) || typeof library.name !== "string" || typeof library.module !== "string" || typeof library.file !== "string" || typeof library.archiveEntry !== "string")
|
|
104
|
+
throw new Error("peachsim kotlin/toolchain.json has an incomplete JS library");
|
|
105
|
+
return {
|
|
106
|
+
...download(library),
|
|
107
|
+
name: library.name,
|
|
108
|
+
module: library.module,
|
|
109
|
+
file: library.file,
|
|
110
|
+
archiveEntry: library.archiveEntry
|
|
111
|
+
};
|
|
112
|
+
})
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function kotlinHome() {
|
|
116
|
+
return import_node_path2.default.join(rnxHomeDir(), "kotlin");
|
|
117
|
+
}
|
|
118
|
+
async function fetchVerified(download, target) {
|
|
119
|
+
if (import_node_fs.default.existsSync(target)) {
|
|
120
|
+
if ((0, import_node_crypto.createHash)("sha256").update(import_node_fs.default.readFileSync(target)).digest("hex") !== download.sha256)
|
|
121
|
+
throw new Error(
|
|
122
|
+
`cached Kotlin download differs from its pin: ${import_node_path2.default.basename(target)}`
|
|
123
|
+
);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const response = await fetch(download.url);
|
|
127
|
+
if (!response.ok) throw new Error(`${download.url} answered ${response.status}`);
|
|
128
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
129
|
+
const digest = (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
130
|
+
if (digest !== download.sha256)
|
|
131
|
+
throw new Error(`${download.url} has sha256 ${digest}, expected ${download.sha256}`);
|
|
132
|
+
import_node_fs.default.mkdirSync(import_node_path2.default.dirname(target), { recursive: true });
|
|
133
|
+
const partial = `${target}.${process.pid}.partial`;
|
|
134
|
+
import_node_fs.default.writeFileSync(partial, bytes);
|
|
135
|
+
import_node_fs.default.renameSync(partial, target);
|
|
136
|
+
}
|
|
137
|
+
function ensureToolchain(toolchain) {
|
|
138
|
+
const key = JSON.stringify(toolchain);
|
|
139
|
+
const pending = toolchains.get(key);
|
|
140
|
+
if (pending) return pending;
|
|
141
|
+
const ready = (async () => {
|
|
142
|
+
const dir = import_node_path2.default.join(kotlinHome(), toolchain.compiler.version);
|
|
143
|
+
const kotlinc = import_node_path2.default.join(dir, "kotlinc", "bin", "kotlinc-wasm");
|
|
144
|
+
if (!import_node_fs.default.existsSync(kotlinc)) {
|
|
145
|
+
const zip = import_node_path2.default.join(dir, "kotlin-compiler.zip");
|
|
146
|
+
await fetchVerified(toolchain.compiler, zip);
|
|
147
|
+
await run("unzip", ["-q", "-o", zip, "-d", dir]);
|
|
148
|
+
import_node_fs.default.rmSync(zip);
|
|
149
|
+
}
|
|
150
|
+
const java = process.env.JAVA_HOME ? import_node_path2.default.join(process.env.JAVA_HOME, "bin", "java") : "java";
|
|
151
|
+
const { stderr } = await run(java, ["-XshowSettings:properties", "-version"]).catch(
|
|
152
|
+
() => {
|
|
153
|
+
throw new Error(
|
|
154
|
+
`Kotlin in Peach compiles with kotlinc, which needs a Java runtime (17 or newer, as android builds use); ${process.env.JAVA_HOME ? `JAVA_HOME ${process.env.JAVA_HOME} has none` : "set JAVA_HOME or put java on PATH"}`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
const javaHome = /^\s*java\.home\s*=\s*(.+)$/m.exec(stderr)?.[1]?.trim();
|
|
159
|
+
if (!javaHome || !import_node_path2.default.isAbsolute(javaHome))
|
|
160
|
+
throw new Error("the configured Java runtime did not report an absolute java.home");
|
|
161
|
+
const libraries = [import_node_path2.default.join(dir, "kotlinc", "lib", "kotlin-stdlib-wasm-js.klib")];
|
|
162
|
+
for (const library of toolchain.libraries) {
|
|
163
|
+
const target = import_node_path2.default.join(dir, library.name);
|
|
164
|
+
await fetchVerified(library, target);
|
|
165
|
+
libraries.push(target);
|
|
166
|
+
}
|
|
167
|
+
return { kotlinc, libraries, javaHome };
|
|
168
|
+
})().catch((error) => {
|
|
169
|
+
toolchains.delete(key);
|
|
170
|
+
throw error;
|
|
171
|
+
});
|
|
172
|
+
toolchains.set(key, ready);
|
|
173
|
+
return ready;
|
|
174
|
+
}
|
|
175
|
+
var import_node_child_process, import_node_crypto, import_node_fs, import_node_path2, import_node_util, run, toolchains;
|
|
176
|
+
var init_kotlin_toolchain = __esm({
|
|
177
|
+
"src/kotlin-toolchain.ts"() {
|
|
178
|
+
"use strict";
|
|
179
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
180
|
+
import_node_child_process = require("node:child_process");
|
|
181
|
+
import_node_crypto = require("node:crypto");
|
|
182
|
+
import_node_fs = __toESM(require("node:fs"), 1);
|
|
183
|
+
import_node_path2 = __toESM(require("node:path"), 1);
|
|
184
|
+
import_node_util = require("node:util");
|
|
185
|
+
init_home_paths();
|
|
186
|
+
init_is_record();
|
|
187
|
+
run = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
188
|
+
toolchains = /* @__PURE__ */ new Map();
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// src/forked-script-contract.ts
|
|
193
|
+
var PEACH_FORKED_SCRIPT_ENV;
|
|
194
|
+
var init_forked_script_contract = __esm({
|
|
195
|
+
"src/forked-script-contract.ts"() {
|
|
196
|
+
"use strict";
|
|
197
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
198
|
+
PEACH_FORKED_SCRIPT_ENV = "PEACH_RUNS_FORKED_SCRIPTS";
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// src/android-gradle-sources.ts
|
|
203
|
+
var android_gradle_sources_exports = {};
|
|
204
|
+
__export(android_gradle_sources_exports, {
|
|
205
|
+
resolveAndroidGradleSources: () => resolveAndroidGradleSources
|
|
206
|
+
});
|
|
207
|
+
async function resolveAndroidGradleSources(request) {
|
|
208
|
+
let { root } = request;
|
|
209
|
+
const { projects: projectDirs, variant } = request;
|
|
210
|
+
if (projectDirs.length === 0) return [];
|
|
211
|
+
if (!import_node_path6.default.isAbsolute(root) || projectDirs.some((dir) => !import_node_path6.default.isAbsolute(dir)))
|
|
212
|
+
throw new Error("Android Gradle source selection requires absolute project paths");
|
|
213
|
+
if (!variant) throw new Error("Android Gradle source selection requires a variant");
|
|
214
|
+
root = import_node_fs5.default.realpathSync(root);
|
|
215
|
+
const projects = [...new Set(projectDirs.map((dir) => import_node_fs5.default.realpathSync(dir)))];
|
|
216
|
+
const parent = import_node_path6.default.join(kotlinHome(), "gradle-sources");
|
|
217
|
+
import_node_fs5.default.mkdirSync(parent, { recursive: true });
|
|
218
|
+
const work = import_node_fs5.default.mkdtempSync(import_node_path6.default.join(parent, ".query-"));
|
|
219
|
+
const task = `peachAndroidSources${(0, import_node_crypto5.randomBytes)(8).toString("hex")}`;
|
|
220
|
+
const script = import_node_path6.default.join(work, "sources.gradle");
|
|
221
|
+
const encoded = Buffer.from(
|
|
222
|
+
JSON.stringify({ root, projects, variant, output: work, task })
|
|
223
|
+
).toString("base64");
|
|
224
|
+
import_node_fs5.default.writeFileSync(script, modelQuery.replace("__PEACH_REQUEST__", encoded));
|
|
225
|
+
try {
|
|
226
|
+
await run4(
|
|
227
|
+
"bash",
|
|
228
|
+
[
|
|
229
|
+
import_node_path6.default.join(root, "gradlew"),
|
|
230
|
+
"--init-script",
|
|
231
|
+
script,
|
|
232
|
+
`${task}All`,
|
|
233
|
+
"--no-daemon",
|
|
234
|
+
"--no-configuration-cache",
|
|
235
|
+
"--max-workers=1",
|
|
236
|
+
"--console=plain"
|
|
237
|
+
],
|
|
238
|
+
{
|
|
239
|
+
cwd: root,
|
|
240
|
+
timeout: 3e5,
|
|
241
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
242
|
+
env: { ...process.env, [PEACH_FORKED_SCRIPT_ENV]: "1" }
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
return projects.map((projectDir, index) => {
|
|
246
|
+
const value = JSON.parse(
|
|
247
|
+
import_node_fs5.default.readFileSync(import_node_path6.default.join(work, `${index}.json`), "utf8")
|
|
248
|
+
);
|
|
249
|
+
if (!isRecord(value) || value.projectDir !== projectDir || value.variant !== variant || typeof value.projectPath !== "string" || value.applicationId !== null && typeof value.applicationId !== "string")
|
|
250
|
+
throw new Error("Gradle printed an invalid Android project source model");
|
|
251
|
+
const sources = (field) => {
|
|
252
|
+
const list = value[field];
|
|
253
|
+
if (!Array.isArray(list) || !list.every((file) => typeof file === "string" && import_node_path6.default.isAbsolute(file)))
|
|
254
|
+
throw new Error(`Gradle printed invalid Android ${field} source paths`);
|
|
255
|
+
return list.map(String);
|
|
256
|
+
};
|
|
257
|
+
return {
|
|
258
|
+
projectDir,
|
|
259
|
+
projectPath: value.projectPath,
|
|
260
|
+
variant,
|
|
261
|
+
applicationId: value.applicationId,
|
|
262
|
+
kotlin: sources("kotlin"),
|
|
263
|
+
java: sources("java")
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
} finally {
|
|
267
|
+
import_node_fs5.default.rmSync(work, { recursive: true, force: true });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
var import_node_child_process4, import_node_crypto5, import_node_fs5, import_node_path6, import_node_util4, run4, modelQuery;
|
|
271
|
+
var init_android_gradle_sources = __esm({
|
|
272
|
+
"src/android-gradle-sources.ts"() {
|
|
273
|
+
"use strict";
|
|
274
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
275
|
+
import_node_child_process4 = require("node:child_process");
|
|
276
|
+
import_node_crypto5 = require("node:crypto");
|
|
277
|
+
import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
278
|
+
import_node_path6 = __toESM(require("node:path"), 1);
|
|
279
|
+
import_node_util4 = require("node:util");
|
|
280
|
+
init_forked_script_contract();
|
|
281
|
+
init_is_record();
|
|
282
|
+
init_kotlin_toolchain();
|
|
283
|
+
run4 = (0, import_node_util4.promisify)(import_node_child_process4.execFile);
|
|
284
|
+
modelQuery = `
|
|
285
|
+
import groovy.json.JsonOutput
|
|
286
|
+
import groovy.json.JsonSlurper
|
|
287
|
+
|
|
288
|
+
def request = new JsonSlurper().parseText(new String(Base64.decoder.decode('__PEACH_REQUEST__'), 'UTF-8'))
|
|
289
|
+
gradle.projectsEvaluated {
|
|
290
|
+
if (gradle.rootProject.projectDir.canonicalPath != request.root) return
|
|
291
|
+
def selected = []
|
|
292
|
+
request.projects.eachWithIndex { directory, index ->
|
|
293
|
+
def matches = gradle.rootProject.allprojects.findAll { it.projectDir.canonicalPath == directory }
|
|
294
|
+
if (matches.size() != 1) throw new GradleException('Expected one Android project for ' + directory)
|
|
295
|
+
def project = matches[0]
|
|
296
|
+
if (project.pluginManager.hasPlugin('org.jetbrains.kotlin.multiplatform')) {
|
|
297
|
+
throw new GradleException('Kotlin multiplatform source selection is not supported: ' + project.path)
|
|
298
|
+
}
|
|
299
|
+
def library = project.pluginManager.hasPlugin('com.android.library')
|
|
300
|
+
if (!library && !project.pluginManager.hasPlugin('com.android.application')) {
|
|
301
|
+
throw new GradleException('Project has no Android application or library plugin: ' + project.path)
|
|
302
|
+
}
|
|
303
|
+
def android = project.extensions.getByName('android')
|
|
304
|
+
def variants = library ? android.libraryVariants : android.applicationVariants
|
|
305
|
+
def variant = variants.find { it.name == request.variant }
|
|
306
|
+
if (variant == null) throw new GradleException('Android variant ' + request.variant + ' is absent: ' + project.path)
|
|
307
|
+
def generators = []
|
|
308
|
+
def buildConfig = variant.generateBuildConfigProvider
|
|
309
|
+
if (buildConfig != null) generators.add(buildConfig)
|
|
310
|
+
if (project.pluginManager.hasPlugin('com.facebook.react')) {
|
|
311
|
+
generators.add(project.tasks.named('generateCodegenArtifactsFromSchema'))
|
|
312
|
+
}
|
|
313
|
+
def kotlin = project.tasks.findByName('compile' + variant.name.capitalize() + 'Kotlin')
|
|
314
|
+
def kotlinSources = kotlin == null ? project.files() : kotlin.sources
|
|
315
|
+
def javaSources = variant.javaCompileProvider.get().source
|
|
316
|
+
def query = project.tasks.register(request.task) {
|
|
317
|
+
dependsOn(generators)
|
|
318
|
+
dependsOn(kotlinSources.buildDependencies, javaSources.buildDependencies)
|
|
319
|
+
doLast {
|
|
320
|
+
def files = (kotlinSources.files + javaSources.files).unique()
|
|
321
|
+
def unknown = files.find { !it.name.endsWith('.kt') && !it.name.endsWith('.java') }
|
|
322
|
+
if (unknown != null) throw new GradleException('Unsupported Android source: ' + unknown)
|
|
323
|
+
new File(request.output, index.toString() + '.json').text = JsonOutput.toJson([
|
|
324
|
+
projectDir:project.projectDir.canonicalPath,
|
|
325
|
+
projectPath:project.path,
|
|
326
|
+
variant:variant.name,
|
|
327
|
+
applicationId:library ? null : variant.applicationId,
|
|
328
|
+
kotlin:files.findAll { it.name.endsWith('.kt') }.collect { it.absolutePath }.sort(),
|
|
329
|
+
java:files.findAll { it.name.endsWith('.java') }.collect { it.absolutePath }.sort()
|
|
330
|
+
])
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
selected.add(query)
|
|
334
|
+
}
|
|
335
|
+
gradle.rootProject.tasks.register(request.task + 'All') { dependsOn(selected) }
|
|
336
|
+
}
|
|
337
|
+
`;
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
|
|
32
341
|
// src/kotlin-host.ts
|
|
33
342
|
var kotlin_host_exports = {};
|
|
34
343
|
__export(kotlin_host_exports, {
|
|
@@ -44,21 +353,19 @@ __export(kotlin_host_exports, {
|
|
|
44
353
|
serveKotlinRequest: () => serveKotlinRequest
|
|
45
354
|
});
|
|
46
355
|
module.exports = __toCommonJS(kotlin_host_exports);
|
|
47
|
-
|
|
48
|
-
var
|
|
49
|
-
var
|
|
356
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
357
|
+
var import_node_child_process5 = require("node:child_process");
|
|
358
|
+
var import_node_crypto6 = require("node:crypto");
|
|
359
|
+
var import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
50
360
|
var import_node_module = require("node:module");
|
|
51
|
-
var
|
|
52
|
-
var
|
|
361
|
+
var import_node_path7 = __toESM(require("node:path"), 1);
|
|
362
|
+
var import_node_util5 = require("node:util");
|
|
53
363
|
var import_acorn2 = require("acorn");
|
|
54
364
|
|
|
55
|
-
// src/is-record.ts
|
|
56
|
-
function isRecord(value) {
|
|
57
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
365
|
// src/android-bridge-packages.ts
|
|
61
|
-
|
|
366
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
367
|
+
init_is_record();
|
|
368
|
+
function readBridgeMethod(value) {
|
|
62
369
|
if (!isRecord(value) || typeof value.name !== "string" || typeof value.blocking !== "boolean" || value.returns !== null && typeof value.returns !== "string" || !Array.isArray(value.params))
|
|
63
370
|
throw new Error("bridge-modules printed an invalid method");
|
|
64
371
|
return {
|
|
@@ -96,13 +403,136 @@ function readBridgeFiles(output) {
|
|
|
96
403
|
modules: row.modules.map((entry) => {
|
|
97
404
|
if (!isRecord(entry) || typeof entry.name !== "string" || !Array.isArray(entry.methods))
|
|
98
405
|
throw new Error("bridge-modules printed an invalid module");
|
|
99
|
-
return { name: entry.name, methods: entry.methods.map(
|
|
406
|
+
return { name: entry.name, methods: entry.methods.map(readBridgeMethod) };
|
|
100
407
|
})
|
|
101
408
|
};
|
|
102
409
|
});
|
|
103
410
|
}
|
|
104
411
|
|
|
412
|
+
// src/kotlin-host.ts
|
|
413
|
+
init_is_record();
|
|
414
|
+
|
|
415
|
+
// src/java-module-abi.ts
|
|
416
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
417
|
+
var import_node_child_process2 = require("node:child_process");
|
|
418
|
+
var import_node_crypto2 = require("node:crypto");
|
|
419
|
+
var import_node_fs2 = __toESM(require("node:fs"), 1);
|
|
420
|
+
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
421
|
+
var import_node_util2 = require("node:util");
|
|
422
|
+
init_is_record();
|
|
423
|
+
init_kotlin_toolchain();
|
|
424
|
+
var run2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
|
|
425
|
+
var JAVA_BINDINGS_INITIALIZER = "initializeJavaBindings";
|
|
426
|
+
async function readJavaModuleSpecs(files, sdkRoot, toolchain) {
|
|
427
|
+
const digest = (0, import_node_crypto2.createHash)("sha256");
|
|
428
|
+
const parent = import_node_path3.default.join(kotlinHome(), "java-specs");
|
|
429
|
+
import_node_fs2.default.mkdirSync(parent, { recursive: true });
|
|
430
|
+
const work = import_node_fs2.default.mkdtempSync(import_node_path3.default.join(parent, ".read-"));
|
|
431
|
+
try {
|
|
432
|
+
const origins = /* @__PURE__ */ new Map();
|
|
433
|
+
for (const [index, file] of files.entries()) {
|
|
434
|
+
const bytes = import_node_fs2.default.readFileSync(file);
|
|
435
|
+
digest.update(file).update("\0").update(bytes).update("\0");
|
|
436
|
+
const target = import_node_path3.default.join(work, String(index), import_node_path3.default.basename(file));
|
|
437
|
+
import_node_fs2.default.mkdirSync(import_node_path3.default.dirname(target));
|
|
438
|
+
import_node_fs2.default.writeFileSync(target, bytes);
|
|
439
|
+
origins.set(target, file);
|
|
440
|
+
}
|
|
441
|
+
const { stdout } = await run2(
|
|
442
|
+
import_node_path3.default.join(toolchain.javaHome, "bin", "java"),
|
|
443
|
+
[
|
|
444
|
+
"-cp",
|
|
445
|
+
[
|
|
446
|
+
import_node_path3.default.join(sdkRoot, "tools.jar"),
|
|
447
|
+
import_node_path3.default.resolve(import_node_path3.default.dirname(toolchain.kotlinc), "../lib/kotlin-compiler.jar"),
|
|
448
|
+
import_node_path3.default.resolve(import_node_path3.default.dirname(toolchain.kotlinc), "../lib/kotlin-stdlib.jar")
|
|
449
|
+
].join(import_node_path3.default.delimiter),
|
|
450
|
+
"dev.peach.tools.javaabi.JavaModuleSpecsKt",
|
|
451
|
+
...origins.keys()
|
|
452
|
+
],
|
|
453
|
+
{ maxBuffer: 16 * 1024 * 1024 }
|
|
454
|
+
);
|
|
455
|
+
const specs = stdout.split("\n").filter(Boolean).map((line) => {
|
|
456
|
+
const row = JSON.parse(line);
|
|
457
|
+
if (!isRecord(row) || typeof row.file !== "string" || typeof row.className !== "string" || row.name !== null && typeof row.name !== "string" || typeof row.source !== "string" || !Array.isArray(row.methods))
|
|
458
|
+
throw new Error("Java module reader printed an invalid spec");
|
|
459
|
+
const file = origins.get(row.file);
|
|
460
|
+
if (!file) throw new Error("Java module reader named an unknown input");
|
|
461
|
+
return {
|
|
462
|
+
file,
|
|
463
|
+
className: row.className,
|
|
464
|
+
name: row.name,
|
|
465
|
+
source: row.source,
|
|
466
|
+
methods: row.methods.map(readBridgeMethod)
|
|
467
|
+
};
|
|
468
|
+
});
|
|
469
|
+
return { sha256: digest.digest("hex"), specs };
|
|
470
|
+
} finally {
|
|
471
|
+
import_node_fs2.default.rmSync(work, { recursive: true, force: true });
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
async function compileJavaModuleAbi(input) {
|
|
475
|
+
const { specs, work, hash, toolchain, libraries, sdkRoot, sdkLibrary, language } = input;
|
|
476
|
+
const directory = import_node_path3.default.join(work, "java-abi");
|
|
477
|
+
import_node_fs2.default.mkdirSync(directory);
|
|
478
|
+
const sources = specs.specs.map((spec, index) => {
|
|
479
|
+
const target = import_node_path3.default.join(directory, `Spec${index}.kt`);
|
|
480
|
+
import_node_fs2.default.writeFileSync(target, spec.source);
|
|
481
|
+
return target;
|
|
482
|
+
});
|
|
483
|
+
const initializer = import_node_path3.default.join(directory, "Bindings.kt");
|
|
484
|
+
import_node_fs2.default.writeFileSync(
|
|
485
|
+
initializer,
|
|
486
|
+
[
|
|
487
|
+
"package dev.peach.jni",
|
|
488
|
+
`internal fun ${JAVA_BINDINGS_INITIALIZER}() { error("Java bindings require the compiler plugin") }`
|
|
489
|
+
].join("\n")
|
|
490
|
+
);
|
|
491
|
+
const name = `peach-java-abi-${hash}`;
|
|
492
|
+
await run2(
|
|
493
|
+
toolchain.kotlinc,
|
|
494
|
+
[
|
|
495
|
+
"-J-Xmx2g",
|
|
496
|
+
"-Xwasm-target=js",
|
|
497
|
+
"-libraries",
|
|
498
|
+
libraries.join(import_node_path3.default.delimiter),
|
|
499
|
+
`-Xplugin=${import_node_path3.default.join(sdkRoot, "plugin.jar")}`,
|
|
500
|
+
`-Xfriend-modules=${sdkLibrary}`,
|
|
501
|
+
"-language-version",
|
|
502
|
+
language,
|
|
503
|
+
"-api-version",
|
|
504
|
+
language,
|
|
505
|
+
"-nowarn",
|
|
506
|
+
"-ir-output-dir",
|
|
507
|
+
directory,
|
|
508
|
+
"-ir-output-name",
|
|
509
|
+
name,
|
|
510
|
+
...sources,
|
|
511
|
+
initializer
|
|
512
|
+
],
|
|
513
|
+
{ maxBuffer: 16 * 1024 * 1024 }
|
|
514
|
+
);
|
|
515
|
+
const library = import_node_path3.default.join(directory, "java-abi.klib");
|
|
516
|
+
await run2(
|
|
517
|
+
import_node_path3.default.join(toolchain.javaHome, "bin", "java"),
|
|
518
|
+
[
|
|
519
|
+
"-cp",
|
|
520
|
+
[
|
|
521
|
+
import_node_path3.default.join(sdkRoot, "tools.jar"),
|
|
522
|
+
import_node_path3.default.resolve(import_node_path3.default.dirname(toolchain.kotlinc), "../lib/kotlin-compiler.jar"),
|
|
523
|
+
import_node_path3.default.resolve(import_node_path3.default.dirname(toolchain.kotlinc), "../lib/kotlin-stdlib.jar")
|
|
524
|
+
].join(import_node_path3.default.delimiter),
|
|
525
|
+
"dev.peach.tools.platform.JavaPlatformTypesKt",
|
|
526
|
+
import_node_path3.default.join(directory, `${name}.klib`),
|
|
527
|
+
library
|
|
528
|
+
],
|
|
529
|
+
{ maxBuffer: 16 * 1024 * 1024 }
|
|
530
|
+
);
|
|
531
|
+
return library;
|
|
532
|
+
}
|
|
533
|
+
|
|
105
534
|
// src/kotlin-instance-source.ts
|
|
535
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
106
536
|
var import_acorn = require("acorn");
|
|
107
537
|
function bindingNames(pattern) {
|
|
108
538
|
if (pattern.type === "Identifier") return [pattern.name];
|
|
@@ -209,139 +639,17 @@ return { peachDisposeInstance, ${exports2.map((item) => `${JSON.stringify(item.e
|
|
|
209
639
|
}
|
|
210
640
|
|
|
211
641
|
// src/kotlin-sdk.ts
|
|
212
|
-
|
|
213
|
-
var
|
|
214
|
-
var
|
|
215
|
-
var
|
|
216
|
-
var
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
var import_node_child_process = require("node:child_process");
|
|
220
|
-
var import_node_crypto = require("node:crypto");
|
|
221
|
-
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
222
|
-
var import_node_path2 = __toESM(require("node:path"), 1);
|
|
223
|
-
var import_node_util = require("node:util");
|
|
224
|
-
|
|
225
|
-
// src/home-paths.ts
|
|
226
|
-
var import_node_os = require("node:os");
|
|
227
|
-
var import_node_path = __toESM(require("node:path"), 1);
|
|
228
|
-
var PEACH_HOME_ENV = "PEACH_HOME";
|
|
229
|
-
function ambientHomeDir() {
|
|
230
|
-
return import_node_path.default.join((0, import_node_os.homedir)(), ".peach");
|
|
231
|
-
}
|
|
232
|
-
function rnxHomeDir() {
|
|
233
|
-
const override = process.env[PEACH_HOME_ENV];
|
|
234
|
-
return override && override.length > 0 ? import_node_path.default.resolve(override) : ambientHomeDir();
|
|
235
|
-
}
|
|
236
|
-
var DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
|
|
237
|
-
|
|
238
|
-
// src/kotlin-toolchain.ts
|
|
239
|
-
var run = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
240
|
-
function readToolchain(moduleRoot) {
|
|
241
|
-
const parsed = JSON.parse(
|
|
242
|
-
import_node_fs.default.readFileSync(import_node_path2.default.join(moduleRoot, "toolchain.json"), "utf8")
|
|
243
|
-
);
|
|
244
|
-
const download = (value) => {
|
|
245
|
-
if (!isRecord(value) || typeof value.url !== "string" || typeof value.sha256 !== "string")
|
|
246
|
-
throw new Error(
|
|
247
|
-
"peachsim kotlin/toolchain.json names a download without url and sha256"
|
|
248
|
-
);
|
|
249
|
-
return { url: value.url, sha256: value.sha256 };
|
|
250
|
-
};
|
|
251
|
-
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")
|
|
252
|
-
throw new Error("peachsim kotlin/toolchain.json has no compiler and libraries");
|
|
253
|
-
const version = parsed.compiler.version;
|
|
254
|
-
if (typeof version !== "string")
|
|
255
|
-
throw new Error("peachsim kotlin/toolchain.json has no compiler version");
|
|
256
|
-
const libraries = (values) => values.map((library) => {
|
|
257
|
-
if (!isRecord(library) || typeof library.name !== "string")
|
|
258
|
-
throw new Error("peachsim kotlin/toolchain.json names a library without a name");
|
|
259
|
-
return { ...download(library), name: library.name };
|
|
260
|
-
});
|
|
261
|
-
return {
|
|
262
|
-
compiler: { ...download(parsed.compiler), version },
|
|
263
|
-
libraries: libraries(parsed.libraries),
|
|
264
|
-
composeLibraries: libraries(parsed.composeLibraries),
|
|
265
|
-
composeRuntime: {
|
|
266
|
-
...download(parsed.composeRuntime),
|
|
267
|
-
name: parsed.composeRuntime.name
|
|
268
|
-
},
|
|
269
|
-
composeJsLibraries: parsed.composeJsLibraries.map((library) => {
|
|
270
|
-
if (!isRecord(library) || typeof library.name !== "string" || typeof library.module !== "string" || typeof library.file !== "string" || typeof library.archiveEntry !== "string")
|
|
271
|
-
throw new Error("peachsim kotlin/toolchain.json has an incomplete JS library");
|
|
272
|
-
return {
|
|
273
|
-
...download(library),
|
|
274
|
-
name: library.name,
|
|
275
|
-
module: library.module,
|
|
276
|
-
file: library.file,
|
|
277
|
-
archiveEntry: library.archiveEntry
|
|
278
|
-
};
|
|
279
|
-
})
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
function kotlinHome() {
|
|
283
|
-
return import_node_path2.default.join(rnxHomeDir(), "kotlin");
|
|
284
|
-
}
|
|
285
|
-
async function fetchVerified(download, target) {
|
|
286
|
-
if (import_node_fs.default.existsSync(target)) {
|
|
287
|
-
if ((0, import_node_crypto.createHash)("sha256").update(import_node_fs.default.readFileSync(target)).digest("hex") !== download.sha256)
|
|
288
|
-
throw new Error(
|
|
289
|
-
`cached Kotlin download differs from its pin: ${import_node_path2.default.basename(target)}`
|
|
290
|
-
);
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
const response = await fetch(download.url);
|
|
294
|
-
if (!response.ok) throw new Error(`${download.url} answered ${response.status}`);
|
|
295
|
-
const bytes = Buffer.from(await response.arrayBuffer());
|
|
296
|
-
const digest = (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
297
|
-
if (digest !== download.sha256)
|
|
298
|
-
throw new Error(`${download.url} has sha256 ${digest}, expected ${download.sha256}`);
|
|
299
|
-
import_node_fs.default.mkdirSync(import_node_path2.default.dirname(target), { recursive: true });
|
|
300
|
-
const partial = `${target}.${process.pid}.partial`;
|
|
301
|
-
import_node_fs.default.writeFileSync(partial, bytes);
|
|
302
|
-
import_node_fs.default.renameSync(partial, target);
|
|
303
|
-
}
|
|
304
|
-
var toolchains = /* @__PURE__ */ new Map();
|
|
305
|
-
function ensureToolchain(toolchain) {
|
|
306
|
-
const key = JSON.stringify(toolchain);
|
|
307
|
-
const pending = toolchains.get(key);
|
|
308
|
-
if (pending) return pending;
|
|
309
|
-
const ready = (async () => {
|
|
310
|
-
const dir = import_node_path2.default.join(kotlinHome(), toolchain.compiler.version);
|
|
311
|
-
const kotlinc = import_node_path2.default.join(dir, "kotlinc", "bin", "kotlinc-wasm");
|
|
312
|
-
if (!import_node_fs.default.existsSync(kotlinc)) {
|
|
313
|
-
const zip = import_node_path2.default.join(dir, "kotlin-compiler.zip");
|
|
314
|
-
await fetchVerified(toolchain.compiler, zip);
|
|
315
|
-
await run("unzip", ["-q", "-o", zip, "-d", dir]);
|
|
316
|
-
import_node_fs.default.rmSync(zip);
|
|
317
|
-
}
|
|
318
|
-
const java = process.env.JAVA_HOME ? import_node_path2.default.join(process.env.JAVA_HOME, "bin", "java") : "java";
|
|
319
|
-
const { stderr } = await run(java, ["-XshowSettings:properties", "-version"]).catch(
|
|
320
|
-
() => {
|
|
321
|
-
throw new Error(
|
|
322
|
-
`Kotlin in Peach compiles with kotlinc, which needs a Java runtime (17 or newer, as android builds use); ${process.env.JAVA_HOME ? `JAVA_HOME ${process.env.JAVA_HOME} has none` : "set JAVA_HOME or put java on PATH"}`
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
);
|
|
326
|
-
const javaHome = /^\s*java\.home\s*=\s*(.+)$/m.exec(stderr)?.[1]?.trim();
|
|
327
|
-
if (!javaHome || !import_node_path2.default.isAbsolute(javaHome))
|
|
328
|
-
throw new Error("the configured Java runtime did not report an absolute java.home");
|
|
329
|
-
const libraries = [import_node_path2.default.join(dir, "kotlinc", "lib", "kotlin-stdlib-wasm-js.klib")];
|
|
330
|
-
for (const library of toolchain.libraries) {
|
|
331
|
-
const target = import_node_path2.default.join(dir, library.name);
|
|
332
|
-
await fetchVerified(library, target);
|
|
333
|
-
libraries.push(target);
|
|
334
|
-
}
|
|
335
|
-
return { kotlinc, libraries, javaHome };
|
|
336
|
-
})().catch((error) => {
|
|
337
|
-
toolchains.delete(key);
|
|
338
|
-
throw error;
|
|
339
|
-
});
|
|
340
|
-
toolchains.set(key, ready);
|
|
341
|
-
return ready;
|
|
342
|
-
}
|
|
642
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
643
|
+
var import_node_child_process3 = require("node:child_process");
|
|
644
|
+
var import_node_crypto3 = require("node:crypto");
|
|
645
|
+
var import_node_fs3 = __toESM(require("node:fs"), 1);
|
|
646
|
+
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
647
|
+
var import_node_util3 = require("node:util");
|
|
648
|
+
init_kotlin_toolchain();
|
|
343
649
|
|
|
344
650
|
// src/kotlinSdkContract.ts
|
|
651
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
652
|
+
init_is_record();
|
|
345
653
|
var platform = ["Sources", "JniPlatformSources", "JniSources"];
|
|
346
654
|
var KOTLIN_SDK_PROFILES = {
|
|
347
655
|
core: { compose: false, directories: platform },
|
|
@@ -402,62 +710,67 @@ function readKotlinSdkManifest(source, compilerSha256) {
|
|
|
402
710
|
}
|
|
403
711
|
|
|
404
712
|
// src/kotlin-sdk.ts
|
|
405
|
-
var
|
|
713
|
+
var run3 = (0, import_node_util3.promisify)(import_node_child_process3.execFile);
|
|
406
714
|
function verifyKotlinSdkDirectory(root, compilerSha256) {
|
|
407
715
|
const expectedNames = ["manifest.json", ...KOTLIN_SDK_FILES];
|
|
408
|
-
const names =
|
|
716
|
+
const names = import_node_fs3.default.readdirSync(root);
|
|
409
717
|
if (names.length !== expectedNames.length || names.some((name) => !expectedNames.includes(name)))
|
|
410
718
|
throw new Error("Kotlin SDK directory contains unexpected inputs");
|
|
411
|
-
const manifestStat =
|
|
719
|
+
const manifestStat = import_node_fs3.default.lstatSync(import_node_path4.default.join(root, "manifest.json"));
|
|
412
720
|
if (!manifestStat.isFile() || manifestStat.nlink !== 1)
|
|
413
721
|
throw new Error("Kotlin SDK manifest is not a regular file");
|
|
414
722
|
const manifest = readKotlinSdkManifest(
|
|
415
|
-
|
|
723
|
+
import_node_fs3.default.readFileSync(import_node_path4.default.join(root, "manifest.json"), "utf8"),
|
|
416
724
|
compilerSha256
|
|
417
725
|
);
|
|
418
726
|
for (const [name, expected] of Object.entries(manifest.files)) {
|
|
419
|
-
const target =
|
|
420
|
-
const stat =
|
|
727
|
+
const target = import_node_path4.default.join(root, name);
|
|
728
|
+
const stat = import_node_fs3.default.lstatSync(target);
|
|
421
729
|
if (!stat.isFile() || stat.nlink !== 1)
|
|
422
730
|
throw new Error(`Kotlin SDK binary is not a regular file: ${name}`);
|
|
423
|
-
const bytes =
|
|
424
|
-
if (bytes.length !== expected.bytes || (0,
|
|
731
|
+
const bytes = import_node_fs3.default.readFileSync(target);
|
|
732
|
+
if (bytes.length !== expected.bytes || (0, import_node_crypto3.createHash)("sha256").update(bytes).digest("hex") !== expected.sha256)
|
|
425
733
|
throw new Error(`Kotlin SDK binary differs from its manifest: ${name}`);
|
|
426
734
|
}
|
|
427
735
|
return manifest;
|
|
428
736
|
}
|
|
429
737
|
async function installKotlinSdkArchive(archive, compilerSha256) {
|
|
430
|
-
const sha256 = (0,
|
|
431
|
-
const parent =
|
|
432
|
-
const root =
|
|
433
|
-
if (
|
|
738
|
+
const sha256 = (0, import_node_crypto3.createHash)("sha256").update(archive).digest("hex");
|
|
739
|
+
const parent = import_node_path4.default.join(kotlinHome(), "sdk");
|
|
740
|
+
const root = import_node_path4.default.join(parent, sha256);
|
|
741
|
+
if (import_node_fs3.default.existsSync(root))
|
|
434
742
|
return { root, sha256, manifest: verifyKotlinSdkDirectory(root, compilerSha256) };
|
|
435
|
-
|
|
436
|
-
const work =
|
|
743
|
+
import_node_fs3.default.mkdirSync(parent, { recursive: true });
|
|
744
|
+
const work = import_node_fs3.default.mkdtempSync(import_node_path4.default.join(parent, ".install-"));
|
|
437
745
|
try {
|
|
438
|
-
const packed =
|
|
439
|
-
|
|
440
|
-
const { stdout } = await
|
|
746
|
+
const packed = import_node_path4.default.join(work, "sdk.tar.gz");
|
|
747
|
+
import_node_fs3.default.writeFileSync(packed, archive);
|
|
748
|
+
const { stdout } = await run3("tar", ["-tzf", packed]);
|
|
441
749
|
const names = stdout.trim().split("\n");
|
|
442
750
|
const expected = ["manifest.json", ...KOTLIN_SDK_FILES];
|
|
443
751
|
if (names.length !== expected.length || new Set(names).size !== names.length || names.some((name) => !expected.includes(name)))
|
|
444
752
|
throw new Error("Kotlin SDK archive contains unexpected inputs");
|
|
445
|
-
await
|
|
446
|
-
|
|
753
|
+
await run3("tar", ["-xzf", packed, "-C", work, "--", ...expected]);
|
|
754
|
+
import_node_fs3.default.rmSync(packed);
|
|
447
755
|
const manifest = verifyKotlinSdkDirectory(work, compilerSha256);
|
|
448
756
|
try {
|
|
449
|
-
|
|
757
|
+
import_node_fs3.default.renameSync(work, root);
|
|
450
758
|
} catch (error) {
|
|
451
|
-
if (!
|
|
759
|
+
if (!import_node_fs3.default.existsSync(root)) throw error;
|
|
452
760
|
verifyKotlinSdkDirectory(root, compilerSha256);
|
|
453
761
|
}
|
|
454
762
|
return { root, sha256, manifest };
|
|
455
763
|
} finally {
|
|
456
|
-
|
|
764
|
+
import_node_fs3.default.rmSync(work, { recursive: true, force: true });
|
|
457
765
|
}
|
|
458
766
|
}
|
|
459
767
|
|
|
768
|
+
// src/kotlin-host.ts
|
|
769
|
+
init_kotlin_toolchain();
|
|
770
|
+
|
|
460
771
|
// src/kotlin-view-models.ts
|
|
772
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
773
|
+
init_is_record();
|
|
461
774
|
var VIEW_MODEL = "androidx.lifecycle.ViewModel";
|
|
462
775
|
var ANDROID_VIEW_MODEL = "androidx.lifecycle.AndroidViewModel";
|
|
463
776
|
var APPLICATION = "android.app.Application";
|
|
@@ -533,45 +846,49 @@ function viewModelClasses(rows) {
|
|
|
533
846
|
}
|
|
534
847
|
|
|
535
848
|
// src/kotlin-module.ts
|
|
536
|
-
|
|
537
|
-
var
|
|
538
|
-
var
|
|
849
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
850
|
+
var import_node_crypto4 = require("node:crypto");
|
|
851
|
+
var import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
852
|
+
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
539
853
|
var import_node_url = require("node:url");
|
|
540
854
|
|
|
541
855
|
// cli/standalone.ts
|
|
856
|
+
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
542
857
|
var IS_STANDALONE = typeof __SOOTSIM_STANDALONE__ !== "undefined" && __SOOTSIM_STANDALONE__;
|
|
543
858
|
|
|
544
859
|
// src/kotlin-module.ts
|
|
860
|
+
init_home_paths();
|
|
861
|
+
init_is_record();
|
|
545
862
|
var installedRoot;
|
|
546
863
|
function peachKotlinModuleRoot() {
|
|
547
864
|
if (!IS_STANDALONE)
|
|
548
|
-
return
|
|
865
|
+
return import_node_path5.default.resolve(import_node_path5.default.dirname((0, import_node_url.fileURLToPath)(__sootsim_import_meta_url)), "..", "kotlin");
|
|
549
866
|
if (installedRoot) return installedRoot;
|
|
550
867
|
const files = __PEACH_BUNDLED_KOTLIN__;
|
|
551
|
-
const digest = (0,
|
|
552
|
-
const parent =
|
|
553
|
-
const root =
|
|
554
|
-
|
|
555
|
-
if (!
|
|
556
|
-
const pending =
|
|
868
|
+
const digest = (0, import_node_crypto4.createHash)("sha256").update(JSON.stringify(files)).digest("hex");
|
|
869
|
+
const parent = import_node_path5.default.join(rnxHomeDir(), "kotlin", "modules");
|
|
870
|
+
const root = import_node_path5.default.join(parent, digest);
|
|
871
|
+
import_node_fs4.default.mkdirSync(parent, { recursive: true });
|
|
872
|
+
if (!import_node_fs4.default.existsSync(root)) {
|
|
873
|
+
const pending = import_node_fs4.default.mkdtempSync(import_node_path5.default.join(parent, ".install-"));
|
|
557
874
|
try {
|
|
558
875
|
for (const [name, contents] of Object.entries(files)) {
|
|
559
|
-
const file =
|
|
560
|
-
|
|
561
|
-
|
|
876
|
+
const file = import_node_path5.default.join(pending, name);
|
|
877
|
+
import_node_fs4.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true });
|
|
878
|
+
import_node_fs4.default.writeFileSync(file, Buffer.from(contents, "base64"));
|
|
562
879
|
}
|
|
563
880
|
try {
|
|
564
|
-
|
|
881
|
+
import_node_fs4.default.renameSync(pending, root);
|
|
565
882
|
} catch (error) {
|
|
566
883
|
if (!isRecord(error) || error.code !== "EEXIST" && error.code !== "ENOTEMPTY")
|
|
567
884
|
throw error;
|
|
568
885
|
}
|
|
569
886
|
} finally {
|
|
570
|
-
|
|
887
|
+
import_node_fs4.default.rmSync(pending, { recursive: true, force: true });
|
|
571
888
|
}
|
|
572
889
|
}
|
|
573
890
|
for (const [name, contents] of Object.entries(files)) {
|
|
574
|
-
if (!
|
|
891
|
+
if (!import_node_fs4.default.readFileSync(import_node_path5.default.join(root, name)).equals(Buffer.from(contents, "base64")))
|
|
575
892
|
throw new Error(`packaged Kotlin module differs from this CLI: ${name}`);
|
|
576
893
|
}
|
|
577
894
|
installedRoot = root;
|
|
@@ -579,20 +896,20 @@ function peachKotlinModuleRoot() {
|
|
|
579
896
|
}
|
|
580
897
|
|
|
581
898
|
// src/kotlin-host.ts
|
|
582
|
-
var
|
|
899
|
+
var run5 = (0, import_node_util5.promisify)(import_node_child_process5.execFile);
|
|
583
900
|
function loadKotlinSdk(moduleRoot, toolchain) {
|
|
584
901
|
return installKotlinSdkArchive(
|
|
585
|
-
|
|
902
|
+
import_node_fs6.default.readFileSync(import_node_path7.default.join(moduleRoot, "sdk.tar.gz")),
|
|
586
903
|
toolchain.compiler.sha256
|
|
587
904
|
);
|
|
588
905
|
}
|
|
589
906
|
var KOTLIN_ARTIFACT_PREFIX = "/__peach/kotlin-artifact/";
|
|
590
907
|
function appKotlinLanguage(root) {
|
|
591
|
-
const reactNative =
|
|
592
|
-
(0, import_node_module.createRequire)(
|
|
908
|
+
const reactNative = import_node_path7.default.dirname(
|
|
909
|
+
(0, import_node_module.createRequire)(import_node_path7.default.join(root, "package.json")).resolve("react-native/package.json")
|
|
593
910
|
);
|
|
594
|
-
const versions =
|
|
595
|
-
|
|
911
|
+
const versions = import_node_fs6.default.readFileSync(
|
|
912
|
+
import_node_path7.default.join(reactNative, "gradle", "libs.versions.toml"),
|
|
596
913
|
"utf8"
|
|
597
914
|
);
|
|
598
915
|
const match = /^kotlin\s*=\s*"(\d+)\.(\d+)/m.exec(versions);
|
|
@@ -614,9 +931,9 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
614
931
|
function kotlinSources(root, skip = SKIP_DIRS) {
|
|
615
932
|
const sources = [];
|
|
616
933
|
const walk = (dir) => {
|
|
617
|
-
for (const entry of
|
|
934
|
+
for (const entry of import_node_fs6.default.readdirSync(dir, { withFileTypes: true })) {
|
|
618
935
|
if (entry.name.startsWith(".") || skip.has(entry.name)) continue;
|
|
619
|
-
const full =
|
|
936
|
+
const full = import_node_path7.default.join(dir, entry.name);
|
|
620
937
|
if (entry.isDirectory()) walk(full);
|
|
621
938
|
else if (entry.isFile() && entry.name.endsWith(".kt")) sources.push(full);
|
|
622
939
|
}
|
|
@@ -644,11 +961,12 @@ function entrySource(ids) {
|
|
|
644
961
|
"",
|
|
645
962
|
"@OptIn(kotlin.js.ExperimentalJsExport::class)",
|
|
646
963
|
"@JsExport",
|
|
647
|
-
"fun peachSetAndroidDeviceInfo(model: String, release: String, apiLevel: Int, locale: String, timeZone: String, settings: String) {",
|
|
964
|
+
"fun peachSetAndroidDeviceInfo(model: String, release: String, apiLevel: Int, locale: String, timeZone: String, settings: String, properties: String) {",
|
|
648
965
|
" Build.setDevice(model, release, apiLevel)",
|
|
649
966
|
" java.util.Locale.setDefault(java.util.Locale.forLanguageTag(locale))",
|
|
650
967
|
" java.util.TimeZone.setDevice(timeZone)",
|
|
651
968
|
" dev.peach.android.ProcessSettings.configure(settings)",
|
|
969
|
+
" android.os.SystemProperties.configure(properties)",
|
|
652
970
|
"}",
|
|
653
971
|
"",
|
|
654
972
|
"@OptIn(kotlin.js.ExperimentalJsExport::class, kotlinx.coroutines.DelicateCoroutinesApi::class)",
|
|
@@ -679,7 +997,7 @@ function entrySource(ids) {
|
|
|
679
997
|
var BUILD_FORMAT = 19;
|
|
680
998
|
var builds = /* @__PURE__ */ new Map();
|
|
681
999
|
function buildsDir() {
|
|
682
|
-
return
|
|
1000
|
+
return import_node_path7.default.join(kotlinHome(), "builds");
|
|
683
1001
|
}
|
|
684
1002
|
async function kotlinArtifact(root, moduleRoot, origin, target = "app") {
|
|
685
1003
|
const { kotlinSourceId, nativeSourceContract, renderKotlinSourceGlue } = await import("vxrn/native-source-contract");
|
|
@@ -692,7 +1010,7 @@ async function kotlinArtifact(root, moduleRoot, origin, target = "app") {
|
|
|
692
1010
|
const viewIds = [];
|
|
693
1011
|
let usesCompose = false;
|
|
694
1012
|
for (const file of sources) {
|
|
695
|
-
const source =
|
|
1013
|
+
const source = import_node_fs6.default.readFileSync(file, "utf8");
|
|
696
1014
|
if (/\bandroidx\.compose\./.test(source)) usesCompose = true;
|
|
697
1015
|
const contract = nativeSourceContract(file, source);
|
|
698
1016
|
if (contract.modules.length === 0 && contract.views.length === 0) continue;
|
|
@@ -782,24 +1100,24 @@ function readExpoTypes(output) {
|
|
|
782
1100
|
}
|
|
783
1101
|
var toolScans = /* @__PURE__ */ new Map();
|
|
784
1102
|
async function scanSources(tool, parse3, toolchain, moduleRoot, files) {
|
|
785
|
-
const digest = (0,
|
|
1103
|
+
const digest = (0, import_node_crypto6.createHash)("sha256").update(JSON.stringify(toolchain.compiler));
|
|
786
1104
|
const sdk = await loadKotlinSdk(moduleRoot, toolchain);
|
|
787
|
-
digest.update(
|
|
1105
|
+
digest.update(import_node_fs6.default.readFileSync(import_node_path7.default.join(moduleRoot, "sdk.tar.gz")));
|
|
788
1106
|
digest.update(tool);
|
|
789
|
-
for (const file of files) digest.update(`${file}\0${
|
|
1107
|
+
for (const file of files) digest.update(`${file}\0${import_node_fs6.default.readFileSync(file, "utf8")}\0`);
|
|
790
1108
|
const key = digest.digest("hex");
|
|
791
1109
|
let scan = toolScans.get(key);
|
|
792
1110
|
if (!scan) {
|
|
793
1111
|
scan = (async () => {
|
|
794
1112
|
const { kotlinc } = await ensureToolchain(toolchain);
|
|
795
|
-
const { stdout } = await
|
|
796
|
-
|
|
1113
|
+
const { stdout } = await run5(
|
|
1114
|
+
import_node_path7.default.join(import_node_path7.default.dirname(kotlinc), "kotlin"),
|
|
797
1115
|
[
|
|
798
1116
|
"-cp",
|
|
799
1117
|
[
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
].join(
|
|
1118
|
+
import_node_path7.default.resolve(import_node_path7.default.dirname(kotlinc), "../lib/kotlin-compiler.jar"),
|
|
1119
|
+
import_node_path7.default.join(sdk.root, "tools.jar")
|
|
1120
|
+
].join(import_node_path7.default.delimiter),
|
|
803
1121
|
tool,
|
|
804
1122
|
...files
|
|
805
1123
|
],
|
|
@@ -817,7 +1135,7 @@ async function scanSources(tool, parse3, toolchain, moduleRoot, files) {
|
|
|
817
1135
|
async function scanExpoTypes(toolchain, moduleRoot, sources) {
|
|
818
1136
|
const candidates = sources.filter(
|
|
819
1137
|
(file) => /\bRecord\b|\benum\s+class\b|\bExpoComposeView\b|\bExpoView\b|\bComposeProps\b|:\s*(?:[A-Za-z0-9_.]+\.)?(?:View|FrameLayout|LinearLayout|ViewGroup)\b/.test(
|
|
820
|
-
|
|
1138
|
+
import_node_fs6.default.readFileSync(file, "utf8")
|
|
821
1139
|
)
|
|
822
1140
|
);
|
|
823
1141
|
if (candidates.length === 0) return [];
|
|
@@ -1006,7 +1324,7 @@ function expoTypeSources(files) {
|
|
|
1006
1324
|
)
|
|
1007
1325
|
];
|
|
1008
1326
|
if (edits.length > 0 || views.length > 0) {
|
|
1009
|
-
let text =
|
|
1327
|
+
let text = import_node_fs6.default.readFileSync(file.file, "utf8").replaceAll("\r\n", "\n");
|
|
1010
1328
|
for (const { range, owner, field } of edits.sort((a, b) => b.range[0] - a.range[0]))
|
|
1011
1329
|
text = `${text.slice(0, range[0])}dev.peach.expo.PeachExpoTypes.initial(${owner}::class, ${literal(field.key)}, ${field.required}) { ${text.slice(range[0], range[1])} }${text.slice(range[1])}`;
|
|
1012
1330
|
if (views.length > 0) {
|
|
@@ -1022,7 +1340,7 @@ function expoTypeSources(files) {
|
|
|
1022
1340
|
`${file.package ? `${file.package}.` : ""}peachExpoViews${index}()`
|
|
1023
1341
|
);
|
|
1024
1342
|
}
|
|
1025
|
-
const name = `PeachExpoSource_${index}_${
|
|
1343
|
+
const name = `PeachExpoSource_${index}_${import_node_path7.default.basename(file.file)}`;
|
|
1026
1344
|
generated[name] = text;
|
|
1027
1345
|
origins[name] = file.file;
|
|
1028
1346
|
}
|
|
@@ -1041,11 +1359,30 @@ function expoTypeSources(files) {
|
|
|
1041
1359
|
return { generated, origins, registrations };
|
|
1042
1360
|
}
|
|
1043
1361
|
async function expoKotlinArtifact(root, moduleRoot, origin, modules) {
|
|
1362
|
+
if (modules.gradleSources) {
|
|
1363
|
+
const { resolveAndroidGradleSources: resolveAndroidGradleSources2 } = await Promise.resolve().then(() => (init_android_gradle_sources(), android_gradle_sources_exports));
|
|
1364
|
+
const projects = await resolveAndroidGradleSources2(modules.gradleSources);
|
|
1365
|
+
modules = {
|
|
1366
|
+
...modules,
|
|
1367
|
+
sources: [
|
|
1368
|
+
.../* @__PURE__ */ new Set([
|
|
1369
|
+
...modules.sources,
|
|
1370
|
+
...projects.flatMap((project) => project.kotlin)
|
|
1371
|
+
])
|
|
1372
|
+
],
|
|
1373
|
+
javaSpecs: [
|
|
1374
|
+
.../* @__PURE__ */ new Set([
|
|
1375
|
+
...modules.javaSpecs ?? [],
|
|
1376
|
+
...projects.flatMap((project) => project.java)
|
|
1377
|
+
])
|
|
1378
|
+
]
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1044
1381
|
const toolchain = readToolchain(moduleRoot);
|
|
1045
1382
|
const language = appKotlinLanguage(root);
|
|
1046
1383
|
const scanned = await scanExpoTypes(toolchain, moduleRoot, modules.sources);
|
|
1047
1384
|
const usesCompose = scanned.some((file) => file.views.length > 0) || modules.sources.some(
|
|
1048
|
-
(file) => /\bandroidx\.compose\./.test(
|
|
1385
|
+
(file) => /\bandroidx\.compose\./.test(import_node_fs6.default.readFileSync(file, "utf8"))
|
|
1049
1386
|
);
|
|
1050
1387
|
const types = expoTypeSources(scanned);
|
|
1051
1388
|
const rewritten = new Set(Object.values(types.origins));
|
|
@@ -1064,11 +1401,12 @@ async function expoKotlinArtifact(root, moduleRoot, origin, modules) {
|
|
|
1064
1401
|
" ))",
|
|
1065
1402
|
"}",
|
|
1066
1403
|
"",
|
|
1067
|
-
"@JsExport fun peachSetAndroidDeviceInfo(model: String, release: String, apiLevel: Int, locale: String, timeZone: String, settings: String) {",
|
|
1404
|
+
"@JsExport fun peachSetAndroidDeviceInfo(model: String, release: String, apiLevel: Int, locale: String, timeZone: String, settings: String, properties: String) {",
|
|
1068
1405
|
" android.os.Build.setDevice(model, release, apiLevel)",
|
|
1069
1406
|
" java.util.Locale.setDefault(java.util.Locale.forLanguageTag(locale))",
|
|
1070
1407
|
" java.util.TimeZone.setDevice(timeZone)",
|
|
1071
1408
|
" dev.peach.android.ProcessSettings.configure(settings)",
|
|
1409
|
+
" android.os.SystemProperties.configure(properties)",
|
|
1072
1410
|
" PeachExpoRuntime.configureProcessLocale(locale)",
|
|
1073
1411
|
"}",
|
|
1074
1412
|
"",
|
|
@@ -1090,6 +1428,7 @@ async function expoKotlinArtifact(root, moduleRoot, origin, modules) {
|
|
|
1090
1428
|
toolchain,
|
|
1091
1429
|
language,
|
|
1092
1430
|
sources: modules.sources.filter((file) => !rewritten.has(file)),
|
|
1431
|
+
javaSpecs: modules.javaSpecs,
|
|
1093
1432
|
generated: {
|
|
1094
1433
|
...types.generated,
|
|
1095
1434
|
"PeachExpoEntry.kt": entry,
|
|
@@ -1270,7 +1609,7 @@ function appResourceSources(app) {
|
|
|
1270
1609
|
entries: app.drawables.map((drawable) => ({
|
|
1271
1610
|
name: drawable.name,
|
|
1272
1611
|
init: `listOf(
|
|
1273
|
-
${drawable.files.map((file) => drawableInit(file,
|
|
1612
|
+
${drawable.files.map((file) => drawableInit(file, import_node_path7.default.relative(app.moduleDir, file.file))).join(",\n")}
|
|
1274
1613
|
)`
|
|
1275
1614
|
}))
|
|
1276
1615
|
},
|
|
@@ -1339,7 +1678,7 @@ function drawableInit(drawable, file) {
|
|
|
1339
1678
|
if (drawable.kind === "xml") return `PeachDrawable.Xml(${where})`;
|
|
1340
1679
|
if (drawable.kind === "bitmap")
|
|
1341
1680
|
return `PeachDrawable.Bitmap(${where}, ${drawable.ninePatch}, ${literal(
|
|
1342
|
-
|
|
1681
|
+
import_node_fs6.default.readFileSync(drawable.file).toString("base64")
|
|
1343
1682
|
)})`;
|
|
1344
1683
|
const vector = drawable.vector;
|
|
1345
1684
|
const float = (value) => `${value}f`;
|
|
@@ -1399,11 +1738,13 @@ async function compileKotlin(input, origin) {
|
|
|
1399
1738
|
sdkProfile,
|
|
1400
1739
|
usesCompose,
|
|
1401
1740
|
usesSerialization = false,
|
|
1402
|
-
viewModels
|
|
1741
|
+
viewModels,
|
|
1742
|
+
javaSpecs = []
|
|
1403
1743
|
} = input;
|
|
1404
1744
|
const sdk = await loadKotlinSdk(moduleRoot, toolchain);
|
|
1405
|
-
const plugin =
|
|
1406
|
-
const sdkLibrary =
|
|
1745
|
+
const plugin = import_node_path7.default.join(sdk.root, "plugin.jar");
|
|
1746
|
+
const sdkLibrary = import_node_path7.default.join(sdk.root, `${sdkProfile}.klib`);
|
|
1747
|
+
const java = javaSpecs.length ? await readJavaModuleSpecs(javaSpecs, sdk.root, await ensureToolchain(toolchain)) : null;
|
|
1407
1748
|
const generated = {
|
|
1408
1749
|
...sourceGenerated,
|
|
1409
1750
|
"PeachBindingsInitialization.kt": [
|
|
@@ -1415,6 +1756,7 @@ async function compileKotlin(input, origin) {
|
|
|
1415
1756
|
"@JsExport fun peachInitializeModuleBindings() {",
|
|
1416
1757
|
" if (!initialized) {",
|
|
1417
1758
|
" requireIncomingBindings()",
|
|
1759
|
+
...java ? [` ${JAVA_BINDINGS_INITIALIZER}()`] : [],
|
|
1418
1760
|
" initializeApplicationIncomingBindings()",
|
|
1419
1761
|
...sourceGenerated["PeachViews.kt"] ? [" initializeApplicationViews()"] : [],
|
|
1420
1762
|
" initialized = true",
|
|
@@ -1424,9 +1766,9 @@ async function compileKotlin(input, origin) {
|
|
|
1424
1766
|
};
|
|
1425
1767
|
const inputs = sources.map((file) => ({
|
|
1426
1768
|
file,
|
|
1427
|
-
bytes:
|
|
1769
|
+
bytes: import_node_fs6.default.readFileSync(file)
|
|
1428
1770
|
}));
|
|
1429
|
-
const digest = (0,
|
|
1771
|
+
const digest = (0, import_node_crypto6.createHash)("sha256");
|
|
1430
1772
|
digest.update(
|
|
1431
1773
|
JSON.stringify({
|
|
1432
1774
|
format: BUILD_FORMAT,
|
|
@@ -1434,11 +1776,12 @@ async function compileKotlin(input, origin) {
|
|
|
1434
1776
|
language,
|
|
1435
1777
|
sdk: sdk.sha256,
|
|
1436
1778
|
sdkProfile,
|
|
1437
|
-
usesSerialization
|
|
1779
|
+
usesSerialization,
|
|
1780
|
+
java: java?.sha256
|
|
1438
1781
|
})
|
|
1439
1782
|
);
|
|
1440
1783
|
for (const { file, bytes } of inputs)
|
|
1441
|
-
digest.update(
|
|
1784
|
+
digest.update(import_node_path7.default.relative(root, file)).update("\0").update(bytes).update("\0");
|
|
1442
1785
|
if (viewModels) digest.update(viewModels.toolClass);
|
|
1443
1786
|
for (const [name, text] of Object.entries(generated))
|
|
1444
1787
|
digest.update(`${name}\0${text}\0`);
|
|
@@ -1447,37 +1790,39 @@ async function compileKotlin(input, origin) {
|
|
|
1447
1790
|
url: `${origin}${KOTLIN_ARTIFACT_PREFIX}${hash}/app.mjs`,
|
|
1448
1791
|
hash
|
|
1449
1792
|
};
|
|
1450
|
-
const out =
|
|
1451
|
-
if (
|
|
1793
|
+
const out = import_node_path7.default.join(buildsDir(), hash);
|
|
1794
|
+
if (import_node_fs6.default.existsSync(import_node_path7.default.join(out, "js", "app.wasm"))) return artifact;
|
|
1452
1795
|
const pending = builds.get(hash);
|
|
1453
1796
|
if (pending) return pending;
|
|
1454
1797
|
const build = (async () => {
|
|
1455
1798
|
const ready = await ensureToolchain(toolchain);
|
|
1456
1799
|
const { kotlinc } = ready;
|
|
1457
1800
|
const libraries = [...ready.libraries, sdkLibrary];
|
|
1458
|
-
const composeRuntime =
|
|
1801
|
+
const composeRuntime = import_node_path7.default.join(
|
|
1459
1802
|
kotlinHome(),
|
|
1460
1803
|
toolchain.compiler.version,
|
|
1461
1804
|
toolchain.composeRuntime.name
|
|
1462
1805
|
);
|
|
1463
1806
|
if (usesCompose) {
|
|
1464
1807
|
for (const library of toolchain.composeLibraries) {
|
|
1465
|
-
const target =
|
|
1808
|
+
const target = import_node_path7.default.join(kotlinHome(), toolchain.compiler.version, library.name);
|
|
1466
1809
|
await fetchVerified(library, target);
|
|
1467
1810
|
libraries.push(target);
|
|
1468
1811
|
}
|
|
1469
1812
|
await fetchVerified(toolchain.composeRuntime, composeRuntime);
|
|
1470
1813
|
}
|
|
1471
|
-
|
|
1472
|
-
const work =
|
|
1473
|
-
const
|
|
1474
|
-
|
|
1814
|
+
import_node_fs6.default.mkdirSync(buildsDir(), { recursive: true });
|
|
1815
|
+
const work = import_node_fs6.default.mkdtempSync(import_node_path7.default.join(buildsDir(), `${hash}-`));
|
|
1816
|
+
const javaLibrary = java ? import_node_path7.default.join(work, "java-abi", "java-abi.klib") : null;
|
|
1817
|
+
if (javaLibrary) libraries.push(javaLibrary);
|
|
1818
|
+
const generatedDir = import_node_path7.default.join(work, "generated");
|
|
1819
|
+
import_node_fs6.default.mkdirSync(generatedDir);
|
|
1475
1820
|
for (const [name, text] of Object.entries(generated))
|
|
1476
|
-
|
|
1821
|
+
import_node_fs6.default.writeFileSync(import_node_path7.default.join(generatedDir, name), text);
|
|
1477
1822
|
const compiledSources = inputs.map(({ file, bytes }, index) => {
|
|
1478
|
-
const target =
|
|
1479
|
-
|
|
1480
|
-
|
|
1823
|
+
const target = import_node_path7.default.join(work, "sources", String(index), import_node_path7.default.basename(file));
|
|
1824
|
+
import_node_fs6.default.mkdirSync(import_node_path7.default.dirname(target), { recursive: true });
|
|
1825
|
+
import_node_fs6.default.writeFileSync(target, bytes);
|
|
1481
1826
|
return { file, target };
|
|
1482
1827
|
});
|
|
1483
1828
|
const common = [
|
|
@@ -1486,19 +1831,19 @@ async function compileKotlin(input, origin) {
|
|
|
1486
1831
|
"-Xallow-kotlin-package",
|
|
1487
1832
|
"-Xwasm-target=js",
|
|
1488
1833
|
"-libraries",
|
|
1489
|
-
libraries.join(
|
|
1834
|
+
libraries.join(import_node_path7.default.delimiter)
|
|
1490
1835
|
];
|
|
1491
|
-
const compileKlib = (outputDir) =>
|
|
1836
|
+
const compileKlib = (outputDir) => run5(
|
|
1492
1837
|
kotlinc,
|
|
1493
1838
|
[
|
|
1494
1839
|
...common,
|
|
1495
1840
|
`-Xplugin=${plugin}`,
|
|
1496
|
-
`-Xfriend-modules=${sdkLibrary}`,
|
|
1841
|
+
`-Xfriend-modules=${[sdkLibrary, ...javaLibrary ? [javaLibrary] : []].join(import_node_path7.default.delimiter)}`,
|
|
1497
1842
|
...usesCompose ? [
|
|
1498
|
-
`-Xplugin=${
|
|
1843
|
+
`-Xplugin=${import_node_path7.default.resolve(import_node_path7.default.dirname(kotlinc), "../lib/compose-compiler-plugin.jar")}`
|
|
1499
1844
|
] : [],
|
|
1500
1845
|
...usesSerialization ? [
|
|
1501
|
-
`-Xplugin=${
|
|
1846
|
+
`-Xplugin=${import_node_path7.default.resolve(import_node_path7.default.dirname(kotlinc), "../lib/kotlinx-serialization-compiler-plugin.jar")}`
|
|
1502
1847
|
] : [],
|
|
1503
1848
|
"-language-version",
|
|
1504
1849
|
language,
|
|
@@ -1511,59 +1856,70 @@ async function compileKotlin(input, origin) {
|
|
|
1511
1856
|
"-ir-output-name",
|
|
1512
1857
|
"app",
|
|
1513
1858
|
...compiledSources.map(({ target }) => target),
|
|
1514
|
-
...Object.keys(generated).map((name) =>
|
|
1859
|
+
...Object.keys(generated).map((name) => import_node_path7.default.join(generatedDir, name))
|
|
1515
1860
|
],
|
|
1516
1861
|
{ maxBuffer: 16 * 1024 * 1024 }
|
|
1517
1862
|
);
|
|
1518
1863
|
try {
|
|
1864
|
+
if (java)
|
|
1865
|
+
await compileJavaModuleAbi({
|
|
1866
|
+
specs: java,
|
|
1867
|
+
work,
|
|
1868
|
+
hash,
|
|
1869
|
+
toolchain: ready,
|
|
1870
|
+
libraries: libraries.filter((library) => library !== javaLibrary),
|
|
1871
|
+
sdkRoot: sdk.root,
|
|
1872
|
+
sdkLibrary,
|
|
1873
|
+
language
|
|
1874
|
+
});
|
|
1519
1875
|
if (viewModels && inputs.some(
|
|
1520
1876
|
({ file, bytes }) => sources.includes(file) && bytes.includes("ViewModel")
|
|
1521
1877
|
)) {
|
|
1522
|
-
await compileKlib(
|
|
1523
|
-
const { stdout } = await
|
|
1524
|
-
|
|
1878
|
+
await compileKlib(import_node_path7.default.join(work, "abi"));
|
|
1879
|
+
const { stdout } = await run5(
|
|
1880
|
+
import_node_path7.default.join(import_node_path7.default.dirname(kotlinc), "kotlin"),
|
|
1525
1881
|
[
|
|
1526
1882
|
"-cp",
|
|
1527
1883
|
[
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
].join(
|
|
1884
|
+
import_node_path7.default.resolve(import_node_path7.default.dirname(kotlinc), "../lib/kotlin-compiler.jar"),
|
|
1885
|
+
import_node_path7.default.join(sdk.root, "tools.jar")
|
|
1886
|
+
].join(import_node_path7.default.delimiter),
|
|
1531
1887
|
viewModels.toolClass,
|
|
1532
|
-
|
|
1888
|
+
import_node_path7.default.join(work, "abi")
|
|
1533
1889
|
],
|
|
1534
1890
|
{ maxBuffer: 64 * 1024 * 1024 }
|
|
1535
1891
|
);
|
|
1536
|
-
|
|
1537
|
-
|
|
1892
|
+
import_node_fs6.default.writeFileSync(
|
|
1893
|
+
import_node_path7.default.join(generatedDir, viewModels.file),
|
|
1538
1894
|
viewModels.render(viewModelClasses(readAbiClasses(stdout)))
|
|
1539
1895
|
);
|
|
1540
1896
|
}
|
|
1541
|
-
await compileKlib(
|
|
1542
|
-
await
|
|
1897
|
+
await compileKlib(import_node_path7.default.join(work, "klib"));
|
|
1898
|
+
await run5(
|
|
1543
1899
|
kotlinc,
|
|
1544
1900
|
[
|
|
1545
1901
|
...common,
|
|
1546
1902
|
"-nowarn",
|
|
1547
|
-
`-Xinclude=${
|
|
1903
|
+
`-Xinclude=${import_node_path7.default.join(work, "klib")}`,
|
|
1548
1904
|
"-Xir-produce-js",
|
|
1549
1905
|
"-ir-output-dir",
|
|
1550
|
-
|
|
1906
|
+
import_node_path7.default.join(work, "js"),
|
|
1551
1907
|
"-ir-output-name",
|
|
1552
1908
|
"app"
|
|
1553
1909
|
],
|
|
1554
1910
|
{ maxBuffer: 16 * 1024 * 1024 }
|
|
1555
1911
|
);
|
|
1556
1912
|
if (usesCompose) {
|
|
1557
|
-
await
|
|
1913
|
+
await run5("unzip", [
|
|
1558
1914
|
"-q",
|
|
1559
1915
|
"-j",
|
|
1560
1916
|
composeRuntime,
|
|
1561
1917
|
"skiko.mjs",
|
|
1562
1918
|
"-d",
|
|
1563
|
-
|
|
1919
|
+
import_node_path7.default.join(work, "js")
|
|
1564
1920
|
]);
|
|
1565
|
-
const skikoPath =
|
|
1566
|
-
const upstream = (0, import_acorn2.parse)(
|
|
1921
|
+
const skikoPath = import_node_path7.default.join(work, "js", "skiko.mjs");
|
|
1922
|
+
const upstream = (0, import_acorn2.parse)(import_node_fs6.default.readFileSync(skikoPath, "utf8"), {
|
|
1567
1923
|
ecmaVersion: "latest",
|
|
1568
1924
|
sourceType: "module"
|
|
1569
1925
|
});
|
|
@@ -1586,7 +1942,7 @@ async function compileKotlin(input, origin) {
|
|
|
1586
1942
|
"GL",
|
|
1587
1943
|
...bindings
|
|
1588
1944
|
];
|
|
1589
|
-
|
|
1945
|
+
import_node_fs6.default.writeFileSync(
|
|
1590
1946
|
skikoPath,
|
|
1591
1947
|
[
|
|
1592
1948
|
"const runtime = globalThis.__peachKotlinSkiko;",
|
|
@@ -1600,10 +1956,10 @@ async function compileKotlin(input, origin) {
|
|
|
1600
1956
|
if (usesCompose) {
|
|
1601
1957
|
for (const library of toolchain.composeJsLibraries) {
|
|
1602
1958
|
let imported = false;
|
|
1603
|
-
for (const file of
|
|
1959
|
+
for (const file of import_node_fs6.default.readdirSync(import_node_path7.default.join(work, "js"))) {
|
|
1604
1960
|
if (!file.endsWith(".mjs")) continue;
|
|
1605
|
-
const target =
|
|
1606
|
-
const source =
|
|
1961
|
+
const target = import_node_path7.default.join(work, "js", file);
|
|
1962
|
+
const source = import_node_fs6.default.readFileSync(target, "utf8");
|
|
1607
1963
|
let next = source;
|
|
1608
1964
|
for (const quote of ["'", '"'])
|
|
1609
1965
|
next = next.replaceAll(
|
|
@@ -1611,29 +1967,34 @@ async function compileKotlin(input, origin) {
|
|
|
1611
1967
|
`from ${quote}./${library.file}${quote}`
|
|
1612
1968
|
);
|
|
1613
1969
|
if (next === source) continue;
|
|
1614
|
-
|
|
1970
|
+
import_node_fs6.default.writeFileSync(target, next);
|
|
1615
1971
|
imported = true;
|
|
1616
1972
|
}
|
|
1617
1973
|
if (!imported) continue;
|
|
1618
|
-
const archive =
|
|
1974
|
+
const archive = import_node_path7.default.join(
|
|
1619
1975
|
kotlinHome(),
|
|
1620
1976
|
toolchain.compiler.version,
|
|
1621
1977
|
library.name
|
|
1622
1978
|
);
|
|
1623
1979
|
await fetchVerified(library, archive);
|
|
1624
|
-
const { stdout } = await
|
|
1980
|
+
const { stdout } = await run5("tar", ["-xOf", archive, library.archiveEntry], {
|
|
1625
1981
|
maxBuffer: 16 * 1024 * 1024
|
|
1626
1982
|
});
|
|
1627
|
-
|
|
1983
|
+
import_node_fs6.default.writeFileSync(import_node_path7.default.join(work, "js", library.file), stdout);
|
|
1628
1984
|
}
|
|
1629
1985
|
}
|
|
1630
1986
|
} catch (error) {
|
|
1631
|
-
|
|
1987
|
+
import_node_fs6.default.rmSync(work, { recursive: true, force: true });
|
|
1632
1988
|
let output = isRecord(error) ? `${String(error.stderr ?? "")}${String(error.stdout ?? "")}` : "";
|
|
1633
1989
|
for (const [name, source] of Object.entries(origins))
|
|
1634
|
-
output = output.replaceAll(
|
|
1990
|
+
output = output.replaceAll(import_node_path7.default.join(generatedDir, name), source);
|
|
1635
1991
|
for (const { file, target } of compiledSources)
|
|
1636
|
-
output = output.replaceAll(target, file).replaceAll(
|
|
1992
|
+
output = output.replaceAll(target, file).replaceAll(import_node_path7.default.relative(process.cwd(), target), file);
|
|
1993
|
+
for (const [index, spec] of (java?.specs ?? []).entries())
|
|
1994
|
+
output = output.replaceAll(
|
|
1995
|
+
import_node_path7.default.join(work, "java-abi", `Spec${index}.kt`),
|
|
1996
|
+
spec.file
|
|
1997
|
+
);
|
|
1637
1998
|
throw new Error(
|
|
1638
1999
|
`kotlin compile failed:
|
|
1639
2000
|
${output.trim() || (error instanceof Error ? error.message : String(error))}`
|
|
@@ -1642,9 +2003,9 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
|
|
|
1642
2003
|
const seams = [
|
|
1643
2004
|
["process.release.name", "process.release?.name"]
|
|
1644
2005
|
];
|
|
1645
|
-
const js =
|
|
2006
|
+
const js = import_node_fs6.default.readdirSync(import_node_path7.default.join(work, "js")).filter((file) => file.endsWith(".mjs"));
|
|
1646
2007
|
if (js.some(
|
|
1647
|
-
(file) =>
|
|
2008
|
+
(file) => import_node_fs6.default.readFileSync(import_node_path7.default.join(work, "js", file), "utf8").includes("'kotlinx.coroutines.")
|
|
1648
2009
|
))
|
|
1649
2010
|
seams.push([
|
|
1650
2011
|
"(typeof(window) !== 'undefined' && window != null && typeof(window.addEventListener) === 'function') ? window : null",
|
|
@@ -1653,12 +2014,12 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
|
|
|
1653
2014
|
for (const [from, to] of seams) {
|
|
1654
2015
|
let patched = 0;
|
|
1655
2016
|
for (const file of js) {
|
|
1656
|
-
const target =
|
|
1657
|
-
const text =
|
|
2017
|
+
const target = import_node_path7.default.join(work, "js", file);
|
|
2018
|
+
const text = import_node_fs6.default.readFileSync(target, "utf8");
|
|
1658
2019
|
const next = text.replaceAll(from, to);
|
|
1659
2020
|
if (next !== text) {
|
|
1660
2021
|
patched++;
|
|
1661
|
-
|
|
2022
|
+
import_node_fs6.default.writeFileSync(target, next);
|
|
1662
2023
|
}
|
|
1663
2024
|
}
|
|
1664
2025
|
if (patched === 0)
|
|
@@ -1666,11 +2027,11 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
|
|
|
1666
2027
|
`kotlin output no longer contains ${from}; recheck how it detects its host in Peach`
|
|
1667
2028
|
);
|
|
1668
2029
|
}
|
|
1669
|
-
const entry =
|
|
1670
|
-
const entrySource2 =
|
|
1671
|
-
const importsPath =
|
|
2030
|
+
const entry = import_node_path7.default.join(work, "js/app.mjs");
|
|
2031
|
+
const entrySource2 = import_node_fs6.default.readFileSync(entry, "utf8");
|
|
2032
|
+
const importsPath = import_node_path7.default.join(work, "js/app.import-object.mjs");
|
|
1672
2033
|
const importsFactory = kotlinInstanceSource(
|
|
1673
|
-
|
|
2034
|
+
import_node_fs6.default.readFileSync(importsPath, "utf8"),
|
|
1674
2035
|
"createKotlinImportObject"
|
|
1675
2036
|
);
|
|
1676
2037
|
const runtimeFactory = kotlinInstanceSource(
|
|
@@ -1678,9 +2039,9 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
|
|
|
1678
2039
|
"createKotlinInstance",
|
|
1679
2040
|
/* @__PURE__ */ new Map([["./app.import-object.mjs", "createKotlinImportObject"]])
|
|
1680
2041
|
);
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
2042
|
+
import_node_fs6.default.writeFileSync(importsPath, importsFactory.source);
|
|
2043
|
+
import_node_fs6.default.writeFileSync(import_node_path7.default.join(work, "js/app-runtime.mjs"), runtimeFactory.source);
|
|
2044
|
+
import_node_fs6.default.writeFileSync(
|
|
1684
2045
|
entry,
|
|
1685
2046
|
[
|
|
1686
2047
|
"import { createKotlinInstance } from './app-runtime.mjs';",
|
|
@@ -1693,10 +2054,10 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
|
|
|
1693
2054
|
].join("\n")
|
|
1694
2055
|
);
|
|
1695
2056
|
try {
|
|
1696
|
-
|
|
2057
|
+
import_node_fs6.default.renameSync(work, out);
|
|
1697
2058
|
} catch (error) {
|
|
1698
|
-
if (!
|
|
1699
|
-
|
|
2059
|
+
if (!import_node_fs6.default.existsSync(import_node_path7.default.join(out, "js", "app.wasm"))) throw error;
|
|
2060
|
+
import_node_fs6.default.rmSync(work, { recursive: true, force: true });
|
|
1700
2061
|
}
|
|
1701
2062
|
return artifact;
|
|
1702
2063
|
})().finally(() => builds.delete(hash));
|
|
@@ -1708,24 +2069,24 @@ var CONTENT_TYPES = {
|
|
|
1708
2069
|
".wasm": "application/wasm"
|
|
1709
2070
|
};
|
|
1710
2071
|
function kotlinArtifactFiles(hash) {
|
|
1711
|
-
const dir =
|
|
1712
|
-
return
|
|
1713
|
-
const contentType = CONTENT_TYPES[
|
|
2072
|
+
const dir = import_node_path7.default.join(buildsDir(), hash, "js");
|
|
2073
|
+
return import_node_fs6.default.readdirSync(dir).sort().map((name) => {
|
|
2074
|
+
const contentType = CONTENT_TYPES[import_node_path7.default.extname(name)];
|
|
1714
2075
|
if (!contentType) throw new Error(`unexpected kotlin artifact file ${name}`);
|
|
1715
|
-
return { name, bytes:
|
|
2076
|
+
return { name, bytes: import_node_fs6.default.readFileSync(import_node_path7.default.join(dir, name)), contentType };
|
|
1716
2077
|
});
|
|
1717
2078
|
}
|
|
1718
2079
|
function serveKotlinArtifact(pathname, res) {
|
|
1719
2080
|
if (!pathname.startsWith(KOTLIN_ARTIFACT_PREFIX)) return false;
|
|
1720
2081
|
const [hash, file, ...rest] = pathname.slice(KOTLIN_ARTIFACT_PREFIX.length).split("/");
|
|
1721
|
-
const type = file ? CONTENT_TYPES[
|
|
2082
|
+
const type = file ? CONTENT_TYPES[import_node_path7.default.extname(file)] : void 0;
|
|
1722
2083
|
if (!hash || !/^[0-9a-f]+$/.test(hash) || !file || rest.length > 0 || !type || file.includes("..")) {
|
|
1723
2084
|
res.statusCode = 404;
|
|
1724
2085
|
res.end("not a kotlin artifact");
|
|
1725
2086
|
return true;
|
|
1726
2087
|
}
|
|
1727
|
-
const target =
|
|
1728
|
-
if (!
|
|
2088
|
+
const target = import_node_path7.default.join(buildsDir(), hash, "js", file);
|
|
2089
|
+
if (!import_node_fs6.default.existsSync(target)) {
|
|
1729
2090
|
res.statusCode = 404;
|
|
1730
2091
|
res.end(`kotlin artifact ${hash}/${file} was not built`);
|
|
1731
2092
|
return true;
|
|
@@ -1733,7 +2094,7 @@ function serveKotlinArtifact(pathname, res) {
|
|
|
1733
2094
|
res.setHeader("access-control-allow-origin", "*");
|
|
1734
2095
|
res.setHeader("content-type", type);
|
|
1735
2096
|
res.setHeader("cache-control", "public, max-age=31536000, immutable");
|
|
1736
|
-
res.end(
|
|
2097
|
+
res.end(import_node_fs6.default.readFileSync(target));
|
|
1737
2098
|
return true;
|
|
1738
2099
|
}
|
|
1739
2100
|
var KOTLIN_PACKAGE_PATH = "/__peach/kotlin-package";
|