nixamp 0.30.3 → 0.32.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/dist/library-cli.d.ts +3 -0
- package/dist/library-cli.js +198 -0
- package/dist/library-index.d.ts +190 -0
- package/dist/library-index.js +643 -0
- package/dist/library-mcp.d.ts +230 -0
- package/dist/library-mcp.js +139 -0
- package/dist/library-routes.d.ts +34 -0
- package/dist/library-routes.js +258 -0
- package/dist/library-usage.d.ts +3 -0
- package/dist/library-usage.js +20 -0
- package/dist/library-user.d.ts +67 -0
- package/dist/library-user.js +204 -0
- package/dist/main.js +8 -0
- package/dist/mcp.js +5 -2
- package/dist/server.d.ts +9 -0
- package/dist/server.js +83 -12
- package/dist/station-cli.js +4 -3
- package/dist/station-mcp.d.ts +17 -0
- package/dist/station-mcp.js +25 -19
- package/dist/station-usage.d.ts +1 -1
- package/dist/station-usage.js +1 -1
- package/package.json +1 -1
- package/src/library-cli.ts +175 -0
- package/src/library-index.ts +709 -0
- package/src/library-mcp.ts +132 -0
- package/src/library-routes.ts +282 -0
- package/src/library-usage.ts +21 -0
- package/src/library-user.ts +218 -0
- package/src/main.ts +7 -0
- package/src/mcp.ts +5 -2
- package/src/server.ts +83 -13
- package/src/station-cli.ts +4 -3
- package/src/station-mcp.ts +22 -15
- package/src/station-usage.ts +1 -1
- package/web/dist/assets/{ar-ClCIWtVb.js → ar-C_4gIadE.js} +1 -1
- package/web/dist/assets/{cs-CVG4U823.js → cs-B18R5adY.js} +1 -1
- package/web/dist/assets/{da-igdiQUk8.js → da-B6w5URQ2.js} +1 -1
- package/web/dist/assets/{de-CHPsc6lc.js → de-Dlhr9ikG.js} +1 -1
- package/web/dist/assets/{es-AvbMspQX.js → es-BIpArFOC.js} +1 -1
- package/web/dist/assets/{fi-5JGUOm3W.js → fi-o9W4XS3X.js} +1 -1
- package/web/dist/assets/{fr-YfMwk1FR.js → fr-BgVwhPsP.js} +1 -1
- package/web/dist/assets/{hi-BUZuQTkp.js → hi-zIXqrXNC.js} +1 -1
- package/web/dist/assets/{hls-3VKVEQE3-BCXawNaW.js → hls-3VKVEQE3-5pAjDDLr.js} +1 -1
- package/web/dist/assets/{hu-C7on-yUl.js → hu-Dpn_DIRi.js} +1 -1
- package/web/dist/assets/{id-pIrzVeOi.js → id-Cu1V6gAm.js} +1 -1
- package/web/dist/assets/{index-CDBIr8Tz.js → index-D-PZ4nGC.js} +2 -2
- package/web/dist/assets/{it-Bl9xk5B4.js → it-BNcoJEYQ.js} +1 -1
- package/web/dist/assets/{mpegts-63ylMmge.js → mpegts-CabjhxTI.js} +1 -1
- package/web/dist/assets/{mpegts-LO6RVLD6-DBakOXU5.js → mpegts-LO6RVLD6-CRSxiR1J.js} +1 -1
- package/web/dist/assets/{nl-b5BUih3i.js → nl-gvivlDEE.js} +1 -1
- package/web/dist/assets/{ru-BlAkbEPp.js → ru-BxQnVrHu.js} +1 -1
- package/web/dist/assets/{sv-BEKvqELG.js → sv-BP1JhAR8.js} +1 -1
- package/web/dist/assets/{uk-JY8Dh56p.js → uk-ChYhgzlf.js} +1 -1
- package/web/dist/assets/{vi-DbtxuQPL.js → vi-CD7vzLwP.js} +1 -1
- package/web/dist/assets/{zh-4x0DI5jO.js → zh-BmGS-RcE.js} +1 -1
- package/web/dist/index.html +1 -1
- package/web/dist/sw.js +22 -22
package/dist/station-mcp.js
CHANGED
|
@@ -26,7 +26,7 @@ export const STATION_TOOLS = [
|
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
name: "station_create",
|
|
29
|
-
description: "Make a station from a folder in the library (path relative to it, \"\" for all of it) or
|
|
29
|
+
description: "Make a station from a folder in the library (path relative to it, \"\" for all of it), a playlist, or track indexes. It starts private and stopped; nothing is published.",
|
|
30
30
|
inputSchema: {
|
|
31
31
|
type: "object",
|
|
32
32
|
properties: {
|
|
@@ -34,6 +34,7 @@ export const STATION_TOOLS = [
|
|
|
34
34
|
name: STRING,
|
|
35
35
|
folder: { ...STRING, description: "A folder under the library, e.g. \"Albums/Late Night\"." },
|
|
36
36
|
items: { type: "array", items: { type: "integer" }, description: "Track indexes, as /api/state lists them." },
|
|
37
|
+
playlist: { ...STRING, description: "A playlist id (playlist_list): the station plays its ready items in order." },
|
|
37
38
|
description: STRING,
|
|
38
39
|
shuffle: { type: "boolean" },
|
|
39
40
|
repeat: { type: "boolean", description: "Round and round (default) or once." },
|
|
@@ -84,6 +85,24 @@ export const STATION_TOOLS = [
|
|
|
84
85
|
},
|
|
85
86
|
];
|
|
86
87
|
const say = (value, isError = false) => ({ content: [{ type: "text", text: value }], ...(isError ? { isError: true } : {}) });
|
|
88
|
+
/** Where to send a tool's request, and with which credential. */
|
|
89
|
+
export function connect(args, options) {
|
|
90
|
+
const server = typeof args["server"] === "string" ? args["server"].replace(/\/+$/, "") : "";
|
|
91
|
+
const headers = { "content-type": "application/json" };
|
|
92
|
+
if (server === "") {
|
|
93
|
+
const local = options.local === undefined ? (() => { const state = readState(); return state ? { url: daemonUrl(state), key: state.key } : null; })() : options.local;
|
|
94
|
+
if (!local)
|
|
95
|
+
return { error: "No nixamp daemon runs on this machine. Start one (nixamp daemon start ~/Music) or pass `server`." };
|
|
96
|
+
if (local.key)
|
|
97
|
+
headers[KEY_HEADER] = local.key;
|
|
98
|
+
return { base: local.url, headers };
|
|
99
|
+
}
|
|
100
|
+
const session = options.session === undefined ? readSession() : options.session;
|
|
101
|
+
if (!session)
|
|
102
|
+
return { error: "Another server needs this machine signed in as its owner: nixamp login." };
|
|
103
|
+
headers["authorization"] = `Bearer ${session.token}`;
|
|
104
|
+
return { base: server, headers };
|
|
105
|
+
}
|
|
87
106
|
export function isStationTool(name) {
|
|
88
107
|
return STATION_TOOLS.some((tool) => tool.name === name);
|
|
89
108
|
}
|
|
@@ -95,23 +114,10 @@ function line(station) {
|
|
|
95
114
|
}
|
|
96
115
|
export async function callStationTool(name, args, options = {}) {
|
|
97
116
|
const send = options.fetcher ?? fetch;
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const local = options.local === undefined ? (() => { const state = readState(); return state ? { url: daemonUrl(state), key: state.key } : null; })() : options.local;
|
|
103
|
-
if (!local)
|
|
104
|
-
return say("No nixamp daemon runs on this machine. Start one (nixamp daemon start ~/Music) or pass `server`.", true);
|
|
105
|
-
base = local.url;
|
|
106
|
-
if (local.key)
|
|
107
|
-
headers[KEY_HEADER] = local.key;
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
const session = options.session === undefined ? readSession() : options.session;
|
|
111
|
-
if (!session)
|
|
112
|
-
return say("Another server's stations need this machine signed in as its owner: nixamp login.", true);
|
|
113
|
-
headers["authorization"] = `Bearer ${session.token}`;
|
|
114
|
-
}
|
|
117
|
+
const target = connect(args, options);
|
|
118
|
+
if ("error" in target)
|
|
119
|
+
return say(target.error, true);
|
|
120
|
+
const { base, headers } = target;
|
|
115
121
|
const id = typeof args["id"] === "string" ? args["id"] : "";
|
|
116
122
|
const call = async (method, path, body) => {
|
|
117
123
|
const response = await send(`${base}${path}`, { method, headers, ...(body === undefined ? {} : { body: JSON.stringify(body) }) });
|
|
@@ -135,7 +141,7 @@ export async function callStationTool(name, args, options = {}) {
|
|
|
135
141
|
return answer.ok ? say(JSON.stringify(answer.body["station"], null, 2)) : refused(answer.body);
|
|
136
142
|
}
|
|
137
143
|
if (name === "station_create") {
|
|
138
|
-
const answer = await call("POST", "/api/v1/stations", pick(["name", "folder", "items", "description", "shuffle", "repeat", "bitrate", "idempotencyKey"]));
|
|
144
|
+
const answer = await call("POST", "/api/v1/stations", pick(["name", "folder", "items", "playlist", "description", "shuffle", "repeat", "bitrate", "idempotencyKey"]));
|
|
139
145
|
return answer.ok ? say(`Made, private and stopped: ${line(answer.body["station"])}`) : refused(answer.body);
|
|
140
146
|
}
|
|
141
147
|
if (name === "station_update") {
|
package/dist/station-usage.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** `nixamp station` usage, apart so `nixamp help station` does not load the client. */
|
|
2
|
-
export declare const USAGE = "nixamp station \u2014 make a collection into a station\n\n nixamp station list\n nixamp station create --name NAME (--folder PATH | --items 0,1,2) [--shuffle] [--no-repeat] [--bitrate 128]\n nixamp station show ID\n nixamp station status ID\n nixamp station start ID\n nixamp station stop ID\n nixamp station skip ID\n nixamp station retry ID try every left-out file again\n nixamp station publish ID --basis owned|permission|licensed|public-domain [--note TEXT] [--unlisted] [--no-list]\n nixamp station unpublish ID [--private]\n nixamp station link ID [--rotate]\n nixamp station delete ID\n\n --json machine-readable output\n --url, --key another server, as with `nixamp admin`\n\nA new station is private and stopped. Starting it does not publish it.";
|
|
2
|
+
export declare const USAGE = "nixamp station \u2014 make a collection into a station\n\n nixamp station list\n nixamp station create --name NAME (--folder PATH | --playlist ID | --items 0,1,2) [--shuffle] [--no-repeat] [--bitrate 128]\n nixamp station show ID\n nixamp station status ID\n nixamp station start ID\n nixamp station stop ID\n nixamp station skip ID\n nixamp station retry ID try every left-out file again\n nixamp station publish ID --basis owned|permission|licensed|public-domain [--note TEXT] [--unlisted] [--no-list]\n nixamp station unpublish ID [--private]\n nixamp station link ID [--rotate]\n nixamp station delete ID\n\n --json machine-readable output\n --url, --key another server, as with `nixamp admin`\n\nA new station is private and stopped. Starting it does not publish it.";
|
package/dist/station-usage.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export const USAGE = `nixamp station — make a collection into a station
|
|
3
3
|
|
|
4
4
|
nixamp station list
|
|
5
|
-
nixamp station create --name NAME (--folder PATH | --items 0,1,2) [--shuffle] [--no-repeat] [--bitrate 128]
|
|
5
|
+
nixamp station create --name NAME (--folder PATH | --playlist ID | --items 0,1,2) [--shuffle] [--no-repeat] [--bitrate 128]
|
|
6
6
|
nixamp station show ID
|
|
7
7
|
nixamp station status ID
|
|
8
8
|
nixamp station start ID
|
package/package.json
CHANGED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nixamp library <command>`: the index, from a terminal or a script.
|
|
3
|
+
*
|
|
4
|
+
* `nixamp library ~/Music` still sets the folder a daemon serves (library.ts);
|
|
5
|
+
* these are the questions you ask once it is running. Same conventions as
|
|
6
|
+
* `nixamp station`: the daemon on this machine unless --url/--key, --json for
|
|
7
|
+
* scripts, exit 0 done, 1 refused, 2 usage, 3 unreachable.
|
|
8
|
+
*/
|
|
9
|
+
import { resolveTarget } from "./admin.ts";
|
|
10
|
+
import { KEY_HEADER } from "./share.ts";
|
|
11
|
+
|
|
12
|
+
import { LIBRARY_COMMANDS, LIBRARY_USAGE } from "./library-usage.ts";
|
|
13
|
+
|
|
14
|
+
export { LIBRARY_COMMANDS, LIBRARY_USAGE };
|
|
15
|
+
|
|
16
|
+
function flag(argv: string[], name: string): string | undefined {
|
|
17
|
+
const at = argv.indexOf(name);
|
|
18
|
+
return at === -1 ? undefined : argv[at + 1];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Words that are not flags or flag values. */
|
|
22
|
+
function words(argv: string[]): string[] {
|
|
23
|
+
const out: string[] = [];
|
|
24
|
+
for (let at = 0; at < argv.length; at++) {
|
|
25
|
+
const one = argv[at]!;
|
|
26
|
+
if (one.startsWith("--")) {
|
|
27
|
+
if (!["--json", "--force", "--wait"].includes(one)) at += 1;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
out.push(one);
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function libraryTool(argv: string[]): Promise<number> {
|
|
36
|
+
const [command] = argv;
|
|
37
|
+
const json = argv.includes("--json");
|
|
38
|
+
let target;
|
|
39
|
+
try {
|
|
40
|
+
target = resolveTarget(argv);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error((error as Error).message);
|
|
43
|
+
return 3;
|
|
44
|
+
}
|
|
45
|
+
const headers: Record<string, string> = { "content-type": "application/json", ...(target.key ? { [KEY_HEADER]: target.key } : {}) };
|
|
46
|
+
const call = async (method: string, path: string, body?: unknown): Promise<{ status: number; body: Record<string, unknown> }> => {
|
|
47
|
+
let response: Response;
|
|
48
|
+
try {
|
|
49
|
+
response = await fetch(`${target.url}${path}`, { method, headers, ...(body === undefined ? {} : { body: JSON.stringify(body) }) });
|
|
50
|
+
} catch (error) {
|
|
51
|
+
throw Object.assign(new Error(`could not reach ${target.url}: ${(error as Error).message}`), { unreachable: true });
|
|
52
|
+
}
|
|
53
|
+
const parsed = (await response.json().catch(() => ({}))) as Record<string, unknown>;
|
|
54
|
+
return { status: response.status, body: parsed };
|
|
55
|
+
};
|
|
56
|
+
const out = (answer: { status: number; body: Record<string, unknown> }, line: (body: Record<string, unknown>) => string): number => {
|
|
57
|
+
if (json) console.log(JSON.stringify(answer.body, null, 2));
|
|
58
|
+
else if (answer.status < 400) console.log(line(answer.body));
|
|
59
|
+
if (answer.status >= 400) {
|
|
60
|
+
if (!json) console.error(`nixamp: ${String(answer.body["error"] ?? "refused")} (${String(answer.body["code"] ?? answer.status)})`);
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
return 0;
|
|
64
|
+
};
|
|
65
|
+
const scanLine = (scan: Record<string, unknown> | null | undefined): string =>
|
|
66
|
+
scan ? `${String(scan["status"])}: ${String(scan["found"])} found, ${String(scan["unchanged"])} unchanged, ${String(scan["probed"])} read, ${String(scan["failed"])} failed, ${String(scan["missing"])} gone` : "never scanned";
|
|
67
|
+
const itemLine = (item: Record<string, unknown>): string =>
|
|
68
|
+
`${String(item["id"])} ${String(item["artist"] || "?")} — ${String(item["title"])}${item["album"] ? ` (${String(item["album"])})` : ""}${item["state"] !== "ready" ? ` [${String(item["state"])}]` : ""}`;
|
|
69
|
+
const rest = words(argv.slice(1));
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
switch (command) {
|
|
73
|
+
case "status":
|
|
74
|
+
return out(await call("GET", "/api/v1/library"), (body) => {
|
|
75
|
+
const counts = body["counts"] as Record<string, number>;
|
|
76
|
+
const sources = (body["sources"] as Record<string, unknown>[]) ?? [];
|
|
77
|
+
return [
|
|
78
|
+
`${String(body["items"])} items: ${Object.entries(counts).filter(([, n]) => n > 0).map(([state, n]) => `${n} ${state}`).join(", ") || "none"}`,
|
|
79
|
+
...sources.map((one) => ` ${String(one["id"])} ${String(one["root"] ?? "")}${one["enabled"] ? "" : " (off)"}\n last scan ${scanLine(one["lastScan"] as Record<string, unknown> | null)}`),
|
|
80
|
+
].join("\n");
|
|
81
|
+
});
|
|
82
|
+
case "sources":
|
|
83
|
+
return out(await call("GET", "/api/v1/library/sources"), (body) =>
|
|
84
|
+
((body["sources"] as Record<string, unknown>[]) ?? []).map((one) => `${String(one["id"])} ${String(one["root"] ?? "")}${one["enabled"] ? "" : " (off)"}`).join("\n") || "No sources.");
|
|
85
|
+
case "add": {
|
|
86
|
+
const [path] = rest;
|
|
87
|
+
if (!path) { console.error("nixamp library add needs a folder"); return 2; }
|
|
88
|
+
const { resolve } = await import("node:path");
|
|
89
|
+
const { homedir } = await import("node:os");
|
|
90
|
+
return out(await call("POST", "/api/v1/library/sources", { root: resolve(path.replace(/^~(?=$|\/)/, homedir())) }), (body) =>
|
|
91
|
+
`Indexing ${String((body["source"] as Record<string, unknown>)["root"])} as ${String((body["source"] as Record<string, unknown>)["id"])}.`);
|
|
92
|
+
}
|
|
93
|
+
case "scan": {
|
|
94
|
+
let [source] = rest;
|
|
95
|
+
if (!source) {
|
|
96
|
+
const listed = await call("GET", "/api/v1/library/sources");
|
|
97
|
+
const all = (listed.body["sources"] as Record<string, unknown>[]) ?? [];
|
|
98
|
+
if (all.length !== 1) { console.error("Which source? `nixamp library sources` lists them."); return 2; }
|
|
99
|
+
source = String(all[0]!["id"]);
|
|
100
|
+
}
|
|
101
|
+
const started = await call("POST", `/api/v1/library/sources/${source}/scan`, { force: argv.includes("--force") });
|
|
102
|
+
if (started.status >= 400 || !argv.includes("--wait")) return out(started, (body) => `Scanning: job ${String((body["job"] as Record<string, unknown>)["jobId"])}.`);
|
|
103
|
+
const jobId = String((started.body["job"] as Record<string, unknown>)["jobId"]);
|
|
104
|
+
for (;;) {
|
|
105
|
+
const polled = await call("GET", `/api/v1/library/jobs/${jobId}`);
|
|
106
|
+
const job = polled.body["job"] as Record<string, unknown> | undefined;
|
|
107
|
+
if (polled.status >= 400 || !job || job["status"] !== "running") return out(polled, () => scanLine(job));
|
|
108
|
+
await new Promise((next) => setTimeout(next, 1000));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
case "search": {
|
|
112
|
+
const query = new URLSearchParams({ q: rest.join(" "), limit: flag(argv, "--limit") ?? "20", sort: "artist" });
|
|
113
|
+
for (const name of ["artist", "album", "genre", "state", "folder"]) {
|
|
114
|
+
const value = flag(argv, `--${name}`);
|
|
115
|
+
if (value) query.set(name, value);
|
|
116
|
+
}
|
|
117
|
+
return out(await call("GET", `/api/v1/library/items?${query}`), (body) => {
|
|
118
|
+
const items = (body["items"] as Record<string, unknown>[]) ?? [];
|
|
119
|
+
return items.length ? `${items.map(itemLine).join("\n")}\n${String(body["total"])} in all` : "Nothing matches.";
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
case "show": {
|
|
123
|
+
const [item] = rest;
|
|
124
|
+
if (!item) { console.error("nixamp library show needs an item id"); return 2; }
|
|
125
|
+
return out(await call("GET", `/api/v1/library/items/${item}`), (body) => JSON.stringify(body["item"], null, 2));
|
|
126
|
+
}
|
|
127
|
+
case "fix": {
|
|
128
|
+
const [item] = rest;
|
|
129
|
+
if (!item) { console.error("nixamp library fix needs an item id"); return 2; }
|
|
130
|
+
const patch: Record<string, unknown> = {};
|
|
131
|
+
for (const name of ["title", "artist", "album", "albumArtist", "genre"]) {
|
|
132
|
+
const value = flag(argv, `--${name}`);
|
|
133
|
+
if (value !== undefined) patch[name] = value;
|
|
134
|
+
}
|
|
135
|
+
for (const name of ["track", "disc", "year"]) {
|
|
136
|
+
const value = flag(argv, `--${name}`);
|
|
137
|
+
if (value !== undefined) patch[name] = Number(value);
|
|
138
|
+
}
|
|
139
|
+
if (Object.keys(patch).length === 0) { console.error("nixamp library fix needs at least one of --title --artist --album --genre --track --disc --year"); return 2; }
|
|
140
|
+
return out(await call("PATCH", `/api/v1/library/items/${item}`, patch), (body) => itemLine(body["item"] as Record<string, unknown>));
|
|
141
|
+
}
|
|
142
|
+
case "remove": {
|
|
143
|
+
const [source] = rest;
|
|
144
|
+
if (!source) { console.error("nixamp library remove needs a source id"); return 2; }
|
|
145
|
+
return out(await call("DELETE", `/api/v1/library/sources/${source}`), (body) => `Forgot ${String(body["forgotten"])} items. No file was touched.`);
|
|
146
|
+
}
|
|
147
|
+
case "playlists":
|
|
148
|
+
return out(await call("GET", "/api/v1/library/playlists"), (body) =>
|
|
149
|
+
((body["playlists"] as Record<string, unknown>[]) ?? []).map((one) => `${String(one["id"])} ${String(one["name"])} (${String(one["count"])})`).join("\n") || "No playlists yet.");
|
|
150
|
+
case "playlist": {
|
|
151
|
+
const [verb, first, ...others] = rest;
|
|
152
|
+
const showList = (body: Record<string, unknown>): string => {
|
|
153
|
+
const list = body["playlist"] as Record<string, unknown>;
|
|
154
|
+
const items = (list["items"] as Record<string, unknown>[] | undefined) ?? [];
|
|
155
|
+
return [`${String(list["id"])} ${String(list["name"])} (revision ${String(list["revision"])})`, ...items.map((one, at) => ` ${at + 1}. ${itemLine(one)}`)].join("\n");
|
|
156
|
+
};
|
|
157
|
+
if (verb === "new" && first) return out(await call("POST", "/api/v1/library/playlists", { name: first, items: others }), showList);
|
|
158
|
+
if (verb === "show" && first) return out(await call("GET", `/api/v1/library/playlists/${first}`), showList);
|
|
159
|
+
if (verb === "add" && first && others.length) return out(await call("POST", `/api/v1/library/playlists/${first}/items`, { items: others }), showList);
|
|
160
|
+
if (verb === "delete" && first) return out(await call("DELETE", `/api/v1/library/playlists/${first}`), () => `Deleted playlist ${first}.`);
|
|
161
|
+
console.error("nixamp library playlist new NAME [ITEM...] | show ID | add ID ITEM... | delete ID");
|
|
162
|
+
return 2;
|
|
163
|
+
}
|
|
164
|
+
default:
|
|
165
|
+
console.log(LIBRARY_USAGE);
|
|
166
|
+
return 2;
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if ((error as { unreachable?: boolean }).unreachable) {
|
|
170
|
+
console.error(`nixamp: ${(error as Error).message}`);
|
|
171
|
+
return 3;
|
|
172
|
+
}
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|