@axium/server 0.6.4 → 0.7.1

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/cli.js CHANGED
@@ -16,9 +16,9 @@ program
16
16
  .option('--no-debug', 'override debug mode')
17
17
  .option('-c, --config <path>', 'path to the config file');
18
18
  program.on('option:debug', () => config.set({ debug: true }));
19
- program.on('option:config', () => config.load(program.opts().config));
19
+ program.on('option:config', () => void config.load(program.opts().config));
20
20
  program.hook('preAction', async function (_, action) {
21
- config.loadDefaults();
21
+ await config.loadDefaults();
22
22
  await loadDefaultPlugins();
23
23
  const opt = action.optsWithGlobals();
24
24
  opt.force && output.warn('--force: Protections disabled.');
@@ -196,7 +196,7 @@ program
196
196
  for (const plugin of plugins) {
197
197
  if (!plugin.statusText)
198
198
  continue;
199
- console.log(styleText('bold', plugin.name + ':'));
199
+ console.log(styleText('bold', plugin.name), plugin.version + ':');
200
200
  console.log(await plugin.statusText());
201
201
  }
202
202
  await db.database.destroy();
package/dist/config.d.ts CHANGED
@@ -54,76 +54,119 @@ export declare const Schema: z.ZodObject<{
54
54
  }, {
55
55
  prefix: string;
56
56
  }>;
57
- }, "strip", z.ZodTypeAny, {
58
- debug: boolean;
59
- auth: {
57
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
58
+ auth: z.ZodObject<{
59
+ credentials: z.ZodBoolean;
60
+ debug: z.ZodBoolean;
61
+ secret: z.ZodString;
62
+ secure_cookies: z.ZodBoolean;
63
+ }, "strip", z.ZodTypeAny, {
64
+ debug: boolean;
65
+ credentials: boolean;
66
+ secret: string;
67
+ secure_cookies: boolean;
68
+ }, {
60
69
  debug: boolean;
61
70
  credentials: boolean;
62
71
  secret: string;
63
72
  secure_cookies: boolean;
64
- };
65
- db: {
73
+ }>;
74
+ db: z.ZodObject<{
75
+ host: z.ZodString;
76
+ port: z.ZodNumber;
77
+ password: z.ZodString;
78
+ user: z.ZodString;
79
+ database: z.ZodString;
80
+ }, "strip", z.ZodTypeAny, {
81
+ host: string;
82
+ port: number;
83
+ password: string;
84
+ user: string;
85
+ database: string;
86
+ }, {
66
87
  host: string;
67
88
  port: number;
68
89
  password: string;
69
90
  user: string;
70
91
  database: string;
71
- };
72
- log: {
92
+ }>;
93
+ debug: z.ZodBoolean;
94
+ log: z.ZodObject<{
95
+ level: z.ZodEnum<["error", "warn", "notice", "info", "debug"]>;
96
+ console: z.ZodBoolean;
97
+ }, "strip", z.ZodTypeAny, {
98
+ level: "debug" | "info" | "warn" | "error" | "notice";
99
+ console: boolean;
100
+ }, {
73
101
  level: "debug" | "info" | "warn" | "error" | "notice";
74
102
  console: boolean;
75
- };
76
- web: {
103
+ }>;
104
+ web: z.ZodObject<{
105
+ prefix: z.ZodString;
106
+ }, "strip", z.ZodTypeAny, {
77
107
  prefix: string;
78
- };
79
- }, {
80
- debug: boolean;
81
- auth: {
108
+ }, {
109
+ prefix: string;
110
+ }>;
111
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
112
+ auth: z.ZodObject<{
113
+ credentials: z.ZodBoolean;
114
+ debug: z.ZodBoolean;
115
+ secret: z.ZodString;
116
+ secure_cookies: z.ZodBoolean;
117
+ }, "strip", z.ZodTypeAny, {
82
118
  debug: boolean;
83
119
  credentials: boolean;
84
120
  secret: string;
85
121
  secure_cookies: boolean;
86
- };
87
- db: {
122
+ }, {
123
+ debug: boolean;
124
+ credentials: boolean;
125
+ secret: string;
126
+ secure_cookies: boolean;
127
+ }>;
128
+ db: z.ZodObject<{
129
+ host: z.ZodString;
130
+ port: z.ZodNumber;
131
+ password: z.ZodString;
132
+ user: z.ZodString;
133
+ database: z.ZodString;
134
+ }, "strip", z.ZodTypeAny, {
135
+ host: string;
136
+ port: number;
137
+ password: string;
138
+ user: string;
139
+ database: string;
140
+ }, {
88
141
  host: string;
89
142
  port: number;
90
143
  password: string;
91
144
  user: string;
92
145
  database: string;
93
- };
94
- log: {
146
+ }>;
147
+ debug: z.ZodBoolean;
148
+ log: z.ZodObject<{
149
+ level: z.ZodEnum<["error", "warn", "notice", "info", "debug"]>;
150
+ console: z.ZodBoolean;
151
+ }, "strip", z.ZodTypeAny, {
95
152
  level: "debug" | "info" | "warn" | "error" | "notice";
96
153
  console: boolean;
97
- };
98
- web: {
154
+ }, {
155
+ level: "debug" | "info" | "warn" | "error" | "notice";
156
+ console: boolean;
157
+ }>;
158
+ web: z.ZodObject<{
159
+ prefix: z.ZodString;
160
+ }, "strip", z.ZodTypeAny, {
99
161
  prefix: string;
100
- };
101
- }>;
162
+ }, {
163
+ prefix: string;
164
+ }>;
165
+ }, z.ZodTypeAny, "passthrough">>;
102
166
  export interface Config extends Record<string, unknown>, z.infer<typeof Schema> {
103
167
  }
