inferay 0.1.1 → 0.1.2
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/package.json +1 -1
- package/src/cli.js +3 -16
- package/src/install.js +60 -13
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -2,10 +2,8 @@ import { install } from "./install.js";
|
|
|
2
2
|
import { launchApp } from "./launch.js";
|
|
3
3
|
import { doctor } from "./doctor.js";
|
|
4
4
|
import { getChannel, setChannel } from "./config.js";
|
|
5
|
-
import { fetchRelease, findAsset } from "./releases.js";
|
|
6
|
-
import { platformInfo } from "./platform.js";
|
|
7
5
|
|
|
8
|
-
const VERSION = "0.1.
|
|
6
|
+
const VERSION = "0.1.2";
|
|
9
7
|
|
|
10
8
|
function printHelp() {
|
|
11
9
|
console.log(`inferay ${VERSION}
|
|
@@ -43,19 +41,8 @@ async function printDoctor(args) {
|
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
async function update() {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
const asset = findAsset(release, platformInfo());
|
|
49
|
-
if (!asset) {
|
|
50
|
-
throw new Error(
|
|
51
|
-
`no installable asset found for ${release.tag_name || channel}`
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
console.log(
|
|
55
|
-
`Latest ${channel}: ${release.tag_name || release.name || "unknown"}`
|
|
56
|
-
);
|
|
57
|
-
console.log(`Asset: ${asset.name}`);
|
|
58
|
-
console.log("Run `inferay install` to download and open the installer.");
|
|
44
|
+
const result = await install({ force: true });
|
|
45
|
+
console.log(result.message);
|
|
59
46
|
}
|
|
60
47
|
|
|
61
48
|
async function installAndReport(args) {
|
package/src/install.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { cp, mkdir, readdir, rm } from "node:fs/promises";
|
|
2
3
|
import { existsSync } from "node:fs";
|
|
3
|
-
import { basename, dirname, resolve } from "node:path";
|
|
4
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
4
6
|
import { getChannel } from "./config.js";
|
|
5
7
|
import {
|
|
6
8
|
defaultInstallPath,
|
|
@@ -10,16 +12,60 @@ import {
|
|
|
10
12
|
import { downloadAsset, fetchRelease, findAsset } from "./releases.js";
|
|
11
13
|
import { openFile } from "./launch.js";
|
|
12
14
|
|
|
15
|
+
const execFileAsync = promisify(execFile);
|
|
16
|
+
|
|
13
17
|
async function copyAppBundle(source, destination = defaultInstallPath()) {
|
|
14
18
|
if (!source.endsWith(".app")) {
|
|
15
19
|
throw new Error("local install source must be a .app bundle");
|
|
16
20
|
}
|
|
17
21
|
await mkdir(dirname(destination), { recursive: true });
|
|
22
|
+
await rm(destination, { recursive: true, force: true });
|
|
18
23
|
await cp(source, destination, { recursive: true, force: true });
|
|
19
24
|
return destination;
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
function parseMountPoint(output) {
|
|
28
|
+
return output
|
|
29
|
+
.split("\n")
|
|
30
|
+
.map((line) => line.trim().split(/\s+/).at(-1))
|
|
31
|
+
.find((part) => part?.startsWith("/Volumes/"));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function findAppBundle(directory) {
|
|
35
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
36
|
+
const app = entries.find(
|
|
37
|
+
(entry) => entry.isDirectory() && entry.name.endsWith(".app")
|
|
38
|
+
);
|
|
39
|
+
if (!app) {
|
|
40
|
+
throw new Error(`no .app bundle found in ${directory}`);
|
|
41
|
+
}
|
|
42
|
+
return join(directory, app.name);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function installDmg(dmgPath, { launch = true } = {}) {
|
|
46
|
+
const { stdout } = await execFileAsync("hdiutil", [
|
|
47
|
+
"attach",
|
|
48
|
+
"-nobrowse",
|
|
49
|
+
"-readonly",
|
|
50
|
+
dmgPath,
|
|
51
|
+
]);
|
|
52
|
+
const mountPoint = parseMountPoint(stdout);
|
|
53
|
+
if (!mountPoint) {
|
|
54
|
+
throw new Error("could not determine mounted DMG path");
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const appBundle = await findAppBundle(mountPoint);
|
|
58
|
+
const destination = await copyAppBundle(appBundle);
|
|
59
|
+
if (launch) {
|
|
60
|
+
await openFile(destination);
|
|
61
|
+
}
|
|
62
|
+
return destination;
|
|
63
|
+
} finally {
|
|
64
|
+
await execFileAsync("hdiutil", ["detach", mountPoint]).catch(() => {});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function install({ local, launch = true, force = false } = {}) {
|
|
23
69
|
const platform = platformInfo();
|
|
24
70
|
if (!platform.supported) {
|
|
25
71
|
throw new Error(`unsupported platform ${platform.os}-${platform.cpu}`);
|
|
@@ -40,11 +86,13 @@ export async function install({ local, launch = true } = {}) {
|
|
|
40
86
|
|
|
41
87
|
const existing = findExistingApp();
|
|
42
88
|
if (existing) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
89
|
+
if (!force) {
|
|
90
|
+
return {
|
|
91
|
+
kind: "already-installed",
|
|
92
|
+
message: `Inferay is already available at ${existing}`,
|
|
93
|
+
installedPath: existing,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
48
96
|
}
|
|
49
97
|
|
|
50
98
|
const channel = await getChannel();
|
|
@@ -58,13 +106,12 @@ export async function install({ local, launch = true } = {}) {
|
|
|
58
106
|
|
|
59
107
|
const downloadedPath = await downloadAsset(asset);
|
|
60
108
|
if (downloadedPath.endsWith(".dmg")) {
|
|
61
|
-
|
|
62
|
-
await openFile(downloadedPath);
|
|
63
|
-
}
|
|
109
|
+
const installedPath = await installDmg(downloadedPath, { launch });
|
|
64
110
|
return {
|
|
65
|
-
kind: "dmg",
|
|
66
|
-
message: `
|
|
111
|
+
kind: "dmg-installed",
|
|
112
|
+
message: `Installed ${asset.name} to ${installedPath}`,
|
|
67
113
|
downloadedPath,
|
|
114
|
+
installedPath,
|
|
68
115
|
};
|
|
69
116
|
}
|
|
70
117
|
|