shogun-core 2.0.3 → 3.0.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/README.md +150 -19
- package/dist/browser/shogun-core.js +3241 -1286
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/config/simplified-config.js +230 -0
- package/dist/core.js +49 -571
- package/dist/gundb/db.js +466 -237
- package/dist/gundb/improved-types.js +4 -0
- package/dist/gundb/index.js +4 -0
- package/dist/gundb/simple-api.js +438 -0
- package/dist/index.js +8 -2
- package/dist/managers/AuthManager.js +225 -0
- package/dist/managers/CoreInitializer.js +227 -0
- package/dist/managers/EventManager.js +67 -0
- package/dist/managers/PluginManager.js +296 -0
- package/dist/migration-test.js +91 -0
- package/dist/plugins/nostr/nostrConnectorPlugin.js +1 -1
- package/dist/plugins/oauth/oauthPlugin.js +1 -1
- package/dist/plugins/webauthn/webauthnPlugin.js +1 -1
- package/dist/types/config/simplified-config.d.ts +114 -0
- package/dist/types/core.d.ts +13 -46
- package/dist/types/gundb/db.d.ts +92 -14
- package/dist/types/gundb/improved-types.d.ts +123 -0
- package/dist/types/gundb/index.d.ts +2 -0
- package/dist/types/gundb/rxjs.d.ts +3 -3
- package/dist/types/gundb/simple-api.d.ts +90 -0
- package/dist/types/index.d.ts +6 -4
- package/dist/types/{types → interfaces}/shogun.d.ts +8 -10
- package/dist/types/managers/AuthManager.d.ts +69 -0
- package/dist/types/managers/CoreInitializer.d.ts +40 -0
- package/dist/types/managers/EventManager.d.ts +49 -0
- package/dist/types/managers/PluginManager.d.ts +145 -0
- package/dist/types/migration-test.d.ts +16 -0
- package/dist/types/plugins/base.d.ts +2 -2
- package/dist/types/plugins/index.d.ts +1 -1
- package/dist/types/plugins/nostr/nostrConnectorPlugin.d.ts +1 -1
- package/dist/types/plugins/nostr/types.d.ts +2 -2
- package/dist/types/plugins/oauth/oauthPlugin.d.ts +1 -1
- package/dist/types/plugins/oauth/types.d.ts +2 -2
- package/dist/types/plugins/web3/types.d.ts +2 -2
- package/dist/types/plugins/web3/web3ConnectorPlugin.d.ts +1 -1
- package/dist/types/plugins/webauthn/types.d.ts +2 -2
- package/dist/types/plugins/webauthn/webauthnPlugin.d.ts +1 -1
- package/dist/types/utils/errorHandler.d.ts +1 -1
- package/package.json +1 -1
- /package/dist/{types → interfaces}/common.js +0 -0
- /package/dist/{types → interfaces}/events.js +0 -0
- /package/dist/{types → interfaces}/plugin.js +0 -0
- /package/dist/{types → interfaces}/shogun.js +0 -0
- /package/dist/types/{types → interfaces}/common.d.ts +0 -0
- /package/dist/types/{types → interfaces}/events.d.ts +0 -0
- /package/dist/types/{types → interfaces}/plugin.d.ts +0 -0
package/dist/core.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { NostrConnectorPlugin } from "./plugins/nostr/nostrConnectorPlugin";
|
|
8
|
-
import { OAuthPlugin } from "./plugins/oauth/oauthPlugin";
|
|
9
|
-
import { restrictedPut, DataBase, RxJS, createGun, Gun, derive, } from "./gundb";
|
|
1
|
+
import { ErrorHandler } from "./utils/errorHandler";
|
|
2
|
+
// Import managers
|
|
3
|
+
import { PluginManager } from "./managers/PluginManager";
|
|
4
|
+
import { AuthManager } from "./managers/AuthManager";
|
|
5
|
+
import { EventManager } from "./managers/EventManager";
|
|
6
|
+
import { CoreInitializer } from "./managers/CoreInitializer";
|
|
10
7
|
/**
|
|
11
8
|
* Main ShogunCore class - implements the IShogunCore interface
|
|
12
9
|
*
|
|
@@ -27,10 +24,12 @@ export class ShogunCore {
|
|
|
27
24
|
rx;
|
|
28
25
|
_gun;
|
|
29
26
|
_user = null;
|
|
30
|
-
eventEmitter;
|
|
31
|
-
plugins = new Map();
|
|
32
|
-
currentAuthMethod;
|
|
33
27
|
wallets;
|
|
28
|
+
// Managers
|
|
29
|
+
pluginManager;
|
|
30
|
+
authManager;
|
|
31
|
+
eventManager;
|
|
32
|
+
coreInitializer;
|
|
34
33
|
/**
|
|
35
34
|
* Initialize the Shogun SDK
|
|
36
35
|
* @param config - SDK Configuration object
|
|
@@ -39,113 +38,19 @@ export class ShogunCore {
|
|
|
39
38
|
* and plugin system.
|
|
40
39
|
*/
|
|
41
40
|
constructor(config) {
|
|
42
|
-
// Polyfill console for environments where it might be missing
|
|
43
|
-
if (typeof console === "undefined") {
|
|
44
|
-
global.console = {
|
|
45
|
-
log: () => { },
|
|
46
|
-
warn: () => { },
|
|
47
|
-
error: () => { },
|
|
48
|
-
info: () => { },
|
|
49
|
-
debug: () => { },
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
41
|
this.config = config;
|
|
53
|
-
|
|
54
|
-
this.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
message: error.message,
|
|
59
|
-
type: error.type,
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
if (config.authToken) {
|
|
63
|
-
restrictedPut(Gun, config.authToken);
|
|
64
|
-
}
|
|
65
|
-
try {
|
|
66
|
-
if (config.gunInstance) {
|
|
67
|
-
this._gun = config.gunInstance;
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
this._gun = createGun({
|
|
71
|
-
peers: config.peers || [],
|
|
72
|
-
radisk: config.radisk || false,
|
|
73
|
-
localStorage: config.localStorage || false,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
if (typeof console !== "undefined" && console.error) {
|
|
79
|
-
console.error("Error creating Gun instance:", error);
|
|
80
|
-
}
|
|
81
|
-
throw new Error(`Failed to create Gun instance: ${error}`);
|
|
82
|
-
}
|
|
83
|
-
try {
|
|
84
|
-
this.db = new DataBase(this._gun, config.scope || "");
|
|
85
|
-
this._gun = this.db.gun;
|
|
86
|
-
this.setupGunEventForwarding();
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
if (typeof console !== "undefined" && console.error) {
|
|
90
|
-
console.error("Error initializing GunInstance:", error);
|
|
91
|
-
}
|
|
92
|
-
throw new Error(`Failed to initialize GunInstance: ${error}`);
|
|
93
|
-
}
|
|
94
|
-
try {
|
|
95
|
-
this._user = this._gun.user().recall({ sessionStorage: true });
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
if (typeof console !== "undefined" && console.error) {
|
|
99
|
-
console.error("Error initializing Gun user:", error);
|
|
100
|
-
}
|
|
101
|
-
throw new Error(`Failed to initialize Gun user: ${error}`);
|
|
102
|
-
}
|
|
103
|
-
this._gun.on("auth", (user) => {
|
|
104
|
-
this._user = this._gun.user().recall({ sessionStorage: true });
|
|
105
|
-
this.eventEmitter.emit("auth:login", {
|
|
106
|
-
userPub: user.pub,
|
|
107
|
-
method: "password",
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
// ascolta gun se user è loggato crei i wallets
|
|
111
|
-
this._gun.on("auth", async (user) => {
|
|
112
|
-
if (!user)
|
|
113
|
-
return;
|
|
114
|
-
const priv = user._?.sea?.epriv;
|
|
115
|
-
const pub = user._?.sea?.epub;
|
|
116
|
-
this.wallets = await derive(priv, pub, {
|
|
117
|
-
includeSecp256k1Bitcoin: true,
|
|
118
|
-
includeSecp256k1Ethereum: true,
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
this.rx = new RxJS(this._gun);
|
|
122
|
-
this.registerBuiltinPlugins(config);
|
|
42
|
+
// Initialize managers
|
|
43
|
+
this.eventManager = new EventManager();
|
|
44
|
+
this.pluginManager = new PluginManager(this);
|
|
45
|
+
this.authManager = new AuthManager(this);
|
|
46
|
+
this.coreInitializer = new CoreInitializer(this);
|
|
123
47
|
// Initialize async components
|
|
124
|
-
this.initialize().catch((error) => {
|
|
48
|
+
this.coreInitializer.initialize(config).catch((error) => {
|
|
125
49
|
if (typeof console !== "undefined" && console.warn) {
|
|
126
50
|
console.warn("Error during async initialization:", error);
|
|
127
51
|
}
|
|
128
52
|
});
|
|
129
53
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Initialize the Shogun SDK asynchronously
|
|
132
|
-
* This method handles initialization tasks that require async operations
|
|
133
|
-
*/
|
|
134
|
-
async initialize() {
|
|
135
|
-
try {
|
|
136
|
-
await this.db.initialize();
|
|
137
|
-
this.eventEmitter.emit("debug", {
|
|
138
|
-
action: "core_initialized",
|
|
139
|
-
timestamp: Date.now(),
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
if (typeof console !== "undefined" && console.error) {
|
|
144
|
-
console.error("Error during Shogun Core initialization:", error);
|
|
145
|
-
}
|
|
146
|
-
throw error;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
54
|
/**
|
|
150
55
|
* Access to the Gun instance
|
|
151
56
|
* @returns The Gun instance
|
|
@@ -170,170 +75,23 @@ export class ShogunCore {
|
|
|
170
75
|
}
|
|
171
76
|
return this.db.getCurrentUser();
|
|
172
77
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
*/
|
|
177
|
-
setupGunEventForwarding() {
|
|
178
|
-
const gunEvents = ["gun:put", "gun:get", "gun:set", "gun:remove"];
|
|
179
|
-
gunEvents.forEach((eventName) => {
|
|
180
|
-
this.db.on(eventName, (data) => {
|
|
181
|
-
this.eventEmitter.emit(eventName, data);
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
const peerEvents = [
|
|
185
|
-
"gun:peer:add",
|
|
186
|
-
"gun:peer:remove",
|
|
187
|
-
"gun:peer:connect",
|
|
188
|
-
"gun:peer:disconnect",
|
|
189
|
-
];
|
|
190
|
-
peerEvents.forEach((eventName) => {
|
|
191
|
-
this.db.on(eventName, (data) => {
|
|
192
|
-
this.eventEmitter.emit(eventName, data);
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Register built-in plugins based on configuration
|
|
198
|
-
* @private
|
|
199
|
-
*/
|
|
200
|
-
registerBuiltinPlugins(config) {
|
|
201
|
-
try {
|
|
202
|
-
// Register OAuth plugin if configuration is provided
|
|
203
|
-
if (config.oauth) {
|
|
204
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
205
|
-
console.warn("OAuth plugin will be registered with provided configuration");
|
|
206
|
-
}
|
|
207
|
-
const oauthPlugin = new OAuthPlugin();
|
|
208
|
-
if (typeof oauthPlugin.configure === "function") {
|
|
209
|
-
oauthPlugin.configure(config.oauth);
|
|
210
|
-
}
|
|
211
|
-
this.registerPlugin(oauthPlugin);
|
|
212
|
-
}
|
|
213
|
-
// Register WebAuthn plugin if configuration is provided
|
|
214
|
-
if (config.webauthn) {
|
|
215
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
216
|
-
console.warn("WebAuthn plugin will be registered with provided configuration");
|
|
217
|
-
}
|
|
218
|
-
const webauthnPlugin = new WebauthnPlugin();
|
|
219
|
-
if (typeof webauthnPlugin.configure === "function") {
|
|
220
|
-
webauthnPlugin.configure(config.webauthn);
|
|
221
|
-
}
|
|
222
|
-
this.registerPlugin(webauthnPlugin);
|
|
223
|
-
}
|
|
224
|
-
// Register Web3 plugin if configuration is provided
|
|
225
|
-
if (config.web3) {
|
|
226
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
227
|
-
console.warn("Web3 plugin will be registered with provided configuration");
|
|
228
|
-
}
|
|
229
|
-
const web3Plugin = new Web3ConnectorPlugin();
|
|
230
|
-
if (typeof web3Plugin.configure === "function") {
|
|
231
|
-
web3Plugin.configure(config.web3);
|
|
232
|
-
}
|
|
233
|
-
this.registerPlugin(web3Plugin);
|
|
234
|
-
}
|
|
235
|
-
// Register Nostr plugin if configuration is provided
|
|
236
|
-
if (config.nostr) {
|
|
237
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
238
|
-
console.warn("Nostr plugin will be registered with provided configuration");
|
|
239
|
-
}
|
|
240
|
-
const nostrPlugin = new NostrConnectorPlugin();
|
|
241
|
-
if (typeof nostrPlugin.configure === "function") {
|
|
242
|
-
nostrPlugin.configure(config.nostr);
|
|
243
|
-
}
|
|
244
|
-
this.registerPlugin(nostrPlugin);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
catch (error) {
|
|
248
|
-
if (typeof console !== "undefined" && console.error) {
|
|
249
|
-
console.error("Error registering builtin plugins:", error);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
78
|
+
// *********************************************************************************************************
|
|
79
|
+
// 🔌 PLUGIN MANAGEMENT 🔌
|
|
80
|
+
// *********************************************************************************************************
|
|
253
81
|
/**
|
|
254
82
|
* Registers a plugin with the Shogun SDK
|
|
255
83
|
* @param plugin Plugin instance to register
|
|
256
84
|
* @throws Error if a plugin with the same name is already registered
|
|
257
85
|
*/
|
|
258
86
|
register(plugin) {
|
|
259
|
-
this.
|
|
87
|
+
this.pluginManager.register(plugin);
|
|
260
88
|
}
|
|
261
89
|
/**
|
|
262
90
|
* Unregisters a plugin from the Shogun SDK
|
|
263
91
|
* @param pluginName Name of the plugin to unregister
|
|
264
92
|
*/
|
|
265
93
|
unregister(pluginName) {
|
|
266
|
-
this.
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Internal method to register a plugin
|
|
270
|
-
* @param plugin Plugin instance to register
|
|
271
|
-
*/
|
|
272
|
-
registerPlugin(plugin) {
|
|
273
|
-
try {
|
|
274
|
-
if (!plugin.name) {
|
|
275
|
-
if (typeof console !== "undefined" && console.error) {
|
|
276
|
-
console.error("Plugin registration failed: Plugin must have a name");
|
|
277
|
-
}
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
if (this.plugins.has(plugin.name)) {
|
|
281
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
282
|
-
console.warn(`Plugin "${plugin.name}" is already registered. Skipping.`);
|
|
283
|
-
}
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
// Initialize plugin with core instance
|
|
287
|
-
plugin.initialize(this);
|
|
288
|
-
this.plugins.set(plugin.name, plugin);
|
|
289
|
-
this.eventEmitter.emit("plugin:registered", {
|
|
290
|
-
name: plugin.name,
|
|
291
|
-
version: plugin.version || "unknown",
|
|
292
|
-
category: plugin._category || "unknown",
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
catch (error) {
|
|
296
|
-
if (typeof console !== "undefined" && console.error) {
|
|
297
|
-
console.error(`Error registering plugin "${plugin.name}":`, error);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Internal method to unregister a plugin
|
|
303
|
-
* @param name Name of the plugin to unregister
|
|
304
|
-
*/
|
|
305
|
-
unregisterPlugin(name) {
|
|
306
|
-
try {
|
|
307
|
-
const plugin = this.plugins.get(name);
|
|
308
|
-
if (!plugin) {
|
|
309
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
310
|
-
console.warn(`Plugin "${name}" not found for unregistration`);
|
|
311
|
-
}
|
|
312
|
-
return false;
|
|
313
|
-
}
|
|
314
|
-
// Destroy plugin if it has a destroy method
|
|
315
|
-
if (typeof plugin.destroy === "function") {
|
|
316
|
-
try {
|
|
317
|
-
plugin.destroy();
|
|
318
|
-
}
|
|
319
|
-
catch (destroyError) {
|
|
320
|
-
if (typeof console !== "undefined" && console.error) {
|
|
321
|
-
console.error(`Error destroying plugin "${name}":`, destroyError);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
this.plugins.delete(name);
|
|
326
|
-
this.eventEmitter.emit("plugin:unregistered", {
|
|
327
|
-
name: plugin.name,
|
|
328
|
-
});
|
|
329
|
-
return true;
|
|
330
|
-
}
|
|
331
|
-
catch (error) {
|
|
332
|
-
if (typeof console !== "undefined" && console.error) {
|
|
333
|
-
console.error(`Error unregistering plugin "${name}":`, error);
|
|
334
|
-
}
|
|
335
|
-
return false;
|
|
336
|
-
}
|
|
94
|
+
this.pluginManager.unregister(pluginName);
|
|
337
95
|
}
|
|
338
96
|
/**
|
|
339
97
|
* Retrieve a registered plugin by name
|
|
@@ -342,198 +100,56 @@ export class ShogunCore {
|
|
|
342
100
|
* @template T Type of the plugin or its public interface
|
|
343
101
|
*/
|
|
344
102
|
getPlugin(name) {
|
|
345
|
-
|
|
346
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
347
|
-
console.warn("Invalid plugin name provided to getPlugin");
|
|
348
|
-
}
|
|
349
|
-
return undefined;
|
|
350
|
-
}
|
|
351
|
-
const plugin = this.plugins.get(name);
|
|
352
|
-
if (!plugin) {
|
|
353
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
354
|
-
console.warn(`Plugin "${name}" not found`);
|
|
355
|
-
}
|
|
356
|
-
return undefined;
|
|
357
|
-
}
|
|
358
|
-
return plugin;
|
|
103
|
+
return this.pluginManager.getPlugin(name);
|
|
359
104
|
}
|
|
360
105
|
/**
|
|
361
106
|
* Get information about all registered plugins
|
|
362
107
|
* @returns Array of plugin information objects
|
|
363
108
|
*/
|
|
364
109
|
getPluginsInfo() {
|
|
365
|
-
|
|
366
|
-
this.plugins.forEach((plugin) => {
|
|
367
|
-
pluginsInfo.push({
|
|
368
|
-
name: plugin.name,
|
|
369
|
-
version: plugin.version || "unknown",
|
|
370
|
-
category: plugin._category,
|
|
371
|
-
description: plugin.description,
|
|
372
|
-
});
|
|
373
|
-
});
|
|
374
|
-
return pluginsInfo;
|
|
110
|
+
return this.pluginManager.getPluginsInfo();
|
|
375
111
|
}
|
|
376
112
|
/**
|
|
377
113
|
* Get the total number of registered plugins
|
|
378
114
|
* @returns Number of registered plugins
|
|
379
115
|
*/
|
|
380
116
|
getPluginCount() {
|
|
381
|
-
return this.
|
|
117
|
+
return this.pluginManager.getPluginCount();
|
|
382
118
|
}
|
|
383
119
|
/**
|
|
384
120
|
* Check if all plugins are properly initialized
|
|
385
121
|
* @returns Object with initialization status for each plugin
|
|
386
122
|
*/
|
|
387
123
|
getPluginsInitializationStatus() {
|
|
388
|
-
|
|
389
|
-
this.plugins.forEach((plugin, name) => {
|
|
390
|
-
try {
|
|
391
|
-
// Verifica se il plugin ha un metodo per controllare l'inizializzazione
|
|
392
|
-
if (typeof plugin.assertInitialized === "function") {
|
|
393
|
-
plugin.assertInitialized();
|
|
394
|
-
status[name] = { initialized: true };
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
// Fallback: verifica se il plugin ha un riferimento al core
|
|
398
|
-
status[name] = {
|
|
399
|
-
initialized: !!plugin.core,
|
|
400
|
-
error: !plugin.core
|
|
401
|
-
? "No core reference found"
|
|
402
|
-
: undefined,
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
catch (error) {
|
|
407
|
-
status[name] = {
|
|
408
|
-
initialized: false,
|
|
409
|
-
error: error instanceof Error ? error.message : String(error),
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
});
|
|
413
|
-
return status;
|
|
124
|
+
return this.pluginManager.getPluginsInitializationStatus();
|
|
414
125
|
}
|
|
415
126
|
/**
|
|
416
127
|
* Validate plugin system integrity
|
|
417
128
|
* @returns Object with validation results
|
|
418
129
|
*/
|
|
419
130
|
validatePluginSystem() {
|
|
420
|
-
|
|
421
|
-
const totalPlugins = Object.keys(status).length;
|
|
422
|
-
const initializedPlugins = Object.values(status).filter((s) => s.initialized).length;
|
|
423
|
-
const failedPlugins = Object.entries(status)
|
|
424
|
-
.filter(([_, s]) => !s.initialized)
|
|
425
|
-
.map(([name, _]) => name);
|
|
426
|
-
const warnings = [];
|
|
427
|
-
if (totalPlugins === 0) {
|
|
428
|
-
warnings.push("No plugins registered");
|
|
429
|
-
}
|
|
430
|
-
if (failedPlugins.length > 0) {
|
|
431
|
-
warnings.push(`Failed plugins: ${failedPlugins.join(", ")}`);
|
|
432
|
-
}
|
|
433
|
-
return {
|
|
434
|
-
totalPlugins,
|
|
435
|
-
initializedPlugins,
|
|
436
|
-
failedPlugins,
|
|
437
|
-
warnings,
|
|
438
|
-
};
|
|
131
|
+
return this.pluginManager.validatePluginSystem();
|
|
439
132
|
}
|
|
440
133
|
/**
|
|
441
134
|
* Attempt to reinitialize failed plugins
|
|
442
135
|
* @returns Object with reinitialization results
|
|
443
136
|
*/
|
|
444
137
|
reinitializeFailedPlugins() {
|
|
445
|
-
|
|
446
|
-
const failedPlugins = Object.entries(status)
|
|
447
|
-
.filter(([_, s]) => !s.initialized)
|
|
448
|
-
.map(([name, _]) => name);
|
|
449
|
-
const success = [];
|
|
450
|
-
const failed = [];
|
|
451
|
-
failedPlugins.forEach((pluginName) => {
|
|
452
|
-
try {
|
|
453
|
-
const plugin = this.plugins.get(pluginName);
|
|
454
|
-
if (!plugin) {
|
|
455
|
-
failed.push({ name: pluginName, error: "Plugin not found" });
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
// Reinizializza il plugin
|
|
459
|
-
if (pluginName === CorePlugins.OAuth) {
|
|
460
|
-
// Rimuovo la chiamata a initialize
|
|
461
|
-
plugin.initialize(this);
|
|
462
|
-
}
|
|
463
|
-
else {
|
|
464
|
-
// Rimuovo la chiamata a initialize
|
|
465
|
-
plugin.initialize(this);
|
|
466
|
-
}
|
|
467
|
-
success.push(pluginName);
|
|
468
|
-
}
|
|
469
|
-
catch (error) {
|
|
470
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
471
|
-
failed.push({ name: pluginName, error: errorMessage });
|
|
472
|
-
if (typeof console !== "undefined" && console.error) {
|
|
473
|
-
console.error(`[ShogunCore] Failed to reinitialize plugin ${pluginName}:`, error);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
});
|
|
477
|
-
return { success, failed };
|
|
138
|
+
return this.pluginManager.reinitializeFailedPlugins();
|
|
478
139
|
}
|
|
479
140
|
/**
|
|
480
141
|
* Check plugin compatibility with current ShogunCore version
|
|
481
142
|
* @returns Object with compatibility information
|
|
482
143
|
*/
|
|
483
144
|
checkPluginCompatibility() {
|
|
484
|
-
|
|
485
|
-
const incompatible = [];
|
|
486
|
-
const unknown = [];
|
|
487
|
-
this.plugins.forEach((plugin) => {
|
|
488
|
-
const pluginInfo = {
|
|
489
|
-
name: plugin.name,
|
|
490
|
-
version: plugin.version || "unknown",
|
|
491
|
-
};
|
|
492
|
-
// Verifica se il plugin ha informazioni di compatibilità
|
|
493
|
-
if (typeof plugin.getCompatibilityInfo === "function") {
|
|
494
|
-
try {
|
|
495
|
-
const compatibilityInfo = plugin.getCompatibilityInfo();
|
|
496
|
-
if (compatibilityInfo && compatibilityInfo.compatible) {
|
|
497
|
-
compatible.push(pluginInfo);
|
|
498
|
-
}
|
|
499
|
-
else {
|
|
500
|
-
incompatible.push({
|
|
501
|
-
...pluginInfo,
|
|
502
|
-
reason: compatibilityInfo?.reason || "Unknown compatibility issue",
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
catch (error) {
|
|
507
|
-
unknown.push(pluginInfo);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
else {
|
|
511
|
-
// Se non ha informazioni di compatibilità, considera sconosciuto
|
|
512
|
-
unknown.push(pluginInfo);
|
|
513
|
-
}
|
|
514
|
-
});
|
|
515
|
-
return { compatible, incompatible, unknown };
|
|
145
|
+
return this.pluginManager.checkPluginCompatibility();
|
|
516
146
|
}
|
|
517
147
|
/**
|
|
518
148
|
* Get comprehensive debug information about the plugin system
|
|
519
149
|
* @returns Complete plugin system debug information
|
|
520
150
|
*/
|
|
521
151
|
getPluginSystemDebugInfo() {
|
|
522
|
-
|
|
523
|
-
const initializationStatus = this.getPluginsInitializationStatus();
|
|
524
|
-
const plugins = pluginsInfo.map((info) => ({
|
|
525
|
-
...info,
|
|
526
|
-
initialized: initializationStatus[info.name]?.initialized || false,
|
|
527
|
-
error: initializationStatus[info.name]?.error,
|
|
528
|
-
}));
|
|
529
|
-
return {
|
|
530
|
-
shogunCoreVersion: ShogunCore.API_VERSION,
|
|
531
|
-
totalPlugins: this.getPluginCount(),
|
|
532
|
-
plugins,
|
|
533
|
-
initializationStatus,
|
|
534
|
-
validation: this.validatePluginSystem(),
|
|
535
|
-
compatibility: this.checkPluginCompatibility(),
|
|
536
|
-
};
|
|
152
|
+
return this.pluginManager.getPluginSystemDebugInfo();
|
|
537
153
|
}
|
|
538
154
|
/**
|
|
539
155
|
* Check if a plugin is registered
|
|
@@ -541,7 +157,7 @@ export class ShogunCore {
|
|
|
541
157
|
* @returns true if the plugin is registered, false otherwise
|
|
542
158
|
*/
|
|
543
159
|
hasPlugin(name) {
|
|
544
|
-
return this.
|
|
160
|
+
return this.pluginManager.hasPlugin(name);
|
|
545
161
|
}
|
|
546
162
|
/**
|
|
547
163
|
* Get all plugins of a specific category
|
|
@@ -549,13 +165,7 @@ export class ShogunCore {
|
|
|
549
165
|
* @returns Array of plugins in the specified category
|
|
550
166
|
*/
|
|
551
167
|
getPluginsByCategory(category) {
|
|
552
|
-
|
|
553
|
-
this.plugins.forEach((plugin) => {
|
|
554
|
-
if (plugin._category === category) {
|
|
555
|
-
result.push(plugin);
|
|
556
|
-
}
|
|
557
|
-
});
|
|
558
|
-
return result;
|
|
168
|
+
return this.pluginManager.getPluginsByCategory(category);
|
|
559
169
|
}
|
|
560
170
|
/**
|
|
561
171
|
* Get an authentication method plugin by type
|
|
@@ -564,26 +174,7 @@ export class ShogunCore {
|
|
|
564
174
|
* This is a more modern approach to accessing authentication methods
|
|
565
175
|
*/
|
|
566
176
|
getAuthenticationMethod(type) {
|
|
567
|
-
|
|
568
|
-
case "webauthn":
|
|
569
|
-
return this.getPlugin(CorePlugins.WebAuthn);
|
|
570
|
-
case "web3":
|
|
571
|
-
return this.getPlugin(CorePlugins.Web3);
|
|
572
|
-
case "nostr":
|
|
573
|
-
return this.getPlugin(CorePlugins.Nostr);
|
|
574
|
-
case "oauth":
|
|
575
|
-
return this.getPlugin(CorePlugins.OAuth);
|
|
576
|
-
case "password":
|
|
577
|
-
default:
|
|
578
|
-
return {
|
|
579
|
-
login: async (username, password) => {
|
|
580
|
-
return await this.login(username, password);
|
|
581
|
-
},
|
|
582
|
-
signUp: async (username, password, confirm) => {
|
|
583
|
-
return await this.signUp(username, password, confirm);
|
|
584
|
-
},
|
|
585
|
-
};
|
|
586
|
-
}
|
|
177
|
+
return this.authManager.getAuthenticationMethod(type);
|
|
587
178
|
}
|
|
588
179
|
// *********************************************************************************************************
|
|
589
180
|
// 🔐 ERROR HANDLER 🔐
|
|
@@ -606,7 +197,7 @@ export class ShogunCore {
|
|
|
606
197
|
* and presence of authentication credentials in storage
|
|
607
198
|
*/
|
|
608
199
|
isLoggedIn() {
|
|
609
|
-
return this.
|
|
200
|
+
return this.authManager.isLoggedIn();
|
|
610
201
|
}
|
|
611
202
|
/**
|
|
612
203
|
* Perform user logout
|
|
@@ -614,16 +205,7 @@ export class ShogunCore {
|
|
|
614
205
|
* If user is not authenticated, the logout operation is ignored.
|
|
615
206
|
*/
|
|
616
207
|
logout() {
|
|
617
|
-
|
|
618
|
-
if (!this.isLoggedIn()) {
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
this.db.logout();
|
|
622
|
-
this.eventEmitter.emit("auth:logout");
|
|
623
|
-
}
|
|
624
|
-
catch (error) {
|
|
625
|
-
ErrorHandler.handle(ErrorType.AUTHENTICATION, "LOGOUT_FAILED", error instanceof Error ? error.message : "Error during logout", error);
|
|
626
|
-
}
|
|
208
|
+
this.authManager.logout();
|
|
627
209
|
}
|
|
628
210
|
/**
|
|
629
211
|
* Authenticate user with username and password
|
|
@@ -634,36 +216,7 @@ export class ShogunCore {
|
|
|
634
216
|
* Emits login event on success.
|
|
635
217
|
*/
|
|
636
218
|
async login(username, password, pair) {
|
|
637
|
-
|
|
638
|
-
if (!this.currentAuthMethod) {
|
|
639
|
-
this.currentAuthMethod = "password";
|
|
640
|
-
}
|
|
641
|
-
const result = await this.db.login(username, password, pair);
|
|
642
|
-
if (result.success) {
|
|
643
|
-
// Include SEA pair in the response
|
|
644
|
-
const seaPair = this.user?._?.sea;
|
|
645
|
-
if (seaPair) {
|
|
646
|
-
result.sea = seaPair;
|
|
647
|
-
}
|
|
648
|
-
this.eventEmitter.emit("auth:login", {
|
|
649
|
-
userPub: result.userPub ?? "",
|
|
650
|
-
method: this.currentAuthMethod === "pair"
|
|
651
|
-
? "password"
|
|
652
|
-
: this.currentAuthMethod || "password",
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
|
-
else {
|
|
656
|
-
result.error = result.error || "Wrong user or password";
|
|
657
|
-
}
|
|
658
|
-
return result;
|
|
659
|
-
}
|
|
660
|
-
catch (error) {
|
|
661
|
-
ErrorHandler.handle(ErrorType.AUTHENTICATION, "LOGIN_FAILED", error.message ?? "Unknown error during login", error);
|
|
662
|
-
return {
|
|
663
|
-
success: false,
|
|
664
|
-
error: error.message ?? "Unknown error during login",
|
|
665
|
-
};
|
|
666
|
-
}
|
|
219
|
+
return this.authManager.login(username, password, pair);
|
|
667
220
|
}
|
|
668
221
|
/**
|
|
669
222
|
* Login with GunDB pair directly
|
|
@@ -673,94 +226,20 @@ export class ShogunCore {
|
|
|
673
226
|
* Emits login event on success.
|
|
674
227
|
*/
|
|
675
228
|
async loginWithPair(pair) {
|
|
676
|
-
|
|
677
|
-
if (!pair || !pair.pub || !pair.priv || !pair.epub || !pair.epriv) {
|
|
678
|
-
return {
|
|
679
|
-
success: false,
|
|
680
|
-
error: "Invalid pair structure - missing required keys",
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
// Use the new loginWithPair method from GunInstance
|
|
684
|
-
const result = await this.db.login("", "", pair);
|
|
685
|
-
if (result.success) {
|
|
686
|
-
// Include SEA pair in the response
|
|
687
|
-
const seaPair = this.user?._?.sea;
|
|
688
|
-
if (seaPair) {
|
|
689
|
-
result.sea = seaPair;
|
|
690
|
-
}
|
|
691
|
-
this.currentAuthMethod = "pair";
|
|
692
|
-
this.eventEmitter.emit("auth:login", {
|
|
693
|
-
userPub: result.userPub ?? "",
|
|
694
|
-
method: "password",
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
else {
|
|
698
|
-
result.error =
|
|
699
|
-
result.error || "Authentication failed with provided pair";
|
|
700
|
-
}
|
|
701
|
-
return result;
|
|
702
|
-
}
|
|
703
|
-
catch (error) {
|
|
704
|
-
ErrorHandler.handle(ErrorType.AUTHENTICATION, "PAIR_LOGIN_FAILED", error.message ?? "Unknown error during pair login", error);
|
|
705
|
-
return {
|
|
706
|
-
success: false,
|
|
707
|
-
error: error.message ?? "Unknown error during pair login",
|
|
708
|
-
};
|
|
709
|
-
}
|
|
229
|
+
return this.authManager.loginWithPair(pair);
|
|
710
230
|
}
|
|
711
231
|
/**
|
|
712
232
|
* Register a new user with provided credentials
|
|
713
233
|
* @param username - Username
|
|
714
234
|
* @param password - Password
|
|
715
|
-
* @param
|
|
235
|
+
* @param email - Email (optional)
|
|
716
236
|
* @param pair - Pair of keys
|
|
717
237
|
* @returns {Promise<SignUpResult>} Registration result
|
|
718
238
|
* @description Creates a new user account with the provided credentials.
|
|
719
239
|
* Validates password requirements and emits signup event on success.
|
|
720
240
|
*/
|
|
721
|
-
async signUp(username, password
|
|
722
|
-
|
|
723
|
-
if (!this.db) {
|
|
724
|
-
throw new Error("Database not initialized");
|
|
725
|
-
}
|
|
726
|
-
const result = await this.db.signUp(username, password, pair);
|
|
727
|
-
if (result.success) {
|
|
728
|
-
// Update current authentication method
|
|
729
|
-
this.currentAuthMethod = pair ? "web3" : "password";
|
|
730
|
-
this.eventEmitter.emit("auth:signup", {
|
|
731
|
-
userPub: result.userPub,
|
|
732
|
-
username,
|
|
733
|
-
method: this.currentAuthMethod,
|
|
734
|
-
});
|
|
735
|
-
this.eventEmitter.emit("debug", {
|
|
736
|
-
action: "signup_success",
|
|
737
|
-
userPub: result.userPub,
|
|
738
|
-
method: this.currentAuthMethod,
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
|
-
else {
|
|
742
|
-
this.eventEmitter.emit("debug", {
|
|
743
|
-
action: "signup_failed",
|
|
744
|
-
error: result.error,
|
|
745
|
-
username,
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
return result;
|
|
749
|
-
}
|
|
750
|
-
catch (error) {
|
|
751
|
-
if (typeof console !== "undefined" && console.error) {
|
|
752
|
-
console.error(`Error during registration for user ${username}:`, error);
|
|
753
|
-
}
|
|
754
|
-
this.eventEmitter.emit("debug", {
|
|
755
|
-
action: "signup_error",
|
|
756
|
-
error: error instanceof Error ? error.message : String(error),
|
|
757
|
-
username,
|
|
758
|
-
});
|
|
759
|
-
return {
|
|
760
|
-
success: false,
|
|
761
|
-
error: `Registration failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
762
|
-
};
|
|
763
|
-
}
|
|
241
|
+
async signUp(username, password, pair) {
|
|
242
|
+
return this.authManager.signUp(username, password, pair);
|
|
764
243
|
}
|
|
765
244
|
// 📢 EVENT EMITTER 📢
|
|
766
245
|
/**
|
|
@@ -771,7 +250,7 @@ export class ShogunCore {
|
|
|
771
250
|
* @returns {boolean} Indicates if the event had listeners.
|
|
772
251
|
*/
|
|
773
252
|
emit(eventName, data) {
|
|
774
|
-
return this.
|
|
253
|
+
return this.eventManager.emit(eventName, data);
|
|
775
254
|
}
|
|
776
255
|
/**
|
|
777
256
|
* Add an event listener
|
|
@@ -780,7 +259,7 @@ export class ShogunCore {
|
|
|
780
259
|
* @returns {this} Returns this instance for method chaining
|
|
781
260
|
*/
|
|
782
261
|
on(eventName, listener) {
|
|
783
|
-
this.
|
|
262
|
+
this.eventManager.on(eventName, listener);
|
|
784
263
|
return this;
|
|
785
264
|
}
|
|
786
265
|
/**
|
|
@@ -790,7 +269,7 @@ export class ShogunCore {
|
|
|
790
269
|
* @returns {this} Returns this instance for method chaining
|
|
791
270
|
*/
|
|
792
271
|
once(eventName, listener) {
|
|
793
|
-
this.
|
|
272
|
+
this.eventManager.once(eventName, listener);
|
|
794
273
|
return this;
|
|
795
274
|
}
|
|
796
275
|
/**
|
|
@@ -800,7 +279,7 @@ export class ShogunCore {
|
|
|
800
279
|
* @returns {this} Returns this instance for method chaining
|
|
801
280
|
*/
|
|
802
281
|
off(eventName, listener) {
|
|
803
|
-
this.
|
|
282
|
+
this.eventManager.off(eventName, listener);
|
|
804
283
|
return this;
|
|
805
284
|
}
|
|
806
285
|
/**
|
|
@@ -810,7 +289,7 @@ export class ShogunCore {
|
|
|
810
289
|
* @returns {this} Returns this instance for method chaining
|
|
811
290
|
*/
|
|
812
291
|
removeAllListeners(eventName) {
|
|
813
|
-
this.
|
|
292
|
+
this.eventManager.removeAllListeners(eventName);
|
|
814
293
|
return this;
|
|
815
294
|
}
|
|
816
295
|
/**
|
|
@@ -819,14 +298,14 @@ export class ShogunCore {
|
|
|
819
298
|
* @param method The authentication method used
|
|
820
299
|
*/
|
|
821
300
|
setAuthMethod(method) {
|
|
822
|
-
this.
|
|
301
|
+
this.authManager.setAuthMethod(method);
|
|
823
302
|
}
|
|
824
303
|
/**
|
|
825
304
|
* Get the current authentication method
|
|
826
305
|
* @returns The current authentication method or undefined if not set
|
|
827
306
|
*/
|
|
828
307
|
getAuthMethod() {
|
|
829
|
-
return this.
|
|
308
|
+
return this.authManager.getAuthMethod();
|
|
830
309
|
}
|
|
831
310
|
/**
|
|
832
311
|
* Saves the current user credentials to storage
|
|
@@ -848,9 +327,8 @@ export class ShogunCore {
|
|
|
848
327
|
return !!(this.user && this.user.is);
|
|
849
328
|
}
|
|
850
329
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
}
|
|
330
|
+
// Global declarations are handled in the original core.ts file
|
|
331
|
+
// to avoid conflicts, we only set the window properties here
|
|
854
332
|
if (typeof window !== "undefined") {
|
|
855
333
|
window.SHOGUN_CORE = (config) => {
|
|
856
334
|
return new ShogunCore(config);
|