Socket
Socket
Sign inDemoInstall

@conform-to/dom

Package Overview
Dependencies
Maintainers
1
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@conform-to/dom - npm Package Compare versions

Comparing version 0.9.1 to 1.0.0-pre.0

form.d.ts

58

dom.d.ts

@@ -1,51 +0,43 @@

export type FormControl = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement;
export type Submitter = HTMLInputElement | HTMLButtonElement;
/**
* A type guard to check if the provided reference is a form control element, including
* `input`, `select`, `textarea` or `button`
* Element that user can interact with,
* includes `<input>`, `<select>` and `<textarea>`.
*/
export declare function isFormControl(element: unknown): element is FormControl;
export type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
/**
* A type guard to check if the provided reference is a focusable form control element.
* HTML Element that can be used as a form control,
* includes `<input>`, `<select>`, `<textarea>` and `<button>`.
*/
export declare function isFocusableFormControl(element: unknown): element is FormControl;
export type FormControl = FieldElement | HTMLButtonElement;
/**
* Resolves the form action based on the submit event
* Form Control element. It can either be a submit button or a submit input.
*/
export declare function getFormAction(event: SubmitEvent): string;
export type Submitter = HTMLInputElement | HTMLButtonElement;
/**
* Resolves the form encoding type based on the submit event
* A type guard to check if the provided element is a form control
*/
export declare function getFormEncType(event: SubmitEvent): 'application/x-www-form-urlencoded' | 'multipart/form-data';
export declare function isFormControl(element: unknown): element is FormControl;
/**
* Resolves the form method based on the submit event
* A type guard to check if the provided element is a field element, which
* is a form control excluding submit, button and reset type.
*/
export declare function getFormMethod(event: SubmitEvent): 'get' | 'post' | 'put' | 'patch' | 'delete';
export declare function isFieldElement(element: unknown): element is FieldElement;
/**
* Resolve the form element
* Resolves the action from the submit event
* with respect to the submitter `formaction` attribute.
*/
export declare function getFormElement(element: HTMLFormElement | HTMLFieldSetElement | HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement | null): HTMLFormElement | null;
export declare function getFormAction(event: SubmitEvent): string;
/**
* Returns a list of form control elements in the form
* Resolves the encoding type from the submit event
* with respect to the submitter `formenctype` attribute.
*/
export declare function getFormControls(form: HTMLFormElement): FormControl[];
export declare function getFormEncType(event: SubmitEvent): 'application/x-www-form-urlencoded' | 'multipart/form-data';
/**
* A function to create a submitter button element
* Resolves the method from the submit event
* with respect to the submitter `formmethod` attribute.
*/
export declare function createSubmitter(config: {
name: string;
value: string;
hidden?: boolean;
formAction?: string;
formEnctype?: ReturnType<typeof getFormEncType>;
formMethod?: ReturnType<typeof getFormMethod>;
formNoValidate?: boolean;
}): HTMLButtonElement;
export declare function getFormMethod(event: SubmitEvent): 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
/**
* Trigger form submission with a submitter.
* Trigger a form submit event with an optional submitter.
* If the submitter is not mounted, it will be appended to the form and removed after submission.
*/
export declare function requestSubmit(form: HTMLFormElement, submitter: Submitter | null): void;
/**
* Focus on the first invalid form control in the form
*/
export declare function focusFirstInvalidControl(form: HTMLFormElement): void;
export declare function requestSubmit(form: HTMLFormElement | null | undefined, submitter: Submitter | null): void;

@@ -5,6 +5,21 @@ 'use strict';

