From ff880c3cbfb730547bdca480dc8ef16dd06b5227 Mon Sep 17 00:00:00 2001 From: Elijah Duffy Date: Tue, 1 Jul 2025 15:07:57 -0700 Subject: [PATCH] convert to JSDoc comments --- index.ts | 151 +++++++++++++++++++++++++++++++--------------------- sanitize.ts | 10 ++++ 2 files changed, 100 insertions(+), 61 deletions(-) diff --git a/index.ts b/index.ts index 0d1aa4a..f949a8a 100644 --- a/index.ts +++ b/index.ts @@ -1,60 +1,70 @@ import type { Action } from 'svelte/action'; -// InputElement is a union of all input types that can be validated. +/** InputElement is a union of all input types that can be validated. */ export type InputElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement; -// InputNodeList is a union of all node lists that can be validated. +/** InputNodeList is a union of all node lists that can be validated. */ export type InputNodeList = NodeListOf | NodeListOf | []; -// ValidatorOptions configures the behavior of a validator. +/** ValidatorOptions configures the behavior of a validator. */ export type ValidatorOptions = { - required?: boolean; // required is a flag that indicates whether the input is required. - pattern?: RegExp; // pattern is a regex pattern that the input value must match. - minlength?: number; // minlength is the minimum length of the input value. - maxlength?: number; // maxlength is the maximum length of the input value. - length?: number; // length is the exact length of the input value. - type?: 'email' | 'phone' | 'score'; // NOT IMPLEMENTED. type is a predefined validation type. - baseval?: string; // baseval is a value that the input value must not match (an alternate zero-value). - autovalOnInvalid?: boolean; // autovalOnInvalid is a flag that automatically adds a keyup listener to the input on invalid. + /** required is a flag that indicates whether the input is required. */ + required?: boolean; + /** pattern is a regex pattern that the input value must match. */ + pattern?: RegExp; + /** minlength is the minimum length of the input value. */ + minlength?: number; + /** maxlength is the maximum length of the input value. */ + maxlength?: number; + /** length is the exact length of the input value. */ + length?: number; + /** NOT IMPLEMENTED. type is a predefined validation type. */ + type?: 'email' | 'phone' | 'score'; + /** baseval is a value that the input value must not match (an alternate zero-value). */ + baseval?: string; + /** autovalOnInvalid is a flag that automatically adds a keyup listener to the input on invalid. */ + autovalOnInvalid?: boolean; func?: (node: InputElement) => boolean | Promise; valfunc?: (val: string) => boolean | Promise; }; -// InputValidatorPayload carries the current value of an input element when it is validated. +/** InputValidatorPayload carries the current value of an input element when it is validated. */ export type InputValidatorPayload = { value: string; valid: boolean }; -// InputValidatorEvent is a custom event that is dispatched when an input is validated. +/** InputValidatorEvent is a custom event that is dispatched when an input is validated. */ export class InputValidatorEvent extends CustomEvent {} -// FormValidatorPayload carries a list of invalid and valid inputs when a form is validated. +/** FormValidatorPayload carries a list of invalid and valid inputs when a form is validated. */ export type FormValidatorPayload = { invalidInputs: InputElement[]; validInputs: InputElement[]; valid: boolean; }; -// FormValidatorEvent is a custom event that is dispatched when a form is validated. +/** FormValidatorEvent is a custom event that is dispatched when a form is validated. */ export class FormValidatorEvent extends CustomEvent {} -// ValidatorState is the state of a validator. +/** ValidatorState is the state of a validator. */ export type ValidatorState = 'unknown' | 'valid' | 'invalid'; const VALIDATOR_VALID: ValidatorState = 'valid'; const VALIDATOR_INVALID: ValidatorState = 'invalid'; const VALIDATOR_UNKNOWN: ValidatorState = 'unknown'; -// QUERY_INPUTS is the query string for all input elements that can be validated. +/** QUERY_INPUTS is the query string for all input elements that can be validated. */ const QUERY_INPUTS = 'input[data-validate-identifier], textarea[data-validate-identifier]'; -// DATA_ID is the key for the validator index in the input element's dataset. +/** DATA_ID is the key for the validator index in the input element's dataset. */ const DATA_ID = 'validateIdentifier'; -// DATA_STATE is the key for the validation state in the input element's dataset. +/** DATA_STATE is the key for the validation state in the input element's dataset. */ const DATA_STATE = 'validateState'; -// email is a regex pattern for validating email addresses. +/** email is a regex pattern for validating email addresses. */ export const email: RegExp = new RegExp(String.raw`^[^@\s]+@[^@\s]+\.[^@\s]+$`); -// phone is a regex pattern for validating phone numbers. +/** phone is a regex pattern for validating phone numbers. */ export const phone: RegExp = new RegExp(String.raw`^(\+)?(\(?\d+\)?)(([\s-]+)?(\d+)){0,}$`); -// score is a regex pattern for validating lesson grades. +/** score is a regex pattern for validating lesson grades. */ export const score: RegExp = new RegExp(String.raw`^(-?\d{0,2}|100)$`); -// InputState is some historical state of an input element, tracking its value, -// selectionStart and selectionEnd. +/** + * InputState is some historical state of an input element, tracking its value, + * selectionStart and selectionEnd. + */ export type InputState = { value: string; selectionStart: number; @@ -65,8 +75,10 @@ let nextValidatorID = 0; const validators: Record = {}; const lastState: Record = {}; -// validate attaches rules to an input element that can be used to validate the input. -// If opts is undefined, no validation rules will be attached. +/** + * validate attaches rules to an input element that can be used to validate the input. + * If opts is undefined, no validation rules will be attached. + */ export const validate: Action< InputElement, ValidatorOptions | undefined, @@ -105,10 +117,12 @@ export const validate: Action< }; }; -// keydownValidator attaches a keydown event listener to an input element that will -// process the input value according to any attached validation rules, triggering -// valid or invalid depending on validation success. If opts.constrain is true, -// the input value will be constrained to valid characters. +/** + * keydownValidator attaches a keydown event listener to an input element that will + * process the input value according to any attached validation rules, triggering + * valid or invalid depending on validation success. If opts.constrain is true, + * the input value will be constrained to valid characters. + */ export const keydownValidator: Action< InputElement, { @@ -131,9 +145,11 @@ export const keydownValidator: Action< }); }; -// keyupValidator attaches a keydown event listener to an input element that will -// process the input value according to any attached validation rules, triggering -// the `validate` event with the input value and validation state. +/** + * keyupValidator attaches a keydown event listener to an input element that will + * process the input value according to any attached validation rules, triggering + * the `validate` event with the input value and validation state. + */ export const keyupValidator: Action = (el) => { const node = el as HTMLInputElement; @@ -147,9 +163,11 @@ export const keyupValidator: Action = (el) => { }); }; -// inputValidator attaches an oninput event listener to an input element that will -// process the input value according to any attached validation rules, triggering -// the `validate` event with the input value and validation state. +/** + * inputValidator attaches an oninput event listener to an input element that will + * process the input value according to any attached validation rules, triggering + * the `validate` event with the input value and validation state. + */ export const inputValidator: Action = (el) => { const node = el as HTMLInputElement; @@ -162,10 +180,12 @@ export const inputValidator: Action = (el) => { }); }; -// liveValidator attaches multiple event listeners to an input element that will -// process the input value according to any attached validation rules, triggering -// the `validate` event with the input value and validation state. liveValidator -// supports the constrain option without introducing edge cases with text selection. +/** + * liveValidator attaches multiple event listeners to an input element that will + * process the input value according to any attached validation rules, triggering + * the `validate` event with the input value and validation state. liveValidator + * supports the constrain option without introducing edge cases with text selection. + */ export const liveValidator: Action< InputElement, { @@ -227,11 +247,13 @@ export const liveValidator: Action< node.addEventListener('input', inputHandler); }; -// submitValidator attaches a submit event listener to a form element that will -// process the input values of all children according to any attached validation -// rules, triggering the validate event for individual input elements -// depending on validation success. Similarly, the validate event -// event will be triggered on the form element itself. +/** + * submitValidator attaches a submit event listener to a form element that will + * process the input values of all children according to any attached validation + * rules, triggering the validate event for individual input elements + * depending on validation success. Similarly, the validate event + * event will be triggered on the form element itself. + */ export const submitValidator: Action< HTMLFormElement, undefined, @@ -254,8 +276,7 @@ export const submitValidator: Action< }); }; -// disableFormDefault helper action prevents the default form submission behavior -// and disables all browser validation. +/** disableFormDefault helper action prevents the default form submission behavior and disables all browser validation. */ export const disableFormDefault: Action = (form) => { form.setAttribute('novalidate', 'true'); form.addEventListener('submit', (event) => { @@ -263,10 +284,12 @@ export const disableFormDefault: Action = (form) => { }); }; -// validateInput checks an input element's value against its validation rules, triggering -// the validate events with the current value and validation state, updating the input's -// dataset accordingly. If opts.autovalOnInvalid is true, the input will be revalidated on -// on keyup automatically from now on. +/** + * validateInput checks an input element's value against its validation rules, triggering + * the validate events with the current value and validation state, updating the input's + * dataset accordingly. If opts.autovalOnInvalid is true, the input will be revalidated on + * on keyup automatically from now on. + */ export const validateInput = async ( input: InputElement, valueOverride?: string @@ -289,9 +312,11 @@ export const validateInput = async ( return valid; }; -// validateForm checks all input elements in a form element against their validation rules, -// triggering valid or invalid events for individual input elements depending on validation -// success. Similarly, valid and invalid events will be triggered on the form element. +/** + * validateForm checks all input elements in a form element against their validation rules, + * triggering valid or invalid events for individual input elements depending on validation + * success. Similarly, valid and invalid events will be triggered on the form element. + */ export const validateForm = async (form: HTMLFormElement): Promise => { const inputs = form.querySelectorAll(QUERY_INPUTS); @@ -321,7 +346,7 @@ export const validateForm = async (form: HTMLFormElement): Promise => { return valid; }; -// isInputValid checks an input element's value against its validation rules. +/** isInputValid checks an input element's value against its validation rules. */ export const isInputValid = async ( input: InputElement, valueOverride?: string @@ -360,7 +385,7 @@ export const isInputValid = async ( return true; }; -// isFormValid checks all input elements in a form element against their validation rules. +/** isFormValid checks all input elements in a form element against their validation rules. */ export const isFormValid = async (form: HTMLFormElement): Promise => { const inputs = form.querySelectorAll(QUERY_INPUTS); @@ -375,8 +400,10 @@ export const isFormValid = async (form: HTMLFormElement): Promise => { return valid; }; -// isValueValid checks a value against a set of validation rules. Note: node-based -// custom validator functions are not supported by this function. +/** + * isValueValid checks a value against a set of validation rules. Note: node-based + * custom validator functions are not supported by this function. + */ export const isValueValid = async (val: string, opts: ValidatorOptions): Promise => { console.debug('isValueValid', `val="${val}"`, 'opts:', opts); // if input is required and empty, return false @@ -424,15 +451,17 @@ export const isValueValid = async (val: string, opts: ValidatorOptions): Promise return true; }; -// getid returns the validator ID attached to an input element. Returns -1 if -// no ID is attached. +/** + * getid returns the validator ID attached to an input element. Returns -1 if + * no ID is attached. + */ export const getid = (input: InputElement): number => { const idstr = input.dataset[DATA_ID] || '-1'; const id = parseInt(idstr); return id; }; -// getopts returns the validation rules attached to an input element. +/** getopts returns the validation rules attached to an input element. */ export const getopts = (input: InputElement): ValidatorOptions | undefined => { const id = getid(input); return validators[id]; diff --git a/sanitize.ts b/sanitize.ts index c2581ac..e0c1ea1 100644 --- a/sanitize.ts +++ b/sanitize.ts @@ -1,3 +1,13 @@ +/** + * Sanitizes a FormData value by key, returning a trimmed string. + * If the key is not present, it throws an error or returns a fallback value. + * @param data - The FormData object to sanitize. + * @param key - The key to look for in the FormData. + * @param fallback - Optional fallback value to return if the key is not found. + * @returns The sanitized string value or the fallback value. + * @throws Error if the key is required and not found. + * @template Fallback - The type of the fallback value. + */ export function sanitize(data: FormData, key: string): string; export function sanitize( data: FormData,