@flavoai/fastfold
Version:
Flavo frontend package
106 lines • 3.69 kB
JavaScript
import { eq } from 'drizzle-orm';
/**
* Maps Flavo user fields to possible column names on the local users table.
* Each entry is: [flavoField, [...possibleColumnNames]]
*/
const FIELD_MAPPINGS = [
['email', ['email']],
['displayName', ['displayName', 'display_name', 'name']],
['avatar', ['avatar', 'avatarUrl', 'avatar_url']],
['authProvider', ['authProvider', 'auth_provider']],
['role', ['role']],
];
/**
* Check if a column name exists on a Drizzle table object.
*/
function hasColumn(table, columnName) {
if (!table || !columnName)
return false;
const col = table[columnName];
return (col != null &&
typeof col === 'object' &&
(col.dataType || col.columnType || col.config));
}
/**
* Build an object of { columnName: value } by mapping Flavo user fields
* to whatever column names exist on the local table.
*/
function mapUserToColumns(table, user) {
const mapped = {};
for (const [flavoField, possibleNames] of FIELD_MAPPINGS) {
for (const colName of possibleNames) {
if (hasColumn(table, colName)) {
mapped[colName] = user[flavoField] ?? null;
break;
}
}
}
return mapped;
}
/**
* Sync a Flavo-authenticated user to the app's local database.
*
* - Looks up by `email` column (required on the table)
* - If not found: INSERT
* - If found: UPDATE with latest profile data
* - Returns the local row's `id` (or undefined if sync failed/skipped)
*
* This function never throws — errors are logged and swallowed so that
* auth middleware never blocks a request due to a sync failure.
*/
export async function syncFlavoUserToDb(db, schema, userTableName, user) {
const table = schema[userTableName];
if (!table)
return undefined;
// email column is required for lookup
if (!hasColumn(table, 'email')) {
return undefined;
}
try {
const mapped = mapUserToColumns(table, user);
const now = new Date();
// Check if user already exists
const existing = await db
.select()
.from(table)
.where(eq(table.email, user.email))
.limit(1);
if (existing.length > 0) {
// UPDATE existing user with latest profile data
const updateData = { ...mapped };
// Remove email from update (it's the lookup key, shouldn't change)
delete updateData.email;
if (hasColumn(table, 'updatedAt')) {
updateData.updatedAt = now;
}
// Only update if there are fields to update
if (Object.keys(updateData).length > 0) {
await db
.update(table)
.set(updateData)
.where(eq(table.email, user.email));
}
return existing[0].id;
}
else {
// INSERT new user
if (hasColumn(table, 'createdAt') && !mapped.createdAt) {
mapped.createdAt = now;
}
if (hasColumn(table, 'updatedAt') && !mapped.updatedAt) {
mapped.updatedAt = now;
}
const result = await db.insert(table).values(mapped).returning();
return result?.[0]?.id;
}
}
catch (error) {
// Silently skip if the table doesn't exist yet (pre-migration)
if (error?.message?.includes('no such table')) {
return undefined;
}
console.warn('[Fastfold] Failed to sync Flavo user to local DB:', error?.message || error);
return undefined;
}
}
//# sourceMappingURL=flavo-sync.js.map