UNPKG

genshin-manager

Version:

<div align="center"> <p> <a href="https://www.npmjs.com/package/genshin-manager"><img src="https://img.shields.io/npm/v/genshin-manager.svg?maxAge=3600" alt="npm version" /></a> <a href="https://www.npmjs.com/package/genshin-manager"><img src="https:

1,390 lines (1,352 loc) 375 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/errors/base/ErrorCodes.ts var GenshinManagerErrorCode, errorCategories, retryClassifications; var init_ErrorCodes = __esm({ "src/errors/base/ErrorCodes.ts"() { "use strict"; GenshinManagerErrorCode = /* @__PURE__ */ ((GenshinManagerErrorCode2) => { GenshinManagerErrorCode2["GM_VALIDATION_RANGE"] = "GM1001"; GenshinManagerErrorCode2["GM_VALIDATION_TYPE"] = "GM1002"; GenshinManagerErrorCode2["GM_VALIDATION_REQUIRED"] = "GM1003"; GenshinManagerErrorCode2["GM_VALIDATION_FORMAT"] = "GM1004"; GenshinManagerErrorCode2["GM_VALIDATION_ENUM"] = "GM1005"; GenshinManagerErrorCode2["GM_ASSETS_NOT_FOUND"] = "GM2001"; GenshinManagerErrorCode2["GM_ASSETS_CORRUPTED"] = "GM2002"; GenshinManagerErrorCode2["GM_ASSETS_DOWNLOAD_FAILED"] = "GM2003"; GenshinManagerErrorCode2["GM_ASSETS_AUDIO_NOT_FOUND"] = "GM2004"; GenshinManagerErrorCode2["GM_ASSETS_IMAGE_NOT_FOUND"] = "GM2005"; GenshinManagerErrorCode2["GM_DECODE_MASTER_NOT_FOUND"] = "GM3001"; GenshinManagerErrorCode2["GM_DECODE_PATTERN_MISMATCH"] = "GM3002"; GenshinManagerErrorCode2["GM_DECODE_LOW_CONFIDENCE"] = "GM3003"; GenshinManagerErrorCode2["GM_DECODE_KEY_MATCHING_FAILED"] = "GM3004"; GenshinManagerErrorCode2["GM_NETWORK_TIMEOUT"] = "GM4001"; GenshinManagerErrorCode2["GM_NETWORK_UNAVAILABLE"] = "GM4002"; GenshinManagerErrorCode2["GM_NETWORK_ENKA_ERROR"] = "GM4003"; GenshinManagerErrorCode2["GM_NETWORK_ENKA_STATUS_ERROR"] = "GM4004"; GenshinManagerErrorCode2["GM_CONFIG_INVALID"] = "GM5001"; GenshinManagerErrorCode2["GM_CONFIG_MISSING"] = "GM5002"; GenshinManagerErrorCode2["GM_CONTENT_ANN_NOT_FOUND"] = "GM6001"; GenshinManagerErrorCode2["GM_CONTENT_BODY_NOT_FOUND"] = "GM6002"; GenshinManagerErrorCode2["GM_CONTENT_TEXT_MAP_FORMAT"] = "GM6003"; GenshinManagerErrorCode2["GM_GENERAL_UNKNOWN"] = "GM9001"; return GenshinManagerErrorCode2; })(GenshinManagerErrorCode || {}); errorCategories = { ["GM1001" /* GM_VALIDATION_RANGE */]: "VALIDATION", ["GM1002" /* GM_VALIDATION_TYPE */]: "VALIDATION", ["GM1003" /* GM_VALIDATION_REQUIRED */]: "VALIDATION", ["GM1004" /* GM_VALIDATION_FORMAT */]: "VALIDATION", ["GM1005" /* GM_VALIDATION_ENUM */]: "VALIDATION", ["GM2001" /* GM_ASSETS_NOT_FOUND */]: "ASSETS", ["GM2002" /* GM_ASSETS_CORRUPTED */]: "ASSETS", ["GM2003" /* GM_ASSETS_DOWNLOAD_FAILED */]: "ASSETS", ["GM2004" /* GM_ASSETS_AUDIO_NOT_FOUND */]: "ASSETS", ["GM2005" /* GM_ASSETS_IMAGE_NOT_FOUND */]: "ASSETS", ["GM3001" /* GM_DECODE_MASTER_NOT_FOUND */]: "DECODING", ["GM3002" /* GM_DECODE_PATTERN_MISMATCH */]: "DECODING", ["GM3003" /* GM_DECODE_LOW_CONFIDENCE */]: "DECODING", ["GM3004" /* GM_DECODE_KEY_MATCHING_FAILED */]: "DECODING", ["GM4001" /* GM_NETWORK_TIMEOUT */]: "NETWORK", ["GM4002" /* GM_NETWORK_UNAVAILABLE */]: "NETWORK", ["GM4003" /* GM_NETWORK_ENKA_ERROR */]: "NETWORK", ["GM4004" /* GM_NETWORK_ENKA_STATUS_ERROR */]: "NETWORK", ["GM5001" /* GM_CONFIG_INVALID */]: "CONFIG", ["GM5002" /* GM_CONFIG_MISSING */]: "CONFIG", ["GM6001" /* GM_CONTENT_ANN_NOT_FOUND */]: "CONTENT", ["GM6002" /* GM_CONTENT_BODY_NOT_FOUND */]: "CONTENT", ["GM6003" /* GM_CONTENT_TEXT_MAP_FORMAT */]: "CONTENT", ["GM9001" /* GM_GENERAL_UNKNOWN */]: "GENERAL" }; retryClassifications = { ["GM1001" /* GM_VALIDATION_RANGE */]: { isRetryable: false }, ["GM1002" /* GM_VALIDATION_TYPE */]: { isRetryable: false }, ["GM1003" /* GM_VALIDATION_REQUIRED */]: { isRetryable: false }, ["GM1004" /* GM_VALIDATION_FORMAT */]: { isRetryable: false }, ["GM1005" /* GM_VALIDATION_ENUM */]: { isRetryable: false }, ["GM2001" /* GM_ASSETS_NOT_FOUND */]: { isRetryable: true, maxRetries: 3, retryDelay: 1e3, backoffMultiplier: 2 }, ["GM2002" /* GM_ASSETS_CORRUPTED */]: { isRetryable: false }, ["GM2003" /* GM_ASSETS_DOWNLOAD_FAILED */]: { isRetryable: true, maxRetries: 3, retryDelay: 2e3, backoffMultiplier: 2 }, ["GM2004" /* GM_ASSETS_AUDIO_NOT_FOUND */]: { isRetryable: true, maxRetries: 2, retryDelay: 1e3 }, ["GM2005" /* GM_ASSETS_IMAGE_NOT_FOUND */]: { isRetryable: true, maxRetries: 2, retryDelay: 1e3 }, ["GM3001" /* GM_DECODE_MASTER_NOT_FOUND */]: { isRetryable: false }, ["GM3002" /* GM_DECODE_PATTERN_MISMATCH */]: { isRetryable: false }, ["GM3003" /* GM_DECODE_LOW_CONFIDENCE */]: { isRetryable: false }, ["GM3004" /* GM_DECODE_KEY_MATCHING_FAILED */]: { isRetryable: false }, ["GM4001" /* GM_NETWORK_TIMEOUT */]: { isRetryable: true, maxRetries: 3, retryDelay: 1e3, backoffMultiplier: 2 }, ["GM4002" /* GM_NETWORK_UNAVAILABLE */]: { isRetryable: true, maxRetries: 5, retryDelay: 5e3, backoffMultiplier: 1.5 }, ["GM4003" /* GM_NETWORK_ENKA_ERROR */]: { isRetryable: true, maxRetries: 3, retryDelay: 2e3 }, ["GM4004" /* GM_NETWORK_ENKA_STATUS_ERROR */]: { isRetryable: true, maxRetries: 2, retryDelay: 3e3 }, ["GM5001" /* GM_CONFIG_INVALID */]: { isRetryable: false }, ["GM5002" /* GM_CONFIG_MISSING */]: { isRetryable: false }, ["GM6001" /* GM_CONTENT_ANN_NOT_FOUND */]: { isRetryable: true, maxRetries: 2, retryDelay: 1e3 }, ["GM6002" /* GM_CONTENT_BODY_NOT_FOUND */]: { isRetryable: true, maxRetries: 2, retryDelay: 1e3 }, ["GM6003" /* GM_CONTENT_TEXT_MAP_FORMAT */]: { isRetryable: false }, ["GM9001" /* GM_GENERAL_UNKNOWN */]: { isRetryable: true, maxRetries: 1, retryDelay: 2e3 } }; } }); // src/errors/general/GeneralError.ts var GeneralError_exports = {}; __export(GeneralError_exports, { GeneralError: () => GeneralError }); var GeneralError; var init_GeneralError = __esm({ "src/errors/general/GeneralError.ts"() { "use strict"; init_ErrorCodes(); init_GenshinManagerError(); GeneralError = class extends GenshinManagerError { constructor() { super(...arguments); this.errorCode = "GM9001" /* GM_GENERAL_UNKNOWN */; } }; } }); // src/errors/base/GenshinManagerError.ts var GenshinManagerError; var init_GenshinManagerError = __esm({ "src/errors/base/GenshinManagerError.ts"() { "use strict"; init_ErrorCodes(); GenshinManagerError = class _GenshinManagerError extends Error { /** * Constructor for GenshinManagerError * @param message - Human-readable error message * @param context - Rich error context for debugging * @param cause - Original error that caused this error */ constructor(message, context, cause) { super(message); /** * Whether this error originated from genshin-manager library */ this.isGenshinManagerError = true; this.name = this.constructor.name; this.context = context; this.timestamp = /* @__PURE__ */ new Date(); this.cause = cause; this.initializeConfig(); Object.setPrototypeOf(this, new.target.prototype); if (typeof Error.captureStackTrace === "function") Error.captureStackTrace(this, this.constructor); } /** * Static helper to check if an error is a GenshinManagerError */ static isGenshinManagerError(error2) { return error2 instanceof Error && "isGenshinManagerError" in error2 && error2.isGenshinManagerError === true; } /** * Static helper to create error from unknown type */ static async fromUnknown(error2, fallbackMessage = "Unknown error occurred", context) { if (_GenshinManagerError.isGenshinManagerError(error2)) return error2; const { GeneralError: generalError } = await Promise.resolve().then(() => (init_GeneralError(), GeneralError_exports)); if (error2 instanceof Error) return new generalError(error2.message, context, error2); return new generalError( typeof error2 === "string" ? error2 : fallbackMessage, context ); } /** * Generate detailed error message with context information */ getDetailedMessage() { let detailedMessage = `[${this.errorCode}] ${this.message}`; if (this.context) { const contextInfo = []; if (this.context.filePath) contextInfo.push(`File: ${this.context.filePath}`); if (this.context.url) contextInfo.push(`URL: ${this.context.url}`); if (this.context.operation) contextInfo.push(`Operation: ${this.context.operation}`); if (this.context.propertyKey) contextInfo.push(`Property: ${this.context.propertyKey}`); if (this.context.expectedValue !== void 0) { contextInfo.push( `Expected: ${JSON.stringify(this.context.expectedValue)}` ); } if (this.context.actualValue !== void 0) contextInfo.push(`Actual: ${JSON.stringify(this.context.actualValue)}`); if (contextInfo.length > 0) detailedMessage += ` | Context: ${contextInfo.join(", ")}`; } return detailedMessage; } /** * Check if this error is retryable */ isRetryable() { return this.retryConfig.isRetryable; } /** * Get retry configuration */ getRetryConfig() { return this.retryConfig; } /** * Serialize error for logging or transport */ toJSON() { return { name: this.name, message: this.message, errorCode: this.errorCode, category: this.category, timestamp: this.timestamp.toISOString(), context: this.context, retryConfig: this.retryConfig, stack: this.stack, isGenshinManagerError: this.isGenshinManagerError }; } /** * Create a copy of this error with additional context */ withContext(additionalContext) { const mergedContext = { ...this.context, ...additionalContext }; const errorClass = this.constructor; return new errorClass(this.message, mergedContext, this.cause); } /** * Initialize category and retry configuration after errorCode is available */ initializeConfig() { const category = errorCategories[this.errorCode]; const retryConfig = retryClassifications[this.errorCode]; Object.assign(this, { category, retryConfig }); } }; } }); // src/index.ts var index_exports = {}; __export(index_exports, { AnnContentNotFoundError: () => AnnContentNotFoundError, Artifact: () => Artifact, ArtifactType: () => EquipType, AssetCorruptedError: () => AssetCorruptedError, AssetDownloadFailedError: () => AssetDownloadFailedError, AssetError: () => AssetError, AssetErrorFactory: () => AssetErrorFactory, AssetNotFoundError: () => AssetNotFoundError, AudioAssets: () => AudioAssets, AudioNotFoundError: () => AudioNotFoundError, BodyNotFoundError: () => BodyNotFoundError, BodyType: () => BodyType, Character: () => Character, CharacterAscension: () => CharacterAscension, CharacterBaseStats: () => CharacterBaseStats, CharacterConstellation: () => CharacterConstellation, CharacterCostume: () => CharacterCostume, CharacterDetail: () => CharacterDetail, CharacterInfo: () => CharacterInfo, CharacterInherentSkill: () => CharacterInherentSkill, CharacterPreview: () => CharacterPreview, CharacterProfile: () => CharacterProfile, CharacterSkill: () => CharacterSkill, CharacterSkillAscension: () => CharacterSkillAscension, CharacterStatusManager: () => CharacterStatusManager, CharacterStory: () => CharacterStory, CharacterVoice: () => CharacterVoice, Client: () => Client, ConfigInvalidError: () => ConfigInvalidError, ConfigMissingError: () => ConfigMissingError, DailyFarming: () => DailyFarming, EnkaAccount: () => EnkaAccount, EnkaBuild: () => EnkaBuild, EnkaManager: () => EnkaManager, EnkaManagerEvents: () => EnkaManagerEvents, EnkaNetworkError: () => EnkaNetworkError, EnkaNetworkStatusError: () => EnkaNetworkStatusError, EnumValidationError: () => EnumValidationError, ErrorContextFactory: () => ErrorContextFactory, FormatValidationError: () => FormatValidationError, GeneralError: () => GeneralError, GenshinAccount: () => GenshinAccount, GenshinManagerError: () => GenshinManagerError, GenshinManagerErrorCode: () => GenshinManagerErrorCode, ImageAssets: () => ImageAssets, ImageNotFoundError: () => ImageNotFoundError, ItemType: () => ItemType, KeyMatchingError: () => KeyMatchingError, LowConfidenceError: () => LowConfidenceError, MasterFileConfigurationError: () => MasterFileConfigurationError, Material: () => Material, MaterialType: () => MaterialType, Monster: () => Monster, NetworkError: () => NetworkError, NetworkTimeoutError: () => NetworkTimeoutError, NetworkUnavailableError: () => NetworkUnavailableError, Notice: () => Notice, NoticeLanguage: () => NoticeLanguage, NoticeManager: () => NoticeManager, NoticeManagerEvents: () => NoticeManagerEvents, PatternMismatchError: () => PatternMismatchError, PlayerDetail: () => PlayerDetail, ProfilePicture: () => ProfilePicture, QualityType: () => QualityType, RangeValidationError: () => RangeValidationError, RequiredFieldError: () => RequiredFieldError, StatProperty: () => StatProperty, TextMapFormatError: () => TextMapFormatError, TimeZonesPerRegion: () => TimeZonesPerRegion, ValidationError: () => ValidationError, ValidationHelper: () => ValidationHelper, Weapon: () => Weapon, WeaponAscension: () => WeaponAscension, WeaponInfo: () => WeaponInfo, WeaponRefinement: () => WeaponRefinement, WeaponType: () => WeaponType, ascensionLevelSchema: () => ascensionLevelSchema, assetIdSchema: () => assetIdSchema, assetProcessingConfigSchema: () => assetProcessingConfigSchema, cacheConfigSchema: () => cacheConfigSchema, characterLevelSchema: () => characterLevelSchema, characterRaritySchema: () => characterRaritySchema, configSchema: () => configSchema, constellationLevelSchema: () => constellationLevelSchema, convertToUTC: () => convertToUTC, createArtifactLevelSchema: () => createArtifactLevelSchema, createDynamicWeaponLevelSchema: () => createDynamicWeaponLevelSchema, createPromoteLevelSchema: () => createPromoteLevelSchema, createRangeSchema: () => createRangeSchema, createUpdateIntervalSchema: () => createUpdateIntervalSchema, dayOfWeekSchema: () => dayOfWeekSchema, elementSchema: () => elementSchema, errorCategories: () => errorCategories, filePathSchema: () => filePathSchema, fixedRefinementSchema: () => fixedRefinementSchema, languageCodeSchema: () => languageCodeSchema, loggingConfigSchema: () => loggingConfigSchema, monsterLevelSchema: () => monsterLevelSchema, networkConfigSchema: () => networkConfigSchema, playerCountSchema: () => playerCountSchema, refinementLevelSchema: () => refinementLevelSchema, retryClassifications: () => retryClassifications, schemas: () => schemas, skillLevelSchema: () => skillLevelSchema, travelerIdSchema: () => travelerIdSchema, uidSchema: () => uidSchema, urlSchema: () => urlSchema, weaponLevelSchema: () => weaponLevelSchema, weaponRaritySchema: () => weaponRaritySchema, weaponTypeSchema: () => weaponTypeSchema }); module.exports = __toCommonJS(index_exports); // src/client/AssetCacheManager.ts var cliProgress = __toESM(require("cli-progress")); var import_events2 = __toESM(require("events")); var import_fs3 = __toESM(require("fs")); var path4 = __toESM(require("path")); var import_promises = require("stream/promises"); // src/errors/index.ts init_ErrorCodes(); // src/errors/base/ErrorContext.ts var ErrorContextFactory = { /** * Create file-related error context */ createFileContext(filePath, operation) { return { filePath, operation, timestamp: /* @__PURE__ */ new Date() }; }, /** * Create network-related error context */ createNetworkContext(url, requestMethod = "GET", statusCode, responseHeaders) { return { url, requestMethod, statusCode, responseHeaders, timestamp: /* @__PURE__ */ new Date() }; }, /** * Create validation-related error context */ createValidationContext(propertyKey, expectedValue, actualValue, validationPath) { return { propertyKey, expectedValue, actualValue, validationPath, timestamp: /* @__PURE__ */ new Date() }; }, /** * Create decoding-related error context */ createDecodingContext(sourceData, targetData, operation) { return { sourceData, targetData, operation, timestamp: /* @__PURE__ */ new Date() }; }, /** * Create asset-related error context */ createAssetContext(filePath, imageFile, audioFile, operation) { return { filePath, imageFile, audioFile, operation, timestamp: /* @__PURE__ */ new Date() }; }, /** * Create configuration-related error context */ createConfigContext(propertyKey, jsonFile, expectedValue, actualValue) { return { propertyKey, jsonFile, expectedValue, actualValue, timestamp: /* @__PURE__ */ new Date() }; }, /** * Merge multiple error contexts */ merge(...contexts) { const result = { timestamp: /* @__PURE__ */ new Date() }; for (const context of contexts) if (context) Object.assign(result, context); return result; } }; // src/errors/index.ts init_GenshinManagerError(); // src/errors/validation/EnumValidationError.ts init_ErrorCodes(); // src/errors/validation/ValidationError.ts init_ErrorCodes(); init_GenshinManagerError(); var ValidationError = class _ValidationError extends GenshinManagerError { /** * Constructor for ValidationError * @param message - Human-readable error message * @param context - Error context * @param zodIssues - Zod validation issues * @param cause - Original error */ constructor(message, context, zodIssues, cause) { super(message, context, cause); this.errorCode = "GM1002" /* GM_VALIDATION_TYPE */; this.zodIssues = zodIssues; } /** * Create ValidationError from Zod error */ static fromZodError(zodError, context) { const issues = zodError.issues; const firstIssue = issues[0]; const message = `Validation failed at ${firstIssue.path.join(".")}: ${firstIssue.message}`; const validationContext = ErrorContextFactory.createValidationContext( firstIssue.path.join(".") || "unknown", "valid format", "received" in firstIssue ? firstIssue.received : void 0 ); const mergedContext = ErrorContextFactory.merge(context, validationContext); return new _ValidationError(message, mergedContext, issues, zodError); } /** * Get detailed validation error information */ getValidationDetails() { if (!this.zodIssues) return []; return this.zodIssues.map((issue) => ({ path: issue.path.join(".") || "root", issue: issue.message, expected: "expected" in issue ? issue.expected : void 0, received: "received" in issue ? issue.received : void 0 })); } /** * Get formatted error message with all validation issues */ getFormattedMessage() { if (!this.zodIssues || this.zodIssues.length === 0) return this.message; const details = this.getValidationDetails(); if (details.length === 1) return this.message; const additionalIssues = details.slice(1).map((detail) => ` - ${detail.path}: ${detail.issue}`).join("\n"); return `${this.message} Additional issues: ${additionalIssues}`; } }; // src/errors/validation/EnumValidationError.ts var EnumValidationError = class extends ValidationError { /** * Constructor for EnumValidationError * @param value - The invalid value * @param allowedValues - Array of allowed values * @param propertyName - Name of the property being validated * @param context - Additional error context * @param cause - Original error */ constructor(value, allowedValues2, propertyName = "value", context, cause) { const allowedStr = allowedValues2.map(String).join(", "); const contextPrefix = (context == null ? void 0 : context.propertyKey) ? `[${context.propertyKey}] ` : ""; const message = `${contextPrefix}${propertyName} must be one of: ${allowedStr}, got ${String(value)}`; const enumContext = ErrorContextFactory.createValidationContext( propertyName, `one of: ${allowedStr}`, value ); const mergedContext = ErrorContextFactory.merge(context, enumContext); super(message, mergedContext, void 0, cause); this.errorCode = "GM1005" /* GM_VALIDATION_ENUM */; } }; // src/errors/validation/FormatValidationError.ts init_ErrorCodes(); var FormatValidationError = class extends ValidationError { /** * Constructor for FormatValidationError * @param value - The invalid value * @param expectedFormat - Description of expected format * @param propertyName - Name of the property being validated * @param context - Additional error context * @param cause - Original error */ constructor(value, expectedFormat, propertyName = "value", context, cause) { const message = `${propertyName} has invalid format: expected ${expectedFormat}, got ${String(value)}`; const formatContext = ErrorContextFactory.createValidationContext( propertyName, expectedFormat, value ); const mergedContext = ErrorContextFactory.merge(context, formatContext); super(message, mergedContext, void 0, cause); this.errorCode = "GM1004" /* GM_VALIDATION_FORMAT */; } }; // src/errors/validation/RangeValidationError.ts init_ErrorCodes(); var RangeValidationError = class extends ValidationError { /** * Constructor for RangeValidationError * @param value - The value that was out of range * @param min - Minimum allowed value * @param max - Maximum allowed value * @param propertyName - Name of the property being validated * @param context - Additional error context * @param cause - Original error */ constructor(value, min, max, propertyName = "value", context, cause) { const message = `${propertyName} must be between ${min.toString()} and ${max.toString()}, got ${value.toString()}`; const rangeContext = ErrorContextFactory.createValidationContext( propertyName, `${min.toString()}-${max.toString()}`, value ); const mergedContext = ErrorContextFactory.merge(context, rangeContext); super(message, mergedContext, void 0, cause); this.errorCode = "GM1001" /* GM_VALIDATION_RANGE */; } }; // src/errors/validation/RequiredFieldError.ts init_ErrorCodes(); var RequiredFieldError = class extends ValidationError { /** * Constructor for RequiredFieldError * @param fieldName - Name of the required field * @param context - Additional error context * @param cause - Original error */ constructor(fieldName, context, cause) { const message = `Required field '${fieldName}' is missing`; const fieldContext = ErrorContextFactory.createValidationContext( fieldName, "non-null value", void 0 ); const mergedContext = ErrorContextFactory.merge(context, fieldContext); super(message, mergedContext, void 0, cause); this.errorCode = "GM1003" /* GM_VALIDATION_REQUIRED */; } }; // src/errors/assets/AssetError.ts init_GenshinManagerError(); var AssetError = class extends GenshinManagerError { /** * Constructor for AssetError * @param message - Error message * @param assetPath - Asset file path or identifier * @param assetType - Type of asset * @param context - Additional error context * @param cause - Original error */ constructor(message, assetPath, assetType, context, cause) { const assetContext = ErrorContextFactory.createAssetContext( assetPath, assetType === "image" ? assetPath : void 0, assetType === "audio" ? assetPath : void 0, `load ${assetType}` ); const mergedContext = ErrorContextFactory.merge(context, assetContext); super(message, mergedContext, cause); this.assetPath = assetPath; this.assetType = assetType; } }; // src/errors/assets/AssetCorruptedError.ts init_ErrorCodes(); var AssetCorruptedError = class extends AssetError { /** * Constructor for AssetCorruptedError * @param assetPath - Asset file path or identifier * @param assetType - Type of asset * @param corruptionDetails - Details about the corruption * @param context - Additional error context * @param cause - Original error */ constructor(assetPath, assetType, corruptionDetails, context, cause) { const message = `${assetType.charAt(0).toUpperCase() + assetType.slice(1)} is corrupted: ${assetPath}${corruptionDetails ? ` (${corruptionDetails})` : ""}`; super(message, assetPath, assetType, context, cause); this.errorCode = "GM2002" /* GM_ASSETS_CORRUPTED */; this.corruptionDetails = corruptionDetails; } }; // src/errors/assets/AssetDownloadFailedError.ts init_ErrorCodes(); var AssetDownloadFailedError = class extends AssetError { /** * Constructor for AssetDownloadFailedError * @param assetPath - Asset file path or identifier * @param assetType - Type of asset * @param downloadUrl - Download URL * @param statusCode - HTTP status code * @param context - Additional error context * @param cause - Original error */ constructor(assetPath, assetType, downloadUrl, statusCode, context, cause) { const urlToShow = downloadUrl != null ? downloadUrl : assetPath; const message = `Failed to download ${assetType}: ${urlToShow}${statusCode ? ` (HTTP ${statusCode.toString()})` : ""}`; const downloadContext = downloadUrl ? ErrorContextFactory.createNetworkContext(downloadUrl, "GET", statusCode) : void 0; const mergedContext = ErrorContextFactory.merge(context, downloadContext); super(message, assetPath, assetType, mergedContext, cause); this.errorCode = "GM2003" /* GM_ASSETS_DOWNLOAD_FAILED */; this.downloadUrl = downloadUrl; this.statusCode = statusCode; } }; // src/errors/assets/AssetErrorFactory.ts var AssetErrorFactory = { /** * Create asset error based on the type of failure */ createFromFailure(assetPath, assetType, failureType, details) { const { downloadUrl, statusCode, corruptionDetails, context, cause } = details != null ? details : {}; switch (failureType) { case "not_found": return new AssetNotFoundError(assetPath, assetType, context, cause); case "corrupted": return new AssetCorruptedError( assetPath, assetType, corruptionDetails, context, cause ); case "download_failed": return new AssetDownloadFailedError( assetPath, assetType, downloadUrl, statusCode, context, cause ); default: return new AssetNotFoundError(assetPath, assetType, context, cause); } }, /** * Create image-specific error */ createImageError(imagePath, failureType, details) { const { context, cause } = details != null ? details : {}; switch (failureType) { case "not_found": return new ImageNotFoundError(imagePath, context, cause); case "corrupted": return new AssetCorruptedError( imagePath, "image", details == null ? void 0 : details.corruptionDetails, context, cause ); case "download_failed": return new AssetDownloadFailedError( imagePath, "image", details == null ? void 0 : details.downloadUrl, details == null ? void 0 : details.statusCode, context, cause ); default: return new ImageNotFoundError(imagePath, context, cause); } }, /** * Create audio-specific error */ createAudioError(audioPath, failureType, details) { const { context, cause } = details != null ? details : {}; switch (failureType) { case "not_found": return new AudioNotFoundError(audioPath, context, cause); case "corrupted": return new AssetCorruptedError( audioPath, "audio", details == null ? void 0 : details.corruptionDetails, context, cause ); case "download_failed": return new AssetDownloadFailedError( audioPath, "audio", details == null ? void 0 : details.downloadUrl, details == null ? void 0 : details.statusCode, context, cause ); default: return new AudioNotFoundError(audioPath, context, cause); } } }; // src/errors/assets/AssetNotFoundError.ts init_ErrorCodes(); var AssetNotFoundError = class extends AssetError { /** * Constructor for AssetNotFoundError * @param assetPath - Asset file path or identifier * @param assetType - Type of asset * @param context - Additional error context * @param cause - Original error */ constructor(assetPath, assetType = "asset", context, cause) { const message = `${assetType.charAt(0).toUpperCase() + assetType.slice(1)} not found: ${assetPath}`; super(message, assetPath, assetType, context, cause); this.errorCode = "GM2001" /* GM_ASSETS_NOT_FOUND */; } }; // src/errors/assets/AudioNotFoundError.ts init_ErrorCodes(); var AudioNotFoundError = class extends AssetError { /** * Constructor for AudioNotFoundError * @param audioPath - Audio file path or identifier * @param context - Additional error context * @param cause - Original error */ constructor(audioPath, context, cause) { const message = `Audio not found: ${audioPath}`; super(message, audioPath, "audio", context, cause); this.errorCode = "GM2004" /* GM_ASSETS_AUDIO_NOT_FOUND */; } }; // src/errors/assets/ImageNotFoundError.ts init_ErrorCodes(); var ImageNotFoundError = class extends AssetError { /** * Constructor for ImageNotFoundError * @param imagePath - Image file path or identifier * @param context - Additional error context * @param cause - Original error */ constructor(imagePath, context, cause) { const message = `Image not found: ${imagePath}`; super(message, imagePath, "image", context, cause); this.errorCode = "GM2005" /* GM_ASSETS_IMAGE_NOT_FOUND */; } }; // src/errors/network/EnkaNetworkError.ts init_ErrorCodes(); // src/errors/network/NetworkError.ts init_GenshinManagerError(); var NetworkError = class extends GenshinManagerError { /** * Constructor for NetworkError * @param message - Error message * @param url - Request URL * @param method - HTTP method * @param statusCode - HTTP status code * @param timeout - Request timeout * @param context - Additional error context * @param cause - Original error */ constructor(message, url, method, statusCode, timeout, context, cause) { const networkContext = url ? ErrorContextFactory.createNetworkContext( url, method != null ? method : "GET", statusCode ) : void 0; const mergedContext = ErrorContextFactory.merge(context, networkContext); super(message, mergedContext, cause); this.url = url; this.method = method; this.statusCode = statusCode; this.timeout = timeout; } }; // src/errors/network/EnkaNetworkError.ts var EnkaNetworkError = class _EnkaNetworkError extends NetworkError { /** * Constructor for EnkaNetworkError * @param message - Error message * @param url - Request URL * @param statusCode - HTTP status code * @param enkaErrorCode - Enka-specific error code * @param method - HTTP method * @param context - Additional error context * @param cause - Original error */ constructor(message, url, statusCode, enkaErrorCode, method = "GET", context, cause) { super(message, url, method, statusCode, void 0, context, cause); this.errorCode = "GM4003" /* GM_NETWORK_ENKA_ERROR */; this.enkaErrorCode = enkaErrorCode; } /** * Create EnkaNetworkError from API response * @param response - Fetch response object * @param responseBody - Response body if available * @param context - Additional error context */ static fromResponse(response, responseBody, context) { const url = response.url; const statusCode = response.status; let message = `Enka Network API error: ${response.status.toString()} ${response.statusText}`; let enkaErrorCode; if (responseBody && typeof responseBody === "object") { const body = responseBody; if (typeof body.message === "string") message = body.message; if (typeof body.error === "string") enkaErrorCode = body.error; } const errorContext = ErrorContextFactory.createNetworkContext( url, "GET", statusCode ); const mergedContext = ErrorContextFactory.merge(context, errorContext); return new _EnkaNetworkError( message, url, statusCode, enkaErrorCode, "GET", mergedContext ); } }; // src/errors/network/EnkaNetworkStatusError.ts init_ErrorCodes(); var EnkaNetworkStatusError = class _EnkaNetworkStatusError extends NetworkError { /** * Constructor for EnkaNetworkStatusError * @param message - Error message * @param statusType - Type of status error * @param url - Request URL * @param statusCode - HTTP status code * @param retryAfter - Retry after duration in seconds * @param context - Additional error context * @param cause - Original error */ constructor(message, statusType, url, statusCode, retryAfter, context, cause) { super(message, url, "GET", statusCode, void 0, context, cause); this.errorCode = "GM4004" /* GM_NETWORK_ENKA_STATUS_ERROR */; this.statusType = statusType; this.retryAfter = retryAfter; } /** * Create rate limit error * @param retryAfter - Retry after duration in seconds * @param url - Request URL * @param context - Additional error context */ static createRateLimitError(retryAfter, url, context) { const message = `Rate limit exceeded. Retry after ${retryAfter.toString()} seconds`; const rateLimitContext = ErrorContextFactory.createNetworkContext( url != null ? url : "unknown", "GET", 429 ); const mergedContext = ErrorContextFactory.merge(context, rateLimitContext); return new _EnkaNetworkStatusError( message, "rate_limit", url, 429, retryAfter, mergedContext ); } /** * Create maintenance error * @param url - Request URL * @param context - Additional error context */ static createMaintenanceError(url, context) { const message = "Enka Network is currently under maintenance"; const maintenanceContext = ErrorContextFactory.createNetworkContext( url != null ? url : "unknown", "GET", 503 ); const mergedContext = ErrorContextFactory.merge(context, maintenanceContext); return new _EnkaNetworkStatusError( message, "maintenance", url, 503, void 0, mergedContext ); } }; // src/errors/network/NetworkTimeoutError.ts init_ErrorCodes(); var NetworkTimeoutError = class extends NetworkError { /** * Constructor for NetworkTimeoutError * @param url - Request URL * @param timeout - Timeout duration in milliseconds * @param method - HTTP method * @param context - Additional error context * @param cause - Original error */ constructor(url, timeout, method = "GET", context, cause) { const message = `Network request timed out after ${timeout.toString()}ms: ${url}`; super(message, url, method, void 0, timeout, context, cause); this.errorCode = "GM4001" /* GM_NETWORK_TIMEOUT */; } }; // src/errors/network/NetworkUnavailableError.ts init_ErrorCodes(); var NetworkUnavailableError = class extends NetworkError { /** * Constructor for NetworkUnavailableError * @param url - Request URL * @param method - HTTP method * @param context - Additional error context * @param cause - Original error */ constructor(url, method = "GET", context, cause) { const message = url ? `Network is unavailable: ${url}` : "Network is unavailable"; super(message, url, method, void 0, void 0, context, cause); this.errorCode = "GM4002" /* GM_NETWORK_UNAVAILABLE */; } }; // src/errors/decoding/KeyMatchingError.ts init_ErrorCodes(); init_GenshinManagerError(); var KeyMatchingError = class extends GenshinManagerError { /** * Constructor for KeyMatchingError * @param sourceFile - Source file being decoded * @param failedKeys - Keys that failed to match * @param expectedKeys - Expected keys from master file * @param context - Additional error context */ constructor(sourceFile, failedKeys, expectedKeys, context) { const message = `Key matching failed for ${sourceFile}. Failed to match ${String(failedKeys.length)} out of ${String(expectedKeys.length)} keys`; const decodingContext = ErrorContextFactory.createDecodingContext( sourceFile, void 0, "key matching" ); const mergedContext = ErrorContextFactory.merge(context, decodingContext, { metadata: { failedKeys: failedKeys.slice(0, 10), // Limit to first 10 for readability expectedKeys: expectedKeys.slice(0, 10), totalFailedKeys: failedKeys.length, totalExpectedKeys: expectedKeys.length } }); super(message, mergedContext); this.errorCode = "GM3004" /* GM_DECODE_KEY_MATCHING_FAILED */; this.failedKeys = failedKeys; this.expectedKeys = expectedKeys; } /** * Get detailed key matching information */ getKeyMatchingDetails() { const unmatchedExpected = this.expectedKeys.filter( (key) => !this.failedKeys.includes(key) ); const totalKeys = this.expectedKeys.length; const failedCount = this.failedKeys.length; const successRate = totalKeys > 0 ? (totalKeys - failedCount) / totalKeys : 0; return { failedKeys: this.failedKeys, expectedKeys: this.expectedKeys, unmatchedExpected, successRate }; } /** * Get suggestions for troubleshooting */ getTroubleshootingSuggestions() { const suggestions = []; if (this.failedKeys.length === this.expectedKeys.length) { suggestions.push( "Complete key matching failure - check if master file matches data structure" ); suggestions.push( "Consider regenerating the master file if data format has changed" ); } else if (this.failedKeys.length > this.expectedKeys.length * 0.5) { suggestions.push("High failure rate - verify master file compatibility"); suggestions.push("Check if data source has been updated"); } else { suggestions.push( "Partial failure - some keys may have been renamed or removed" ); suggestions.push( "Consider using enablePartialMatch: true for partial decoding" ); } suggestions.push("Enable debug logging to see detailed matching process"); return suggestions; } }; // src/errors/decoding/LowConfidenceError.ts init_ErrorCodes(); init_GenshinManagerError(); var LowConfidenceError = class extends GenshinManagerError { /** * Constructor for LowConfidenceError * @param sourceFile - Source file being decoded * @param confidence - Confidence level achieved * @param threshold - Minimum required confidence * @param context - Additional error context */ constructor(sourceFile, confidence, threshold = 0.8, context) { const message = `Low confidence decoding for ${sourceFile}. Got ${(confidence * 100).toFixed(1)}%, required ${(threshold * 100).toFixed(1)}%`; const decodingContext = ErrorContextFactory.createDecodingContext( sourceFile, void 0, "confidence check" ); const mergedContext = ErrorContextFactory.merge(context, decodingContext, { actualValue: confidence, expectedValue: threshold }); super(message, mergedContext); this.errorCode = "GM3003" /* GM_DECODE_LOW_CONFIDENCE */; } }; // src/errors/decoding/MasterFileConfigurationError.ts init_ErrorCodes(); init_GenshinManagerError(); var MasterFileConfigurationError = class extends GenshinManagerError { /** * Constructor for MasterFileConfigurationError * @param masterFilePath - Path to the master file * @param context - Additional error context * @param cause - Original error */ constructor(masterFilePath, context, cause) { const message = `Failed to load or parse master file: ${masterFilePath}`; const fileContext = ErrorContextFactory.createFileContext( masterFilePath, "load master file" ); const mergedContext = ErrorContextFactory.merge(context, fileContext); super(message, mergedContext, cause); this.errorCode = "GM3001" /* GM_DECODE_MASTER_NOT_FOUND */; } }; // src/errors/decoding/PatternMismatchError.ts init_ErrorCodes(); init_GenshinManagerError(); var PatternMismatchError = class extends GenshinManagerError { /** * Constructor for PatternMismatchError * @param sourceFile - Source file being decoded * @param confidence - Confidence level achieved * @param context - Additional error context */ constructor(sourceFile, confidence, context) { const message = `Pattern mismatch in ${sourceFile}. Confidence level: ${(confidence * 100).toFixed(1)}%`; const decodingContext = ErrorContextFactory.createDecodingContext( sourceFile, void 0, "pattern matching" ); const mergedContext = ErrorContextFactory.merge(context, decodingContext, { actualValue: confidence, expectedValue: "confidence > 0.5" }); super(message, mergedContext); this.errorCode = "GM3002" /* GM_DECODE_PATTERN_MISMATCH */; } }; // src/errors/content/AnnContentNotFoundError.ts init_ErrorCodes(); init_GenshinManagerError(); var AnnContentNotFoundError = class extends GenshinManagerError { /** * Constructor for AnnContentNotFoundError * @param announcementId - Announcement ID or identifier * @param context - Additional error context * @param cause - Original error */ constructor(announcementId, context, cause) { const message = `Announcement content not found: ${announcementId}`; const contentContext = ErrorContextFactory.merge(context, { propertyKey: "announcementId", actualValue: announcementId, operation: "fetch announcement content", timestamp: /* @__PURE__ */ new Date() }); super(message, contentContext, cause); this.errorCode = "GM6001" /* GM_CONTENT_ANN_NOT_FOUND */; this.announcementId = announcementId; } }; // src/errors/content/BodyNotFoundError.ts init_ErrorCodes(); init_GenshinManagerError(); var BodyNotFoundError = class extends GenshinManagerError { /** * Constructor for BodyNotFoundError * @param contentType - Content type or identifier * @param context - Additional error context * @param cause - Original error */ constructor(contentType, context, cause) { const message = `Body content not found for: ${contentType}`; const contentContext = ErrorContextFactory.merge(context, { propertyKey: "contentType", actualValue: contentType, operation: "fetch body content", timestamp: /* @__PURE__ */ new Date() }); super(message, contentContext, cause); this.errorCode = "GM6002" /* GM_CONTENT_BODY_NOT_FOUND */; this.contentType = contentType; } }; // src/errors/content/TextMapFormatError.ts init_ErrorCodes(); init_GenshinManagerError(); var TextMapFormatError = class extends GenshinManagerError { /** * Constructor for TextMapFormatError * @param textMapKey - Text map key or identifier * @param expectedFormat - Expected format description * @param actualValue - Actual invalid value * @param context - Additional error context * @param cause - Original error */ constructor(textMapKey, expectedFormat, actualValue, context, cause) { const message = `Invalid text map format for '${textMapKey}': expected ${expectedFormat}, got ${String(actualValue)}`; const contentContext = ErrorContextFactory.createValidationContext( textMapKey, expectedFormat, actualValue ); const mergedContext = ErrorContextFactory.merge(context, contentContext, { operation: "parse text map" }); super(message, mergedContext, cause); this.errorCode = "GM6003" /* GM_CONTENT_TEXT_MAP_FORMAT */; this.textMapKey = textMapKey; this.expectedFormat = expectedFormat; } }; // src/errors/config/ConfigInvalidError.ts init_ErrorCodes(); init_GenshinManagerError(); var ConfigInvalidError = class extends GenshinManagerError { /** * Constructor for ConfigInvalidError * @param configProperty - Configuration property that is invalid * @param expectedValue - Expected value or type * @param actualValue - Actual invalid value * @param configFile - Configuration file path * @param context - Additional error context * @param cause - Original error */ constructor(configProperty, expectedValue, actualValue, configFile, context, cause) { const message = `Invalid configuration for '${configProperty}': expected ${String(expectedValue)}, got ${String(actualValue)}`; const configContext = ErrorContextFactory.createConfigContext( configProperty, configFile, expectedValue, actualValue ); const mergedContext = ErrorContextFactory.merge(context, configContext); super(message, mergedContext, cause); this.errorCode = "GM5001" /* GM_CONFIG_INVALID */; this.configProperty = configProperty; this.configFile = configFile; } }; // src/errors/config/ConfigMissingError.ts init_ErrorCodes(); init_GenshinManagerError(); var ConfigMissingError = class extends GenshinManagerError { /** * Constructor for ConfigMissingError * @param configProperty - Missing configuration property * @param configFile - Configuration file path * @param context - Additional error context * @param cause - Original error */ constructor(configProperty, configFile, context, cause) { const message = `Missing required configuration: '${configProperty}'${configFile ? ` in ${configFile}` : ""}`; const configContext = ErrorContextFactory.createConfigContext( configProperty, configFile, "required value", "undefined" ); const mergedContext = ErrorContextFactory.merge(context, configContext); super(message, mergedContext, cause); this.errorCode = "GM5002" /* GM_CONFIG_MISSING */; this.configProperty = configProperty; this.configFile = configFile; } }; // src/errors/index.ts init_GeneralError(); // src/types/index.ts var ElementKeys = { Physical: "Phys", Fire: "Pyro", Electric: "Electro", Ice: "Cryo", Wind: "Anemo", Water: "Hydro", Rock: "Geo", Grass: "Dendro" }; var FightProps = { 0: "FIGHT_PROP_NONE", 1: "FIGHT_PROP_BASE_HP", 2: "FIGHT_PROP_HP", 3: "FIGHT_PROP_HP_PERCENT", 4: "FIGHT_PROP_BASE_ATTACK", 5: "FIGHT_PROP_ATTACK", 6: "FIGHT_PROP_ATTACK_PERCENT", 7: "FIGHT_PROP_BASE_DEFENSE", 8: "FIGHT_PROP_DEFENSE", 9: "FIGHT_PROP_DEFENSE_PERCENT", 10: "FIGHT_PROP_BASE_SPEED", 11: "FIGHT_PROP_SPEED_PERCENT", // 12: 'FIGHT_PROP_HP_MP_PERCENT', // 13: 'FIGHT_PROP_ATTACK_MP_PERCENT', 20: "FIGHT_PROP_CRITICAL", // 21: 'FIGHT_PROP_ANTI_CRITICAL', 22: "FIGHT_PROP_CRITICAL_HURT", 23: "FIGHT_PROP_CHARGE_EFFICIENCY", // 24: 'FIGHT_PROP_ADD_HURT', // 25: 'FIGHT_PROP_SUB_HURT', 26: "FIGHT_PROP_HEAL_ADD", 27: "FIGHT_PROP_HEALED_ADD", 28: "FIGHT_PROP_ELEMENT_MASTERY", 29: "FIGHT_PROP_