Source: utils/searchIndex.js

// @ts-check
import { query } from '@commtool/sql-query';

/**
 * Replace all SearchIndex entries for a given object + index type.
 * Deletes existing rows then inserts the new values.
 * Safe to call with an empty values array (just removes stale entries).
 *
 * @param {Buffer} UID         - Member.UID (= ObjectBase.UID for person/extern)
 * @param {string} objType     - Object type: 'person', 'extern', 'group', …
 * @param {string} indexType   - Index category: 'email', 'phone', …
 * @param {string[]} values    - Lowercased, trimmed values to index
 * @returns {Promise<void>}
 */
export const upsertSearchIndex = async (UID, objType, indexType, values) => {
    await query(`DELETE FROM SearchIndex WHERE UID = ? AND IndexType = ?`, [UID, indexType]);
    for (const value of values) {
        if (value) {
            await query(
                `INSERT IGNORE INTO SearchIndex (UID, ObjType, IndexType, Value) VALUES (?, ?, ?, ?)`,
                [UID, objType, indexType, value]
            );
        }
    }
};

/**
 * Extract all email addresses from a Data.email array into a lowercased string list.
 *
 * @param {Array<{email?: string}>} [emailArray]
 * @returns {string[]}
 */
export const emailValues = (emailArray) => {
    if (!Array.isArray(emailArray)) return [];
    return emailArray
        .map(e => e?.email?.toLowerCase().trim())
        .map(e => e ? e.replace(/^.*<([^>]+)>.*$/, '$1').trim() : e) // strip display-name wrapper
        .filter(Boolean);
};