@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.
- package/LICENSE +30 -0
- package/README.md +108 -2
- package/dist/asar.d.ts +11 -0
- package/dist/asar.js +43 -0
- package/dist/asar.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +10 -0
- package/dist/bin.js.map +1 -0
- package/dist/build-android.d.ts +13 -0
- package/dist/build-android.js +93 -0
- package/dist/build-android.js.map +1 -0
- package/dist/build-windows.d.ts +13 -0
- package/dist/build-windows.js +73 -0
- package/dist/build-windows.js.map +1 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +14 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -0
- package/dist/create.d.ts +5 -0
- package/dist/create.js +58 -0
- package/dist/create.js.map +1 -0
- package/dist/dev.d.ts +9 -0
- package/dist/dev.js +165 -0
- package/dist/dev.js.map +1 -0
- package/dist/doctor.d.ts +2 -0
- package/dist/doctor.js +56 -0
- package/dist/doctor.js.map +1 -0
- package/dist/download.d.ts +19 -0
- package/dist/download.js +115 -0
- package/dist/download.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/project.d.ts +12 -0
- package/dist/project.js +55 -0
- package/dist/project.js.map +1 -0
- package/dist/templates.d.ts +35 -0
- package/dist/templates.js +288 -0
- package/dist/templates.js.map +1 -0
- package/dist/web.d.ts +3 -0
- package/dist/web.js +33 -0
- package/dist/web.js.map +1 -0
- package/package.json +54 -5
- package/templates/web/icon.png +0 -0
- package/templates/web/index.html +113 -0
- package/templates/web/mio.config.json +20 -0
- package/templates/web/package.json +18 -0
- package/templates/web/src/main.ts +158 -0
- package/templates/web/src/style.css +389 -0
- package/templates/web/vite.config.ts +12 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { extractZip, listZipEntries } from "@iyexin/mio-android-tools";
|
|
6
|
+
import { fetchText, fetchToFile } from "./download.js";
|
|
7
|
+
import { MIO_API_VERSION, MIO_CLI_VERSION } from "./constants.js";
|
|
8
|
+
import { cliRoot, exists } from "./project.js";
|
|
9
|
+
/**
|
|
10
|
+
* Templates are no longer committed to the repository: they are release assets
|
|
11
|
+
* (see .github/workflows/release.yml), downloaded on first use and cached per
|
|
12
|
+
* CLI version. An explicit path always wins, so teams can ship their own build.
|
|
13
|
+
*/
|
|
14
|
+
const RELEASE_BASE = "https://github.com/iYeXin/Mio/releases/download";
|
|
15
|
+
export class TemplateError extends Error {
|
|
16
|
+
}
|
|
17
|
+
function cacheRoot() {
|
|
18
|
+
const base = process.platform === "win32"
|
|
19
|
+
? process.env.LOCALAPPDATA || join(homedir(), "AppData", "Local")
|
|
20
|
+
: process.env.XDG_CACHE_HOME || join(homedir(), ".cache");
|
|
21
|
+
return join(base, "mio", "templates", MIO_CLI_VERSION);
|
|
22
|
+
}
|
|
23
|
+
function extensionOf(name) {
|
|
24
|
+
const dot = name.lastIndexOf(".");
|
|
25
|
+
return dot >= 0 ? name.slice(dot) : "";
|
|
26
|
+
}
|
|
27
|
+
async function sha256(path) {
|
|
28
|
+
const hash = createHash("sha256");
|
|
29
|
+
hash.update(await readFile(path));
|
|
30
|
+
return hash.digest("hex");
|
|
31
|
+
}
|
|
32
|
+
function assertCompatible(manifest, source) {
|
|
33
|
+
const wanted = MIO_API_VERSION.split(".")[0];
|
|
34
|
+
const found = String(manifest.apiVersion ?? "").split(".")[0];
|
|
35
|
+
if (!found) {
|
|
36
|
+
throw new TemplateError(`${source} has no apiVersion; cannot verify compatibility`);
|
|
37
|
+
}
|
|
38
|
+
if (found !== wanted) {
|
|
39
|
+
throw new TemplateError(`${source} targets Mio API ${manifest.apiVersion}, this CLI implements ${MIO_API_VERSION}. ` +
|
|
40
|
+
`Use a template from the v${MIO_CLI_VERSION} release, or upgrade the CLI.`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function readManifest(directory) {
|
|
44
|
+
const path = join(directory, "manifest.json");
|
|
45
|
+
if (!(await exists(path)))
|
|
46
|
+
return null;
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(await readFile(path, "utf8"));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
throw new TemplateError(`Template manifest is not valid JSON: ${path}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Downloads and unpacks the template bundle into the per-version cache. */
|
|
55
|
+
async function fetchTemplates(log) {
|
|
56
|
+
const root = cacheRoot();
|
|
57
|
+
const manifestUrl = `${RELEASE_BASE}/v${MIO_CLI_VERSION}/manifest.json`;
|
|
58
|
+
log(`Downloading template manifest: ${manifestUrl}`);
|
|
59
|
+
const manifest = JSON.parse(await fetchText(manifestUrl));
|
|
60
|
+
assertCompatible(manifest, `release v${MIO_CLI_VERSION}`);
|
|
61
|
+
await mkdir(root, { recursive: true });
|
|
62
|
+
await writeFile(join(root, "manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
63
|
+
for (const [key, file] of Object.entries(manifest.files)) {
|
|
64
|
+
const target = join(root, file.name);
|
|
65
|
+
if (await exists(target)) {
|
|
66
|
+
if ((await sha256(target)) === file.sha256)
|
|
67
|
+
continue;
|
|
68
|
+
await rm(target, { force: true });
|
|
69
|
+
}
|
|
70
|
+
const url = `${RELEASE_BASE}/v${MIO_CLI_VERSION}/${file.name}`;
|
|
71
|
+
log(`Downloading ${key}: ${file.name} (${formatBytes(file.size)})`);
|
|
72
|
+
await fetchToFile(url, target);
|
|
73
|
+
const actual = await sha256(target);
|
|
74
|
+
if (actual !== file.sha256) {
|
|
75
|
+
await rm(target, { force: true });
|
|
76
|
+
throw new TemplateError(`Checksum mismatch for ${file.name}: expected ${file.sha256}, got ${actual}`);
|
|
77
|
+
}
|
|
78
|
+
if (file.kind === "zip") {
|
|
79
|
+
const directory = join(root, stripArchiveSuffix(file.name));
|
|
80
|
+
await extractZip(target, directory);
|
|
81
|
+
await writeFile(join(directory, ".mio-template"), `${file.sha256}\n`, "utf8");
|
|
82
|
+
await rm(target, { force: true });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return manifest;
|
|
86
|
+
}
|
|
87
|
+
function stripArchiveSuffix(name) {
|
|
88
|
+
return name.replace(/\.zip$/i, "");
|
|
89
|
+
}
|
|
90
|
+
async function ensureTemplates(log) {
|
|
91
|
+
const root = cacheRoot();
|
|
92
|
+
const manifest = await readManifest(root);
|
|
93
|
+
if (!manifest)
|
|
94
|
+
return await fetchTemplates(log);
|
|
95
|
+
assertCompatible(manifest, `template cache ${root}`);
|
|
96
|
+
return manifest;
|
|
97
|
+
}
|
|
98
|
+
function formatBytes(value) {
|
|
99
|
+
if (value < 1024)
|
|
100
|
+
return `${value} B`;
|
|
101
|
+
if (value < 1024 * 1024)
|
|
102
|
+
return `${(value / 1024).toFixed(1)} KB`;
|
|
103
|
+
return `${(value / (1024 * 1024)).toFixed(1)} MB`;
|
|
104
|
+
}
|
|
105
|
+
const ABI_KEY = {
|
|
106
|
+
universal: "android-universal",
|
|
107
|
+
arm64: "android-arm64",
|
|
108
|
+
x64: "android-x64",
|
|
109
|
+
};
|
|
110
|
+
const LOCAL_APK = {
|
|
111
|
+
universal: "mio-shell-universal.apk",
|
|
112
|
+
arm64: "mio-shell-arm64.apk",
|
|
113
|
+
x64: "mio-shell-x64.apk",
|
|
114
|
+
};
|
|
115
|
+
/** Templates built into the checkout by scripts/build-templates.ps1. */
|
|
116
|
+
function localTemplateRoot() {
|
|
117
|
+
return join(cliRoot, "templates");
|
|
118
|
+
}
|
|
119
|
+
async function localAndroidTemplate(abi) {
|
|
120
|
+
const path = join(localTemplateRoot(), "android", LOCAL_APK[abi]);
|
|
121
|
+
if (!(await exists(path)))
|
|
122
|
+
return null;
|
|
123
|
+
await assertApkFormat(path);
|
|
124
|
+
return { path, source: "local", version: null };
|
|
125
|
+
}
|
|
126
|
+
async function localWindowsTemplate() {
|
|
127
|
+
const path = join(localTemplateRoot(), "windows");
|
|
128
|
+
if (!(await exists(join(path, "data"))))
|
|
129
|
+
return null;
|
|
130
|
+
return { path, source: "local", version: null };
|
|
131
|
+
}
|
|
132
|
+
export function androidAbiOf(config) {
|
|
133
|
+
return config.android?.abi ?? "universal";
|
|
134
|
+
}
|
|
135
|
+
/** Checks the zip layout of a template APK without unpacking it. */
|
|
136
|
+
async function assertApkFormat(path) {
|
|
137
|
+
let entries;
|
|
138
|
+
try {
|
|
139
|
+
entries = await listZipEntries(path);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
throw new TemplateError(`Template is not a zip/APK: ${path} (${message(error)})`);
|
|
143
|
+
}
|
|
144
|
+
if (!entries.includes("AndroidManifest.xml")) {
|
|
145
|
+
throw new TemplateError(`Template is not an APK (no AndroidManifest.xml): ${path}`);
|
|
146
|
+
}
|
|
147
|
+
if (!entries.some((entry) => entry.endsWith("libapp.so"))) {
|
|
148
|
+
throw new TemplateError(`Template APK has no Flutter engine libraries: ${path}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function message(error) {
|
|
152
|
+
return error instanceof Error ? error.message : String(error);
|
|
153
|
+
}
|
|
154
|
+
async function abisInApk(path) {
|
|
155
|
+
const entries = await listZipEntries(path);
|
|
156
|
+
const abis = new Set();
|
|
157
|
+
for (const entry of entries) {
|
|
158
|
+
const match = /^lib\/([^/]+)\//.exec(entry);
|
|
159
|
+
if (match?.[1])
|
|
160
|
+
abis.add(match[1]);
|
|
161
|
+
}
|
|
162
|
+
return abis;
|
|
163
|
+
}
|
|
164
|
+
async function resolveExplicitAndroid(path, abi) {
|
|
165
|
+
await assertApkFormat(path);
|
|
166
|
+
if (abi !== "universal") {
|
|
167
|
+
const abis = await abisInApk(path);
|
|
168
|
+
if (!abis.has(`arm64-v8a`) && !abis.has(`x86_64`) && !abis.has(`armeabi-v7a`)) {
|
|
169
|
+
throw new TemplateError(`Template APK has no native libraries: ${path}`);
|
|
170
|
+
}
|
|
171
|
+
const wanted = abi === "arm64" ? "arm64-v8a" : abi === "x64" ? "x86_64" : "armeabi-v7a";
|
|
172
|
+
if (!abis.has(wanted)) {
|
|
173
|
+
throw new TemplateError(`Template ${path} does not contain ${wanted}; it has ${[...abis].join(", ") || "none"}. ` +
|
|
174
|
+
`Build with --target-platform android-${abi}.`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { path, source: "explicit", version: null };
|
|
178
|
+
}
|
|
179
|
+
export async function resolveAndroidTemplate(projectDir, config, options = {}) {
|
|
180
|
+
const abi = androidAbiOf(config);
|
|
181
|
+
const log = options.log ?? (() => { });
|
|
182
|
+
const explicit = [
|
|
183
|
+
options.explicit,
|
|
184
|
+
config.android?.template ? resolve(projectDir, config.android.template) : undefined,
|
|
185
|
+
process.env.MIO_ANDROID_TEMPLATE,
|
|
186
|
+
].filter((value) => Boolean(value));
|
|
187
|
+
for (const candidate of explicit) {
|
|
188
|
+
if (await exists(candidate))
|
|
189
|
+
return await resolveExplicitAndroid(candidate, abi);
|
|
190
|
+
}
|
|
191
|
+
if (explicit.length > 0) {
|
|
192
|
+
throw new TemplateError(`Configured Android template does not exist: ${explicit[0]}`);
|
|
193
|
+
}
|
|
194
|
+
// Local builds (repo checkout, or a team that vendors its own templates) win
|
|
195
|
+
// over downloading: the directory is gitignored, so it only exists on purpose.
|
|
196
|
+
const local = await localAndroidTemplate(abi);
|
|
197
|
+
if (local)
|
|
198
|
+
return local;
|
|
199
|
+
const manifest = await ensureTemplates(log);
|
|
200
|
+
const file = manifest.files[ABI_KEY[abi]];
|
|
201
|
+
if (!file) {
|
|
202
|
+
throw new TemplateError(`Release v${MIO_CLI_VERSION} has no ${ABI_KEY[abi]} template. ` +
|
|
203
|
+
`Available: ${Object.keys(manifest.files).join(", ")}. ` +
|
|
204
|
+
`Build one locally with \`./scripts/build-templates.ps1 -Abi ${abi}\`.`);
|
|
205
|
+
}
|
|
206
|
+
const path = join(cacheRoot(), file.name);
|
|
207
|
+
if (!(await exists(path))) {
|
|
208
|
+
throw new TemplateError(`Template file is missing from the cache: ${path}`);
|
|
209
|
+
}
|
|
210
|
+
// The release can be rebuilt for the same tag; a cached file must still match
|
|
211
|
+
// the manifest it was downloaded with, otherwise the CLI would silently use a
|
|
212
|
+
// different shell than the apiVersion it verified.
|
|
213
|
+
if ((await sha256(path)) !== file.sha256) {
|
|
214
|
+
await rm(path, { force: true });
|
|
215
|
+
await fetchTemplates(log);
|
|
216
|
+
}
|
|
217
|
+
await assertApkFormat(path);
|
|
218
|
+
return { path, source: "cache", version: manifest.templateVersion };
|
|
219
|
+
}
|
|
220
|
+
export async function resolveWindowsTemplate(projectDir, config, options = {}) {
|
|
221
|
+
const log = options.log ?? (() => { });
|
|
222
|
+
const explicit = [
|
|
223
|
+
options.explicit,
|
|
224
|
+
config.windows?.templateDir ? resolve(projectDir, config.windows.templateDir) : undefined,
|
|
225
|
+
process.env.MIO_WINDOWS_TEMPLATE,
|
|
226
|
+
].filter((value) => Boolean(value));
|
|
227
|
+
for (const candidate of explicit) {
|
|
228
|
+
if (!(await exists(candidate)))
|
|
229
|
+
continue;
|
|
230
|
+
if (!(await exists(join(candidate, "data")))) {
|
|
231
|
+
throw new TemplateError(`Windows template directory has no data/ folder: ${candidate}`);
|
|
232
|
+
}
|
|
233
|
+
return { path: candidate, source: "explicit", version: null };
|
|
234
|
+
}
|
|
235
|
+
if (explicit.length > 0) {
|
|
236
|
+
throw new TemplateError(`Configured Windows template does not exist: ${explicit[0]}`);
|
|
237
|
+
}
|
|
238
|
+
const local = await localWindowsTemplate();
|
|
239
|
+
if (local)
|
|
240
|
+
return local;
|
|
241
|
+
const manifest = await ensureTemplates(log);
|
|
242
|
+
const file = manifest.files["windows"];
|
|
243
|
+
if (!file) {
|
|
244
|
+
throw new TemplateError(`Release v${MIO_CLI_VERSION} has no Windows template. Build one locally with ` +
|
|
245
|
+
`\`./scripts/build-templates.ps1 -Platform windows\`.`);
|
|
246
|
+
}
|
|
247
|
+
const directory = join(cacheRoot(), stripArchiveSuffix(file.name));
|
|
248
|
+
if (!(await exists(join(directory, "data")))) {
|
|
249
|
+
throw new TemplateError(`Windows template is missing from the cache: ${directory}`);
|
|
250
|
+
}
|
|
251
|
+
const marker = join(directory, ".mio-template");
|
|
252
|
+
const cached = (await exists(marker)) ? (await readFile(marker, "utf8")).trim() : "";
|
|
253
|
+
if (cached !== file.sha256) {
|
|
254
|
+
await rm(directory, { recursive: true, force: true });
|
|
255
|
+
await fetchTemplates(log);
|
|
256
|
+
}
|
|
257
|
+
return { path: directory, source: "cache", version: manifest.templateVersion };
|
|
258
|
+
}
|
|
259
|
+
/** Template used by `mio dev`: prefer the universal build so emulators work too. */
|
|
260
|
+
export async function resolveDevAndroidTemplate(projectDir, config, options = {}) {
|
|
261
|
+
try {
|
|
262
|
+
return await resolveAndroidTemplate(projectDir, config, options);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
// Dev on an emulator needs the universal (or x64) build; if the configured
|
|
266
|
+
// ABI is missing from the release, try universal before giving up.
|
|
267
|
+
if (androidAbiOf(config) === "universal")
|
|
268
|
+
throw error;
|
|
269
|
+
return await resolveAndroidTemplate(projectDir, { ...config, android: { ...(config.android ?? {}), abi: "universal" } }, options);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/** Human-readable summary for `mio doctor`. */
|
|
273
|
+
export async function describeTemplates() {
|
|
274
|
+
const lines = [];
|
|
275
|
+
const root = cacheRoot();
|
|
276
|
+
const manifest = await readManifest(root);
|
|
277
|
+
if (!manifest) {
|
|
278
|
+
lines.push(`templates: not cached (run \`mio build\` to download v${MIO_CLI_VERSION})`);
|
|
279
|
+
return lines;
|
|
280
|
+
}
|
|
281
|
+
lines.push(`templates: v${manifest.templateVersion} (api ${manifest.apiVersion}) in ${root}`);
|
|
282
|
+
for (const [key, file] of Object.entries(manifest.files)) {
|
|
283
|
+
const path = join(root, file.kind === "zip" ? stripArchiveSuffix(file.name) : file.name);
|
|
284
|
+
lines.push(` ${key}: ${(await exists(path)) ? "ok" : "missing"} (${formatBytes(file.size)})`);
|
|
285
|
+
}
|
|
286
|
+
return lines;
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"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"}
|
package/dist/web.d.ts
ADDED
package/dist/web.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { access } from "node:fs/promises";
|
|
3
|
+
import { constants } from "node:fs";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
export async function ensureWebBuild(projectDir, config, skipWeb) {
|
|
6
|
+
const outDir = resolve(projectDir, config.web?.outDir ?? "dist");
|
|
7
|
+
if (!skipWeb) {
|
|
8
|
+
const command = config.web?.buildCommand ?? "npm run build";
|
|
9
|
+
await runShell(command, projectDir);
|
|
10
|
+
}
|
|
11
|
+
await access(join(outDir, "index.html"), constants.F_OK).catch(() => {
|
|
12
|
+
throw new Error(`Web build output is missing index.html: ${outDir}`);
|
|
13
|
+
});
|
|
14
|
+
return outDir;
|
|
15
|
+
}
|
|
16
|
+
export function runShell(command, cwd) {
|
|
17
|
+
return new Promise((resolvePromise, reject) => {
|
|
18
|
+
const child = spawn(command, {
|
|
19
|
+
cwd,
|
|
20
|
+
shell: true,
|
|
21
|
+
stdio: "inherit",
|
|
22
|
+
env: process.env,
|
|
23
|
+
});
|
|
24
|
+
child.on("error", reject);
|
|
25
|
+
child.on("exit", (code) => {
|
|
26
|
+
if (code === 0)
|
|
27
|
+
resolvePromise();
|
|
28
|
+
else
|
|
29
|
+
reject(new Error(`Command failed (${code}): ${command}`));
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=web.js.map
|
package/dist/web.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAAkB,EAClB,MAAiB,EACjB,OAAgB;IAEhB,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,IAAI,MAAM,CAAC,CAAC;IACjE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,YAAY,IAAI,eAAe,CAAC;QAC5D,MAAM,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QAClE,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,GAAW;IACnD,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE;YAC3B,GAAG;YACH,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC;gBAAE,cAAc,EAAE,CAAC;;gBAC5B,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@iyexin/mio-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
1
|
+
{
|
|
2
|
+
"name": "@iyexin/mio-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Mio application CLI",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mio": "./dist/bin.js"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"templates/web"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc -p tsconfig.json",
|
|
22
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
23
|
+
"test": "node --import tsx --test test/create.test.ts test/abi.test.ts test/download.test.ts"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@electron/asar": "^4.3.1",
|
|
27
|
+
"@iyexin/mio-android-tools": "workspace:*",
|
|
28
|
+
"@iyexin/mio-api": "workspace:*",
|
|
29
|
+
"undici": "^7.16.0"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.12"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/iYeXin/Mio.git",
|
|
38
|
+
"directory": "packages/cli"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/iYeXin/Mio#readme",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/iYeXin/Mio/issues"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"mio",
|
|
46
|
+
"flutter",
|
|
47
|
+
"webview",
|
|
48
|
+
"web-app",
|
|
49
|
+
"android",
|
|
50
|
+
"windows"
|
|
51
|
+
],
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
}
|
|
6
55
|
}
|
|
Binary file
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Hello Mio</title>
|
|
7
|
+
<link rel="stylesheet" href="./src/style.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div class="frame">
|
|
11
|
+
<header class="masthead">
|
|
12
|
+
<span class="wordmark">MIO</span>
|
|
13
|
+
<span class="masthead-meta" id="masthead-meta">shell 0.1.0</span>
|
|
14
|
+
</header>
|
|
15
|
+
|
|
16
|
+
<section class="intro">
|
|
17
|
+
<div class="intro-text">
|
|
18
|
+
<h1 id="app-name">Hello Mio</h1>
|
|
19
|
+
<p class="lede">
|
|
20
|
+
A Flutter shell serving a web app over localhost. Every call below crosses
|
|
21
|
+
the bridge into native code.
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
<svg class="mark" viewBox="1300 410 1659 1655" aria-hidden="true">
|
|
25
|
+
<rect x="1300" y="410" width="822" height="681" fill="#f2a6a6" />
|
|
26
|
+
<rect x="1300" y="1238" width="532" height="827" fill="#b9b9b6" />
|
|
27
|
+
<rect x="1972" y="1382" width="946" height="681" fill="#a9c0d2" />
|
|
28
|
+
<path
|
|
29
|
+
d="M2256.85 1237.84 2432.35 409.836 2958.85 409.836 2783.35 1237.84Z"
|
|
30
|
+
fill="#4a4a4a"
|
|
31
|
+
/>
|
|
32
|
+
</svg>
|
|
33
|
+
</section>
|
|
34
|
+
|
|
35
|
+
<dl class="spec">
|
|
36
|
+
<div class="spec-cell">
|
|
37
|
+
<dt>Application</dt>
|
|
38
|
+
<dd id="spec-id" class="mono">—</dd>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="spec-cell">
|
|
41
|
+
<dt>Version</dt>
|
|
42
|
+
<dd id="spec-version" class="mono">—</dd>
|
|
43
|
+
</div>
|
|
44
|
+
<div class="spec-cell">
|
|
45
|
+
<dt>Platform</dt>
|
|
46
|
+
<dd id="spec-platform" class="mono">—</dd>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="spec-cell">
|
|
49
|
+
<dt>Bridge</dt>
|
|
50
|
+
<dd class="mono">
|
|
51
|
+
<span class="status" id="bridge-status" data-state="pending">
|
|
52
|
+
<span class="status-dot"></span><span id="bridge-text">connecting</span>
|
|
53
|
+
</span>
|
|
54
|
+
</dd>
|
|
55
|
+
</div>
|
|
56
|
+
</dl>
|
|
57
|
+
|
|
58
|
+
<section class="calls">
|
|
59
|
+
<h2 class="section-label">Bridge calls</h2>
|
|
60
|
+
<ol class="call-list">
|
|
61
|
+
<li>
|
|
62
|
+
<button type="button" data-action="ping">
|
|
63
|
+
<span class="num">01</span>
|
|
64
|
+
<span class="call-name">Ping</span>
|
|
65
|
+
<span class="call-note">round trip to the shell</span>
|
|
66
|
+
<span class="arrow" aria-hidden="true">→</span>
|
|
67
|
+
</button>
|
|
68
|
+
</li>
|
|
69
|
+
<li>
|
|
70
|
+
<button type="button" data-action="clipboard">
|
|
71
|
+
<span class="num">02</span>
|
|
72
|
+
<span class="call-name">Clipboard</span>
|
|
73
|
+
<span class="call-note">write then read back</span>
|
|
74
|
+
<span class="arrow" aria-hidden="true">→</span>
|
|
75
|
+
</button>
|
|
76
|
+
</li>
|
|
77
|
+
<li>
|
|
78
|
+
<button type="button" data-action="write">
|
|
79
|
+
<span class="num">03</span>
|
|
80
|
+
<span class="call-name">Write & read a file</span>
|
|
81
|
+
<span class="call-note">app data directory</span>
|
|
82
|
+
<span class="arrow" aria-hidden="true">→</span>
|
|
83
|
+
</button>
|
|
84
|
+
</li>
|
|
85
|
+
<li>
|
|
86
|
+
<button type="button" data-action="binary">
|
|
87
|
+
<span class="num">04</span>
|
|
88
|
+
<span class="call-name">64 MB round trip</span>
|
|
89
|
+
<span class="call-note">streamed over the blob endpoint</span>
|
|
90
|
+
<span class="arrow" aria-hidden="true">→</span>
|
|
91
|
+
</button>
|
|
92
|
+
</li>
|
|
93
|
+
</ol>
|
|
94
|
+
</section>
|
|
95
|
+
|
|
96
|
+
<section class="log">
|
|
97
|
+
<div class="log-head">
|
|
98
|
+
<h2 class="section-label">Output</h2>
|
|
99
|
+
<span class="log-id" id="log-id">idle</span>
|
|
100
|
+
</div>
|
|
101
|
+
<pre id="output" aria-live="polite">Waiting for the bridge…</pre>
|
|
102
|
+
</section>
|
|
103
|
+
|
|
104
|
+
<footer class="colophon">
|
|
105
|
+
<span>Mio shell</span>
|
|
106
|
+
<span id="spec-api">api —</span>
|
|
107
|
+
<span id="spec-template">template —</span>
|
|
108
|
+
</footer>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<script type="module" src="./src/main.ts"></script>
|
|
112
|
+
</body>
|
|
113
|
+
</html>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"app": {
|
|
3
|
+
"id": "com.example.hello",
|
|
4
|
+
"name": "Hello Mio",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"icon": "icon.png"
|
|
7
|
+
},
|
|
8
|
+
"window": {
|
|
9
|
+
"width": 1000,
|
|
10
|
+
"height": 720
|
|
11
|
+
},
|
|
12
|
+
"web": {
|
|
13
|
+
"outDir": "dist"
|
|
14
|
+
},
|
|
15
|
+
"android": {
|
|
16
|
+
"minSdk": 24,
|
|
17
|
+
"pageSize": 16,
|
|
18
|
+
"abi": "arm64"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mio-web-template",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@iyexin/mio-api": "workspace:*"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"typescript": "^5.9.3",
|
|
16
|
+
"vite": "^7.2.2"
|
|
17
|
+
}
|
|
18
|
+
}
|