FE_Dev / utils /normalize-strategy-keys.ts
GitHub Actions
Deploy from GitHub Actions [dev] - 2025-10-31 07:28:50
68f7925
/**
* 文字列キーから余分な記号を除去する汎用関数
* @param key - 正規化する文字列
* @param options - 正規化オプション
* @returns 正規化された文字列
*/
export function normalizeKey(
key: string,
options: {
removeSymbols?: boolean;
unicodeNormalize?: boolean | 'NFC' | 'NFD' | 'NFKC' | 'NFKD';
trim?: boolean;
} = {},
): string {
if (!key || typeof key !== 'string') return key;
const { removeSymbols = true, unicodeNormalize = false, trim = true } = options;
let result = key;
// 記号除去
if (removeSymbols) {
result = result
.replace(/^["']?\[['"]?/, '') // 先頭の"[' や [' や ["などを削除
.replace(/['"]?\]?["']?$/, '') // 末尾の'] や "]や '"などを削除
.replace(/^['"]/, '') // 先頭の' または "を削除
.replace(/['"]$/, ''); // 末尾の' または "を削除
}
// 空白除去
if (trim) {
result = result.trim();
}
// Unicode正規化
if (unicodeNormalize) {
const normalizationForm = typeof unicodeNormalize === 'string' ? unicodeNormalize : 'NFKC';
result = result.normalize(normalizationForm);
}
return result;
}
/**
* オブジェクトのキーを正規化する汎用関数
* @param data - 正規化対象のデータ
* @param keyNormalizer - キー正規化関数(デフォルト: normalizeKey)
* @returns キーが正規化されたデータ
*/
export function normalizeObjectKeys(data: unknown, keyNormalizer: (key: string) => string = normalizeKey): unknown {
if (!data || typeof data !== 'object') {
return data;
}
// 配列の場合は各要素を再帰的に処理
if (Array.isArray(data)) {
return data.map((item) => normalizeObjectKeys(item, keyNormalizer));
}
// オブジェクトの場合はキーを正規化
const normalized: Record<string, unknown> = {};
for (const [key, value] of Object.entries(data)) {
const cleanKey = keyNormalizer(key);
// 値も再帰的に処理
normalized[cleanKey] = normalizeObjectKeys(value, keyNormalizer);
}
return normalized;
}
/**
* @deprecated normalizeObjectKeysを使用してください
*/
export function normalizeStrategyKeys(strategyData: unknown): unknown {
return normalizeObjectKeys(strategyData);
}
/**
* 配列の特定インデックスの要素を正規化する汎用関数
* @param array - 対象の配列
* @param indices - 正規化するインデックスの配列
* @param normalizer - 正規化関数(デフォルト: normalizeObjectKeys)
* @returns 指定インデックスが正規化された配列
*/
export function normalizeArrayAtIndices(
array: unknown[],
indices: number[],
normalizer: (data: unknown) => unknown = normalizeObjectKeys,
): unknown[] {
if (!Array.isArray(array)) {
return array as unknown[];
}
const normalized = [...array];
indices.forEach((index) => {
if (index >= 0 && index < array.length) {
normalized[index] = normalizer(array[index]);
}
});
return normalized;
}
/**
* @deprecated normalizeArrayAtIndicesを使用してください
*/
export function normalizeThemeByMomentResponse(response: unknown): unknown {
if (!Array.isArray(response) || response.length < 3) {
return response;
}
// response[2]がstrategy_x_moment
return normalizeArrayAtIndices(response, [2]);
}
/**
* 正規化されたキーでオブジェクトから値を検索する汎用関数
* @param data - 検索対象のオブジェクト
* @param originalKey - 検索するキー
* @param normalizeOptions - 正規化オプション
* @returns マッチした値、見つからない場合はundefined
*/
export function findWithNormalizedKey<T>(
data: Record<string, T> | undefined,
originalKey: string,
normalizeOptions: Parameters<typeof normalizeKey>[1] = {
removeSymbols: true,
unicodeNormalize: 'NFKC',
trim: true,
},
): T | undefined {
if (!data) {
return undefined;
}
// まず元のキーで検索
if (data[originalKey]) {
return data[originalKey];
}
// 正規化したキーで検索
const normalizedKey = normalizeKey(originalKey, normalizeOptions);
for (const [key, value] of Object.entries(data)) {
const normalizedDataKey = normalizeKey(key, normalizeOptions);
if (normalizedDataKey === normalizedKey) {
return value;
}
}
return undefined;
}