mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-15 02:23:07 +00:00
`campaignJsonMutationRoute` now builds every JSON POST route under /campanha — `isSameOriginRequest` had been copied into five of them, so the CSRF policy was failing open by omission; a convention guard sweeps all of `src/app` and names its three exceptions. `postCampaignJson` is the only place that spells `credentials: 'same-origin'`, and `useCampaignCellAutosave` is the debounce / abort / revert / flush-on-close machine the quick-edit cells shipped three times. The shell keeps the `aria-live` region outside the Popover/Drawer, since closing is what commits and it was unmounting the node that would announce the result; `variant="sheet"` took a `footer` slot, which let the signal control drop the overlay it only kept for one button. Two bugs the extraction made visible: a revert issued while a different payload was in flight was dropped silently, and `change()` never cleared a past failure, which outranks everything the live region would otherwise say.
25 lines
976 B
TypeScript
25 lines
976 B
TypeScript
/**
|
|
* Transport half of the list cells' quick edits: the preamble every control
|
|
* repeated around `fetch` (same-origin credentials, JSON headers, the cast of
|
|
* the discriminated response). Deliberately knows nothing about revert, retry
|
|
* or debounce — that is `useCampaignCellAutosave`'s, or the caller's.
|
|
*
|
|
* `ok` travels next to the payload because a route can answer a real body with
|
|
* a non-200 status (`engagement-level` returns its `blocked` state as 409), so
|
|
* the two are not the same question.
|
|
*/
|
|
export const postCampaignJson = async <TResponse>(
|
|
url: string,
|
|
body: unknown,
|
|
signal?: AbortSignal,
|
|
): Promise<{ ok: boolean; payload: TResponse }> => {
|
|
const response = await fetch(url, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
|
|
credentials: 'same-origin',
|
|
signal,
|
|
body: JSON.stringify(body),
|
|
})
|
|
|
|
return { ok: response.ok, payload: (await response.json()) as TResponse }
|
|
}
|