shogun-core 3.0.4 → 3.0.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.
- package/dist/browser/shogun-core.js +92134 -0
- package/dist/browser/shogun-core.js.map +1 -0
- package/dist/config/simplified-config.js +230 -0
- package/dist/core.js +338 -0
- package/dist/gundb/crypto.js +268 -0
- package/dist/gundb/db.js +1833 -0
- package/dist/gundb/derive.js +229 -0
- package/dist/gundb/errors.js +66 -0
- package/dist/gundb/index.js +6 -0
- package/dist/gundb/restricted-put.js +81 -0
- package/dist/gundb/rxjs.js +445 -0
- package/dist/gundb/simple-api.js +438 -0
- package/dist/gundb/types.js +4 -0
- package/dist/index.js +16 -0
- package/dist/interfaces/common.js +1 -0
- package/dist/interfaces/events.js +36 -0
- package/dist/interfaces/plugin.js +1 -0
- package/dist/interfaces/shogun.js +34 -0
- package/dist/managers/AuthManager.js +225 -0
- package/dist/managers/CoreInitializer.js +240 -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/base.js +47 -0
- package/dist/plugins/index.js +15 -0
- package/dist/plugins/nostr/index.js +4 -0
- package/dist/plugins/nostr/nostrConnector.js +413 -0
- package/dist/plugins/nostr/nostrConnectorPlugin.js +446 -0
- package/dist/plugins/nostr/nostrSigner.js +313 -0
- package/dist/plugins/nostr/types.js +1 -0
- package/dist/plugins/oauth/index.js +3 -0
- package/dist/plugins/oauth/oauthConnector.js +753 -0
- package/dist/plugins/oauth/oauthPlugin.js +396 -0
- package/dist/plugins/oauth/types.js +1 -0
- package/dist/plugins/web3/index.js +4 -0
- package/dist/plugins/web3/types.js +1 -0
- package/dist/plugins/web3/web3Connector.js +528 -0
- package/dist/plugins/web3/web3ConnectorPlugin.js +448 -0
- package/dist/plugins/web3/web3Signer.js +308 -0
- package/dist/plugins/webauthn/index.js +3 -0
- package/dist/plugins/webauthn/types.js +11 -0
- package/dist/plugins/webauthn/webauthn.js +478 -0
- package/dist/plugins/webauthn/webauthnPlugin.js +398 -0
- package/dist/plugins/webauthn/webauthnSigner.js +304 -0
- package/dist/storage/storage.js +147 -0
- package/dist/types/config/simplified-config.d.ts +114 -0
- package/dist/types/core.d.ts +305 -0
- package/dist/types/gundb/crypto.d.ts +95 -0
- package/dist/types/gundb/db.d.ts +404 -0
- package/dist/types/gundb/derive.d.ts +21 -0
- package/dist/types/gundb/errors.d.ts +42 -0
- package/dist/types/gundb/index.d.ts +3 -0
- package/dist/types/gundb/restricted-put.d.ts +15 -0
- package/dist/types/gundb/rxjs.d.ts +110 -0
- package/dist/types/gundb/simple-api.d.ts +90 -0
- package/dist/types/gundb/types.d.ts +264 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/interfaces/common.d.ts +85 -0
- package/dist/types/interfaces/events.d.ts +131 -0
- package/dist/types/interfaces/plugin.d.ts +162 -0
- package/dist/types/interfaces/shogun.d.ts +215 -0
- package/dist/types/managers/AuthManager.d.ts +72 -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 +35 -0
- package/dist/types/plugins/index.d.ts +14 -0
- package/dist/types/plugins/nostr/index.d.ts +4 -0
- package/dist/types/plugins/nostr/nostrConnector.d.ts +119 -0
- package/dist/types/plugins/nostr/nostrConnectorPlugin.d.ts +163 -0
- package/dist/types/plugins/nostr/nostrSigner.d.ts +105 -0
- package/dist/types/plugins/nostr/types.d.ts +122 -0
- package/dist/types/plugins/oauth/index.d.ts +3 -0
- package/dist/types/plugins/oauth/oauthConnector.d.ts +110 -0
- package/dist/types/plugins/oauth/oauthPlugin.d.ts +91 -0
- package/dist/types/plugins/oauth/types.d.ts +114 -0
- package/dist/types/plugins/web3/index.d.ts +4 -0
- package/dist/types/plugins/web3/types.d.ts +107 -0
- package/dist/types/plugins/web3/web3Connector.d.ts +129 -0
- package/dist/types/plugins/web3/web3ConnectorPlugin.d.ts +160 -0
- package/dist/types/plugins/web3/web3Signer.d.ts +114 -0
- package/dist/types/plugins/webauthn/index.d.ts +3 -0
- package/dist/types/plugins/webauthn/types.d.ts +162 -0
- package/dist/types/plugins/webauthn/webauthn.d.ts +129 -0
- package/dist/types/plugins/webauthn/webauthnPlugin.d.ts +158 -0
- package/dist/types/plugins/webauthn/webauthnSigner.d.ts +91 -0
- package/dist/types/storage/storage.d.ts +50 -0
- package/dist/types/utils/errorHandler.d.ts +119 -0
- package/dist/types/utils/eventEmitter.d.ts +39 -0
- package/dist/types/utils/validation.d.ts +27 -0
- package/dist/utils/errorHandler.js +241 -0
- package/dist/utils/eventEmitter.js +76 -0
- package/dist/utils/validation.js +72 -0
- package/package.json +1 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage implementation based on StorageMock
|
|
3
|
+
* Provides a unified storage interface that works in both browser and non-browser environments
|
|
4
|
+
* In browser environments, data is persisted to localStorage as a backup
|
|
5
|
+
*/
|
|
6
|
+
export declare class ShogunStorage {
|
|
7
|
+
private store;
|
|
8
|
+
private isTestMode;
|
|
9
|
+
private useLocalStorage;
|
|
10
|
+
/**
|
|
11
|
+
* Initializes storage and loads any existing keypair from localStorage if available
|
|
12
|
+
*/
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Gets the stored keypair asynchronously
|
|
16
|
+
* @returns Promise resolving to the keypair or null if not found
|
|
17
|
+
*/
|
|
18
|
+
getPair(): Promise<any>;
|
|
19
|
+
/**
|
|
20
|
+
* Gets the stored keypair synchronously
|
|
21
|
+
* @returns The keypair or null if not found
|
|
22
|
+
*/
|
|
23
|
+
getPairSync(): any;
|
|
24
|
+
/**
|
|
25
|
+
* Stores a keypair both in memory and localStorage if available
|
|
26
|
+
* @param pair - The keypair to store
|
|
27
|
+
*/
|
|
28
|
+
setPair(pair: any): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Clears all stored data from both memory and localStorage
|
|
31
|
+
*/
|
|
32
|
+
clearAll(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Gets an item from storage
|
|
35
|
+
* @param key - The key to retrieve
|
|
36
|
+
* @returns The stored value, or null if not found
|
|
37
|
+
*/
|
|
38
|
+
getItem(key: string): any;
|
|
39
|
+
/**
|
|
40
|
+
* Stores an item in both memory and localStorage if available
|
|
41
|
+
* @param key - The key to store under
|
|
42
|
+
* @param value - The value to store (must be JSON stringifiable)
|
|
43
|
+
*/
|
|
44
|
+
setItem(key: string, value: any): void;
|
|
45
|
+
/**
|
|
46
|
+
* Removes an item from both memory and localStorage if available
|
|
47
|
+
* @param key - The key to remove
|
|
48
|
+
*/
|
|
49
|
+
removeItem(key: string): void;
|
|
50
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { LogLevel } from "../interfaces/common";
|
|
2
|
+
/**
|
|
3
|
+
* Types of errors that can occur in the application
|
|
4
|
+
*/
|
|
5
|
+
export declare enum ErrorType {
|
|
6
|
+
AUTHENTICATION = "AuthenticationError",
|
|
7
|
+
AUTHORIZATION = "AuthorizationError",
|
|
8
|
+
VALIDATION = "ValidationError",
|
|
9
|
+
NETWORK = "NetworkError",
|
|
10
|
+
DATABASE = "DatabaseError",
|
|
11
|
+
WALLET = "WalletError",
|
|
12
|
+
STORAGE = "StorageError",
|
|
13
|
+
ENCRYPTION = "EncryptionError",
|
|
14
|
+
SIGNATURE = "SignatureError",
|
|
15
|
+
ENVIRONMENT = "EnvironmentError",
|
|
16
|
+
SECURITY = "SecurityError",
|
|
17
|
+
GUN = "GunError",
|
|
18
|
+
STEALTH = "StealthError",
|
|
19
|
+
WEBAUTHN = "WebAuthnError",
|
|
20
|
+
PLUGIN = "PluginError",
|
|
21
|
+
UNKNOWN = "UnknownError",
|
|
22
|
+
CONNECTOR = "ConnectorError",
|
|
23
|
+
GENERAL = "GeneralError",
|
|
24
|
+
CONTRACT = "ContractError",
|
|
25
|
+
BIP32 = "BIP32Error",
|
|
26
|
+
ETHEREUM = "EthereumError",
|
|
27
|
+
BITCOIN = "BitcoinError"
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Standard interface for Shogun errors
|
|
31
|
+
*/
|
|
32
|
+
export interface ShogunError {
|
|
33
|
+
type: ErrorType;
|
|
34
|
+
code: string;
|
|
35
|
+
message: string;
|
|
36
|
+
originalError?: Error | unknown;
|
|
37
|
+
timestamp: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Wrapper to standardize errors
|
|
41
|
+
* @param type - Error type
|
|
42
|
+
* @param code - Error code
|
|
43
|
+
* @param message - Error message
|
|
44
|
+
* @param originalError - Original error
|
|
45
|
+
* @returns A structured error object
|
|
46
|
+
*/
|
|
47
|
+
export declare function createError(type: ErrorType, code: string, message: string, originalError?: Error | unknown): ShogunError;
|
|
48
|
+
/**
|
|
49
|
+
* Centralized error handler
|
|
50
|
+
*/
|
|
51
|
+
export declare class ErrorHandler {
|
|
52
|
+
private static errors;
|
|
53
|
+
private static maxErrors;
|
|
54
|
+
private static listeners;
|
|
55
|
+
private static externalLogger;
|
|
56
|
+
/**
|
|
57
|
+
* Set an external logging service for production error monitoring
|
|
58
|
+
* @param logger - External logger function to send errors to a monitoring service
|
|
59
|
+
*/
|
|
60
|
+
static setExternalLogger(logger: (error: ShogunError) => void): void;
|
|
61
|
+
/**
|
|
62
|
+
* Handles an error by logging it and notifying listeners
|
|
63
|
+
* @param error - The error to handle
|
|
64
|
+
*/
|
|
65
|
+
static handleError(error: ShogunError): void;
|
|
66
|
+
/**
|
|
67
|
+
* Handles a raw error by converting it to ShogunError
|
|
68
|
+
* @param type - Error type
|
|
69
|
+
* @param code - Error code
|
|
70
|
+
* @param message - Error message
|
|
71
|
+
* @param originalError - Original error
|
|
72
|
+
* @param logLevel - Log level for the error
|
|
73
|
+
*/
|
|
74
|
+
static handle(type: ErrorType, code: string, message: string, originalError?: Error | unknown, logLevel?: LogLevel): ShogunError;
|
|
75
|
+
/**
|
|
76
|
+
* Handles errors and throws them as standardized ShogunError objects
|
|
77
|
+
* @param type - Error type
|
|
78
|
+
* @param code - Error code
|
|
79
|
+
* @param message - Error message
|
|
80
|
+
* @param originalError - Original error
|
|
81
|
+
* @throws ShogunError
|
|
82
|
+
*/
|
|
83
|
+
static handleAndThrow(type: ErrorType, code: string, message: string, originalError?: Error | unknown): never;
|
|
84
|
+
/**
|
|
85
|
+
* Retrieves the last N errors
|
|
86
|
+
* @param count - Number of errors to retrieve
|
|
87
|
+
* @returns List of most recent errors
|
|
88
|
+
*/
|
|
89
|
+
static getRecentErrors(count?: number): ShogunError[];
|
|
90
|
+
/**
|
|
91
|
+
* Adds a listener for errors
|
|
92
|
+
* @param listener - Function that will be called when an error occurs
|
|
93
|
+
*/
|
|
94
|
+
static addListener(listener: (error: ShogunError) => void): void;
|
|
95
|
+
/**
|
|
96
|
+
* Removes an error listener
|
|
97
|
+
* @param listener - Function to remove
|
|
98
|
+
*/
|
|
99
|
+
static removeListener(listener: (error: ShogunError) => void): void;
|
|
100
|
+
/**
|
|
101
|
+
* Notifies all listeners of an error
|
|
102
|
+
* @param error - Error to notify
|
|
103
|
+
*/
|
|
104
|
+
private static notifyListeners;
|
|
105
|
+
/**
|
|
106
|
+
* Helper function to format error messages from native errors
|
|
107
|
+
* @param error - Error to format
|
|
108
|
+
* @returns Formatted error message
|
|
109
|
+
*/
|
|
110
|
+
static formatError(error: Error | unknown): string;
|
|
111
|
+
/**
|
|
112
|
+
* Error handling with retry logic
|
|
113
|
+
*/
|
|
114
|
+
static withRetry<T>(fn: () => Promise<T>, errorType: ErrorType, errorCode: string, maxRetries?: number, retryDelay?: number): Promise<T>;
|
|
115
|
+
/**
|
|
116
|
+
* Clear all stored errors
|
|
117
|
+
*/
|
|
118
|
+
static clearErrors(): void;
|
|
119
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type for any event data
|
|
3
|
+
*/
|
|
4
|
+
export type EventData = Record<string, unknown>;
|
|
5
|
+
/**
|
|
6
|
+
* Generic event listener type
|
|
7
|
+
*/
|
|
8
|
+
export type Listener<T = unknown> = (data: T) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Event type che può essere string o symbol per compatibilità con Node.js EventEmitter
|
|
11
|
+
*/
|
|
12
|
+
export type EventType = string | symbol;
|
|
13
|
+
/**
|
|
14
|
+
* Simple event emitter implementation with generic event types
|
|
15
|
+
*/
|
|
16
|
+
export declare class EventEmitter<Events extends Record<string, unknown> = Record<string, unknown>> {
|
|
17
|
+
private events;
|
|
18
|
+
constructor();
|
|
19
|
+
/**
|
|
20
|
+
* Registers an event listener
|
|
21
|
+
*/
|
|
22
|
+
on(event: EventType, listener: (data: unknown) => void): void;
|
|
23
|
+
/**
|
|
24
|
+
* Emits an event with arguments
|
|
25
|
+
*/
|
|
26
|
+
emit(event: EventType, data?: unknown): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Removes an event listener
|
|
29
|
+
*/
|
|
30
|
+
off(event: EventType, listener: (data: unknown) => void): void;
|
|
31
|
+
/**
|
|
32
|
+
* Registers a one-time event listener
|
|
33
|
+
*/
|
|
34
|
+
once(event: EventType, listener: (data: unknown) => void): void;
|
|
35
|
+
/**
|
|
36
|
+
* Removes all listeners for an event or all events
|
|
37
|
+
*/
|
|
38
|
+
removeAllListeners(event?: EventType): void;
|
|
39
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { OAuthProvider } from "../plugins/oauth/types";
|
|
2
|
+
/**
|
|
3
|
+
* Valida uno username secondo le regole comuni
|
|
4
|
+
*/
|
|
5
|
+
export declare function validateUsername(username: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Valida una email
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateEmail(email: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Valida un provider OAuth supportato
|
|
12
|
+
*/
|
|
13
|
+
export declare function validateProvider(provider: string): provider is OAuthProvider;
|
|
14
|
+
/**
|
|
15
|
+
* Genera uno username uniforme a partire da provider e userInfo
|
|
16
|
+
* Esempio: google_utente, github_12345, nostr_pubkey, web3_0xabc...
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateUsernameFromIdentity(provider: string, userInfo: {
|
|
19
|
+
id?: string;
|
|
20
|
+
email?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
}): string;
|
|
23
|
+
/**
|
|
24
|
+
* Genera una password deterministica sicura a partire da un salt
|
|
25
|
+
* Usare per OAuth, Web3, Nostr, ecc.
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateDeterministicPassword(salt: string): string;
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types of errors that can occur in the application
|
|
3
|
+
*/
|
|
4
|
+
export var ErrorType;
|
|
5
|
+
(function (ErrorType) {
|
|
6
|
+
ErrorType["AUTHENTICATION"] = "AuthenticationError";
|
|
7
|
+
ErrorType["AUTHORIZATION"] = "AuthorizationError";
|
|
8
|
+
ErrorType["VALIDATION"] = "ValidationError";
|
|
9
|
+
ErrorType["NETWORK"] = "NetworkError";
|
|
10
|
+
ErrorType["DATABASE"] = "DatabaseError";
|
|
11
|
+
ErrorType["WALLET"] = "WalletError";
|
|
12
|
+
ErrorType["STORAGE"] = "StorageError";
|
|
13
|
+
ErrorType["ENCRYPTION"] = "EncryptionError";
|
|
14
|
+
ErrorType["SIGNATURE"] = "SignatureError";
|
|
15
|
+
ErrorType["ENVIRONMENT"] = "EnvironmentError";
|
|
16
|
+
ErrorType["SECURITY"] = "SecurityError";
|
|
17
|
+
ErrorType["GUN"] = "GunError";
|
|
18
|
+
ErrorType["STEALTH"] = "StealthError";
|
|
19
|
+
ErrorType["WEBAUTHN"] = "WebAuthnError";
|
|
20
|
+
ErrorType["PLUGIN"] = "PluginError";
|
|
21
|
+
ErrorType["UNKNOWN"] = "UnknownError";
|
|
22
|
+
ErrorType["CONNECTOR"] = "ConnectorError";
|
|
23
|
+
ErrorType["GENERAL"] = "GeneralError";
|
|
24
|
+
ErrorType["CONTRACT"] = "ContractError";
|
|
25
|
+
ErrorType["BIP32"] = "BIP32Error";
|
|
26
|
+
ErrorType["ETHEREUM"] = "EthereumError";
|
|
27
|
+
ErrorType["BITCOIN"] = "BitcoinError";
|
|
28
|
+
})(ErrorType || (ErrorType = {}));
|
|
29
|
+
/**
|
|
30
|
+
* Wrapper to standardize errors
|
|
31
|
+
* @param type - Error type
|
|
32
|
+
* @param code - Error code
|
|
33
|
+
* @param message - Error message
|
|
34
|
+
* @param originalError - Original error
|
|
35
|
+
* @returns A structured error object
|
|
36
|
+
*/
|
|
37
|
+
export function createError(type, code, message, originalError) {
|
|
38
|
+
return {
|
|
39
|
+
type,
|
|
40
|
+
code,
|
|
41
|
+
message,
|
|
42
|
+
originalError,
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Centralized error handler
|
|
48
|
+
*/
|
|
49
|
+
export class ErrorHandler {
|
|
50
|
+
static errors = [];
|
|
51
|
+
static maxErrors = 100;
|
|
52
|
+
static listeners = [];
|
|
53
|
+
static externalLogger = null;
|
|
54
|
+
/**
|
|
55
|
+
* Set an external logging service for production error monitoring
|
|
56
|
+
* @param logger - External logger function to send errors to a monitoring service
|
|
57
|
+
*/
|
|
58
|
+
static setExternalLogger(logger) {
|
|
59
|
+
this.externalLogger = logger;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Handles an error by logging it and notifying listeners
|
|
63
|
+
* @param error - The error to handle
|
|
64
|
+
*/
|
|
65
|
+
static handleError(error) {
|
|
66
|
+
// Log essential errors only
|
|
67
|
+
if (error.type === ErrorType.AUTHENTICATION ||
|
|
68
|
+
error.type === ErrorType.AUTHORIZATION ||
|
|
69
|
+
error.type === ErrorType.SECURITY) {
|
|
70
|
+
// Ensure console.error is available and safe to use
|
|
71
|
+
if (typeof console !== "undefined" && console.error) {
|
|
72
|
+
console.error(`[${error.type}] ${error.code}: ${error.message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Store the error in memory
|
|
76
|
+
this.errors.push(error);
|
|
77
|
+
// Keep only the last maxErrors
|
|
78
|
+
if (this.errors.length > this.maxErrors) {
|
|
79
|
+
this.errors = this.errors.slice(-this.maxErrors);
|
|
80
|
+
}
|
|
81
|
+
// Send to external logger if set (for production monitoring)
|
|
82
|
+
if (this.externalLogger) {
|
|
83
|
+
try {
|
|
84
|
+
this.externalLogger(error);
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
// Fallback logging for external logger errors
|
|
88
|
+
console.error("Failed to send error to external logger:", e);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Notify all listeners
|
|
92
|
+
this.listeners.forEach((listener) => {
|
|
93
|
+
try {
|
|
94
|
+
listener(error);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
// Silent error to prevent infinite loops
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Handles a raw error by converting it to ShogunError
|
|
103
|
+
* @param type - Error type
|
|
104
|
+
* @param code - Error code
|
|
105
|
+
* @param message - Error message
|
|
106
|
+
* @param originalError - Original error
|
|
107
|
+
* @param logLevel - Log level for the error
|
|
108
|
+
*/
|
|
109
|
+
static handle(type, code, message, originalError, logLevel = "error") {
|
|
110
|
+
// Create a formatted error message (tests expect the plain message)
|
|
111
|
+
const finalMessage = message;
|
|
112
|
+
// Log the error
|
|
113
|
+
switch (logLevel) {
|
|
114
|
+
case "debug":
|
|
115
|
+
console.log(`[${type}] ${code}: ${finalMessage}`);
|
|
116
|
+
break;
|
|
117
|
+
case "warn":
|
|
118
|
+
console.log(`[${type}] ${code}: ${finalMessage}`);
|
|
119
|
+
break;
|
|
120
|
+
case "info":
|
|
121
|
+
console.log(`[${type}] ${code}: ${finalMessage}`);
|
|
122
|
+
break;
|
|
123
|
+
case "error":
|
|
124
|
+
default:
|
|
125
|
+
console.log(`[${type}] ${code}: ${finalMessage}`);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
const error = createError(type, code, finalMessage, originalError);
|
|
129
|
+
this.handleError(error);
|
|
130
|
+
return error;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Handles errors and throws them as standardized ShogunError objects
|
|
134
|
+
* @param type - Error type
|
|
135
|
+
* @param code - Error code
|
|
136
|
+
* @param message - Error message
|
|
137
|
+
* @param originalError - Original error
|
|
138
|
+
* @throws ShogunError
|
|
139
|
+
*/
|
|
140
|
+
static handleAndThrow(type, code, message, originalError) {
|
|
141
|
+
const error = this.handle(type, code, message, originalError);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Retrieves the last N errors
|
|
146
|
+
* @param count - Number of errors to retrieve
|
|
147
|
+
* @returns List of most recent errors
|
|
148
|
+
*/
|
|
149
|
+
static getRecentErrors(count = 10) {
|
|
150
|
+
return this.errors.slice(-Math.min(count, this.errors.length));
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Adds a listener for errors
|
|
154
|
+
* @param listener - Function that will be called when an error occurs
|
|
155
|
+
*/
|
|
156
|
+
static addListener(listener) {
|
|
157
|
+
this.listeners.push(listener);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Removes an error listener
|
|
161
|
+
* @param listener - Function to remove
|
|
162
|
+
*/
|
|
163
|
+
static removeListener(listener) {
|
|
164
|
+
const index = this.listeners.indexOf(listener);
|
|
165
|
+
if (index !== -1) {
|
|
166
|
+
this.listeners.splice(index, 1);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Notifies all listeners of an error
|
|
171
|
+
* @param error - Error to notify
|
|
172
|
+
*/
|
|
173
|
+
static notifyListeners(error) {
|
|
174
|
+
for (const listener of this.listeners) {
|
|
175
|
+
try {
|
|
176
|
+
listener(error);
|
|
177
|
+
}
|
|
178
|
+
catch (listenerError) {
|
|
179
|
+
console.error(`Error in error listener: ${listenerError}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Helper function to format error messages from native errors
|
|
185
|
+
* @param error - Error to format
|
|
186
|
+
* @returns Formatted error message
|
|
187
|
+
*/
|
|
188
|
+
static formatError(error) {
|
|
189
|
+
if (!error) {
|
|
190
|
+
return "Unknown error";
|
|
191
|
+
}
|
|
192
|
+
if (error instanceof Error) {
|
|
193
|
+
return `${error.name}: ${error.message}`;
|
|
194
|
+
}
|
|
195
|
+
if (typeof error === "string") {
|
|
196
|
+
return error;
|
|
197
|
+
}
|
|
198
|
+
if (typeof error === "object") {
|
|
199
|
+
try {
|
|
200
|
+
return JSON.stringify(error);
|
|
201
|
+
}
|
|
202
|
+
catch (e) {
|
|
203
|
+
return `Object: ${Object.prototype.toString.call(error)}`;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return String(error);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Error handling with retry logic
|
|
210
|
+
*/
|
|
211
|
+
static async withRetry(fn, errorType, errorCode, maxRetries = 3, retryDelay = 1000) {
|
|
212
|
+
let lastError;
|
|
213
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
214
|
+
try {
|
|
215
|
+
return await fn();
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
lastError = error;
|
|
219
|
+
const delay = retryDelay * attempt;
|
|
220
|
+
if (attempt < maxRetries) {
|
|
221
|
+
console.log(`Retrying operation after ${delay}ms (attempt ${attempt}/${maxRetries})`);
|
|
222
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// If we got here, all retries failed.
|
|
227
|
+
// Log the failure and rethrow the last error message for test expectations compatibility.
|
|
228
|
+
this.handle(errorType, errorCode, `Operation failed after ${maxRetries} attempts`, lastError);
|
|
229
|
+
// Prefer the original error message if available
|
|
230
|
+
if (lastError instanceof Error) {
|
|
231
|
+
throw new Error(lastError.message);
|
|
232
|
+
}
|
|
233
|
+
throw new Error(this.formatError(lastError));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Clear all stored errors
|
|
237
|
+
*/
|
|
238
|
+
static clearErrors() {
|
|
239
|
+
this.errors = [];
|
|
240
|
+
}
|
|
241
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple event emitter implementation with generic event types
|
|
3
|
+
*/
|
|
4
|
+
export class EventEmitter {
|
|
5
|
+
events;
|
|
6
|
+
constructor() {
|
|
7
|
+
this.events = new Map();
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Registers an event listener
|
|
11
|
+
*/
|
|
12
|
+
on(event, listener) {
|
|
13
|
+
if (!this.events.has(event)) {
|
|
14
|
+
this.events.set(event, []);
|
|
15
|
+
}
|
|
16
|
+
this.events.get(event)?.push(listener);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Emits an event with arguments
|
|
20
|
+
*/
|
|
21
|
+
emit(event, data) {
|
|
22
|
+
if (!this.events.has(event))
|
|
23
|
+
return false;
|
|
24
|
+
const listeners = this.events.get(event) || [];
|
|
25
|
+
listeners.forEach((listener) => {
|
|
26
|
+
try {
|
|
27
|
+
listener(data);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
// Ensure error is properly formatted for console.error and pass Error instance
|
|
31
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
32
|
+
console.error(`Error in event listener for ${String(event)}:`, err);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Removes an event listener
|
|
39
|
+
*/
|
|
40
|
+
off(event, listener) {
|
|
41
|
+
if (!this.events.has(event))
|
|
42
|
+
return;
|
|
43
|
+
const listeners = this.events.get(event) || [];
|
|
44
|
+
const index = listeners.indexOf(listener);
|
|
45
|
+
if (index !== -1) {
|
|
46
|
+
listeners.splice(index, 1);
|
|
47
|
+
if (listeners.length === 0) {
|
|
48
|
+
this.events.delete(event);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.events.set(event, listeners);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Registers a one-time event listener
|
|
57
|
+
*/
|
|
58
|
+
once(event, listener) {
|
|
59
|
+
const onceWrapper = (data) => {
|
|
60
|
+
listener(data);
|
|
61
|
+
this.off(event, onceWrapper);
|
|
62
|
+
};
|
|
63
|
+
this.on(event, onceWrapper);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Removes all listeners for an event or all events
|
|
67
|
+
*/
|
|
68
|
+
removeAllListeners(event) {
|
|
69
|
+
if (event) {
|
|
70
|
+
this.events.delete(event);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this.events.clear();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Utility di validazione e generazione credenziali per ShogunCore
|
|
2
|
+
// --- VALIDAZIONE ---
|
|
3
|
+
/**
|
|
4
|
+
* Valida uno username secondo le regole comuni
|
|
5
|
+
*/
|
|
6
|
+
export function validateUsername(username) {
|
|
7
|
+
if (!username || typeof username !== "string")
|
|
8
|
+
return false;
|
|
9
|
+
if (username.length < 3 || username.length > 64)
|
|
10
|
+
return false;
|
|
11
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(username))
|
|
12
|
+
return false;
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Valida una email
|
|
17
|
+
*/
|
|
18
|
+
export function validateEmail(email) {
|
|
19
|
+
if (!email || typeof email !== "string")
|
|
20
|
+
return false;
|
|
21
|
+
// Regex semplice per email
|
|
22
|
+
return /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Valida un provider OAuth supportato
|
|
26
|
+
*/
|
|
27
|
+
export function validateProvider(provider) {
|
|
28
|
+
return ["google", "github", "discord", "twitter", "custom"].includes(provider);
|
|
29
|
+
}
|
|
30
|
+
// --- GENERAZIONE USERNAME ---
|
|
31
|
+
/**
|
|
32
|
+
* Genera uno username uniforme a partire da provider e userInfo
|
|
33
|
+
* Esempio: google_utente, github_12345, nostr_pubkey, web3_0xabc...
|
|
34
|
+
*/
|
|
35
|
+
export function generateUsernameFromIdentity(provider, userInfo) {
|
|
36
|
+
if (provider === "web3" && userInfo.id) {
|
|
37
|
+
return `web3_${userInfo.id.toLowerCase()}`;
|
|
38
|
+
}
|
|
39
|
+
if (provider === "nostr" && userInfo.id) {
|
|
40
|
+
return `nostr_${userInfo.id}`;
|
|
41
|
+
}
|
|
42
|
+
if (provider === "webauthn" && userInfo.id) {
|
|
43
|
+
return `webauthn_${userInfo.id}`;
|
|
44
|
+
}
|
|
45
|
+
if (userInfo.email && validateEmail(userInfo.email)) {
|
|
46
|
+
return `${provider}_${userInfo.email.split("@")[0]}`;
|
|
47
|
+
}
|
|
48
|
+
if (userInfo.name) {
|
|
49
|
+
return `${provider}_${userInfo.name.replace(/\s+/g, "_")}`;
|
|
50
|
+
}
|
|
51
|
+
if (userInfo.id) {
|
|
52
|
+
return `${provider}_${userInfo.id}`;
|
|
53
|
+
}
|
|
54
|
+
return `${provider}_user`;
|
|
55
|
+
}
|
|
56
|
+
// --- GENERAZIONE PASSWORD DETERMINISTICA ---
|
|
57
|
+
import { ethers } from "ethers";
|
|
58
|
+
/**
|
|
59
|
+
* Genera una password deterministica sicura a partire da un salt
|
|
60
|
+
* Usare per OAuth, Web3, Nostr, ecc.
|
|
61
|
+
*/
|
|
62
|
+
export function generateDeterministicPassword(salt) {
|
|
63
|
+
try {
|
|
64
|
+
// Restituisce una stringa hex di 32 caratteri
|
|
65
|
+
return ethers.keccak256(ethers.toUtf8Bytes(salt)).slice(2, 34);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// Fallback in case ethers is not available
|
|
69
|
+
console.warn("ethers not available, using fallback password generation");
|
|
70
|
+
return Buffer.from(salt).toString("hex").slice(0, 32);
|
|
71
|
+
}
|
|
72
|
+
}
|