0.1.3•Updated 6 months ago
// deno-lint-ignore-file no-explicit-any
type valid_value_types = string | boolean | number | Date | valid_value_types[]
type PostifyCallback<T extends Record<string, any> = Record<string, any>> = (error: Error | null, response?: T) => void;
interface PostifyOptions {
callback?: PostifyCallback | null
overrides: Record<string, any>
}
export const Postify = ({ callback, overrides = {} }: PostifyOptions) => async (e: SubmitEvent) => {
e.preventDefault();
e.stopPropagation();
const form = e.target as HTMLFormElement;
const data: Record<string, valid_value_types> = {};
const input_elements = form.querySelectorAll<HTMLInputElement>('input[name]');
for(const input of input_elements as any) {
const name = input.name as string;
let value: string | number | boolean | Date;
switch(input.type) {
case 'number': {
value = parseFloat(input.value);
break;
}
case 'checkbox': {
value = input.checked;
break;
}
case 'date': {
value = new Date(input.value);
break;
}
default: {
value = input.value;
}
}
if(data[name] === undefined) {
data[name] = value;
} else {
data[name] = [data[name], value].flat();
}
}
for(const [key, value] of Object.entries(overrides)) {
data[key] = value;
}
const result = await fetch(form.action, {
method: 'POST',
body: JSON.stringify(data)
});
if(!result.ok) return callback?.(new Error(`${result.statusText}\n${await result.text()}`));
try {
const response_body = await result.json() as Record<string, any>;
callback?.(null, response_body);
} catch(e: any) {
callback?.(new Error(`Could not parse response json. [${e.message}]`));
}
return false;
}