@iyexin/mio-cli 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +30 -0
  2. package/README.md +108 -2
  3. package/dist/asar.d.ts +11 -0
  4. package/dist/asar.js +43 -0
  5. package/dist/asar.js.map +1 -0
  6. package/dist/bin.d.ts +2 -0
  7. package/dist/bin.js +10 -0
  8. package/dist/bin.js.map +1 -0
  9. package/dist/build-android.d.ts +13 -0
  10. package/dist/build-android.js +93 -0
  11. package/dist/build-android.js.map +1 -0
  12. package/dist/build-windows.d.ts +13 -0
  13. package/dist/build-windows.js +73 -0
  14. package/dist/build-windows.js.map +1 -0
  15. package/dist/config.d.ts +44 -0
  16. package/dist/config.js +38 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/constants.d.ts +14 -0
  19. package/dist/constants.js +15 -0
  20. package/dist/constants.js.map +1 -0
  21. package/dist/create.d.ts +5 -0
  22. package/dist/create.js +58 -0
  23. package/dist/create.js.map +1 -0
  24. package/dist/dev.d.ts +9 -0
  25. package/dist/dev.js +165 -0
  26. package/dist/dev.js.map +1 -0
  27. package/dist/doctor.d.ts +2 -0
  28. package/dist/doctor.js +56 -0
  29. package/dist/doctor.js.map +1 -0
  30. package/dist/download.d.ts +19 -0
  31. package/dist/download.js +115 -0
  32. package/dist/download.js.map +1 -0
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.js +118 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/project.d.ts +12 -0
  37. package/dist/project.js +55 -0
  38. package/dist/project.js.map +1 -0
  39. package/dist/templates.d.ts +35 -0
  40. package/dist/templates.js +288 -0
  41. package/dist/templates.js.map +1 -0
  42. package/dist/web.d.ts +3 -0
  43. package/dist/web.js +33 -0
  44. package/dist/web.js.map +1 -0
  45. package/package.json +54 -5
  46. package/templates/web/icon.png +0 -0
  47. package/templates/web/index.html +113 -0
  48. package/templates/web/mio.config.json +20 -0
  49. package/templates/web/package.json +18 -0
  50. package/templates/web/src/main.ts +158 -0
  51. package/templates/web/src/style.css +389 -0
  52. package/templates/web/vite.config.ts +12 -0
