zumito-framework 1.23.3 → 1.25.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/ZumitoFramework.js +5 -2
- package/dist/definitions/config/moduleHelpers.d.ts +32 -0
- package/dist/definitions/config/moduleHelpers.js +71 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/services/ServiceContainer.d.ts +6 -0
- package/dist/services/ServiceContainer.js +12 -0
- package/dist/services/managers/CommandManager.js +2 -0
- package/dist/utils/Inspector.d.ts +61 -0
- package/dist/utils/Inspector.js +194 -0
- package/package.json +1 -1
package/dist/ZumitoFramework.js
CHANGED
|
@@ -25,6 +25,7 @@ import { ErrorType } from './definitions/ErrorType.js';
|
|
|
25
25
|
import { MongoService } from './services/MongoService.js';
|
|
26
26
|
import { registerDefaultExecutionRules } from './modules/core/baseModule/defaultRules.js';
|
|
27
27
|
import { DatabaseManager } from 'zumito-db';
|
|
28
|
+
import { registerFrameworkInspector, startInspectorFileWriter } from './utils/Inspector.js';
|
|
28
29
|
// import better-logging
|
|
29
30
|
betterLogging(console);
|
|
30
31
|
/**
|
|
@@ -148,6 +149,7 @@ export class ZumitoFramework {
|
|
|
148
149
|
ServiceContainer.addService(CommandManager, [], true, this.commands);
|
|
149
150
|
ServiceContainer.addService(EventManager, [], true, this.eventManager);
|
|
150
151
|
ServiceContainer.addService(SlashCommandRefresher, [], true, new SlashCommandRefresher(this));
|
|
152
|
+
registerFrameworkInspector(this);
|
|
151
153
|
if (settings.logLevel) {
|
|
152
154
|
console.logLevel = settings.logLevel;
|
|
153
155
|
}
|
|
@@ -155,6 +157,7 @@ export class ZumitoFramework {
|
|
|
155
157
|
.then(() => {
|
|
156
158
|
if (callback)
|
|
157
159
|
callback(this);
|
|
160
|
+
startInspectorFileWriter(this);
|
|
158
161
|
})
|
|
159
162
|
.catch((err) => {
|
|
160
163
|
console.error(err, err.message, err.stack, err.name);
|
|
@@ -188,7 +191,7 @@ export class ZumitoFramework {
|
|
|
188
191
|
}
|
|
189
192
|
}
|
|
190
193
|
async initializeDatabase() {
|
|
191
|
-
const mongoUri = this.settings?.mongoQueryString || process.env.
|
|
194
|
+
const mongoUri = this.settings?.mongoQueryString || process.env.DATABASE_URI;
|
|
192
195
|
const dbSettings = this.settings.database;
|
|
193
196
|
let config;
|
|
194
197
|
if (dbSettings?.default) {
|
|
@@ -208,7 +211,7 @@ export class ZumitoFramework {
|
|
|
208
211
|
else {
|
|
209
212
|
console.error('[🗄️🔴] No database configured.');
|
|
210
213
|
console.error(' Set database.default in zumito.config.ts (memory, tingo, mongo, sqlite)');
|
|
211
|
-
console.error(' or set
|
|
214
|
+
console.error(' or set DATABASE_URI / mongoQueryString for MongoDB.');
|
|
212
215
|
process.exit(1);
|
|
213
216
|
}
|
|
214
217
|
if (this.settings.models) {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ZumitoFramework } from '../../ZumitoFramework.js';
|
|
2
|
+
import type { ModuleEntry } from '../settings/FrameworkSettings.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a type-safe factory function that returns a `ModuleEntry`.
|
|
5
|
+
* Reads the module name from the nearest `package.json` by walking up
|
|
6
|
+
* from the caller's location.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // admin/index.ts
|
|
11
|
+
* export const adminModule = createModuleEntry<AdminConfig>(import.meta.url);
|
|
12
|
+
*
|
|
13
|
+
* // Consumer's zumito.config.ts
|
|
14
|
+
* adminModule({ colors: { primary: '#ff0000' } })
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function createModuleEntry<T = Record<string, any>>(metaUrl: string): (config?: T) => ModuleEntry;
|
|
18
|
+
/**
|
|
19
|
+
* Retrieves the module-specific configuration from the framework settings
|
|
20
|
+
* by matching the module's package name against the `modules` array.
|
|
21
|
+
*
|
|
22
|
+
* Modules that are registered as plain strings in the `modules` array
|
|
23
|
+
* (without config) will return an empty object.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { getModuleConfig } from 'zumito-framework';
|
|
28
|
+
*
|
|
29
|
+
* const config = getModuleConfig<MyConfig>(framework, import.meta.url);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function getModuleConfig<T = Record<string, any>>(framework: ZumitoFramework | undefined, metaUrl: string): T;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { dirname, resolve } from 'path';
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
|
+
function findPackageJson(startPath) {
|
|
6
|
+
let dir = startPath;
|
|
7
|
+
for (let i = 0; i < 10; i++) {
|
|
8
|
+
const candidate = resolve(dir, 'package.json');
|
|
9
|
+
if (existsSync(candidate))
|
|
10
|
+
return candidate;
|
|
11
|
+
const parent = resolve(dir, '..');
|
|
12
|
+
if (parent === dir)
|
|
13
|
+
break;
|
|
14
|
+
dir = parent;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
function readModuleName(metaUrl) {
|
|
19
|
+
const filePath = fileURLToPath(metaUrl);
|
|
20
|
+
const callerDir = dirname(filePath);
|
|
21
|
+
const pkgPath = findPackageJson(callerDir);
|
|
22
|
+
if (!pkgPath)
|
|
23
|
+
return null;
|
|
24
|
+
const require = createRequire(pkgPath);
|
|
25
|
+
return require(pkgPath)?.name ?? null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates a type-safe factory function that returns a `ModuleEntry`.
|
|
29
|
+
* Reads the module name from the nearest `package.json` by walking up
|
|
30
|
+
* from the caller's location.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* // admin/index.ts
|
|
35
|
+
* export const adminModule = createModuleEntry<AdminConfig>(import.meta.url);
|
|
36
|
+
*
|
|
37
|
+
* // Consumer's zumito.config.ts
|
|
38
|
+
* adminModule({ colors: { primary: '#ff0000' } })
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function createModuleEntry(metaUrl) {
|
|
42
|
+
const name = readModuleName(metaUrl);
|
|
43
|
+
if (!name) {
|
|
44
|
+
throw new Error(`createModuleEntry: could not read 'name' from package.json near ${metaUrl}`);
|
|
45
|
+
}
|
|
46
|
+
return (config) => ({ name, config });
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Retrieves the module-specific configuration from the framework settings
|
|
50
|
+
* by matching the module's package name against the `modules` array.
|
|
51
|
+
*
|
|
52
|
+
* Modules that are registered as plain strings in the `modules` array
|
|
53
|
+
* (without config) will return an empty object.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { getModuleConfig } from 'zumito-framework';
|
|
58
|
+
*
|
|
59
|
+
* const config = getModuleConfig<MyConfig>(framework, import.meta.url);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export function getModuleConfig(framework, metaUrl) {
|
|
63
|
+
if (!framework)
|
|
64
|
+
return {};
|
|
65
|
+
const name = readModuleName(metaUrl);
|
|
66
|
+
if (!name)
|
|
67
|
+
return {};
|
|
68
|
+
const modules = framework.settings?.modules ?? [];
|
|
69
|
+
const entry = modules.find((m) => typeof m !== 'string' && m.name === name);
|
|
70
|
+
return (entry?.config ?? {});
|
|
71
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export { CommandBinds } from './definitions/commands/CommandBinds.js';
|
|
|
42
42
|
export { Injectable } from './definitions/decorators/Injectable.decorator.js';
|
|
43
43
|
export { LauncherConfig } from './definitions/config/LauncherConfig.js';
|
|
44
44
|
export { defineConfig } from './definitions/config/defineConfig.js';
|
|
45
|
+
export { createModuleEntry, getModuleConfig } from './definitions/config/moduleHelpers.js';
|
|
45
46
|
export type { ModuleEntry } from './definitions/settings/FrameworkSettings.js';
|
|
46
47
|
export { ModuleParameters } from './definitions/parameters/ModuleParameters.js';
|
|
47
48
|
export { ZumitoFramework, FrameworkSettings, Command, Module, ModuleDeclaration, ModuleRequeriments, CommandParameters, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse, SelectMenuParameters, CommandType, CommandArgDefinition, CommandChoiceDefinition, ButtonPressed, ButtonPressedParams, TextFormatter, EmojiFallback, DatabaseConfigLoader, PresenceDataRule, RuledPresenceData, StatusManagerOptions, discord, EventParameters, ServiceContainer, GuildDataGetter, SlashCommandRefresher, CommandParser, ErrorHandler, ErrorType, Route, RouteMethod, InteractionHandler, CommandManager, InviteUrlGenerator, PrefixResolver, CommandExecutionChecker, DatabaseManager, };
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ import { DatabaseManager } from 'zumito-db';
|
|
|
29
29
|
export { Collection, Field, HasMany, BelongsTo, HasOne, Migration, Repository, QueryBuilder } from 'zumito-db';
|
|
30
30
|
export { Injectable } from './definitions/decorators/Injectable.decorator.js';
|
|
31
31
|
export { defineConfig } from './definitions/config/defineConfig.js';
|
|
32
|
+
export { createModuleEntry, getModuleConfig } from './definitions/config/moduleHelpers.js';
|
|
32
33
|
ServiceContainer.addService(TextFormatter, []);
|
|
33
34
|
ServiceContainer.addService(EmojiFallback, [discord.Client.name, TranslationManager.name]);
|
|
34
35
|
ServiceContainer.addService(GuildDataGetter, [ZumitoFramework.name]);
|
|
@@ -5,6 +5,12 @@ declare class ServiceContainerManager {
|
|
|
5
5
|
getServiceByName<T>(serviceName: string): T;
|
|
6
6
|
addInstance(serviceClass: any, instance: any): void;
|
|
7
7
|
hasService(serviceClass: any): boolean;
|
|
8
|
+
getAllServiceEntries(): Array<{
|
|
9
|
+
name: string;
|
|
10
|
+
dependencies: string[];
|
|
11
|
+
singleton: boolean;
|
|
12
|
+
hasInstance: boolean;
|
|
13
|
+
}>;
|
|
8
14
|
}
|
|
9
15
|
export declare const ServiceContainer: ServiceContainerManager;
|
|
10
16
|
export {};
|
|
@@ -62,6 +62,18 @@ class ServiceContainerManager {
|
|
|
62
62
|
const serviceName = typeof serviceClass == 'string' ? serviceClass : serviceClass.name;
|
|
63
63
|
return this.services.has(serviceName);
|
|
64
64
|
}
|
|
65
|
+
getAllServiceEntries() {
|
|
66
|
+
const entries = [];
|
|
67
|
+
for (const [name, svc] of this.services) {
|
|
68
|
+
entries.push({
|
|
69
|
+
name,
|
|
70
|
+
dependencies: svc.dependencies,
|
|
71
|
+
singleton: svc.singleton,
|
|
72
|
+
hasInstance: svc.instance !== undefined,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return entries;
|
|
76
|
+
}
|
|
65
77
|
}
|
|
66
78
|
if (!global.ServiceContainer)
|
|
67
79
|
global.ServiceContainer = new ServiceContainerManager();
|
|
@@ -42,6 +42,8 @@ export class CommandManager {
|
|
|
42
42
|
if (!filePath.endsWith('.js') && !filePath.endsWith('.ts')) {
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
|
+
if (filePath.endsWith('.d.ts'))
|
|
46
|
+
return;
|
|
45
47
|
const counter = (this.importCounters.get(filePath) || 0) + 1;
|
|
46
48
|
this.importCounters.set(filePath, counter);
|
|
47
49
|
const baseName = path.basename(filePath).split('.').slice(0, -1).join('.');
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ZumitoFramework } from '../ZumitoFramework.js';
|
|
2
|
+
export interface FrameworkSnapshot {
|
|
3
|
+
version: string;
|
|
4
|
+
uptime: number;
|
|
5
|
+
discord: {
|
|
6
|
+
status: 'connected' | 'disconnected';
|
|
7
|
+
user: {
|
|
8
|
+
id: string;
|
|
9
|
+
tag: string;
|
|
10
|
+
} | null;
|
|
11
|
+
guildCount: number;
|
|
12
|
+
};
|
|
13
|
+
database: {
|
|
14
|
+
connected: boolean;
|
|
15
|
+
driver: string;
|
|
16
|
+
};
|
|
17
|
+
commands: {
|
|
18
|
+
total: number;
|
|
19
|
+
items: Array<{
|
|
20
|
+
name: string;
|
|
21
|
+
type: string;
|
|
22
|
+
description: string;
|
|
23
|
+
aliases: string[];
|
|
24
|
+
categories: string[];
|
|
25
|
+
hidden: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
28
|
+
modules: {
|
|
29
|
+
total: number;
|
|
30
|
+
items: Array<{
|
|
31
|
+
name: string;
|
|
32
|
+
displayName: string;
|
|
33
|
+
status: string;
|
|
34
|
+
dependencies: string[];
|
|
35
|
+
commandCount: number;
|
|
36
|
+
eventCount: number;
|
|
37
|
+
}>;
|
|
38
|
+
};
|
|
39
|
+
services: {
|
|
40
|
+
total: number;
|
|
41
|
+
items: Array<{
|
|
42
|
+
name: string;
|
|
43
|
+
singleton: boolean;
|
|
44
|
+
hasInstance: boolean;
|
|
45
|
+
dependencies: string[];
|
|
46
|
+
}>;
|
|
47
|
+
};
|
|
48
|
+
events: {
|
|
49
|
+
total: number;
|
|
50
|
+
items: Array<{
|
|
51
|
+
name: string;
|
|
52
|
+
source: string;
|
|
53
|
+
}>;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Write the inspector snapshot to .zumito/inspector-state.json in the current
|
|
58
|
+
* working directory. Returns a cleanup function that stops the write interval.
|
|
59
|
+
*/
|
|
60
|
+
export declare function startInspectorFileWriter(framework: ZumitoFramework): () => void;
|
|
61
|
+
export declare function registerFrameworkInspector(framework: ZumitoFramework): void;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { ServiceContainer } from '../services/ServiceContainer.js';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
/**
|
|
7
|
+
* Write the inspector snapshot to .zumito/inspector-state.json in the current
|
|
8
|
+
* working directory. Returns a cleanup function that stops the write interval.
|
|
9
|
+
*/
|
|
10
|
+
export function startInspectorFileWriter(framework) {
|
|
11
|
+
const startTime = Date.now();
|
|
12
|
+
let pkg = {};
|
|
13
|
+
try {
|
|
14
|
+
pkg = require('../../package.json');
|
|
15
|
+
}
|
|
16
|
+
catch { /* ignore */ }
|
|
17
|
+
let lastJson = '';
|
|
18
|
+
let timer;
|
|
19
|
+
const write = () => {
|
|
20
|
+
const state = {
|
|
21
|
+
version: pkg.version || 'unknown',
|
|
22
|
+
uptime: Date.now() - startTime,
|
|
23
|
+
discord: {
|
|
24
|
+
status: framework.client?.isReady() ? 'connected' : 'disconnected',
|
|
25
|
+
user: framework.client?.user
|
|
26
|
+
? { id: framework.client.user.id, tag: framework.client.user.tag }
|
|
27
|
+
: null,
|
|
28
|
+
guildCount: framework.client?.guilds?.cache?.size ?? 0,
|
|
29
|
+
},
|
|
30
|
+
database: {
|
|
31
|
+
connected: !!framework.db,
|
|
32
|
+
driver: framework.db ? getDriverName(framework) : 'none',
|
|
33
|
+
},
|
|
34
|
+
commands: serializeCommands(framework),
|
|
35
|
+
modules: serializeModules(framework),
|
|
36
|
+
services: serializeServices(),
|
|
37
|
+
events: serializeEvents(framework),
|
|
38
|
+
};
|
|
39
|
+
const json = JSON.stringify(state);
|
|
40
|
+
if (json === lastJson) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
lastJson = json;
|
|
44
|
+
try {
|
|
45
|
+
const dir = path.join(process.cwd(), '.zumito');
|
|
46
|
+
if (!fs.existsSync(dir)) {
|
|
47
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
fs.writeFileSync(path.join(dir, 'inspector-state.json'), json, 'utf-8');
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// can't write – silently ignore
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
// Write immediately, then every 3s
|
|
56
|
+
write();
|
|
57
|
+
timer = setInterval(write, 3000);
|
|
58
|
+
return () => {
|
|
59
|
+
if (timer) {
|
|
60
|
+
clearInterval(timer);
|
|
61
|
+
timer = undefined;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function registerFrameworkInspector(framework) {
|
|
66
|
+
const startTime = Date.now();
|
|
67
|
+
let pkg = {};
|
|
68
|
+
try {
|
|
69
|
+
pkg = require('../../package.json');
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// fallback if package.json can't be read
|
|
73
|
+
}
|
|
74
|
+
const inspector = {
|
|
75
|
+
getSnapshot() {
|
|
76
|
+
const state = {
|
|
77
|
+
version: pkg.version || 'unknown',
|
|
78
|
+
uptime: Date.now() - startTime,
|
|
79
|
+
discord: {
|
|
80
|
+
status: framework.client?.isReady() ? 'connected' : 'disconnected',
|
|
81
|
+
user: framework.client?.user
|
|
82
|
+
? { id: framework.client.user.id, tag: framework.client.user.tag }
|
|
83
|
+
: null,
|
|
84
|
+
guildCount: framework.client?.guilds?.cache?.size ?? 0,
|
|
85
|
+
},
|
|
86
|
+
database: {
|
|
87
|
+
connected: !!framework.db,
|
|
88
|
+
driver: framework.db ? getDriverName(framework) : 'none',
|
|
89
|
+
},
|
|
90
|
+
commands: serializeCommands(framework),
|
|
91
|
+
modules: serializeModules(framework),
|
|
92
|
+
services: serializeServices(),
|
|
93
|
+
events: serializeEvents(framework),
|
|
94
|
+
};
|
|
95
|
+
return JSON.stringify(state);
|
|
96
|
+
},
|
|
97
|
+
getCommands() {
|
|
98
|
+
return JSON.stringify(serializeCommands(framework));
|
|
99
|
+
},
|
|
100
|
+
getModules() {
|
|
101
|
+
return JSON.stringify(serializeModules(framework));
|
|
102
|
+
},
|
|
103
|
+
getServices() {
|
|
104
|
+
return JSON.stringify(serializeServices());
|
|
105
|
+
},
|
|
106
|
+
getEvents() {
|
|
107
|
+
return JSON.stringify(serializeEvents(framework));
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
try {
|
|
111
|
+
globalThis.__ZUMITO_INSPECT__ = inspector;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// globalThis not available (non-Node environment?)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function getDriverName(framework) {
|
|
118
|
+
try {
|
|
119
|
+
const driver = framework.db.getDriver?.();
|
|
120
|
+
if (driver) {
|
|
121
|
+
return driver.constructor?.name || 'custom';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// ignore
|
|
126
|
+
}
|
|
127
|
+
return 'unknown';
|
|
128
|
+
}
|
|
129
|
+
function serializeCommands(framework) {
|
|
130
|
+
const items = [];
|
|
131
|
+
const allCommands = framework.commands?.getAll();
|
|
132
|
+
if (allCommands) {
|
|
133
|
+
for (const [, cmd] of allCommands) {
|
|
134
|
+
items.push({
|
|
135
|
+
name: cmd.name,
|
|
136
|
+
type: cmd.type || 'any',
|
|
137
|
+
description: cmd.description || '',
|
|
138
|
+
aliases: cmd.aliases || [],
|
|
139
|
+
categories: cmd.categories || [],
|
|
140
|
+
hidden: cmd.hidden === true,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return { total: items.length, items };
|
|
145
|
+
}
|
|
146
|
+
function serializeModules(framework) {
|
|
147
|
+
const items = [];
|
|
148
|
+
const allModules = framework.modules?.getAll();
|
|
149
|
+
if (allModules) {
|
|
150
|
+
for (const [name, mod] of allModules) {
|
|
151
|
+
const modClass = Object.getPrototypeOf(mod)?.constructor;
|
|
152
|
+
items.push({
|
|
153
|
+
name,
|
|
154
|
+
displayName: modClass?.moduleName || name,
|
|
155
|
+
status: 'loaded',
|
|
156
|
+
dependencies: Array.from(modClass?.dependencies || []),
|
|
157
|
+
commandCount: mod.getCommands?.()?.size ?? 0,
|
|
158
|
+
eventCount: mod.events?.size ?? 0,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return { total: items.length, items };
|
|
163
|
+
}
|
|
164
|
+
function serializeServices() {
|
|
165
|
+
const items = [];
|
|
166
|
+
try {
|
|
167
|
+
const entries = ServiceContainer.getAllServiceEntries();
|
|
168
|
+
for (const entry of entries) {
|
|
169
|
+
items.push({
|
|
170
|
+
name: entry.name,
|
|
171
|
+
singleton: entry.singleton,
|
|
172
|
+
hasInstance: entry.hasInstance,
|
|
173
|
+
dependencies: entry.dependencies,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// service container not ready
|
|
179
|
+
}
|
|
180
|
+
return { total: items.length, items };
|
|
181
|
+
}
|
|
182
|
+
function serializeEvents(framework) {
|
|
183
|
+
const items = [];
|
|
184
|
+
const allEvents = framework.events;
|
|
185
|
+
if (allEvents) {
|
|
186
|
+
for (const [, evt] of allEvents) {
|
|
187
|
+
items.push({
|
|
188
|
+
name: evt.name || 'unknown',
|
|
189
|
+
source: evt.source || evt.emitter || 'framework',
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return { total: items.length, items };
|
|
194
|
+
}
|