@nahisaho/shikigami-mcp-server 1.7.0 → 1.10.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 +29 -0
- package/dist/cache/__tests__/global.test.d.ts +6 -0
- package/dist/cache/__tests__/global.test.d.ts.map +1 -0
- package/dist/cache/__tests__/global.test.js +269 -0
- package/dist/cache/__tests__/global.test.js.map +1 -0
- package/dist/cache/__tests__/manager.test.d.ts +6 -0
- package/dist/cache/__tests__/manager.test.d.ts.map +1 -0
- package/dist/cache/__tests__/manager.test.js +286 -0
- package/dist/cache/__tests__/manager.test.js.map +1 -0
- package/dist/cache/__tests__/semantic.test.d.ts +6 -0
- package/dist/cache/__tests__/semantic.test.d.ts.map +1 -0
- package/dist/cache/__tests__/semantic.test.js +271 -0
- package/dist/cache/__tests__/semantic.test.js.map +1 -0
- package/dist/cache/__tests__/store.test.d.ts +6 -0
- package/dist/cache/__tests__/store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/store.test.js +289 -0
- package/dist/cache/__tests__/store.test.js.map +1 -0
- package/dist/cache/global.d.ts +140 -0
- package/dist/cache/global.d.ts.map +1 -0
- package/dist/cache/global.js +260 -0
- package/dist/cache/global.js.map +1 -0
- package/dist/cache/index.d.ts +10 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +10 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/manager.d.ts +146 -0
- package/dist/cache/manager.d.ts.map +1 -0
- package/dist/cache/manager.js +229 -0
- package/dist/cache/manager.js.map +1 -0
- package/dist/cache/semantic.d.ts +164 -0
- package/dist/cache/semantic.d.ts.map +1 -0
- package/dist/cache/semantic.js +241 -0
- package/dist/cache/semantic.js.map +1 -0
- package/dist/cache/store.d.ts +98 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/store.js +469 -0
- package/dist/cache/store.js.map +1 -0
- package/dist/cache/types.d.ts +171 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +8 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/config/types.d.ts +67 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +30 -0
- package/dist/config/types.js.map +1 -1
- package/dist/tools/__tests__/multilingual-search.test.d.ts +7 -0
- package/dist/tools/__tests__/multilingual-search.test.d.ts.map +1 -0
- package/dist/tools/__tests__/multilingual-search.test.js +71 -0
- package/dist/tools/__tests__/multilingual-search.test.js.map +1 -0
- package/dist/tools/search/recovery/__tests__/logger.test.d.ts +8 -0
- package/dist/tools/search/recovery/__tests__/logger.test.d.ts.map +1 -0
- package/dist/tools/search/recovery/__tests__/logger.test.js +249 -0
- package/dist/tools/search/recovery/__tests__/logger.test.js.map +1 -0
- package/dist/tools/search/recovery/__tests__/manager-logger.test.d.ts +8 -0
- package/dist/tools/search/recovery/__tests__/manager-logger.test.d.ts.map +1 -0
- package/dist/tools/search/recovery/__tests__/manager-logger.test.js +158 -0
- package/dist/tools/search/recovery/__tests__/manager-logger.test.js.map +1 -0
- package/dist/tools/search/recovery/index.d.ts +31 -2
- package/dist/tools/search/recovery/index.d.ts.map +1 -1
- package/dist/tools/search/recovery/index.js +51 -7
- package/dist/tools/search/recovery/index.js.map +1 -1
- package/dist/tools/search/recovery/logger.d.ts +149 -0
- package/dist/tools/search/recovery/logger.d.ts.map +1 -0
- package/dist/tools/search/recovery/logger.js +218 -0
- package/dist/tools/search/recovery/logger.js.map +1 -0
- package/dist/tools/search.d.ts +48 -0
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +152 -0
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/visit/recovery/__tests__/index.test.d.ts +10 -0
- package/dist/tools/visit/recovery/__tests__/index.test.d.ts.map +1 -0
- package/dist/tools/visit/recovery/__tests__/index.test.js +239 -0
- package/dist/tools/visit/recovery/__tests__/index.test.js.map +1 -0
- package/dist/tools/visit/recovery/__tests__/wayback.test.d.ts +8 -0
- package/dist/tools/visit/recovery/__tests__/wayback.test.d.ts.map +1 -0
- package/dist/tools/visit/recovery/__tests__/wayback.test.js +271 -0
- package/dist/tools/visit/recovery/__tests__/wayback.test.js.map +1 -0
- package/dist/tools/visit/recovery/index.d.ts +126 -0
- package/dist/tools/visit/recovery/index.d.ts.map +1 -0
- package/dist/tools/visit/recovery/index.js +203 -0
- package/dist/tools/visit/recovery/index.js.map +1 -0
- package/dist/tools/visit/recovery/wayback.d.ts +101 -0
- package/dist/tools/visit/recovery/wayback.d.ts.map +1 -0
- package/dist/tools/visit/recovery/wayback.js +140 -0
- package/dist/tools/visit/recovery/wayback.js.map +1 -0
- package/dist/tools/visit.d.ts +33 -0
- package/dist/tools/visit.d.ts.map +1 -1
- package/dist/tools/visit.js +127 -1
- package/dist/tools/visit.js.map +1 -1
- package/package.json +7 -3
- package/shikigami.config.example.yaml +9 -0
- package/src/cache/__tests__/global.test.ts +340 -0
- package/src/cache/__tests__/manager.test.ts +353 -0
- package/src/cache/__tests__/semantic.test.ts +331 -0
- package/src/cache/__tests__/store.test.ts +369 -0
- package/src/cache/global.ts +351 -0
- package/src/cache/index.ts +10 -0
- package/src/cache/manager.ts +325 -0
- package/src/cache/semantic.ts +368 -0
- package/src/cache/store.ts +555 -0
- package/src/cache/types.ts +189 -0
- package/src/config/types.ts +108 -0
- package/src/tools/__tests__/multilingual-search.test.ts +88 -0
- package/src/tools/search/recovery/__tests__/logger.test.ts +334 -0
- package/src/tools/search/recovery/__tests__/manager-logger.test.ts +199 -0
- package/src/tools/search/recovery/index.ts +67 -9
- package/src/tools/search/recovery/logger.ts +351 -0
- package/src/tools/search.ts +212 -0
- package/src/tools/visit/recovery/__tests__/index.test.ts +297 -0
- package/src/tools/visit/recovery/__tests__/wayback.test.ts +344 -0
- package/src/tools/visit/recovery/index.ts +312 -0
- package/src/tools/visit/recovery/wayback.ts +210 -0
- package/src/tools/visit.ts +159 -2
- package/vitest.config.ts +22 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Module Types
|
|
3
|
+
* v1.0.0 - REQ-CACHE-001
|
|
4
|
+
*
|
|
5
|
+
* キャッシュシステムの型定義
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* キャッシュエントリのメタデータ
|
|
10
|
+
*/
|
|
11
|
+
export interface CacheEntryMeta {
|
|
12
|
+
/** エントリ作成日時 (ISO 8601) */
|
|
13
|
+
createdAt: string;
|
|
14
|
+
/** 最終アクセス日時 (ISO 8601) */
|
|
15
|
+
lastAccessedAt: string;
|
|
16
|
+
/** 有効期限 (ISO 8601) */
|
|
17
|
+
expiresAt: string;
|
|
18
|
+
/** アクセス回数 */
|
|
19
|
+
accessCount: number;
|
|
20
|
+
/** データサイズ (bytes) */
|
|
21
|
+
size: number;
|
|
22
|
+
/** ソース識別子 (search, visit, embedding等) */
|
|
23
|
+
source: CacheSource;
|
|
24
|
+
/** クエリのハッシュ */
|
|
25
|
+
queryHash: string;
|
|
26
|
+
/** 元のキャッシュキー */
|
|
27
|
+
originalKey: string;
|
|
28
|
+
/** 関連タグ */
|
|
29
|
+
tags?: string[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* キャッシュエントリ
|
|
34
|
+
*/
|
|
35
|
+
export interface CacheEntry<T = unknown> {
|
|
36
|
+
/** キャッシュキー */
|
|
37
|
+
key: string;
|
|
38
|
+
/** キャッシュされた値 */
|
|
39
|
+
value: T;
|
|
40
|
+
/** メタデータ */
|
|
41
|
+
meta: CacheEntryMeta;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* キャッシュソース種別
|
|
46
|
+
*/
|
|
47
|
+
export type CacheSource = 'search' | 'visit' | 'embedding' | 'analysis' | 'other';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* キャッシュ設定
|
|
51
|
+
*/
|
|
52
|
+
export interface CacheConfig {
|
|
53
|
+
/** キャッシュを有効にするか */
|
|
54
|
+
enabled: boolean;
|
|
55
|
+
/** 最大エントリ数 */
|
|
56
|
+
maxEntries: number;
|
|
57
|
+
/** デフォルトTTL (秒) */
|
|
58
|
+
defaultTtlSeconds: number;
|
|
59
|
+
/** 最大キャッシュサイズ (bytes) */
|
|
60
|
+
maxSizeBytes: number;
|
|
61
|
+
/** キャッシュディレクトリパス */
|
|
62
|
+
cacheDir: string;
|
|
63
|
+
/** ソース別TTL設定 */
|
|
64
|
+
ttlBySource?: Partial<Record<CacheSource, number>>;
|
|
65
|
+
/** グローバルキャッシュを使用するか */
|
|
66
|
+
useGlobalCache?: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* キャッシュ統計情報
|
|
71
|
+
*/
|
|
72
|
+
export interface CacheStats {
|
|
73
|
+
/** 総エントリ数 */
|
|
74
|
+
totalEntries: number;
|
|
75
|
+
/** 総サイズ (bytes) */
|
|
76
|
+
totalSizeBytes: number;
|
|
77
|
+
/** キャッシュヒット数 */
|
|
78
|
+
hits: number;
|
|
79
|
+
/** キャッシュミス数 */
|
|
80
|
+
misses: number;
|
|
81
|
+
/** ヒット率 (0-1) */
|
|
82
|
+
hitRate: number;
|
|
83
|
+
/** 削除されたエントリ数 (TTL期限切れ) */
|
|
84
|
+
expiredEvictions: number;
|
|
85
|
+
/** 削除されたエントリ数 (LRU) */
|
|
86
|
+
lruEvictions: number;
|
|
87
|
+
/** ソース別統計 */
|
|
88
|
+
bySource: Partial<Record<CacheSource, SourceCacheStats>>;
|
|
89
|
+
/** 統計開始日時 */
|
|
90
|
+
statsStartedAt: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* ソース別キャッシュ統計
|
|
95
|
+
*/
|
|
96
|
+
export interface SourceCacheStats {
|
|
97
|
+
/** エントリ数 */
|
|
98
|
+
entries: number;
|
|
99
|
+
/** サイズ (bytes) */
|
|
100
|
+
sizeBytes: number;
|
|
101
|
+
/** ヒット数 */
|
|
102
|
+
hits: number;
|
|
103
|
+
/** ミス数 */
|
|
104
|
+
misses: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* キャッシュ操作結果
|
|
109
|
+
*/
|
|
110
|
+
export interface CacheResult<T = unknown> {
|
|
111
|
+
/** キャッシュヒットしたか */
|
|
112
|
+
hit: boolean;
|
|
113
|
+
/** 取得した値 (hitの場合) */
|
|
114
|
+
value?: T;
|
|
115
|
+
/** メタデータ (hitの場合) */
|
|
116
|
+
meta?: CacheEntryMeta;
|
|
117
|
+
/** キャッシュキー */
|
|
118
|
+
key: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* キャッシュ保存オプション
|
|
123
|
+
*/
|
|
124
|
+
export interface CacheSetOptions {
|
|
125
|
+
/** TTL (秒)。省略時はデフォルトTTL */
|
|
126
|
+
ttlSeconds?: number;
|
|
127
|
+
/** タグ */
|
|
128
|
+
tags?: string[];
|
|
129
|
+
/** ソース */
|
|
130
|
+
source?: CacheSource;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* キャッシュクエリオプション
|
|
135
|
+
*/
|
|
136
|
+
export interface CacheQueryOptions {
|
|
137
|
+
/** ソースでフィルタ */
|
|
138
|
+
source?: CacheSource;
|
|
139
|
+
/** タグでフィルタ (AND条件) */
|
|
140
|
+
tags?: string[];
|
|
141
|
+
/** 期限切れを含むか */
|
|
142
|
+
includeExpired?: boolean;
|
|
143
|
+
/** 最大取得数 */
|
|
144
|
+
limit?: number;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* LRU削除候補
|
|
149
|
+
*/
|
|
150
|
+
export interface LruCandidate {
|
|
151
|
+
/** キャッシュキー */
|
|
152
|
+
key: string;
|
|
153
|
+
/** 最終アクセス日時 */
|
|
154
|
+
lastAccessedAt: string;
|
|
155
|
+
/** サイズ */
|
|
156
|
+
size: number;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* キャッシュストアインターフェース
|
|
161
|
+
*/
|
|
162
|
+
export interface ICacheStore {
|
|
163
|
+
/** エントリを取得 */
|
|
164
|
+
get<T = unknown>(key: string): Promise<CacheResult<T>>;
|
|
165
|
+
|
|
166
|
+
/** エントリを保存 */
|
|
167
|
+
set<T = unknown>(key: string, value: T, options?: CacheSetOptions): Promise<void>;
|
|
168
|
+
|
|
169
|
+
/** エントリを削除 */
|
|
170
|
+
delete(key: string): Promise<boolean>;
|
|
171
|
+
|
|
172
|
+
/** 全エントリを削除 */
|
|
173
|
+
clear(): Promise<void>;
|
|
174
|
+
|
|
175
|
+
/** キーが存在するか確認 */
|
|
176
|
+
has(key: string): Promise<boolean>;
|
|
177
|
+
|
|
178
|
+
/** 統計情報を取得 */
|
|
179
|
+
getStats(): Promise<CacheStats>;
|
|
180
|
+
|
|
181
|
+
/** 期限切れエントリを削除 */
|
|
182
|
+
evictExpired(): Promise<number>;
|
|
183
|
+
|
|
184
|
+
/** LRUポリシーでエントリを削除 */
|
|
185
|
+
evictLru(targetSizeBytes: number): Promise<number>;
|
|
186
|
+
|
|
187
|
+
/** エントリを検索 */
|
|
188
|
+
query(options: CacheQueryOptions): Promise<CacheEntry[]>;
|
|
189
|
+
}
|
package/src/config/types.ts
CHANGED
|
@@ -311,6 +311,16 @@ export interface ShikigamiConfig {
|
|
|
311
311
|
/** PDF解析設定 (v1.7.0) */
|
|
312
312
|
pdfParsing?: PdfParsingConfig;
|
|
313
313
|
|
|
314
|
+
// v1.8.0: 新機能設定
|
|
315
|
+
/** 多言語並列検索設定 (v1.8.0) */
|
|
316
|
+
multilingualSearch?: MultilingualSearchConfig;
|
|
317
|
+
|
|
318
|
+
/** ナレッジ継承設定 (v1.8.0) */
|
|
319
|
+
knowledgeInheritance?: KnowledgeInheritanceConfig;
|
|
320
|
+
|
|
321
|
+
/** ページ訪問リカバリー設定 (v1.10.0) */
|
|
322
|
+
visitRecovery?: VisitRecoveryConfig;
|
|
323
|
+
|
|
314
324
|
/** カスタム設定(拡張用) */
|
|
315
325
|
custom?: Record<string, unknown>;
|
|
316
326
|
}
|
|
@@ -415,3 +425,101 @@ export const DEFAULT_PDF_PARSING_CONFIG: Required<PdfParsingConfig> = {
|
|
|
415
425
|
timeoutMs: 60000,
|
|
416
426
|
tempDir: '/tmp/shikigami-pdf',
|
|
417
427
|
};
|
|
428
|
+
|
|
429
|
+
// ============================================================
|
|
430
|
+
// v1.8.0: 多言語並列検索設定 (REQ-SRCH-004)
|
|
431
|
+
// ============================================================
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* 多言語並列検索設定 (v1.8.0)
|
|
435
|
+
* REQ-SRCH-004: 多言語並列検索
|
|
436
|
+
*/
|
|
437
|
+
export interface MultilingualSearchConfig {
|
|
438
|
+
/** 多言語検索を有効にするか */
|
|
439
|
+
enabled: boolean;
|
|
440
|
+
/** 優先言語(結果マージ時の優先順位) */
|
|
441
|
+
priorityLanguage?: 'ja' | 'en';
|
|
442
|
+
/** 言語別最大結果数 */
|
|
443
|
+
maxResults?: number;
|
|
444
|
+
/** 検索タイムアウト(ms) */
|
|
445
|
+
timeoutMs?: number;
|
|
446
|
+
/** カスタム翻訳辞書(v1.7.0辞書に追加) */
|
|
447
|
+
customDictionary?: Record<string, string>;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* デフォルト多言語検索設定
|
|
452
|
+
*/
|
|
453
|
+
export const DEFAULT_MULTILINGUAL_SEARCH_CONFIG: Required<MultilingualSearchConfig> = {
|
|
454
|
+
enabled: true,
|
|
455
|
+
priorityLanguage: 'ja',
|
|
456
|
+
maxResults: 20,
|
|
457
|
+
timeoutMs: 10000,
|
|
458
|
+
customDictionary: {},
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
// ============================================================
|
|
462
|
+
// v1.8.0: ナレッジ継承設定 (REQ-KM-004)
|
|
463
|
+
// ============================================================
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* ナレッジ継承設定 (v1.8.0)
|
|
467
|
+
* REQ-KM-004: ナレッジ継承の自動実行
|
|
468
|
+
*/
|
|
469
|
+
export interface KnowledgeInheritanceConfig {
|
|
470
|
+
/** ナレッジ継承を有効にするか */
|
|
471
|
+
enabled: boolean;
|
|
472
|
+
/** 鮮度閾値(日数、これを超えるとSTALE警告) */
|
|
473
|
+
freshnessThresholdDays?: number;
|
|
474
|
+
/** 関連プロジェクト自動検出を有効にするか */
|
|
475
|
+
autoDetectRelated?: boolean;
|
|
476
|
+
/** 継承対象ファイルパターン */
|
|
477
|
+
includePatterns?: string[];
|
|
478
|
+
/** 継承除外ファイルパターン */
|
|
479
|
+
excludePatterns?: string[];
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* デフォルトナレッジ継承設定
|
|
484
|
+
*/
|
|
485
|
+
export const DEFAULT_KNOWLEDGE_INHERITANCE_CONFIG: Required<KnowledgeInheritanceConfig> = {
|
|
486
|
+
enabled: true,
|
|
487
|
+
freshnessThresholdDays: 30,
|
|
488
|
+
autoDetectRelated: true,
|
|
489
|
+
includePatterns: ['research/**/*.md', 'reports/**/*.md'],
|
|
490
|
+
excludePatterns: ['**/draft-*.md', '**/temp-*.md'],
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
// ============================================================
|
|
494
|
+
// v1.10.0: ページ訪問リカバリー設定 (REQ-SRCH-004)
|
|
495
|
+
// ============================================================
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* ページ訪問リカバリー設定 (v1.10.0)
|
|
499
|
+
* REQ-SRCH-004-01: visit失敗時フォールバック
|
|
500
|
+
* REQ-SRCH-004-02: 自動リトライ
|
|
501
|
+
*/
|
|
502
|
+
export interface VisitRecoveryConfig {
|
|
503
|
+
/** リカバリーを有効にするか */
|
|
504
|
+
enabled: boolean;
|
|
505
|
+
/** 最大リトライ回数 */
|
|
506
|
+
maxRetries?: number;
|
|
507
|
+
/** リトライ間隔(ms) */
|
|
508
|
+
retryDelayMs?: number;
|
|
509
|
+
/** タイムアウト(ms) */
|
|
510
|
+
timeoutMs?: number;
|
|
511
|
+
/** Wayback Machine を使用するか */
|
|
512
|
+
enableWayback?: boolean;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* デフォルトページ訪問リカバリー設定
|
|
517
|
+
*/
|
|
518
|
+
export const DEFAULT_VISIT_RECOVERY_CONFIG: Required<VisitRecoveryConfig> = {
|
|
519
|
+
enabled: true,
|
|
520
|
+
maxRetries: 2,
|
|
521
|
+
retryDelayMs: 1000,
|
|
522
|
+
timeoutMs: 30000,
|
|
523
|
+
enableWayback: true,
|
|
524
|
+
};
|
|
525
|
+
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 多言語検索ユニットテスト
|
|
3
|
+
* @description v1.8.0: REQ-SRCH-004 多言語並列検索のテスト
|
|
4
|
+
* @requirement REQ-SRCH-004-01, REQ-SRCH-004-02, REQ-SRCH-004-04
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import {
|
|
9
|
+
detectLanguage,
|
|
10
|
+
translateQuery,
|
|
11
|
+
normalizeUrl,
|
|
12
|
+
} from '../search.js';
|
|
13
|
+
|
|
14
|
+
describe('v1.8.0 多言語検索 (REQ-SRCH-004)', () => {
|
|
15
|
+
describe('detectLanguage (TSK-002)', () => {
|
|
16
|
+
it('日本語のみのクエリを検出', () => {
|
|
17
|
+
expect(detectLanguage('ネオジム磁石')).toBe('ja');
|
|
18
|
+
expect(detectLanguage('自動車業界')).toBe('ja');
|
|
19
|
+
expect(detectLanguage('プロテリアル 磁石')).toBe('ja');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('英語のみのクエリを検出', () => {
|
|
23
|
+
expect(detectLanguage('neodymium magnet')).toBe('en');
|
|
24
|
+
expect(detectLanguage('automotive industry')).toBe('en');
|
|
25
|
+
expect(detectLanguage('Proterial')).toBe('en');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('混合クエリを検出', () => {
|
|
29
|
+
expect(detectLanguage('ネオジム magnet')).toBe('mixed');
|
|
30
|
+
expect(detectLanguage('TDK 磁石')).toBe('mixed');
|
|
31
|
+
expect(detectLanguage('Proterial ネオジム磁石')).toBe('mixed');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('translateQuery (TSK-003)', () => {
|
|
36
|
+
it('日本語用語を英語に翻訳', () => {
|
|
37
|
+
const result = translateQuery('ネオジム磁石');
|
|
38
|
+
expect(result).toBe('neodymium magnet');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('複数用語を翻訳', () => {
|
|
42
|
+
const result = translateQuery('プロテリアル ネオジム磁石');
|
|
43
|
+
expect(result).toBe('Proterial neodymium magnet');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('辞書にない語はそのまま', () => {
|
|
47
|
+
const result = translateQuery('未知の用語');
|
|
48
|
+
expect(result).toBeNull(); // 変換なし = null
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('カスタム辞書で拡張可能', () => {
|
|
52
|
+
const customDict = { 'カスタム語': 'custom term' };
|
|
53
|
+
const result = translateQuery('カスタム語', customDict);
|
|
54
|
+
expect(result).toBe('custom term');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('v1.7.0辞書も使用可能', () => {
|
|
58
|
+
// BUILTIN_DICTIONARYの用語
|
|
59
|
+
const result = translateQuery('自動車');
|
|
60
|
+
expect(result).toBe('automotive');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('normalizeUrl (TSK-004)', () => {
|
|
65
|
+
it('末尾スラッシュを削除', () => {
|
|
66
|
+
expect(normalizeUrl('https://example.com/page/')).toBe('https://example.com/page');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('トラッキングパラメータを削除', () => {
|
|
70
|
+
const url = 'https://example.com/page?utm_source=test&id=123';
|
|
71
|
+
const normalized = normalizeUrl(url);
|
|
72
|
+
expect(normalized).not.toContain('utm_source');
|
|
73
|
+
expect(normalized).toContain('id=123');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('大文字を小文字に正規化', () => {
|
|
77
|
+
expect(normalizeUrl('https://Example.COM/Page')).toBe('https://example.com/page');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('フラグメントを削除', () => {
|
|
81
|
+
expect(normalizeUrl('https://example.com/page#section')).toBe('https://example.com/page');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('不正なURLはそのまま小文字化', () => {
|
|
85
|
+
expect(normalizeUrl('invalid-url')).toBe('invalid-url');
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|