@axium/sysadmin 0.2.3 → 0.2.5

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.
@@ -111,31 +111,19 @@ function storage() {
111
111
  }
112
112
  return result;
113
113
  }
114
- function memory() {
115
- const info = {};
116
- const content = read('/proc/meminfo');
117
- if (content)
118
- for (const line of content.split('\n')) {
119
- const match = /^(\w+):\s+(\d+)(?:\s+kB)?$/.exec(line.trim());
120
- if (!match)
121
- continue;
122
- const [, key, value] = match;
123
- info[key] = BigInt(value) * (line.endsWith('kB') ? 1024n : 1n);
124
- }
125
- const total = info.MemTotal ?? BigInt(os.totalmem());
126
- const available = info.MemAvailable ?? BigInt(os.freemem());
127
- const memory = {
128
- speed: 0,
129
- total,
130
- used: total - available,
131
- };
114
+ let dmiMemory;
115
+ /** Static memory hardware details from DMI. */
116
+ function memoryHardware() {
117
+ if (dmiMemory)
118
+ return dmiMemory;
119
+ dmiMemory = { speed: 0 };
132
120
  try {
133
121
  const dmiMemoryInfo = execFileSync('sudo', ['-n', 'dmidecode', '-t', '17'], {
134
122
  encoding: 'utf8',
135
123
  stdio: ['ignore', 'pipe', 'ignore'],
136
124
  });
137
125
  for (const match of dmiMemoryInfo.matchAll(/^\s*(?:Configured Memory|Configured Clock)?\s*Speed:\s*(\d+)\s*MT\/s/gim)) {
138
- memory.speed = Math.max(memory.speed, Number(match[1]));
126
+ dmiMemory.speed = Math.max(dmiMemory.speed, Number(match[1]));
139
127
  }
140
128
  const populated = (field) => {
141
129
  for (const [, match] of dmiMemoryInfo.matchAll(new RegExp(`^[ \\t]*${field}:[ \\t]*(.+)$`, 'gim'))) {
@@ -144,12 +132,32 @@ function memory() {
144
132
  return value;
145
133
  }
146
134
  };
147
- memory.formFactor = populated('Form Factor');
148
- memory.type = populated('Type');
135
+ dmiMemory.formFactor = populated('Form Factor');
136
+ dmiMemory.type = populated('Type');
149
137
  }
150
138
  catch {
151
139
  // dmidecode missing, not root, or sudo needs a password
152
140
  }
141
+ return dmiMemory;
142
+ }
143
+ function memory() {
144
+ const info = {};
145
+ const content = read('/proc/meminfo');
146
+ if (content)
147
+ for (const line of content.split('\n')) {
148
+ const match = /^(\w+):\s+(\d+)(?:\s+kB)?$/.exec(line.trim());
149
+ if (!match)
150
+ continue;
151
+ const [, key, value] = match;
152
+ info[key] = BigInt(value) * (line.endsWith('kB') ? 1024n : 1n);
153
+ }
154
+ const total = info.MemTotal ?? BigInt(os.totalmem());
155
+ const available = info.MemAvailable ?? BigInt(os.freemem());
156
+ const memory = {
157
+ ...memoryHardware(),
158
+ total,
159
+ used: total - available,
160
+ };
153
161
  const swapTotal = info.SwapTotal ?? 0n;
154
162
  if (swapTotal > 0n)
155
163
  memory.swap = { total: swapTotal, used: swapTotal - (info.SwapFree ?? 0n) };
@@ -0,0 +1 @@
1
+ export declare function getOnlineHosts(): Promise<string[]>;
@@ -0,0 +1,12 @@
1
+ import { socket } from '@axium/client/socket';
2
+ export async function getOnlineHosts() {
3
+ if (!socket)
4
+ return [];
5
+ try {
6
+ const systems = await socket.emitWithAck('sysadmin:ping');
7
+ return systems.map(s => s.hostname);
8
+ }
9
+ catch {
10
+ return [];
11
+ }
12
+ }
package/dist/common.d.ts CHANGED
@@ -26,8 +26,8 @@ export declare const System: z.ZodObject<{
26
26
  user: z.ZodOptional<z.ZodNullable<z.ZodObject<{
27
27
  id: z.ZodUUID;
28
28
  name: z.ZodString;
29
- username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
30
- email: z.ZodOptional<z.ZodEmail>;
29
+ username: z.ZodString;
30
+ email: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodEmail>>>;
31
31
  emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>>;
32
32
  preferences: z.ZodOptional<z.ZodLazy<z.ZodObject<{
33
33
  debug: z.ZodDefault<z.ZodBoolean>;
@@ -81,8 +81,8 @@ declare const SysadminAPI: {
81
81
  user: z.ZodOptional<z.ZodNullable<z.ZodObject<{
82
82
  id: z.ZodUUID;
83
83
  name: z.ZodString;
84
- username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
85
- email: z.ZodOptional<z.ZodEmail>;
84
+ username: z.ZodString;
85
+ email: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodEmail>>>;
86
86
  emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>>;
87
87
  preferences: z.ZodOptional<z.ZodLazy<z.ZodObject<{
88
88
  debug: z.ZodDefault<z.ZodBoolean>;
@@ -117,8 +117,8 @@ declare const SysadminAPI: {
117
117
  user: z.ZodOptional<z.ZodNullable<z.ZodObject<{
118
118
  id: z.ZodUUID;
119
119
  name: z.ZodString;
120
- username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
121
- email: z.ZodOptional<z.ZodEmail>;
120
+ username: z.ZodString;
121
+ email: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodEmail>>>;
122
122
  emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>>;
123
123
  preferences: z.ZodOptional<z.ZodLazy<z.ZodObject<{
124
124
  debug: z.ZodDefault<z.ZodBoolean>;
@@ -167,8 +167,8 @@ declare const SysadminAPI: {
167
167
  user: z.ZodOptional<z.ZodNullable<z.ZodObject<{
168
168
  id: z.ZodUUID;
169
169
  name: z.ZodString;
170
- username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
171
- email: z.ZodOptional<z.ZodEmail>;
170
+ username: z.ZodString;
171
+ email: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodEmail>>>;
172
172
  emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>>;
173
173
  preferences: z.ZodOptional<z.ZodLazy<z.ZodObject<{
174
174
  debug: z.ZodDefault<z.ZodBoolean>;
@@ -203,8 +203,8 @@ declare const SysadminAPI: {
203
203
  user: z.ZodOptional<z.ZodNullable<z.ZodObject<{
204
204
  id: z.ZodUUID;
205
205
  name: z.ZodString;
206
- username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
207
- email: z.ZodOptional<z.ZodEmail>;
206
+ username: z.ZodString;
207
+ email: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodEmail>>>;
208
208
  emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>>;
209
209
  preferences: z.ZodOptional<z.ZodLazy<z.ZodObject<{
210
210
  debug: z.ZodDefault<z.ZodBoolean>;
@@ -234,8 +234,8 @@ declare const SysadminAPI: {
234
234
  user: z.ZodOptional<z.ZodNullable<z.ZodObject<{
235
235
  id: z.ZodUUID;
236
236
  name: z.ZodString;
237
- username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
238
- email: z.ZodOptional<z.ZodEmail>;
237
+ username: z.ZodString;
238
+ email: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodEmail>>>;
239
239
  emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>>;
240
240
  preferences: z.ZodOptional<z.ZodLazy<z.ZodObject<{
241
241
  debug: z.ZodDefault<z.ZodBoolean>;
@@ -290,8 +290,8 @@ declare const SysadminAPI: {
290
290
  user: z.ZodOptional<z.ZodNullable<z.ZodObject<{
291
291
  id: z.ZodUUID;
292
292
  name: z.ZodString;
293
- username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
294
- email: z.ZodOptional<z.ZodEmail>;
293
+ username: z.ZodString;
294
+ email: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodEmail>>>;
295
295
  emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>>;
296
296
  preferences: z.ZodOptional<z.ZodLazy<z.ZodObject<{
297
297
  debug: z.ZodDefault<z.ZodBoolean>;
@@ -1,9 +1,15 @@
1
1
  import { addListener, io } from '@axium/server/socket';
2
2
  addListener('sysadmin:ping', async (socket, cb) => {
3
- const result = await io.in(`local:${socket.data.user.id}`).timeout(5000).emitWithAck('sysadmin:ping');
4
- cb(result);
3
+ cb(await io
4
+ .in(`local:${socket.data.user.id}`)
5
+ .timeout(5000)
6
+ .emitWithAck('sysadmin:ping')
7
+ .catch(e => e.responses || []));
5
8
  });
6
9
  addListener('sysadmin:getSystemInfo', async (socket, cb) => {
7
- const result = await io.in(`local:${socket.data.user.id}`).timeout(5000).emitWithAck('sysadmin:getSystemInfo');
8
- cb(result);
10
+ cb(await io
11
+ .in(`local:${socket.data.user.id}`)
12
+ .timeout(5000)
13
+ .emitWithAck('sysadmin:getSystemInfo')
14
+ .catch(e => e.responses || []));
9
15
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/sysadmin",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "author": "James Prevett <axium@jamespre.dev>",
5
5
  "description": "System administration for Axium",
6
6
  "funding": {
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { text } from '@axium/client';
3
3
  import { Icon } from '@axium/client/components';
4
- import { socket } from '@axium/client/socket';
4
+ import { getOnlineHosts } from '@axium/sysadmin/client/web';
5
5
  import { SystemCard, SystemInitDialog, UserCard, UserInitDialog } from '@axium/sysadmin/components';
6
6
 
7
7
  const { data } = $props();
@@ -9,7 +9,7 @@
9
9
  let systems = $state(data.systems);
10
10
  let users = $state(data.users);
11
11
 
12
- const onlineHosts = $derived(await socket?.emitWithAck('sysadmin:ping').then(systems => systems.map(s => s.hostname)));
12
+ const onlineHosts = $derived(await getOnlineHosts());
13
13
  </script>
14
14
 
15
15
  <svelte:head>
@@ -1,14 +1,14 @@
1
1
  <script lang="ts">
2
2
  import { text } from '@axium/client';
3
3
  import { Icon } from '@axium/client/components';
4
- import { socket } from '@axium/client/socket';
4
+ import { getOnlineHosts } from '@axium/sysadmin/client/web';
5
5
  import { SystemCard, SystemInitDialog } from '@axium/sysadmin/components';
6
6
 
7
7
  const { data } = $props();
8
8
 
9
9
  let systems = $state(data.systems);
10
10
 
11
- const onlineHosts = $derived(await socket?.emitWithAck('sysadmin:ping').then(systems => systems.map(s => s.hostname)));
11
+ const onlineHosts = $derived(await getOnlineHosts());
12
12
  </script>
13
13
 
14
14
  <svelte:head>
@@ -2,7 +2,7 @@
2
2
  import { goto } from '$app/navigation';
3
3
  import { fetchAPI, text } from '@axium/client';
4
4
  import { Icon } from '@axium/client/components';
5
- import { socket } from '@axium/client/socket';
5
+ import { getOnlineHosts } from '@axium/sysadmin/client/web';
6
6
  import { toastStatus } from '@axium/client/toast';
7
7
  import { SystemCard, UserInitDialog } from '@axium/sysadmin/components';
8
8
 
@@ -12,7 +12,7 @@
12
12
  let systems = $state(data.systems);
13
13
  let editDialog = $state<HTMLDialogElement>();
14
14
 
15
- const onlineHosts = $derived(await socket?.emitWithAck('sysadmin:ping').then(systems => systems.map(s => s.hostname)));
15
+ const onlineHosts = $derived(await getOnlineHosts());
16
16
 
17
17
  function remove() {
18
18
  toastStatus(