@axium/core 0.12.1 → 0.14.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/access.d.ts +1 -0
- package/dist/api.d.ts +6 -5
- package/dist/node/plugins.d.ts +1 -1
- package/dist/node/plugins.js +8 -23
- package/dist/packages.d.ts +12 -0
- package/dist/packages.js +51 -0
- package/dist/plugins.d.ts +3 -1
- package/dist/plugins.js +3 -1
- package/package.json +4 -2
package/dist/access.d.ts
CHANGED
package/dist/api.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { PublicKeyCredentialCreationOptionsJSON, PublicKeyCredentialRequestOptionsJSON } from '@simplewebauthn/types';
|
|
2
|
+
import type { Omit } from 'utilium';
|
|
2
3
|
import type z from 'zod';
|
|
3
4
|
import type { AccessControl, AccessMap } from './access.js';
|
|
4
5
|
import type { App } from './apps.js';
|
|
5
6
|
import type { AuditEvent, AuditFilter, Severity } from './audit.js';
|
|
6
7
|
import type { NewSessionResponse, Session, Verification } from './auth.js';
|
|
8
|
+
import type { PackageVersionInfo } from './packages.js';
|
|
7
9
|
import type { Passkey, PasskeyAuthenticationResponse, PasskeyChangeable, PasskeyRegistration } from './passkeys.js';
|
|
10
|
+
import type { PluginInternal } from './plugins.js';
|
|
8
11
|
import type { RequestMethod } from './requests.js';
|
|
9
12
|
import type { LogoutSessions, User, UserAuthOptions, UserChangeable, UserInternal, UserPublic, UserRegistration } from './user.js';
|
|
10
|
-
import type { PluginInternal } from './plugins.js';
|
|
11
13
|
export interface AdminSummary {
|
|
12
14
|
users: number;
|
|
13
15
|
passkeys: number;
|
|
@@ -15,7 +17,7 @@ export interface AdminSummary {
|
|
|
15
17
|
auditEvents: Record<keyof typeof Severity, number>;
|
|
16
18
|
configFiles: number;
|
|
17
19
|
plugins: number;
|
|
18
|
-
|
|
20
|
+
versions: Record<'core' | 'server' | 'client', PackageVersionInfo>;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Types for all API endpoints
|
|
@@ -24,12 +26,11 @@ export interface AdminSummary {
|
|
|
24
26
|
export interface $API {
|
|
25
27
|
metadata: {
|
|
26
28
|
GET: {
|
|
27
|
-
|
|
29
|
+
versions: PackageVersionInfo[];
|
|
28
30
|
routes: Record<string, {
|
|
29
31
|
params: Record<string, string | null>;
|
|
30
32
|
methods: string[];
|
|
31
33
|
}>;
|
|
32
|
-
plugins: Record<string, string>;
|
|
33
34
|
};
|
|
34
35
|
};
|
|
35
36
|
apps: {
|
|
@@ -115,7 +116,7 @@ export interface $API {
|
|
|
115
116
|
};
|
|
116
117
|
};
|
|
117
118
|
'admin/plugins': {
|
|
118
|
-
GET: PluginInternal[];
|
|
119
|
+
GET: (Omit<PluginInternal, '_hooks' | '_client'> & PackageVersionInfo)[];
|
|
119
120
|
};
|
|
120
121
|
'admin/audit/events': {
|
|
121
122
|
OPTIONS: {
|
package/dist/node/plugins.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type PluginInternal } from '@axium/core/plugins';
|
|
2
2
|
export declare function pluginText(plugin: PluginInternal): Generator<string>;
|
|
3
|
-
export declare function loadPlugin<const T extends 'client' | 'server'>(mode: T, specifier: string,
|
|
3
|
+
export declare function loadPlugin<const T extends 'client' | 'server'>(mode: T, specifier: string, loadedBy: string, safeMode?: boolean): Promise<PluginInternal | void>;
|
package/dist/node/plugins.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as io from '@axium/core/node/io';
|
|
2
2
|
import { Plugin, plugins } from '@axium/core/plugins';
|
|
3
3
|
import * as fs from 'node:fs';
|
|
4
|
-
import { dirname,
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { dirname, resolve } from 'node:path/posix';
|
|
6
5
|
import { styleText } from 'node:util';
|
|
7
6
|
import * as z from 'zod';
|
|
8
7
|
import { apps } from '../apps.js';
|
|
8
|
+
import { locatePackage } from '../packages.js';
|
|
9
9
|
export function* pluginText(plugin) {
|
|
10
10
|
yield styleText('whiteBright', plugin.name);
|
|
11
11
|
yield `Version: ${plugin.version}`;
|
|
@@ -19,25 +19,10 @@ export function* pluginText(plugin) {
|
|
|
19
19
|
yield `Hooks: ${plugin._client ? styleText(['dim', 'bold'], `(${Object.keys(plugin._client).length}) `) + Object.keys(plugin._client).join(', ') : plugin.client.hooks || styleText('dim', '(none)')}`;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
if (specifier[0] == '/' || ['.', '..'].includes(specifier.split('/')[0])) {
|
|
24
|
-
const path = resolve(dirname(_loadedBy), specifier);
|
|
25
|
-
const stats = fs.statSync(path);
|
|
26
|
-
if (stats.isFile())
|
|
27
|
-
return path;
|
|
28
|
-
if (!stats.isDirectory())
|
|
29
|
-
throw new Error('Can not resolve plugin path: ' + path);
|
|
30
|
-
return join(path, 'package.json');
|
|
31
|
-
}
|
|
32
|
-
let packageDir = dirname(fileURLToPath(import.meta.resolve(specifier)));
|
|
33
|
-
for (; !fs.existsSync(join(packageDir, 'package.json')); packageDir = dirname(packageDir))
|
|
34
|
-
;
|
|
35
|
-
return join(packageDir, 'package.json');
|
|
36
|
-
}
|
|
37
|
-
export async function loadPlugin(mode, specifier, _loadedBy, safeMode = false) {
|
|
22
|
+
export async function loadPlugin(mode, specifier, loadedBy, safeMode = false) {
|
|
38
23
|
try {
|
|
39
|
-
const path =
|
|
40
|
-
io.debug(`Loading plugin at ${path} (from ${
|
|
24
|
+
const path = locatePackage(specifier, loadedBy);
|
|
25
|
+
io.debug(`Loading plugin at ${path} (from ${loadedBy})`);
|
|
41
26
|
let imported;
|
|
42
27
|
try {
|
|
43
28
|
imported = JSON.parse(fs.readFileSync(path, 'utf8'));
|
|
@@ -49,12 +34,12 @@ export async function loadPlugin(mode, specifier, _loadedBy, safeMode = false) {
|
|
|
49
34
|
Object.assign(imported, imported.axium); // support axium field in package.json
|
|
50
35
|
const plugin = Object.assign(await Plugin.parseAsync(imported).catch(e => {
|
|
51
36
|
throw e instanceof z.core.$ZodError ? z.prettifyError(e) : e;
|
|
52
|
-
}), { path, specifier,
|
|
37
|
+
}), { path, specifier, loadedBy, dirname: dirname(path), cli: imported[mode]?.cli, isServer: mode === 'server' });
|
|
53
38
|
if (!plugin[mode])
|
|
54
39
|
throw `Plugin does not support running ${mode}-side`;
|
|
55
40
|
if (!safeMode) {
|
|
56
|
-
if (plugin
|
|
57
|
-
await import(resolve(plugin.dirname, plugin
|
|
41
|
+
if (plugin.cli)
|
|
42
|
+
await import(resolve(plugin.dirname, plugin.cli));
|
|
58
43
|
if (mode == 'client') {
|
|
59
44
|
if (plugin.client.hooks)
|
|
60
45
|
Object.assign(plugin, { _client: await import(resolve(plugin.dirname, plugin.client.hooks)) });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function locatePackage(specifier: string, loadedBy: string): string;
|
|
2
|
+
export interface PackageVersionInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
latest: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function setPackageCacheTTL(seconds: number): void;
|
|
8
|
+
/**
|
|
9
|
+
* @param name Package name
|
|
10
|
+
* @param version The current/installed version
|
|
11
|
+
*/
|
|
12
|
+
export declare function getVersionInfo(specifier: string, from?: string): Promise<PackageVersionInfo>;
|
package/dist/packages.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path/posix';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { lt as ltVersion } from 'semver';
|
|
5
|
+
import { warn } from './io.js';
|
|
6
|
+
function isRelative(specifier) {
|
|
7
|
+
return specifier[0] == '/' || ['.', '..'].includes(specifier.split('/')[0]);
|
|
8
|
+
}
|
|
9
|
+
export function locatePackage(specifier, loadedBy) {
|
|
10
|
+
if (isRelative(specifier)) {
|
|
11
|
+
const path = resolve(dirname(loadedBy), specifier);
|
|
12
|
+
const stats = fs.statSync(path);
|
|
13
|
+
if (stats.isFile())
|
|
14
|
+
return path;
|
|
15
|
+
if (!stats.isDirectory())
|
|
16
|
+
throw new Error('Can not resolve package path: ' + path);
|
|
17
|
+
return join(path, 'package.json');
|
|
18
|
+
}
|
|
19
|
+
let packageDir = dirname(fileURLToPath(import.meta.resolve(specifier)));
|
|
20
|
+
for (; !fs.existsSync(join(packageDir, 'package.json')); packageDir = dirname(packageDir))
|
|
21
|
+
;
|
|
22
|
+
return join(packageDir, 'package.json');
|
|
23
|
+
}
|
|
24
|
+
let cacheTTL = 1000 * 60 * 60;
|
|
25
|
+
export function setPackageCacheTTL(seconds) {
|
|
26
|
+
cacheTTL = seconds * 1000;
|
|
27
|
+
}
|
|
28
|
+
const cache = new Map();
|
|
29
|
+
/**
|
|
30
|
+
* @param name Package name
|
|
31
|
+
* @param version The current/installed version
|
|
32
|
+
*/
|
|
33
|
+
export async function getVersionInfo(specifier, from = import.meta.filename) {
|
|
34
|
+
const path = locatePackage(specifier, from);
|
|
35
|
+
const { version, name } = JSON.parse(fs.readFileSync(path, 'utf8'));
|
|
36
|
+
const info = { name, version, latest: null };
|
|
37
|
+
if (isRelative(specifier))
|
|
38
|
+
return info;
|
|
39
|
+
const cached = cache.get(specifier);
|
|
40
|
+
const useCache = cached && Date.now() - cached.timestamp < cacheTTL;
|
|
41
|
+
try {
|
|
42
|
+
const pkg = useCache ? cached.data : await fetch('https://registry.npmjs.org/' + specifier).then(res => res.json());
|
|
43
|
+
if (!useCache)
|
|
44
|
+
cache.set(specifier, { timestamp: Date.now(), data: pkg });
|
|
45
|
+
info.latest = pkg['dist-tags']?.latest || Object.keys(pkg.versions).sort((a, b) => (ltVersion(a, b) ? 1 : -1))[0];
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
warn(`Failed to fetch version info for package ${name}: ${e instanceof Error ? e.message : String(e)}`);
|
|
49
|
+
}
|
|
50
|
+
return info;
|
|
51
|
+
}
|
package/dist/plugins.d.ts
CHANGED
|
@@ -22,13 +22,15 @@ export declare const Plugin: z.ZodObject<{
|
|
|
22
22
|
routes: z.ZodOptional<z.ZodString>;
|
|
23
23
|
db: z.ZodOptional<z.ZodString>;
|
|
24
24
|
}, z.core.$strip>>;
|
|
25
|
+
/** If set Axium can check the npm registry for updates */
|
|
26
|
+
update_checks: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
25
27
|
}, z.core.$loose>;
|
|
26
28
|
export type Plugin = z.infer<typeof Plugin>;
|
|
27
29
|
export interface PluginInfo {
|
|
28
30
|
path: string;
|
|
29
31
|
dirname: string;
|
|
30
32
|
specifier: string;
|
|
31
|
-
|
|
33
|
+
loadedBy: string;
|
|
32
34
|
cli?: string;
|
|
33
35
|
/** @internal */
|
|
34
36
|
_hooks?: ServerHooks;
|
package/dist/plugins.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as z from 'zod';
|
|
2
|
-
import { zAsyncFunction } from './schemas.js';
|
|
3
2
|
import { App } from './apps.js';
|
|
4
3
|
import { debug, warn } from './io.js';
|
|
4
|
+
import { zAsyncFunction } from './schemas.js';
|
|
5
5
|
const PluginCommon = z.object({
|
|
6
6
|
/** CLI mixin path */
|
|
7
7
|
cli: z.string().optional(),
|
|
@@ -22,6 +22,8 @@ export const Plugin = z.looseObject({
|
|
|
22
22
|
routes: z.string().optional(),
|
|
23
23
|
db: z.string().optional(),
|
|
24
24
|
}).optional(),
|
|
25
|
+
/** If set Axium can check the npm registry for updates */
|
|
26
|
+
update_checks: z.boolean().nullish(),
|
|
25
27
|
});
|
|
26
28
|
export const plugins = new Map();
|
|
27
29
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axium/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"author": "James Prevett <axium@jamespre.dev>",
|
|
5
5
|
"funding": {
|
|
6
6
|
"type": "individual",
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@simplewebauthn/types": "^12.0.0",
|
|
38
|
-
"
|
|
38
|
+
"@types/semver": "^7.7.1",
|
|
39
|
+
"mime": "^4.0.7",
|
|
40
|
+
"semver": "^7.7.3"
|
|
39
41
|
}
|
|
40
42
|
}
|