package/dist/dev.js ADDED
@@ -0,0 +1,165 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { createServer } from "node:net";
4
+ import { join } from "node:path";
5
+ import { findFirstExe } from "./project.js";
6
+ import { resolveDevAndroidTemplate, resolveWindowsTemplate } from "./templates.js";
7
+ export async function dev(options) {
8
+ const { config, projectDir } = options.loaded;
9
+ const port = await freePort(config.web?.devUrl);
10
+ const devUrl = `http://127.0.0.1:${port}`;
11
+ const baseCommand = config.web?.devCommand ?? "npm run dev";
12
+ const devCommand = baseCommand.includes("--port")
13
+ ? baseCommand
14
+ : `${baseCommand} -- --host 127.0.0.1 --port ${port}`;
15
+ console.log(`Starting web dev server: ${devCommand}`);
16
+ const vite = spawn(devCommand, {
17
+ cwd: projectDir,
18
+ shell: true,
19
+ stdio: "inherit",
20
+ env: process.env,
21
+ });
22
+ const children = [vite];
23
+ try {
24
+ await waitForHttp(devUrl, 60_000);
25
+ console.log(`Web dev server is ready at ${devUrl}`);
26
+ if (options.platform === "windows") {
27
+ await startWindows(options, devUrl, children);
28
+ }
29
+ else {
30
+ await startAndroid(options, devUrl);
31
+ }
32
+ console.log("Mio dev is running. Press Ctrl+C to stop.");
33
+ await new Promise((resolve) => {
34
+ const stop = () => {
35
+ for (const child of children)
36
+ child.kill();
37
+ resolve();
38
+ };
39
+ process.once("SIGINT", stop);
40
+ process.once("SIGTERM", stop);
41
+ });
42
+ }
43
+ finally {
44
+ for (const child of children) {
45
+ if (!child.killed)
46
+ child.kill();
47
+ }
48
+ }
49
+ }
50
+ async function startWindows(options, devUrl, children) {
51
+ const { config, projectDir } = options.loaded;
52
+ const templateDir = (await resolveWindowsTemplate(projectDir, config, {
53
+ explicit: options.template,
54
+ })).path;
55
+ const exe = config.windows?.exe
56
+ ? join(templateDir, config.windows.exe)
57
+ : await findFirstExe(templateDir);
58
+ if (!exe)
59
+ throw new Error(`No Windows executable in ${templateDir}`);
60
+ console.log(`Launching Windows shell: ${exe}`);
61
+ const child = spawn(exe, [], {
62
+ cwd: templateDir,
63
+ stdio: "inherit",
64
+ env: {
65
+ ...process.env,
66
+ MIO_DEV_URL: devUrl,
67
+ MIO_DEV_APP_ID: config.app.id,
68
+ MIO_DEV_APP_NAME: config.app.name,
69
+ MIO_DEV_APP_VERSION: config.app.version,
70
+ MIO_DEV_WINDOW_WIDTH: String(config.window?.width ?? 1024),
71
+ MIO_DEV_WINDOW_HEIGHT: String(config.window?.height ?? 720),
72
+ },
73
+ });
74
+ children.push(child);
75
+ }
76
+ async function startAndroid(options, devUrl) {
77
+ const adb = findAdb();
78
+ const template = (await resolveDevAndroidTemplate(options.loaded.projectDir, options.loaded.config, {
79
+ explicit: options.template,
80
+ })).path;
81
+ const port = new URL(devUrl).port || "5173";
82
+ await run(adb, ["reverse", `tcp:${port}`, `tcp:${port}`]);
83
+ if (options.install) {
84
+ console.log(`Installing Android template: ${template}`);
85
+ await run(adb, ["install", "-r", template]);
86
+ }
87
+ const appConfig = Buffer.from(JSON.stringify({
88
+ id: options.loaded.config.app.id,
89
+ name: options.loaded.config.app.name,
90
+ version: options.loaded.config.app.version,
91
+ width: options.loaded.config.window?.width ?? 1024,
92
+ height: options.loaded.config.window?.height ?? 720,
93
+ })).toString("base64");
94
+ await run(adb, [
95
+ "shell",
96
+ "am",
97
+ "start",
98
+ "-n",
99
+ "dev.mio.mio_shell/dev.mio.mio_shell.MainActivity",
100
+ "--es",
101
+ "mio.devUrl",
102
+ devUrl,
103
+ "--es",
104
+ "mio.appConfig",
105
+ appConfig,
106
+ ]);
107
+ }
108
+ function findAdb() {
109
+ const sdk = process.env.ANDROID_HOME ?? process.env.ANDROID_SDK_ROOT;
110
+ if (sdk) {
111
+ const candidate = join(sdk, "platform-tools", process.platform === "win32" ? "adb.exe" : "adb");
112
+ if (existsSync(candidate))
113
+ return candidate;
114
+ }
115
+ return "adb";
116
+ }
117
+ function run(command, args) {
118
+ return new Promise((resolve, reject) => {
119
+ const child = spawn(command, args, { stdio: "inherit", env: process.env });
120
+ child.on("error", reject);
121
+ child.on("exit", (code) => {
122
+ if (code === 0)
123
+ resolve();
124
+ else
125
+ reject(new Error(`${command} ${args.join(" ")} failed with ${code}`));
126
+ });
127
+ });
128
+ }
129
+ async function waitForHttp(url, timeoutMs) {
130
+ const deadline = Date.now() + timeoutMs;
131
+ while (Date.now() < deadline) {
132
+ try {
133
+ const response = await fetch(url, { signal: AbortSignal.timeout(1500) });
134
+ if (response.ok)
135
+ return;
136
+ }
137
+ catch {
138
+ // retry
139
+ }
140
+ await new Promise((resolve) => setTimeout(resolve, 300));
141
+ }
142
+ throw new Error(`Timed out waiting for ${url}`);
143
+ }
144
+ function freePort(preferred) {
145
+ const desired = preferred ? Number(new URL(preferred).port) : 0;
146
+ return new Promise((resolve, reject) => {
147
+ const server = createServer();
148
+ server.once("error", () => {
149
+ // Preferred port unavailable; let the OS choose one.
150
+ const fallback = createServer();
151
+ fallback.once("error", reject);
152
+ fallback.listen(0, "127.0.0.1", () => {
153
+ const address = fallback.address();
154
+ const port = typeof address === "object" && address ? address.port : 0;
155
+ fallback.close(() => resolve(port));
156
+ });
157
+ });
158
+ server.listen(desired, "127.0.0.1", () => {
159
+ const address = server.address();
160
+ const port = typeof address === "object" && address ? address.port : 0;
161
+ server.close(() => resolve(port));
162
+ });
163
+ });
164
+ }
165
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { LoadedConfig } from "./config.js";
2
+ export declare function doctor(loaded?: LoadedConfig): Promise<void>;
package/dist/doctor.js ADDED
@@ -0,0 +1,56 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { describeAndroidTools, discoverAndroidTools } from "@iyexin/mio-android-tools";
4
+ import { androidAbiOf, describeTemplates, resolveAndroidTemplate, resolveWindowsTemplate, } from "./templates.js";
5
+ import { MIO_API_VERSION, MIO_CLI_VERSION } from "./constants.js";
6
+ export async function doctor(loaded) {
7
+ console.log(`Mio CLI: ${MIO_CLI_VERSION}`);
8
+ console.log(`Mio API: ${MIO_API_VERSION}`);
9
+ console.log(`Node: ${process.version} (${process.platform}-${process.arch})`);
10
+ console.log(`Working directory: ${process.cwd()}`);
11
+ try {
12
+ const tools = await discoverAndroidTools();
13
+ console.log("\nAndroid tools:");
14
+ console.log(describeAndroidTools(tools));
15
+ }
16
+ catch (error) {
17
+ console.log(`\nAndroid tools: NOT READY — ${message(error)}`);
18
+ }
19
+ const adb = findAdb();
20
+ console.log(`adb: ${adb ?? "not found"}`);
21
+ const templates = await describeTemplates();
22
+ console.log("\nTemplates:");
23
+ for (const line of templates)
24
+ console.log(` ${line}`);
25
+ if (loaded) {
26
+ console.log(`\nProject: ${loaded.config.app.name} (${loaded.config.app.id})`);
27
+ console.log(`Android abi: ${androidAbiOf(loaded.config)}`);
28
+ try {
29
+ const android = await resolveAndroidTemplate(loaded.projectDir, loaded.config);
30
+ console.log(`Android template: ${android.path} (${android.source})`);
31
+ }
32
+ catch (error) {
33
+ console.log(`Android template: MISSING — ${message(error)}`);
34
+ }
35
+ try {
36
+ const windows = await resolveWindowsTemplate(loaded.projectDir, loaded.config);
37
+ console.log(`Windows template: ${windows.path} (${windows.source})`);
38
+ }
39
+ catch (error) {
40
+ console.log(`Windows template: MISSING — ${message(error)}`);
41
+ }
42
+ }
43
+ }
44
+ function findAdb() {
45
+ const sdk = process.env.ANDROID_HOME ?? process.env.ANDROID_SDK_ROOT;
46
+ if (sdk) {
47
+ const candidate = join(sdk, "platform-tools", process.platform === "win32" ? "adb.exe" : "adb");
48
+ if (existsSync(candidate))
49
+ return candidate;
50
+ }
51
+ return undefined;
52
+ }
53
+ function message(error) {
54
+ return error instanceof Error ? error.message : String(error);
55
+ }
56
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Proxy used for release downloads.
3
+ *
4
+ * Order: standard env vars, then git's `http.proxy`. The git fallback matters on
5
+ * machines where only git is configured to reach GitHub (which is exactly where
6
+ * an un-proxied `fetch` dies with ECONNRESET).
7
+ */
8
+ export declare function resolveProxy(): string | undefined;
9
+ /** Whether NO_PROXY excludes this host. */
10
+ export declare function shouldBypassProxy(host: string, noProxy: string | undefined): boolean;
11
+ export interface DownloadOptions {
12
+ proxy?: string;
13
+ }
14
+ export declare class DownloadError extends Error {
15
+ constructor(url: string, cause: unknown);
16
+ }
17
+ export declare function fetchText(url: string, options?: DownloadOptions): Promise<string>;
18
+ export declare function fetchToFile(url: string, target: string, options?: DownloadOptions): Promise<void>;
19
+ export declare function readIfExists(path: string): Promise<string | null>;
@@ -0,0 +1,115 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { createWriteStream } from "node:fs";
3
+ import { mkdir, readFile, rename, rm } from "node:fs/promises";
4
+ import { dirname } from "node:path";
5
+ import { Readable } from "node:stream";
6
+ import { pipeline } from "node:stream/promises";
7
+ import { ProxyAgent, fetch as undiciFetch } from "undici";
8
+ /**
9
+ * Proxy used for release downloads.
10
+ *
11
+ * Order: standard env vars, then git's `http.proxy`. The git fallback matters on
12
+ * machines where only git is configured to reach GitHub (which is exactly where
13
+ * an un-proxied `fetch` dies with ECONNRESET).
14
+ */
15
+ export function resolveProxy() {
16
+ const env = process.env;
17
+ const candidates = [
18
+ env.HTTPS_PROXY,
19
+ env.https_proxy,
20
+ env.HTTP_PROXY,
21
+ env.http_proxy,
22
+ env.npm_config_https_proxy,
23
+ env.npm_config_proxy,
24
+ ];
25
+ for (const candidate of candidates) {
26
+ if (candidate && candidate.trim())
27
+ return candidate.trim();
28
+ }
29
+ try {
30
+ const result = spawnSync("git", ["config", "--get", "http.proxy"], {
31
+ encoding: "utf8",
32
+ timeout: 5000,
33
+ });
34
+ if (result.status === 0 && result.stdout.trim())
35
+ return result.stdout.trim();
36
+ }
37
+ catch {
38
+ // git is optional; fall through to a direct connection.
39
+ }
40
+ return undefined;
41
+ }
42
+ /** Whether NO_PROXY excludes this host. */
43
+ export function shouldBypassProxy(host, noProxy) {
44
+ if (!noProxy)
45
+ return false;
46
+ return noProxy
47
+ .split(",")
48
+ .map((entry) => entry.trim().toLowerCase())
49
+ .filter(Boolean)
50
+ .some((entry) => entry === "*" || host === entry || host.endsWith(`.${entry}`));
51
+ }
52
+ function dispatcherFor(url) {
53
+ const proxy = resolveProxy();
54
+ if (!proxy)
55
+ return undefined;
56
+ const host = new URL(url).hostname;
57
+ if (shouldBypassProxy(host, process.env.NO_PROXY ?? process.env.no_proxy))
58
+ return undefined;
59
+ return new ProxyAgent(proxy);
60
+ }
61
+ function describe(error) {
62
+ if (error instanceof Error) {
63
+ const cause = error.cause;
64
+ const detail = cause?.code ?? cause?.message;
65
+ return detail ? `${error.message} (${detail})` : error.message;
66
+ }
67
+ return String(error);
68
+ }
69
+ export class DownloadError extends Error {
70
+ constructor(url, cause) {
71
+ super(`Could not download ${url}: ${describe(cause)}. ` +
72
+ `If this machine cannot reach GitHub directly, set HTTPS_PROXY ` +
73
+ `(or configure http.proxy in git) and retry.`);
74
+ }
75
+ }
76
+ export async function fetchText(url, options = {}) {
77
+ const dispatcher = options.proxy ? new ProxyAgent(options.proxy) : dispatcherFor(url);
78
+ try {
79
+ const response = await undiciFetch(url, { redirect: "follow", dispatcher });
80
+ if (!response.ok) {
81
+ throw new Error(`HTTP ${response.status} ${response.statusText}`);
82
+ }
83
+ return await response.text();
84
+ }
85
+ catch (error) {
86
+ throw new DownloadError(url, error);
87
+ }
88
+ }
89
+ export async function fetchToFile(url, target, options = {}) {
90
+ const dispatcher = options.proxy ? new ProxyAgent(options.proxy) : dispatcherFor(url);
91
+ const temporary = `${target}.part`;
92
+ try {
93
+ const response = await undiciFetch(url, { redirect: "follow", dispatcher });
94
+ if (!response.ok || !response.body) {
95
+ throw new Error(`HTTP ${response.status} ${response.statusText}`);
96
+ }
97
+ await mkdir(dirname(target), { recursive: true });
98
+ await pipeline(Readable.fromWeb(response.body), createWriteStream(temporary));
99
+ await rm(target, { force: true });
100
+ await rename(temporary, target);
101
+ }
102
+ catch (error) {
103
+ await rm(temporary, { force: true });
104
+ throw new DownloadError(url, error);
105
+ }
106
+ }
107
+ export async function readIfExists(path) {
108
+ try {
109
+ return await readFile(path, "utf8");
110
+ }
111
+ catch {
112
+ return null;
113
+ }
114
+ }
115
+ //# sourceMappingURL=download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function main(argv?: string[]): Promise<void>;
package/dist/index.js ADDED
@@ -0,0 +1,118 @@
1
+ import { parseArgs } from "node:util";
2
+ import { join } from "node:path";
3
+ import { MIO_CLI_VERSION } from "./constants.js";
4
+ import { loadConfig } from "./config.js";
5
+ import { createProject } from "./create.js";
6
+ import { buildAndroid } from "./build-android.js";
7
+ import { buildWindows } from "./build-windows.js";
8
+ import { dev } from "./dev.js";
9
+ import { doctor } from "./doctor.js";
10
+ import { exists } from "./project.js";
11
+ const HELP = `Mio — lightweight cross-platform app framework
12
+
13
+ Usage:
14
+ mio create [target] [--no-install]
15
+ mio build [--platform android|windows] [--skip-web] [--template <path>] [--config mio.config.json]
16
+ mio dev --platform android|windows [--no-install] [--template <path>]
17
+ mio doctor
18
+
19
+ Examples:
20
+ mio create hello
21
+ mio build --platform android
22
+ mio dev --platform windows
23
+ `;
24
+ export async function main(argv = process.argv.slice(2)) {
25
+ const { values, positionals } = parseArgs({
26
+ args: argv,
27
+ allowPositionals: true,
28
+ options: {
29
+ help: { type: "boolean", short: "h" },
30
+ version: { type: "boolean", short: "v" },
31
+ platform: { type: "string", multiple: true },
32
+ abi: { type: "string" },
33
+ template: { type: "string" },
34
+ config: { type: "string" },
35
+ "skip-web": { type: "boolean" },
36
+ "no-install": { type: "boolean" },
37
+ },
38
+ });
39
+ if (values.help) {
40
+ console.log(HELP);
41
+ return;
42
+ }
43
+ if (values.version) {
44
+ console.log(MIO_CLI_VERSION);
45
+ return;
46
+ }
47
+ const command = positionals[0];
48
+ if (!command) {
49
+ console.log(HELP);
50
+ return;
51
+ }
52
+ switch (command) {
53
+ case "create": {
54
+ const target = positionals[1] ?? "mio-app";
55
+ await createProject({ target, install: !values["no-install"] });
56
+ return;
57
+ }
58
+ case "build": {
59
+ const loaded = await loadConfig(process.cwd(), values.config);
60
+ if (values.abi) {
61
+ const abi = values.abi;
62
+ if (abi !== "universal" && abi !== "arm64" && abi !== "x64") {
63
+ throw new Error(`Unknown --abi: ${abi} (expected universal, arm64 or x64)`);
64
+ }
65
+ loaded.config.android = { ...(loaded.config.android ?? {}), abi };
66
+ }
67
+ const platforms = normalizePlatforms(values.platform);
68
+ for (const platform of platforms) {
69
+ if (platform === "android") {
70
+ const result = await buildAndroid({ loaded, skipWeb: values["skip-web"] ?? false, template: values.template });
71
+ console.log(`Android: ${result.output} (${formatBytes(result.size)}, verified=${result.verified})`);
72
+ }
73
+ else {
74
+ const result = await buildWindows({ loaded, skipWeb: values["skip-web"] ?? false, template: values.template });
75
+ console.log(`Windows: ${result.outputDir} (${formatBytes(result.size)})`);
76
+ }
77
+ }
78
+ return;
79
+ }
80
+ case "dev": {
81
+ const loaded = await loadConfig(process.cwd(), values.config);
82
+ const platform = normalizePlatforms(values.platform)[0] ?? "windows";
83
+ await dev({ loaded, platform, install: !values["no-install"], template: values.template });
84
+ return;
85
+ }
86
+ case "doctor": {
87
+ const hasConfig = await exists(join(process.cwd(), values.config ?? "mio.config.json"));
88
+ await doctor(hasConfig ? await loadConfig(process.cwd(), values.config) : undefined);
89
+ return;
90
+ }
91
+ default:
92
+ throw new Error(`Unknown command: ${command}\n\n${HELP}`);
93
+ }
94
+ }
95
+ function normalizePlatforms(values) {
96
+ if (!values || values.length === 0)
97
+ return ["android", "windows"];
98
+ const parsed = values
99
+ .flatMap((value) => value.split(","))
100
+ .map((value) => value.trim())
101
+ .filter(Boolean);
102
+ const platforms = [];
103
+ for (const value of parsed) {
104
+ if (value !== "android" && value !== "windows") {
105
+ throw new Error(`Unknown platform: ${value} (expected android or windows)`);
106
+ }
107
+ platforms.push(value);
108
+ }
109
+ return [...new Set(platforms)];
110
+ }
111
+ function formatBytes(value) {
112
+ if (value < 1024)
113
+ return `${value} B`;
114
+ if (value < 1024 * 1024)
115
+ return `${(value / 1024).toFixed(1)} KB`;
116
+ return `${(value / (1024 * 1024)).toFixed(1)} MB`;
117
+ }
118
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare const cliRoot: string;
2
+ export declare const repoRoot: string;
3
+ export declare function exists(path: string): Promise<boolean>;
4
+ export declare function readJson<T>(path: string): Promise<T>;
5
+ export declare function writeJson(path: string, value: unknown): Promise<void>;
6
+ export declare function safeName(value: string): string;
7
+ export declare function safePackageName(value: string): string;
8
+ export declare function copyDirectory(source: string, target: string): Promise<void>;
9
+ export declare function packageVersion(manifest: {
10
+ version: string;
11
+ }): string;
12
+ export declare function findFirstExe(directory: string): Promise<string | undefined>;
@@ -0,0 +1,55 @@
1
+ import { access, cp, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import { basename, dirname, join, resolve } from "node:path";
5
+ export const cliRoot = fileURLToPath(new URL("..", import.meta.url));
6
+ export const repoRoot = resolve(cliRoot, "..", "..");
7
+ export async function exists(path) {
8
+ try {
9
+ await access(path, constants.F_OK);
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ export async function readJson(path) {
17
+ return JSON.parse(await readFile(path, "utf8"));
18
+ }
19
+ export async function writeJson(path, value) {
20
+ await mkdir(dirname(path), { recursive: true });
21
+ await writeFile(path, `${JSON.stringify(value, null, 2)}\n`, "utf8");
22
+ }
23
+ export function safeName(value) {
24
+ return value
25
+ .replace(/[^a-zA-Z0-9._-]+/g, "-")
26
+ .replace(/^-+|-+$/g, "")
27
+ .slice(0, 80) || "mio-app";
28
+ }
29
+ export function safePackageName(value) {
30
+ const cleaned = value
31
+ .toLowerCase()
32
+ .replace(/[^a-z0-9._-]+/g, "-")
33
+ .replace(/^-+|-+$/g, "");
34
+ return /^[a-z]/.test(cleaned) ? cleaned : `mio-${cleaned || "app"}`;
35
+ }
36
+ export async function copyDirectory(source, target) {
37
+ await mkdir(target, { recursive: true });
38
+ await cp(source, target, {
39
+ recursive: true,
40
+ filter: (path) => {
41
+ const name = basename(path);
42
+ return name !== "node_modules" && name !== ".mio" && name !== "dist";
43
+ },
44
+ });
45
+ }
46
+ export function packageVersion(manifest) {
47
+ return manifest.version;
48
+ }
49
+ export async function findFirstExe(directory) {
50
+ const { readdir } = await import("node:fs/promises");
51
+ const entries = await readdir(directory, { withFileTypes: true });
52
+ const exe = entries.find((entry) => entry.isFile() && entry.name.toLowerCase().endsWith(".exe"));
53
+ return exe ? join(directory, exe.name) : undefined;
54
+ }
55
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAI,IAAY;IAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAM,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,KAAc;IAC1D,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,OAAO,KAAK;SACT,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC;SACjC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,OAAO,GAAG,KAAK;SAClB,WAAW,EAAE;SACb,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;SAC9B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,OAAO,IAAI,KAAK,EAAE,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc,EAAE,MAAc;IAChE,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE;QACvB,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACf,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,CAAC;QACvE,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAA6B;IAC1D,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAClD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACjG,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACrD,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { AndroidAbi, LoadedConfig, MioConfig } from "./config.js";
2
+ export type TemplateSource = "explicit" | "local" | "cache";
3
+ export interface TemplateFile {
4
+ name: string;
5
+ sha256: string;
6
+ size: number;
7
+ abi?: AndroidAbi;
8
+ kind?: "apk" | "zip";
9
+ }
10
+ export interface TemplateManifest {
11
+ templateVersion: string;
12
+ apiVersion: string;
13
+ builtAt?: string;
14
+ files: Record<string, TemplateFile>;
15
+ }
16
+ export interface ResolvedTemplate {
17
+ path: string;
18
+ source: TemplateSource;
19
+ version: string | null;
20
+ }
21
+ export declare class TemplateError extends Error {
22
+ }
23
+ export declare function androidAbiOf(config: MioConfig): AndroidAbi;
24
+ export interface TemplateOptions {
25
+ /** Explicit path from --template or MIO_*_TEMPLATE. */
26
+ explicit?: string;
27
+ log?: (message: string) => void;
28
+ }
29
+ export declare function resolveAndroidTemplate(projectDir: string, config: MioConfig, options?: TemplateOptions): Promise<ResolvedTemplate>;
30
+ export declare function resolveWindowsTemplate(projectDir: string, config: MioConfig, options?: TemplateOptions): Promise<ResolvedTemplate>;
31
+ /** Template used by `mio dev`: prefer the universal build so emulators work too. */
32
+ export declare function resolveDevAndroidTemplate(projectDir: string, config: MioConfig, options?: TemplateOptions): Promise<ResolvedTemplate>;
33
+ /** Human-readable summary for `mio doctor`. */
34
+ export declare function describeTemplates(): Promise<string[]>;
35
+ export type { LoadedConfig };