104
168
  export declare const configFiles: Map<string, PartialRecursive<Config>>;
105
- export declare const config: {
106
- auth: {
107
- credentials: false;
108
- debug: false;
109
- secret: string;
110
- secure_cookies: true;
111
- };
112
- db: {
113
- database: string;
114
- host: string;
115
- password: string;
116
- port: number;
117
- user: string;
118
- };
119
- debug: false;
120
- log: {
121
- console: true;
122
- level: "info";
123
- };
124
- web: {
125
- prefix: string;
126
- };
169
+ declare const configShortcuts: {
127
170
  findPath: typeof findConfigPath;
128
171
  load: typeof loadConfig;
129
172
  loadDefaults: typeof loadDefaultConfigs;
@@ -132,6 +175,7 @@ export declare const config: {
132
175
  set: typeof setConfig;
133
176
  files: Map<string, PartialRecursive<Config>>;
134
177
  };
178
+ export declare const config: Config & typeof configShortcuts;
135
179
  export default config;
136
180
  export declare const File: z.ZodObject<z.objectUtil.extendShape<{
137
181
  auth: z.ZodOptional<z.ZodObject<{
@@ -189,53 +233,122 @@ export declare const File: z.ZodObject<z.objectUtil.extendShape<{
189
233
  }>>;
190
234
  }, {
191
235
  include: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
192
- }>, "strip", z.ZodTypeAny, {
193
- debug?: boolean | undefined;
194
- auth?: {
236
+ plugins: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
237
+ }>, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<{
238
+ auth: z.ZodOptional<z.ZodObject<{
239
+ credentials: z.ZodOptional<z.ZodBoolean>;
240
+ debug: z.ZodOptional<z.ZodBoolean>;
241
+ secret: z.ZodOptional<z.ZodString>;
242
+ secure_cookies: z.ZodOptional<z.ZodBoolean>;
243
+ }, "strip", z.ZodTypeAny, {
244
+ debug?: boolean | undefined;
245
+ credentials?: boolean | undefined;
246
+ secret?: string | undefined;
247
+ secure_cookies?: boolean | undefined;
248
+ }, {
195
249
  debug?: boolean | undefined;
196
250
  credentials?: boolean | undefined;
197
251
  secret?: string | undefined;
198
252
  secure_cookies?: boolean | undefined;
199
- } | undefined;
200
- db?: {
253
+ }>>;
254
+ db: z.ZodOptional<z.ZodObject<{
255
+ host: z.ZodOptional<z.ZodString>;
256
+ port: z.ZodOptional<z.ZodNumber>;
257
+ password: z.ZodOptional<z.ZodString>;
258
+ user: z.ZodOptional<z.ZodString>;
259
+ database: z.ZodOptional<z.ZodString>;
260
+ }, "strip", z.ZodTypeAny, {
261
+ host?: string | undefined;
262
+ port?: number | undefined;
263
+ password?: string | undefined;
264
+ user?: string | undefined;
265
+ database?: string | undefined;
266
+ }, {
201
267
  host?: string | undefined;
202
268
  port?: number | undefined;
203
269
  password?: string | undefined;
204
270
  user?: string | undefined;
205
271
  database?: string | undefined;
206
- } | undefined;
207
- log?: {
272
+ }>>;
273
+ debug: z.ZodOptional<z.ZodBoolean>;
274
+ log: z.ZodOptional<z.ZodObject<{
275
+ level: z.ZodOptional<z.ZodEnum<["error", "warn", "notice", "info", "debug"]>>;
276
+ console: z.ZodOptional<z.ZodBoolean>;
277
+ }, "strip", z.ZodTypeAny, {
208
278
  level?: "debug" | "info" | "warn" | "error" | "notice" | undefined;
209
279
  console?: boolean | undefined;
210
- } | undefined;
211
- web?: {
280
+ }, {
281
+ level?: "debug" | "info" | "warn" | "error" | "notice" | undefined;
282
+ console?: boolean | undefined;
283
+ }>>;
284
+ web: z.ZodOptional<z.ZodObject<{
285
+ prefix: z.ZodOptional<z.ZodString>;
286
+ }, "strip", z.ZodTypeAny, {
287
+ prefix?: string | undefined;
288
+ }, {
212
289
  prefix?: string | undefined;
213
- } | undefined;
214
- include?: string[] | undefined;
290
+ }>>;
215
291
  }, {
216
- debug?: boolean | undefined;
217
- auth?: {
292
+ include: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
293
+ plugins: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
294
+ }>, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<{
295
+ auth: z.ZodOptional<z.ZodObject<{
296
+ credentials: z.ZodOptional<z.ZodBoolean>;
297
+ debug: z.ZodOptional<z.ZodBoolean>;
298
+ secret: z.ZodOptional<z.ZodString>;
299
+ secure_cookies: z.ZodOptional<z.ZodBoolean>;
300
+ }, "strip", z.ZodTypeAny, {
301
+ debug?: boolean | undefined;
302
+ credentials?: boolean | undefined;
303
+ secret?: string | undefined;
304
+ secure_cookies?: boolean | undefined;
305
+ }, {
218
306
  debug?: boolean | undefined;
219
307
  credentials?: boolean | undefined;
220
308
  secret?: string | undefined;
221
309
  secure_cookies?: boolean | undefined;
222
- } | undefined;
223
- db?: {
310
+ }>>;
311
+ db: z.ZodOptional<z.ZodObject<{
312
+ host: z.ZodOptional<z.ZodString>;
313
+ port: z.ZodOptional<z.ZodNumber>;
314
+ password: z.ZodOptional<z.ZodString>;
315
+ user: z.ZodOptional<z.ZodString>;
316
+ database: z.ZodOptional<z.ZodString>;
317
+ }, "strip", z.ZodTypeAny, {
224
318
  host?: string | undefined;
225
319
  port?: number | undefined;
226
320
  password?: string | undefined;
227
321
  user?: string | undefined;
228
322
  database?: string | undefined;
229
- } | undefined;
230
- log?: {
323
+ }, {
324
+ host?: string | undefined;
325
+ port?: number | undefined;
326
+ password?: string | undefined;
327
+ user?: string | undefined;
328
+ database?: string | undefined;
329
+ }>>;
330
+ debug: z.ZodOptional<z.ZodBoolean>;
331
+ log: z.ZodOptional<z.ZodObject<{
332
+ level: z.ZodOptional<z.ZodEnum<["error", "warn", "notice", "info", "debug"]>>;
333
+ console: z.ZodOptional<z.ZodBoolean>;
334
+ }, "strip", z.ZodTypeAny, {
231
335
  level?: "debug" | "info" | "warn" | "error" | "notice" | undefined;
232
336
  console?: boolean | undefined;
233
- } | undefined;
234
- web?: {
337
+ }, {
338
+ level?: "debug" | "info" | "warn" | "error" | "notice" | undefined;
339
+ console?: boolean | undefined;
340
+ }>>;
341
+ web: z.ZodOptional<z.ZodObject<{
342
+ prefix: z.ZodOptional<z.ZodString>;
343
+ }, "strip", z.ZodTypeAny, {
235
344
  prefix?: string | undefined;
236
- } | undefined;
237
- include?: string[] | undefined;
238
- }>;
345
+ }, {
346
+ prefix?: string | undefined;
347
+ }>>;
348
+ }, {
349
+ include: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
350
+ plugins: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
351
+ }>, z.ZodTypeAny, "passthrough">>;
239
352
  export interface File extends PartialRecursive<Config>, z.infer<typeof File> {
240
353
  }
241
354
  /**
@@ -259,8 +372,8 @@ export interface LoadOptions {
259
372
  /**
260
373
  * Load the config from the provided path
261
374
  */
262
- export declare function loadConfig(path: string, options?: LoadOptions): void;
263
- export declare function loadDefaultConfigs(): void;
375
+ export declare function loadConfig(path: string, options?: LoadOptions): Promise<void>;
376
+ export declare function loadDefaultConfigs(): Promise<void>;
264
377
  /**
265
378
  * Update the current config and write the updated config to the appropriate file
266
379
  */
package/dist/config.js CHANGED
@@ -5,7 +5,9 @@ import { dirname, join } from 'node:path/posix';
5
5
  import { deepAssign } from 'utilium';
6
6
  import * as z from 'zod';
7
7
  import { findDir, logger, output } from './io.js';
8
- export const Schema = z.object({
8
+ import { loadPlugin } from './plugins.js';
9
+ export const Schema = z
10
+ .object({
9
11
  auth: z.object({
10
12
  credentials: z.boolean(),
11
13
  debug: z.boolean(),
@@ -27,9 +29,20 @@ export const Schema = z.object({
27
29
  web: z.object({
28
30
  prefix: z.string(),
29
31
  }),
30
- });
32
+ })
33
+ .passthrough();
31
34
  export const configFiles = new Map();
35
+ const configShortcuts = {
36
+ findPath: findConfigPath,
37
+ load: loadConfig,
38
+ loadDefaults: loadDefaultConfigs,
39
+ save: saveConfig,
40
+ saveTo: saveConfigTo,
41
+ set: setConfig,
42
+ files: configFiles,
43
+ };
32
44
  export const config = {
45
+ ...configShortcuts,
33
46
  auth: {
34
47
  credentials: false,
35
48
  debug: false,
@@ -51,19 +64,15 @@ export const config = {
51
64
  web: {
52
65
  prefix: '',
53
66
  },
54
- findPath: findConfigPath,
55
- load: loadConfig,
56
- loadDefaults: loadDefaultConfigs,
57
- save: saveConfig,
58
- saveTo: saveConfigTo,
59
- set: setConfig,
60
- files: configFiles,
61
67
  };
62
68
  export default config;
63
69
  // config from file
64
- export const File = Schema.deepPartial().extend({
70
+ export const File = Schema.deepPartial()
71
+ .extend({
65
72
  include: z.array(z.string()).optional(),
66
- });
73
+ plugins: z.array(z.string()).optional(),
74
+ })
75
+ .passthrough();
67
76
  /**
68
77
  * Update the current config
69
78
  */
@@ -76,7 +85,7 @@ export function setConfig(other) {
76
85
  /**
77
86
  * Load the config from the provided path
78
87
  */
79
- export function loadConfig(path, options = {}) {
88
+ export async function loadConfig(path, options = {}) {
80
89
  let json;
81
90
  try {
82
91
  json = JSON.parse(readFileSync(path, 'utf8'));
@@ -91,11 +100,13 @@ export function loadConfig(path, options = {}) {
91
100
  configFiles.set(path, file);
92
101
  setConfig(file);
93
102
  for (const include of file.include ?? [])
94
- loadConfig(join(dirname(path), include), { optional: true });
103
+ await loadConfig(join(dirname(path), include), { optional: true });
104
+ for (const plugin of file.plugins ?? [])
105
+ await loadPlugin(plugin);
95
106
  }
96
- export function loadDefaultConfigs() {
97
- loadConfig(findConfigPath(true), { optional: true });
98
- loadConfig(findConfigPath(false), { optional: true });
107
+ export async function loadDefaultConfigs() {
108
+ await loadConfig(findConfigPath(true), { optional: true });
109
+ await loadConfig(findConfigPath(false), { optional: true });
99
110
  }
100
111
  /**
101
112
  * Update the current config and write the updated config to the appropriate file
@@ -122,4 +133,4 @@ export function findConfigPath(global) {
122
133
  return join(findDir(global), 'config.json');
123
134
  }
124
135
  if (process.env.AXIUM_CONFIG)
125
- loadConfig(process.env.AXIUM_CONFIG);
136
+ await loadConfig(process.env.AXIUM_CONFIG);
@@ -49,8 +49,10 @@ export interface Schema {
49
49
  transports: string | null;
50
50
  };
51
51
  }
52
- export declare let database: Kysely<Schema> & AsyncDisposable;
53
- export declare function connect(): Kysely<Schema> & AsyncDisposable;
52
+ export interface Database extends Kysely<Schema>, AsyncDisposable {
53
+ }
54
+ export declare let database: Database;
55
+ export declare function connect(): Database;
54
56
  export interface Stats {
55
57
  users: number;
56
58
  accounts: number;
@@ -67,6 +69,10 @@ export interface InitOptions extends OpOptions {
67
69
  skip: boolean;
68
70
  }
69
71
  export declare function shouldRecreate(opt: InitOptions & WithOutput): boolean;
72
+ export interface PluginShortcuts {
73
+ done: () => void;
74
+ warnExists: (error: string | Error) => void;
75
+ }
70
76
  export declare function init(opt: InitOptions): Promise<void>;
71
77
  /**
72
78
  * Completely remove Axium from the database.
package/dist/database.js CHANGED
@@ -208,10 +208,10 @@ export async function init(opt) {
208
208
  opt.output('start', 'Creating index for Authenticator.credentialID');
209
209
  await db.schema.createIndex('Authenticator_credentialID_key').on('Authenticator').column('credentialID').execute().then(done).catch(warnExists);
210
210
  for (const plugin of plugins) {
211
- if (!plugin.db)
211
+ if (!plugin.db_init)
212
212
  continue;
213
213
  opt.output('plugin', plugin.name);
214
- await plugin.db.init(opt, db, { warnExists, done });
214
+ await plugin.db_init(opt, db, { warnExists, done });
215
215
  }
216
216
  }
217
217
  catch (e_1) {
@@ -231,10 +231,10 @@ export async function uninstall(opt) {
231
231
  _fixOutput(opt);
232
232
  const db = connect();
233
233
  for (const plugin of plugins) {
234
- if (!plugin.db)
234
+ if (!plugin.db_remove)
235
235
  continue;
236
236
  opt.output('plugin', plugin.name);
237
- await plugin.db.remove(opt, db);
237
+ await plugin.db_remove(opt, db);
238
238
  }
239
239
  await db.destroy();
240
240
  const _sql = (command, message) => run(opt, message, `sudo -u postgres psql -c "${command}"`);
@@ -249,10 +249,10 @@ export async function wipe(opt) {
249
249
  _fixOutput(opt);
250
250
  const db = connect();
251
251
  for (const plugin of plugins) {
252
- if (!plugin.db)
252
+ if (!plugin.db_wipe)
253
253
  continue;
254
254
  opt.output('plugin', plugin.name);
255
- await plugin.db.wipe(opt, db);
255
+ await plugin.db_wipe(opt, db);
256
256
  }
257
257
  for (const table of ['User', 'Account', 'Session', 'VerificationToken', 'Authenticator']) {
258
258
  opt.output('start', `Removing data from ${table}`);
package/dist/plugins.d.ts CHANGED
@@ -5,47 +5,33 @@ export declare const Plugin: z.ZodObject<{
5
5
  version: z.ZodString;
6
6
  description: z.ZodOptional<z.ZodString>;
7
7
  statusText: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>>;
8
- db: z.ZodOptional<z.ZodObject<{
9
- init: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
10
- remove: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
11
- wipe: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
12
- }, "strip", z.ZodTypeAny, {
13
- init: (...args: unknown[]) => unknown;
14
- remove: (...args: unknown[]) => unknown;
15
- wipe: (...args: unknown[]) => unknown;
16
- }, {
17
- init: (...args: unknown[]) => unknown;
18
- remove: (...args: unknown[]) => unknown;
19
- wipe: (...args: unknown[]) => unknown;
20
- }>>;
8
+ db_init: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
9
+ db_remove: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
10
+ db_wipe: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
21
11
  }, "strip", z.ZodTypeAny, {
22
12
  name: string;
23
13
  id: string;
24
14
  version: string;
25
- db?: {
26
- init: (...args: unknown[]) => unknown;
27
- remove: (...args: unknown[]) => unknown;
28
- wipe: (...args: unknown[]) => unknown;
29
- } | undefined;
30
15
  description?: string | undefined;
31
16
  statusText?: ((...args: unknown[]) => string | Promise<string>) | undefined;
17
+ db_init?: ((...args: unknown[]) => unknown) | undefined;
18
+ db_remove?: ((...args: unknown[]) => unknown) | undefined;
19
+ db_wipe?: ((...args: unknown[]) => unknown) | undefined;
32
20
  }, {
33
21
  name: string;
34
22
  id: string;
35
23
  version: string;
36
- db?: {
37
- init: (...args: unknown[]) => unknown;
38
- remove: (...args: unknown[]) => unknown;
39
- wipe: (...args: unknown[]) => unknown;
40
- } | undefined;
41
24
  description?: string | undefined;
42
25
  statusText?: ((...args: unknown[]) => string | Promise<string>) | undefined;
26
+ db_init?: ((...args: unknown[]) => unknown) | undefined;
27
+ db_remove?: ((...args: unknown[]) => unknown) | undefined;
28
+ db_wipe?: ((...args: unknown[]) => unknown) | undefined;
43
29
  }>;
44
30
  export interface Plugin extends z.infer<typeof Plugin> {
45
31
  }
46
32
  export declare const plugins: Set<Plugin>;
47
33
  export declare function resolvePlugin(search: string): Plugin | undefined;
48
34
  export declare function pluginText(plugin: Plugin): string;
49
- export declare function loadPlugin(path: string): Promise<void>;
35
+ export declare function loadPlugin(specifier: string): Promise<void>;
50
36
  export declare function loadPlugins(dir: string): Promise<void>;
51
37
  export declare function loadDefaultPlugins(): Promise<void>;
package/dist/plugins.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import * as fs from 'node:fs';
2
- import { join, resolve } from 'node:path/posix';
2
+ import { join } from 'node:path/posix';
3
3
  import { styleText } from 'node:util';
4
4
  import * as z from 'zod';
5
- import { findDir, output } from './io.js';
6
5
  import { fromZodError } from 'zod-validation-error';
6
+ import { findDir, output } from './io.js';
7
+ import { fileURLToPath } from 'node:url';
7
8
  export const Plugin = z.object({
8
9
  id: z.string(),
9
10
  name: z.string(),
@@ -14,13 +15,9 @@ export const Plugin = z.object({
14
15
  .args()
15
16
  .returns(z.union([z.string(), z.promise(z.string())]))
16
17
  .optional(),
17
- db: z
18
- .object({
19
- init: z.function(),
20
- remove: z.function(),
21
- wipe: z.function(),
22
- })
23
- .optional(),
18
+ db_init: z.function().optional(),
19
+ db_remove: z.function().optional(),
20
+ db_wipe: z.function().optional(),
24
21
  });
25
22
  export const plugins = new Set();
26
23
  export function resolvePlugin(search) {
@@ -36,23 +33,26 @@ export function pluginText(plugin) {
36
33
  `Version: ${plugin.version}`,
37
34
  `Description: ${plugin.description ?? styleText('dim', '(none)')}`,
38
35
  `Status text integration: ${plugin.statusText ? styleText('whiteBright', 'yes') : styleText('yellow', 'no')}`,
39
- `Database integration: ${plugin.db ? 'yes' : 'no'}`,
36
+ `Database integration: ${[plugin.db_init, plugin.db_remove, plugin.db_wipe]
37
+ .filter(Boolean)
38
+ .map(fn => fn?.name.slice(3))
39
+ .join(', ') || styleText('dim', '(none)')}`,
40
40
  ].join('\n');
41
41
  }
42
- export async function loadPlugin(path) {
43
- path = resolve(path);
44
- const stats = fs.statSync(path);
45
- if (stats.isDirectory() || !['.js', '.mjs'].some(ext => path.endsWith(ext)))
42
+ export async function loadPlugin(specifier) {
43
+ specifier = fileURLToPath(import.meta.resolve(specifier));
44
+ const stats = fs.statSync(specifier);
45
+ if (stats.isDirectory() || !['.js', '.mjs'].some(ext => specifier.endsWith(ext)))
46
46
  return;
47
47
  try {
48
- const plugin = await Plugin.parseAsync(await import(path)).catch(e => {
48
+ const plugin = await Plugin.parseAsync(await import(specifier)).catch(e => {
49
49
  throw fromZodError(e);
50
50
  });
51
51
  plugins.add(plugin);
52
52
  output.debug(`Loaded plugin: "${plugin.name}" (${plugin.id}) ${plugin.version}`);
53
53
  }
54
54
  catch (e) {
55
- output.debug(`Failed to load plugin from ${path}: ${e}`);
55
+ output.debug(`Failed to load plugin from ${specifier}: ${e}`);
56
56
  }
57
57
  }
58
58
  export async function loadPlugins(dir) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/server",
3
- "version": "0.6.4",
3
+ "version": "0.7.1",
4
4
  "author": "James Prevett <axium@jamespre.dev> (https://jamespre.dev)",
5
5
  "funding": {
6
6
  "type": "individual",
package/web/auth.ts CHANGED
@@ -7,6 +7,6 @@ import { findDir, logger } from '../dist/io.js';
7
7
  import { allLogLevels } from 'logzen';
8
8
 
9
9
  logger.attach(createWriteStream(join(findDir(false), 'server.log')), { output: allLogLevels });
10
- config.loadDefaults();
10
+ await config.loadDefaults();
11
11
 
12
12
  export const { handle, signIn, signOut } = SvelteKitAuth(getConfig());
@@ -0,0 +1,48 @@
1
+ <script lang="ts">
2
+ import type { User } from '@axium/core/schemas';
3
+ import { getUserImage } from '@axium/core';
4
+
5
+ const {
6
+ user,
7
+ compact = false,
8
+ self = false,
9
+ href = `/users/${user.id}`,
10
+ you = false,
11
+ }: {
12
+ user: { [K in keyof User]?: User[K] | null };
13
+ /** If true, don't show the picture */
14
+ compact?: boolean;
15
+ /** Whether the user is viewing their own profile */
16
+ self?: boolean;
17
+ /** The URL to link to */
18
+ href?: string;
19
+ /** Whether to display a "You" label if `self` */
20
+ you?: boolean;
21
+ } = $props();
22
+ </script>
23
+
24
+ <a class={['User', self && 'self']} {href}>
25
+ {#if !compact}
26
+ <img src={getUserImage(user as Required<User>)} alt={user.name} />
27
+ {/if}
28
+ {user.name}
29
+ {#if self && you}
30
+ <span class="subtle">(You)</span>
31
+ {/if}
32
+ </a>
33
+
34
+ <style>
35
+ .User {
36
+ cursor: pointer;
37
+ width: max-content;
38
+ height: max-content;
39
+ }
40
+
41
+ img {
42
+ width: 2em;
43
+ height: 2em;
44
+ border-radius: 50%;
45
+ vertical-align: middle;
46
+ margin-right: 0.5em;
47
+ }
48
+ </style>
package/web/lib/index.ts CHANGED
@@ -4,3 +4,4 @@ export { default as FormDialog } from './FormDialog.svelte';
4
4
  export { default as Icon } from './Icon.svelte';
5
5
  export { default as SignUp } from './SignUp.svelte';
6
6
  export { default as Toast } from './Toast.svelte';
7
+ export { default as UserCard } from './UserCard.svelte';