@axium/client 0.31.2 → 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/assets/theme.css +2 -0
- package/axium-client.service +1 -1
- package/dist/cli/cache.js +8 -2
- package/dist/cli/config.d.ts +1 -0
- package/dist/cli/config.js +7 -7
- package/dist/cli/index.js +45 -11
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/requests.d.ts +1 -0
- package/dist/requests.js +1 -1
- package/dist/socket.d.ts +10 -0
- package/dist/socket.js +40 -0
- package/package.json +4 -3
package/assets/theme.css
CHANGED
|
@@ -51,6 +51,8 @@ html {
|
|
|
51
51
|
--fg-error: hsl(0 50 calc(var(--fg-light) - var(--light-step)));
|
|
52
52
|
--fg-warning: hsl(60 50 calc(var(--fg-light) - var(--light-step)));
|
|
53
53
|
|
|
54
|
+
--green: hsl(140 50 50);
|
|
55
|
+
|
|
54
56
|
--border-disabled: 1px solid hsl(0 5 calc(var(--bg-light) - var(--light-step)));
|
|
55
57
|
--border-accent: 1px solid hsl(var(--hue) 10 calc(var(--bg-light) + (var(--light-step) * 3)));
|
|
56
58
|
--border-alt: 1px solid var(--bg-alt);
|
package/axium-client.service
CHANGED
|
@@ -11,7 +11,7 @@ FailureAction=none
|
|
|
11
11
|
[Service]
|
|
12
12
|
Type=simple
|
|
13
13
|
ExecStartPre=/usr/bin/env cd "%Y/../../.."
|
|
14
|
-
ExecStart=/usr/bin/env npx --prefix "%Y/../../.." axium-client
|
|
14
|
+
ExecStart=/usr/bin/env npx --prefix "%Y/../../.." axium-client daemon
|
|
15
15
|
ExecReload=kill -HUP $MAINPID
|
|
16
16
|
SyslogIdentifier=axium-client
|
|
17
17
|
Restart=on-failure
|
package/dist/cli/cache.js
CHANGED
|
@@ -136,9 +136,15 @@ export async function update(force = false) {
|
|
|
136
136
|
}
|
|
137
137
|
export function clear() {
|
|
138
138
|
for (const handle of handles)
|
|
139
|
-
|
|
139
|
+
try {
|
|
140
|
+
unlinkSync(handle.path);
|
|
141
|
+
}
|
|
142
|
+
catch { }
|
|
140
143
|
for (const { path } of persistedAPICaches)
|
|
141
|
-
|
|
144
|
+
try {
|
|
145
|
+
unlinkSync(path);
|
|
146
|
+
}
|
|
147
|
+
catch { }
|
|
142
148
|
}
|
|
143
149
|
export async function* info() {
|
|
144
150
|
for (const handle of handles) {
|
package/dist/cli/config.d.ts
CHANGED
package/dist/cli/config.js
CHANGED
|
@@ -8,9 +8,9 @@ import { setPrefix, setToken } from '../requests.js';
|
|
|
8
8
|
import * as cache from './cache.js';
|
|
9
9
|
export const configDir = join(process.env.XDG_CONFIG_HOME || join(homedir(), '.config'), 'axium');
|
|
10
10
|
mkdirSync(configDir, { recursive: true });
|
|
11
|
-
const
|
|
12
|
-
if (!existsSync(
|
|
13
|
-
writeFileSync(
|
|
11
|
+
export const axcConfigPath = join(configDir, 'config.json');
|
|
12
|
+
if (!existsSync(axcConfigPath))
|
|
13
|
+
writeFileSync(axcConfigPath, '{}');
|
|
14
14
|
export function session() {
|
|
15
15
|
if (!config.token)
|
|
16
16
|
io.exit('Not logged in.', 4);
|
|
@@ -20,19 +20,19 @@ export function session() {
|
|
|
20
20
|
}
|
|
21
21
|
export async function loadConfig(safe) {
|
|
22
22
|
try {
|
|
23
|
-
Object.assign(config, io.readJSON(
|
|
23
|
+
Object.assign(config, io.readJSON(axcConfigPath, ClientConfig));
|
|
24
24
|
if (config.server)
|
|
25
25
|
setPrefix(config.server);
|
|
26
26
|
if (config.token)
|
|
27
27
|
setToken(config.token);
|
|
28
28
|
for (const plugin of config.plugins ?? [])
|
|
29
|
-
await loadPlugin('client', plugin,
|
|
29
|
+
await loadPlugin('client', plugin, axcConfigPath, safe);
|
|
30
30
|
}
|
|
31
31
|
catch (e) {
|
|
32
32
|
io.warn('Failed to load config: ' + io.errorText(e));
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
export function saveConfig() {
|
|
36
|
-
io.writeJSON(
|
|
37
|
-
io.debug('Saved config to ' +
|
|
36
|
+
io.writeJSON(axcConfigPath, config);
|
|
37
|
+
io.debug('Saved config to ' + axcConfigPath);
|
|
38
38
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
import { formatBytes } from '@axium/core';
|
|
3
|
-
import { outputDaemonStatus, pluginText } from '@axium/core/node';
|
|
3
|
+
import { loadPlugin, outputDaemonStatus, pluginText } from '@axium/core/node';
|
|
4
4
|
import { _findPlugin, plugins } from '@axium/core/plugins';
|
|
5
5
|
import { CommanderError, program } from 'commander';
|
|
6
6
|
import * as io from 'ioium/node';
|
|
@@ -10,10 +10,11 @@ import * as z from 'zod';
|
|
|
10
10
|
import $pkg from '../../package.json' with { type: 'json' };
|
|
11
11
|
import { config } from '../config.js';
|
|
12
12
|
import { prefix, useUserAgent } from '../requests.js';
|
|
13
|
+
import { connect as connectSocket } from '../socket.js';
|
|
13
14
|
import { logout } from '../user.js';
|
|
14
15
|
import { clientUA, login } from './auth.js';
|
|
15
16
|
import * as cache from './cache.js';
|
|
16
|
-
import { loadConfig, saveConfig, session } from './config.js';
|
|
17
|
+
import { axcConfigPath, loadConfig, saveConfig, session } from './config.js';
|
|
17
18
|
const safe = z.stringbool().default(false).parse(process.env.SAFE?.toLowerCase()) || process.argv.includes('--safe');
|
|
18
19
|
const debug = z.stringbool().default(false).parse(process.env.DEBUG?.toLowerCase()) || process.argv.includes('--debug');
|
|
19
20
|
if (debug)
|
|
@@ -62,18 +63,26 @@ program.command('status').action(() => {
|
|
|
62
63
|
outputDaemonStatus('axium-client');
|
|
63
64
|
});
|
|
64
65
|
program
|
|
65
|
-
.command('
|
|
66
|
-
.
|
|
67
|
-
.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
await plugin._client?.run();
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
66
|
+
.command('daemon')
|
|
67
|
+
.description('Run as the Axium client daemon')
|
|
68
|
+
.option('--no-socket', 'do not open a socket connection to the server')
|
|
69
|
+
.option('--insecure', 'allow connecting to a server with an untrusted (e.g. self-signed) TLS certificate', false)
|
|
70
|
+
.action(async (opt) => {
|
|
73
71
|
for (const plugin of plugins.values())
|
|
74
|
-
await plugin._client?.run();
|
|
72
|
+
await plugin._client?.run?.();
|
|
73
|
+
// Hold a socket connection to the server for the lifetime of the daemon.
|
|
74
|
+
if (opt.socket && config.token)
|
|
75
|
+
await connectSocket({ rejectUnauthorized: !opt.insecure });
|
|
75
76
|
});
|
|
76
77
|
const axcPlugin = program.command('plugin').alias('plugins').description('Manage plugins');
|
|
78
|
+
axcPlugin
|
|
79
|
+
.command('run')
|
|
80
|
+
.description('Run a plugin')
|
|
81
|
+
.argument('<plugin>', 'the plugin to run')
|
|
82
|
+
.action(async (search) => {
|
|
83
|
+
const plugin = _findPlugin(search);
|
|
84
|
+
await plugin._client?.run?.();
|
|
85
|
+
});
|
|
77
86
|
axcPlugin
|
|
78
87
|
.command('list')
|
|
79
88
|
.alias('ls')
|
|
@@ -103,6 +112,31 @@ axcPlugin
|
|
|
103
112
|
for (const line of pluginText(plugin))
|
|
104
113
|
console.log(line);
|
|
105
114
|
});
|
|
115
|
+
axcPlugin
|
|
116
|
+
.command('add')
|
|
117
|
+
.description('Add a plugin')
|
|
118
|
+
.option('-k, --keep-going', 'continue adding plugins even if one fails')
|
|
119
|
+
.argument('<spec...>', 'the plugin specifier (e.g. a package name) to add')
|
|
120
|
+
.action(async (specs, { keepGoing }) => {
|
|
121
|
+
for (const spec of specs) {
|
|
122
|
+
try {
|
|
123
|
+
if (config.plugins.includes(spec))
|
|
124
|
+
throw `Plugin "${spec}" is already added.`;
|
|
125
|
+
const plugin = await loadPlugin('client', spec, axcConfigPath, safe);
|
|
126
|
+
if (!plugin)
|
|
127
|
+
throw `Failed to load a client plugin from "${spec}".`;
|
|
128
|
+
config.plugins.push(spec);
|
|
129
|
+
saveConfig();
|
|
130
|
+
console.log('Added plugin:', plugin.name, styleText('dim', 'v' + plugin.version));
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
if (keepGoing)
|
|
134
|
+
io.error(e);
|
|
135
|
+
else
|
|
136
|
+
io.exit(e);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
});
|
|
106
140
|
axcPlugin
|
|
107
141
|
.command('remove')
|
|
108
142
|
.alias('rm')
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from './access.js';
|
|
2
|
-
export * as preferences from './preferences.js';
|
|
3
2
|
export * from './cache.js';
|
|
4
3
|
export * from './config.js';
|
|
5
4
|
export * from './locales.js';
|
|
5
|
+
export * as preferences from './preferences.js';
|
|
6
6
|
export * from './requests.js';
|
|
7
|
+
export * as socket from './socket.js';
|
|
7
8
|
export * from './user.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from './access.js';
|
|
2
|
-
export * as preferences from './preferences.js';
|
|
3
2
|
export * from './cache.js';
|
|
4
3
|
export * from './config.js';
|
|
5
4
|
export * from './locales.js';
|
|
5
|
+
export * as preferences from './preferences.js';
|
|
6
6
|
export * from './requests.js';
|
|
7
|
+
export * as socket from './socket.js';
|
|
7
8
|
export * from './user.js';
|
package/dist/requests.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare let token: string | null;
|
|
|
5
5
|
export declare function setToken(value: string | null): void;
|
|
6
6
|
export declare let prefix: string, origin: string;
|
|
7
7
|
export declare function setPrefix(value: string): void;
|
|
8
|
+
export declare let userAgent: string | null;
|
|
8
9
|
/**
|
|
9
10
|
* Only for use on non-browser clients, e.g. Node.js
|
|
10
11
|
*/
|
package/dist/requests.js
CHANGED
package/dist/socket.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ClientToServerEvents, ServerToClientEvents } from '@axium/core/socket';
|
|
2
|
+
import { ServerToClient } from '@axium/core/socket';
|
|
3
|
+
import type { ManagerOptions, Socket as PlainSocket, SocketOptions } from 'socket.io-client';
|
|
4
|
+
export interface Socket extends PlainSocket<ServerToClientEvents, ClientToServerEvents> {
|
|
5
|
+
}
|
|
6
|
+
export declare function addListener<T extends keyof ServerToClient & string>(event: T, listener: ServerToClientEvents[T]): void;
|
|
7
|
+
export interface ConnectOptions extends Partial<ManagerOptions & SocketOptions> {
|
|
8
|
+
}
|
|
9
|
+
export declare let socket: Socket | null;
|
|
10
|
+
export declare function connect(opts?: ConnectOptions): Promise<Socket>;
|
package/dist/socket.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ServerToClient } from '@axium/core/socket';
|
|
2
|
+
import * as io from 'ioium';
|
|
3
|
+
import { io as socketIO } from 'socket.io-client';
|
|
4
|
+
import { origin, token, userAgent } from './requests.js';
|
|
5
|
+
const listeners = new Set();
|
|
6
|
+
export function addListener(event, listener) {
|
|
7
|
+
const schema = ServerToClient[event];
|
|
8
|
+
if (schema)
|
|
9
|
+
listeners.add([event, schema.implement(listener)]);
|
|
10
|
+
else {
|
|
11
|
+
io.warn(`Attaching a listener to the '${event}' socket event without schema`);
|
|
12
|
+
listeners.add([event, listener]);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export let socket = null;
|
|
16
|
+
export function connect(opts) {
|
|
17
|
+
if (socket)
|
|
18
|
+
return Promise.resolve(socket);
|
|
19
|
+
if (!token)
|
|
20
|
+
io.warn('Connecting to the server socket without a session token.');
|
|
21
|
+
const { extraHeaders = {} } = opts || {};
|
|
22
|
+
if (token)
|
|
23
|
+
extraHeaders.Authorization = 'Bearer ' + token;
|
|
24
|
+
if (userAgent)
|
|
25
|
+
extraHeaders['User-Agent'] = userAgent;
|
|
26
|
+
socket = socketIO(origin, { ...opts, extraHeaders });
|
|
27
|
+
for (const [event, listener] of listeners)
|
|
28
|
+
socket.on(event, listener);
|
|
29
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
30
|
+
socket.on('connect', () => {
|
|
31
|
+
io.debug('socket: Connected as ' + socket.id);
|
|
32
|
+
resolve(socket);
|
|
33
|
+
});
|
|
34
|
+
socket.on('connect_error', err => {
|
|
35
|
+
if (!socket.active)
|
|
36
|
+
socket = null;
|
|
37
|
+
reject(err);
|
|
38
|
+
});
|
|
39
|
+
return promise;
|
|
40
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axium/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"author": "James Prevett <jp@jamespre.dev>",
|
|
5
5
|
"funding": {
|
|
6
6
|
"type": "individual",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"build": "tsc"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@axium/core": ">=0.
|
|
52
|
+
"@axium/core": ">=0.33.0",
|
|
53
53
|
"ioium": "^1.0.2",
|
|
54
54
|
"semver": "^7.7.4",
|
|
55
55
|
"svelte": "^5.36.0",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@simplewebauthn/browser": "^13.1.0",
|
|
61
61
|
"commander": "^15.0.0",
|
|
62
|
-
"music-metadata": "^11.12.3"
|
|
62
|
+
"music-metadata": "^11.12.3",
|
|
63
|
+
"socket.io-client": "^4.8.3"
|
|
63
64
|
}
|
|
64
65
|
}
|