var util = require('./util.js');
/**
* A type guard to check if the provided reference is a form control element, including
* `input`, `select`, `textarea` or `button`
* Element that user can interact with,
* includes `<input>`, `<select>` and `<textarea>`.
*/
/**
* HTML Element that can be used as a form control,
* includes `<input>`, `<select>`, `<textarea>` and `<button>`.
*/
/**
* Form Control element. It can either be a submit button or a submit input.
*/
/**
* A type guard to check if the provided element is a form control
*/
function isFormControl(element) {

@@ -15,10 +30,12 @@ return element instanceof Element && (element.tagName === 'INPUT' || element.tagName === 'SELECT' || element.tagName === 'TEXTAREA' || element.tagName === 'BUTTON');

/**
* A type guard to check if the provided reference is a focusable form control element.
* A type guard to check if the provided element is a field element, which
* is a form control excluding submit, button and reset type.
*/
function isFocusableFormControl(element) {
return isFormControl(element) && element.willValidate && element.type !== 'submit';
function isFieldElement(element) {
return isFormControl(element) && element.type !== 'submit' && element.type !== 'button' && element.type !== 'reset';
}
/**
* Resolves the form action based on the submit event
* Resolves the action from the submit event
* with respect to the submitter `formaction` attribute.
*/

@@ -33,3 +50,4 @@ function getFormAction(event) {

/**
* Resolves the form encoding type based on the submit event
* Resolves the encoding type from the submit event
* with respect to the submitter `formenctype` attribute.
*/

@@ -48,63 +66,26 @@ function getFormEncType(event) {

/**
* Resolves the form method based on the submit event
* Resolves the method from the submit event
* with respect to the submitter `formmethod` attribute.
*/
function getFormMethod(event) {
var _submitter$getAttribu3;
var _ref2, _submitter$getAttribu3;
var form = event.target;
var submitter = event.submitter;
var method = (_submitter$getAttribu3 = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute('formmethod')) !== null && _submitter$getAttribu3 !== void 0 ? _submitter$getAttribu3 : form.getAttribute('method');
var method = (_ref2 = (_submitter$getAttribu3 = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute('formmethod')) !== null && _submitter$getAttribu3 !== void 0 ? _submitter$getAttribu3 : form.getAttribute('method')) === null || _ref2 === void 0 ? void 0 : _ref2.toUpperCase();
switch (method) {
case 'post':
case 'put':
case 'patch':
case 'delete':
case 'POST':
case 'PUT':
case 'PATCH':
case 'DELETE':
return method;
}
return 'get';
return 'GET';
}
/**
* Resolve the form element
* Trigger a form submit event with an optional submitter.
* If the submitter is not mounted, it will be appended to the form and removed after submission.
*/
function getFormElement(element) {
var _element$form;
return element instanceof HTMLFormElement ? element : (_element$form = element === null || element === void 0 ? void 0 : element.form) !== null && _element$form !== void 0 ? _element$form : null;
}
/**
* Returns a list of form control elements in the form
*/
function getFormControls(form) {
return Array.from(form.elements).filter(isFormControl);
}
/**
* A function to create a submitter button element
*/
function createSubmitter(config) {
var button = document.createElement('button');
button.name = config.name;
button.value = config.value;
if (config.hidden) {
button.hidden = true;
}
if (config.formAction) {
button.formAction = config.formAction;
}
if (config.formEnctype) {
button.formEnctype = config.formEnctype;
}
if (config.formMethod) {
button.formMethod = config.formMethod;
}
if (config.formNoValidate) {
button.formNoValidate = true;
}
return button;
}
/**
* Trigger form submission with a submitter.
*/
function requestSubmit(form, submitter) {
util.invariant(!!form, 'Failed to submit the form. The element provided is null or undefined.');
var shouldRemoveSubmitter = false;

@@ -130,23 +111,7 @@ if (submitter && !submitter.isConnected) {

/**
* Focus on the first invalid form control in the form
*/
function focusFirstInvalidControl(form) {
for (var element of form.elements) {
if (isFocusableFormControl(element) && !element.validity.valid) {
element.focus();
break;
}
}
}
exports.createSubmitter = createSubmitter;
exports.focusFirstInvalidControl = focusFirstInvalidControl;
exports.getFormAction = getFormAction;
exports.getFormControls = getFormControls;
exports.getFormElement = getFormElement;
exports.getFormEncType = getFormEncType;
exports.getFormMethod = getFormMethod;
exports.isFocusableFormControl = isFocusableFormControl;
exports.isFieldElement = isFieldElement;
exports.isFormControl = isFormControl;
exports.requestSubmit = requestSubmit;
/**
* A ponyfill-like helper to get the form data with the submitter value.
* It does not respect the tree order nor handles the image input.
* Construct a form data with the submitter value.
* It utilizes the submitter argument on the FormData constructor from modern browsers
* with fallback to append the submitter value in case it is not unsupported.
*

@@ -25,18 +26,25 @@ * @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData#parameters

/**
* Check if a name match the prefix paths
*/
export declare function isPrefix(name: string, prefix: string): boolean;
/**
* Assign a value to a target object by following the paths on the name
*/
export declare function setValue(target: Record<string, any>, name: string, valueFn: (prev?: unknown) => any): void;
export declare function setValue<Value>(target: Record<string, any>, name: string, valueFn: (prev?: unknown) => Value): Value;
/**
* Resolves the payload into a plain object based on the JS syntax convention
* Check if a value is a plain object
*/
export declare function resolve(payload: FormData | URLSearchParams, options?: {
ignoreKeys?: string[];
}): {};
export declare function isPlainObject(obj: unknown): obj is Record<string | number | symbol, unknown>;
/**
* Format the error messages into a validation message
* Simplify value by removing empty object or array and null values
*/
export declare function getValidationMessage(errors?: string[]): string;
export declare function simplify<Type extends Record<string, unknown>>(value: Type): Record<string, unknown> | undefined;
export declare function simplify<Type extends Array<unknown>>(value: Type): Array<unknown> | undefined;
export declare function simplify(value: unknown): unknown | undefined;
/**
* Retrieve the error messages from the validation message
* Flatten a tree into a dictionary
*/
export declare function getErrors(validationMessage: string | undefined): string[];
export declare function flatten(data: Record<string | number | symbol, unknown> | Array<unknown> | undefined, options?: {
resolve?: (data: unknown) => unknown | null;
prefix?: string;
}): Record<string, unknown>;

@@ -6,12 +6,17 @@ 'use strict';

/**
* A ponyfill-like helper to get the form data with the submitter value.
* It does not respect the tree order nor handles the image input.
* Construct a form data with the submitter value.
* It utilizes the submitter argument on the FormData constructor from modern browsers
* with fallback to append the submitter value in case it is not unsupported.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData#parameters
*/
function getFormData(form, submitter) {
var payload = new FormData(form);
var payload = new FormData(form, submitter);
if (submitter && submitter.type === 'submit' && submitter.name !== '') {
payload.append(submitter.name, submitter.value);
var entries = payload.getAll(submitter.name);
// This assumes the submitter value to be always unique, which should be fine in most cases
if (!entries.includes(submitter.value)) {
payload.append(submitter.name, submitter.value);
}
}

@@ -65,2 +70,11 @@ return payload;

/**
* Check if a name match the prefix paths
*/
function isPrefix(name, prefix) {
var paths = getPaths(name);
var prefixPaths = getPaths(prefix);
return paths.length >= prefixPaths.length && prefixPaths.every((path, index) => paths[index] === path);
}
/**
* Assign a value to a target object by following the paths on the name

@@ -82,57 +96,104 @@ */

}
// @ts-expect-error: The pointer should be assigned with the result of the valueFn
return pointer;
}
/**
* Resolves the payload into a plain object based on the JS syntax convention
* Check if a value is a plain object
*/
function resolve(payload) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var data = {};
var _loop = function _loop(value) {
var _options$ignoreKeys;
if ((_options$ignoreKeys = options.ignoreKeys) !== null && _options$ignoreKeys !== void 0 && _options$ignoreKeys.includes(key)) {
return "continue";
}
setValue(data, key, prev => {
if (!prev) {
return value;
} else if (Array.isArray(prev)) {
return prev.concat(value);
} else {
return [prev, value];
}
});
};
for (var [key, value] of payload.entries()) {
var _ret = _loop(value);
if (_ret === "continue") continue;
}
return data;
function isPlainObject(obj) {
return !!obj && obj.constructor === Object && Object.getPrototypeOf(obj) === Object.prototype;
}
/**
* Format the error messages into a validation message
* Simplify value by removing empty object or array and null values
*/
function getValidationMessage(errors) {
var _errors$join;
return (_errors$join = errors === null || errors === void 0 ? void 0 : errors.join(String.fromCharCode(31))) !== null && _errors$join !== void 0 ? _errors$join : '';
function simplify(value) {
if (isPlainObject(value)) {
var obj = Object.entries(value).reduce((result, _ref) => {
var [key, value] = _ref;
var data = simplify(value);
if (typeof data !== 'undefined') {
result[key] = data;
}
return result;
}, {});
if (Object.keys(obj).length === 0) {
return;
}
return obj;
}
if (Array.isArray(value)) {
if (value.length === 0) {
return undefined;
}
return value.map(simplify);
}
if (value instanceof File || value === null) {
return;
}
return value;
}
/**
* Retrieve the error messages from the validation message
* Flatten a tree into a dictionary
*/
function getErrors(validationMessage) {
// Empty string should be considered no error as well
if (!validationMessage) {
return [];
function flatten(data, options) {
var _options$resolve;
var result = {};
var resolve = (_options$resolve = options === null || options === void 0 ? void 0 : options.resolve) !== null && _options$resolve !== void 0 ? _options$resolve : data => data;
function setResult(data, name) {
var value = simplify(resolve(data));
if (typeof value !== 'undefined') {
result[name] = value;
}
}
return validationMessage.split(String.fromCharCode(31));
function processObject(obj, prefix) {
setResult(obj, prefix);
for (var [key, _value] of Object.entries(obj)) {
var name = prefix ? "".concat(prefix, ".").concat(key) : key;
if (Array.isArray(_value)) {
processArray(_value, name);
} else if (_value && isPlainObject(_value)) {
processObject(_value, name);
} else {
setResult(_value, name);
}
}
}
function processArray(array, prefix) {
setResult(array, prefix);
for (var i = 0; i < array.length; i++) {
var item = array[i];
var name = "".concat(prefix, "[").concat(i, "]");
if (Array.isArray(item)) {
processArray(item, name);
} else if (item && isPlainObject(item)) {
processObject(item, name);
} else {
setResult(item, name);
}
}
}
if (data) {
var _options$prefix;
var prefix = (_options$prefix = options === null || options === void 0 ? void 0 : options.prefix) !== null && _options$prefix !== void 0 ? _options$prefix : '';
if (Array.isArray(data)) {
processArray(data, prefix);
} else {
processObject(data, prefix);
}
}
return result;
}
exports.flatten = flatten;
exports.formatPaths = formatPaths;
exports.getErrors = getErrors;
exports.getFormData = getFormData;
exports.getPaths = getPaths;
exports.getValidationMessage = getValidationMessage;
exports.resolve = resolve;
exports.isPlainObject = isPlainObject;
exports.isPrefix = isPrefix;
exports.setValue = setValue;
exports.simplify = simplify;

@@ -1,5 +0,5 @@

export { type FormControl as FieldElement, isFormControl as isFieldElement, isFocusableFormControl, getFormAction, getFormControls, getFormElement, getFormEncType, getFormMethod, focusFirstInvalidControl, createSubmitter, requestSubmit, } from './dom.js';
export { formatPaths as getName, getPaths, getFormData, getValidationMessage, getErrors, } from './formdata.js';
export { INTENT, getIntent, parseIntent, validate, list, updateList, requestIntent, } from './intent.js';
export { type Submission, parse, VALIDATION_SKIPPED, VALIDATION_UNDEFINED, } from './parse.js';
export { type FieldConstraint, type FieldsetConstraint, type ResolveType, type KeysOf, } from './types.js';
export { type UnionKeyof, type UnionKeyType, type Constraint, type FormState, type FieldName, type FormValue, type FormContext, type FormOptions, type Form, type SubscriptionSubject, type SubscriptionScope, VALIDATION_SKIPPED, VALIDATION_UNDEFINED, createForm, } from './form';
export { type FieldElement, isFieldElement } from './dom';
export { invariant } from './util';
export { type Submission, type SubmissionResult, type ListIntentPayload, INTENT, STATE, list, validate, requestIntent, parse, } from './submission';
export { getPaths, formatPaths, isPrefix } from './formdata';

@@ -5,33 +5,23 @@ 'use strict';

var form = require('./form.js');
var dom = require('./dom.js');
var util = require('./util.js');
var submission = require('./submission.js');
var formdata = require('./formdata.js');
var intent = require('./intent.js');
var parse = require('./parse.js');
exports.createSubmitter = dom.createSubmitter;
exports.focusFirstInvalidControl = dom.focusFirstInvalidControl;
exports.getFormAction = dom.getFormAction;
exports.getFormControls = dom.getFormControls;
exports.getFormElement = dom.getFormElement;
exports.getFormEncType = dom.getFormEncType;
exports.getFormMethod = dom.getFormMethod;
exports.isFieldElement = dom.isFormControl;
exports.isFocusableFormControl = dom.isFocusableFormControl;
exports.requestSubmit = dom.requestSubmit;
exports.getErrors = formdata.getErrors;
exports.getFormData = formdata.getFormData;
exports.getName = formdata.formatPaths;
exports.VALIDATION_SKIPPED = form.VALIDATION_SKIPPED;
exports.VALIDATION_UNDEFINED = form.VALIDATION_UNDEFINED;
exports.createForm = form.createForm;
exports.isFieldElement = dom.isFieldElement;
exports.invariant = util.invariant;
exports.INTENT = submission.INTENT;
exports.STATE = submission.STATE;
exports.list = submission.list;
exports.parse = submission.parse;
exports.requestIntent = submission.requestIntent;
exports.validate = submission.validate;
exports.formatPaths = formdata.formatPaths;
exports.getPaths = formdata.getPaths;
exports.getValidationMessage = formdata.getValidationMessage;
exports.INTENT = intent.INTENT;
exports.getIntent = intent.getIntent;
exports.list = intent.list;
exports.parseIntent = intent.parseIntent;
exports.requestIntent = intent.requestIntent;
exports.updateList = intent.updateList;
exports.validate = intent.validate;
exports.VALIDATION_SKIPPED = parse.VALIDATION_SKIPPED;
exports.VALIDATION_UNDEFINED = parse.VALIDATION_UNDEFINED;
exports.parse = parse.parse;
exports.isPrefix = formdata.isPrefix;

@@ -6,3 +6,3 @@ {

"license": "MIT",
"version": "0.9.1",
"version": "1.0.0-pre.0",
"main": "index.js",

@@ -9,0 +9,0 @@ "module": "index.mjs",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc