@xivdyetools/core 1.3.7

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.
Files changed (103) hide show
  1. package/LICENSE +37 -0
  2. package/README.md +400 -0
  3. package/dist/constants/index.d.ts +56 -0
  4. package/dist/constants/index.d.ts.map +1 -0
  5. package/dist/constants/index.js +103 -0
  6. package/dist/constants/index.js.map +1 -0
  7. package/dist/data/colors_xiv.json +3130 -0
  8. package/dist/data/locales/de.json +231 -0
  9. package/dist/data/locales/en.json +231 -0
  10. package/dist/data/locales/fr.json +231 -0
  11. package/dist/data/locales/ja.json +231 -0
  12. package/dist/data/locales/ko.json +233 -0
  13. package/dist/data/locales/zh.json +233 -0
  14. package/dist/data/presets.json +390 -0
  15. package/dist/index.d.ts +16 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +18 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/services/APIService.d.ts +246 -0
  20. package/dist/services/APIService.d.ts.map +1 -0
  21. package/dist/services/APIService.js +499 -0
  22. package/dist/services/APIService.js.map +1 -0
  23. package/dist/services/ColorService.d.ts +146 -0
  24. package/dist/services/ColorService.d.ts.map +1 -0
  25. package/dist/services/ColorService.js +209 -0
  26. package/dist/services/ColorService.js.map +1 -0
  27. package/dist/services/DyeService.d.ts +230 -0
  28. package/dist/services/DyeService.d.ts.map +1 -0
  29. package/dist/services/DyeService.js +326 -0
  30. package/dist/services/DyeService.js.map +1 -0
  31. package/dist/services/LocalizationService.d.ts +338 -0
  32. package/dist/services/LocalizationService.d.ts.map +1 -0
  33. package/dist/services/LocalizationService.js +449 -0
  34. package/dist/services/LocalizationService.js.map +1 -0
  35. package/dist/services/PaletteService.d.ts +137 -0
  36. package/dist/services/PaletteService.d.ts.map +1 -0
  37. package/dist/services/PaletteService.js +349 -0
  38. package/dist/services/PaletteService.js.map +1 -0
  39. package/dist/services/PresetService.d.ts +196 -0
  40. package/dist/services/PresetService.d.ts.map +1 -0
  41. package/dist/services/PresetService.js +261 -0
  42. package/dist/services/PresetService.js.map +1 -0
  43. package/dist/services/color/ColorAccessibility.d.ts +39 -0
  44. package/dist/services/color/ColorAccessibility.d.ts.map +1 -0
  45. package/dist/services/color/ColorAccessibility.js +71 -0
  46. package/dist/services/color/ColorAccessibility.js.map +1 -0
  47. package/dist/services/color/ColorConverter.d.ts +146 -0
  48. package/dist/services/color/ColorConverter.d.ts.map +1 -0
  49. package/dist/services/color/ColorConverter.js +393 -0
  50. package/dist/services/color/ColorConverter.js.map +1 -0
  51. package/dist/services/color/ColorManipulator.d.ts +36 -0
  52. package/dist/services/color/ColorManipulator.d.ts.map +1 -0
  53. package/dist/services/color/ColorManipulator.js +56 -0
  54. package/dist/services/color/ColorManipulator.js.map +1 -0
  55. package/dist/services/color/ColorblindnessSimulator.d.ts +35 -0
  56. package/dist/services/color/ColorblindnessSimulator.d.ts.map +1 -0
  57. package/dist/services/color/ColorblindnessSimulator.js +110 -0
  58. package/dist/services/color/ColorblindnessSimulator.js.map +1 -0
  59. package/dist/services/dye/DyeDatabase.d.ts +131 -0
  60. package/dist/services/dye/DyeDatabase.d.ts.map +1 -0
  61. package/dist/services/dye/DyeDatabase.js +367 -0
  62. package/dist/services/dye/DyeDatabase.js.map +1 -0
  63. package/dist/services/dye/DyeSearch.d.ts +55 -0
  64. package/dist/services/dye/DyeSearch.d.ts.map +1 -0
  65. package/dist/services/dye/DyeSearch.js +196 -0
  66. package/dist/services/dye/DyeSearch.js.map +1 -0
  67. package/dist/services/dye/HarmonyGenerator.d.ts +110 -0
  68. package/dist/services/dye/HarmonyGenerator.d.ts.map +1 -0
  69. package/dist/services/dye/HarmonyGenerator.js +221 -0
  70. package/dist/services/dye/HarmonyGenerator.js.map +1 -0
  71. package/dist/services/localization/LocaleLoader.d.ts +38 -0
  72. package/dist/services/localization/LocaleLoader.d.ts.map +1 -0
  73. package/dist/services/localization/LocaleLoader.js +83 -0
  74. package/dist/services/localization/LocaleLoader.js.map +1 -0
  75. package/dist/services/localization/LocaleRegistry.d.ts +73 -0
  76. package/dist/services/localization/LocaleRegistry.d.ts.map +1 -0
  77. package/dist/services/localization/LocaleRegistry.js +84 -0
  78. package/dist/services/localization/LocaleRegistry.js.map +1 -0
  79. package/dist/services/localization/TranslationProvider.d.ts +157 -0
  80. package/dist/services/localization/TranslationProvider.d.ts.map +1 -0
  81. package/dist/services/localization/TranslationProvider.js +289 -0
  82. package/dist/services/localization/TranslationProvider.js.map +1 -0
  83. package/dist/types/index.d.ts +409 -0
  84. package/dist/types/index.d.ts.map +1 -0
  85. package/dist/types/index.js +87 -0
  86. package/dist/types/index.js.map +1 -0
  87. package/dist/types/logger.d.ts +84 -0
  88. package/dist/types/logger.d.ts.map +1 -0
  89. package/dist/types/logger.js +54 -0
  90. package/dist/types/logger.js.map +1 -0
  91. package/dist/utils/index.d.ts +441 -0
  92. package/dist/utils/index.d.ts.map +1 -0
  93. package/dist/utils/index.js +577 -0
  94. package/dist/utils/index.js.map +1 -0
  95. package/dist/utils/kd-tree.d.ts +76 -0
  96. package/dist/utils/kd-tree.d.ts.map +1 -0
  97. package/dist/utils/kd-tree.js +195 -0
  98. package/dist/utils/kd-tree.js.map +1 -0
  99. package/dist/version.d.ts +11 -0
  100. package/dist/version.d.ts.map +1 -0
  101. package/dist/version.js +11 -0
  102. package/dist/version.js.map +1 -0
  103. package/package.json +84 -0
@@ -0,0 +1,246 @@
1
+ /**
2
+ * @xivdyetools/core - API Service
3
+ *
4
+ * Universalis API integration with caching and debouncing
5
+ * Environment-agnostic with pluggable cache backends
6
+ *
7
+ * @module services/APIService
8
+ */
9
+ import type { PriceData, CachedData, Logger } from '../types/index.js';
10
+ /**
11
+ * Fetch client interface for HTTP requests
12
+ * Implement this for different fetch implementations (global fetch, node-fetch, mocked fetch, etc.)
13
+ *
14
+ * Refactored for testability: Allows injecting mock fetch clients
15
+ */
16
+ export interface FetchClient {
17
+ /**
18
+ * Perform HTTP fetch request
19
+ */
20
+ fetch(url: string, options?: RequestInit): Promise<Response>;
21
+ }
22
+ /**
23
+ * Default fetch client using global fetch API
24
+ */
25
+ export declare class DefaultFetchClient implements FetchClient {
26
+ fetch(url: string, options?: RequestInit): Promise<Response>;
27
+ }
28
+ /**
29
+ * Rate limiter interface for controlling request frequency
30
+ * Implement this for different rate limiting strategies
31
+ *
32
+ * Refactored for testability: Allows injecting custom rate limiters or disabling rate limiting for tests
33
+ */
34
+ export interface RateLimiter {
35
+ /**
36
+ * Wait if needed to respect rate limits
37
+ */
38
+ waitIfNeeded(): Promise<void>;
39
+ /**
40
+ * Record that a request was made (updates internal state)
41
+ */
42
+ recordRequest(): void;
43
+ }
44
+ /**
45
+ * Default rate limiter with configurable minimum delay between requests
46
+ */
47
+ export declare class DefaultRateLimiter implements RateLimiter {
48
+ private minDelay;
49
+ private lastRequestTime;
50
+ /**
51
+ * Constructor with optional minimum delay
52
+ * @param minDelay Minimum milliseconds between requests (default: API_RATE_LIMIT_DELAY)
53
+ */
54
+ constructor(minDelay?: number);
55
+ waitIfNeeded(): Promise<void>;
56
+ recordRequest(): void;
57
+ }
58
+ /**
59
+ * Cache backend interface
60
+ * Implement this for different storage backends (localStorage, Redis, Memory, etc.)
61
+ */
62
+ export interface ICacheBackend {
63
+ /**
64
+ * Get item from cache
65
+ */
66
+ get(key: string): Promise<CachedData<PriceData> | null> | CachedData<PriceData> | null;
67
+ /**
68
+ * Set item in cache
69
+ */
70
+ set(key: string, value: CachedData<PriceData>): Promise<void> | void;
71
+ /**
72
+ * Delete item from cache
73
+ */
74
+ delete(key: string): Promise<void> | void;
75
+ /**
76
+ * Clear all cache entries
77
+ */
78
+ clear(): Promise<void> | void;
79
+ /**
80
+ * Get all cache keys
81
+ */
82
+ keys(): Promise<string[]> | string[];
83
+ }
84
+ /**
85
+ * In-memory cache backend (default, no persistence)
86
+ */
87
+ export declare class MemoryCacheBackend implements ICacheBackend {
88
+ private cache;
89
+ get(key: string): CachedData<PriceData> | null;
90
+ set(key: string, value: CachedData<PriceData>): void;
91
+ delete(key: string): void;
92
+ clear(): void;
93
+ keys(): string[];
94
+ }
95
+ /**
96
+ * Configuration options for APIService
97
+ */
98
+ export interface APIServiceOptions {
99
+ /**
100
+ * Cache backend implementation (defaults to memory cache)
101
+ */
102
+ cacheBackend?: ICacheBackend;
103
+ /**
104
+ * Fetch client implementation (defaults to global fetch)
105
+ */
106
+ fetchClient?: FetchClient;
107
+ /**
108
+ * Rate limiter implementation (defaults to standard rate limiting)
109
+ */
110
+ rateLimiter?: RateLimiter;
111
+ /**
112
+ * Logger for API operations (defaults to NoOpLogger)
113
+ */
114
+ logger?: Logger;
115
+ }
116
+ /**
117
+ * Service for Universalis API integration
118
+ * Handles price data fetching with caching and debouncing
119
+ *
120
+ * Refactored for testability: Supports dependency injection of cache, fetch client, and rate limiter
121
+ *
122
+ * @example
123
+ * // With default implementations (memory cache, global fetch, standard rate limiting)
124
+ * const apiService = new APIService();
125
+ *
126
+ * // With custom cache backend (e.g., Redis)
127
+ * const redisCache = new RedisCacheBackend(redisClient);
128
+ * const apiService = new APIService(redisCache);
129
+ *
130
+ * // With custom fetch client for testing
131
+ * const mockFetch = new MockFetchClient();
132
+ * const apiService = new APIService(undefined, mockFetch);
133
+ *
134
+ * // With custom rate limiter (e.g., no rate limiting for tests)
135
+ * const noRateLimit = new NoOpRateLimiter();
136
+ * const apiService = new APIService(undefined, undefined, noRateLimit);
137
+ *
138
+ * // Fetch price data
139
+ * const priceData = await apiService.getPriceData(itemID, worldID, dataCenterID);
140
+ *
141
+ * // With custom logger for debugging
142
+ * import { ConsoleLogger } from 'xivdyetools-core';
143
+ * const apiService = new APIService({ logger: ConsoleLogger });
144
+ */
145
+ export declare class APIService {
146
+ private cache;
147
+ private fetchClient;
148
+ private rateLimiter;
149
+ private pendingRequests;
150
+ private readonly logger;
151
+ /**
152
+ * Constructor with optional dependency injection
153
+ * @param options Configuration options or legacy cache backend
154
+ */
155
+ constructor(options?: ICacheBackend | APIServiceOptions, fetchClient?: FetchClient, rateLimiter?: RateLimiter);
156
+ /**
157
+ * Get price from cache if available and not expired
158
+ * Validates cache version and checksum
159
+ */
160
+ private getCachedPrice;
161
+ /**
162
+ * Set price in cache with version and checksum
163
+ */
164
+ private setCachedPrice;
165
+ /**
166
+ * Clear cache
167
+ */
168
+ clearCache(): Promise<void>;
169
+ /**
170
+ * Get cache stats
171
+ */
172
+ getCacheStats(): Promise<{
173
+ size: number;
174
+ keys: string[];
175
+ }>;
176
+ /**
177
+ * Fetch price data for a dye from Universalis API
178
+ * Implements caching, debouncing, and retry logic
179
+ */
180
+ getPriceData(itemID: number, worldID?: number, dataCenterID?: string): Promise<PriceData | null>;
181
+ /**
182
+ * Internal method to fetch price data from API
183
+ */
184
+ private fetchPriceData;
185
+ /**
186
+ * Fetch with timeout and size limits
187
+ * Uses injected fetch client for better testability
188
+ */
189
+ private fetchWithTimeout;
190
+ /**
191
+ * Parse and validate API response
192
+ */
193
+ private parseApiResponse;
194
+ /**
195
+ * Build API URL for item price query
196
+ */
197
+ private buildApiUrl;
198
+ /**
199
+ * Sanitize datacenter ID to prevent cache key injection.
200
+ * Only allows alphanumeric characters (a-z, A-Z, 0-9).
201
+ */
202
+ private sanitizeDataCenterId;
203
+ /**
204
+ * Build cache key from parameters
205
+ * SECURITY: Uses type prefixes to prevent cache key collisions
206
+ * Format: itemID:type:value where type is 'dc', 'world', or 'global'
207
+ * This prevents crafted dataCenterID values from colliding with other key patterns
208
+ */
209
+ private buildCacheKey;
210
+ /**
211
+ * Fetch prices for multiple items
212
+ * PERFORMANCE: Uses Promise.allSettled for parallel requests
213
+ * Failed requests are logged but don't block other results
214
+ */
215
+ getPricesForItems(itemIDs: number[]): Promise<Map<number, PriceData>>;
216
+ /**
217
+ * Fetch prices for dyes in a specific data center
218
+ * PERFORMANCE: Uses Promise.allSettled for parallel requests
219
+ */
220
+ getPricesForDataCenter(itemIDs: number[], dataCenterID: string): Promise<Map<number, PriceData>>;
221
+ /**
222
+ * Check if Universalis API is available
223
+ * Uses injected fetch client
224
+ */
225
+ isAPIAvailable(): Promise<boolean>;
226
+ /**
227
+ * Get API status information
228
+ */
229
+ getAPIStatus(): Promise<{
230
+ available: boolean;
231
+ latency: number;
232
+ }>;
233
+ /**
234
+ * Format price for display (FFXIV Gil format: 69,420G)
235
+ */
236
+ static formatPrice(price: number): string;
237
+ /**
238
+ * Calculate price trend (simplified)
239
+ */
240
+ static getPriceTrend(currentPrice: number, previousPrice: number): {
241
+ trend: 'up' | 'down' | 'stable';
242
+ change: number;
243
+ changePercent: number;
244
+ };
245
+ }
246
+ //# sourceMappingURL=APIService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"APIService.d.ts","sourceRoot":"","sources":["../../src/services/APIService.ts"],"names":[],"mappings":"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"}