36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
import type { SubmitFormResult } from '../forms/index.js'
|
|
import type { FormNotificationTexts } from './types.js'
|
|
|
|
/**
|
|
* Maps a submitForm result to the user-facing message, interpolating {field}
|
|
* for validation errors. This is the bridge the frontend uses: it gets a result
|
|
* code from submitForm and the resolved texts from getNotificationTexts, and
|
|
* this turns them into one string to display. Keeping the mapping here means the
|
|
* frontend never hard-codes messages or knows about result codes.
|
|
*
|
|
* Never surfaces raw backend/exception detail — 'error' maps to a friendly
|
|
* generic message, not the thrown error's text (which could leak internals).
|
|
*/
|
|
export function resolveFormMessage(result: SubmitFormResult, texts: FormNotificationTexts): string {
|
|
if (result.success) {return texts.success}
|
|
|
|
switch (result.reason) {
|
|
case 'consent':
|
|
return texts.consent
|
|
case 'not_found':
|
|
return texts.notFound
|
|
case 'rate_limited':
|
|
return texts.rateLimited
|
|
case 'turnstile':
|
|
return texts.turnstile
|
|
case 'validation': {
|
|
// Interpolate {field} with the offending field name when present.
|
|
const field = 'field' in result && result.field ? result.field : ''
|
|
return texts.validation.replace('{field}', field)
|
|
}
|
|
case 'error':
|
|
default:
|
|
return texts.error
|
|
}
|
|
}
|