@conform-to/react
Version:
Conform view adapter for react
241 lines (228 loc) • 6.8 kB
JavaScript
import { formatIssues, normalizeFormError, getPathValue, isPlainObject, setPathValue, parsePath, formatPath } from '@conform-to/dom/future';
function isUndefined(value) {
return value === undefined;
}
function isString(value) {
return typeof value === 'string';
}
function isNumber(value) {
return typeof value === 'number';
}
function isNullable(value, typeGuard) {
return value === null || typeGuard(value);
}
function isOptional(value, typeGuard) {
return isUndefined(value) || typeGuard(value);
}
function getPathArray(formValue, name) {
var _getPathValue;
var value = (_getPathValue = getPathValue(formValue, name)) !== null && _getPathValue !== void 0 ? _getPathValue : [];
if (!Array.isArray(value)) {
throw new Error("The value of \"".concat(name, "\" is not an array"));
}
return value;
}
/**
* Immutably updates a value at the specified path.
* Empty path replaces the entire object.
*/
function updatePathValue(data, name, value) {
if (name === '') {
if (!isPlainObject(value)) {
throw new Error('The value must be an object');
}
return value;
}
return setPathValue(data, parsePath(name), value, {
clone: true
});
}
/**
* Creates a function that updates array indices in field paths.
* Returns null to remove fields, or updated path with new index.
*/
function createPathIndexUpdater(listName, update) {
var listPaths = parsePath(listName);
return name => {
var paths = parsePath(name);
if (paths.length > listPaths.length && listPaths.every((path, index) => paths[index] === path)) {
var currentIndex = paths[listPaths.length];
if (typeof currentIndex === 'number') {
var newIndex = update(currentIndex);
if (newIndex === null) {
// To remove the item instead of updating it
return null;
}
if (newIndex !== currentIndex) {
// Replace the index
paths.splice(listPaths.length, 1, newIndex);
return formatPath(paths);
}
}
}
return name;
};
}
function resolveSerialize(customSerialize, _defaultSerialize) {
if (typeof customSerialize === 'undefined') {
return _defaultSerialize;
}
return function serializeValue(value, context) {
return customSerialize(value, {
name: context.name,
defaultSerialize: value => _defaultSerialize(value, context)
});
};
}
function normalizeValidateResult(result) {
if (result !== null && 'error' in result) {
return {
error: normalizeFormError(result.error),
value: result.value
};
}
return {
error: normalizeFormError(result)
};
}
/**
* Handles different validation result formats:
* - Promise: async validation only
* - Array: [syncResult, asyncPromise]
* - Object: sync validation only
*/
function resolveValidateResult(result) {
var syncResult;
var asyncResult;
if (result instanceof Promise) {
asyncResult = result;
} else if (Array.isArray(result)) {
syncResult = result[0];
asyncResult = result[1];
} else {
syncResult = result;
}
return {
syncResult: syncResult ? normalizeValidateResult(syncResult) : undefined,
asyncResult: asyncResult ? asyncResult.then(normalizeValidateResult) : undefined
};
}
/**
* Resolves a StandardSchema validation result to conform's format.
*/
function resolveStandardSchemaResult(result) {
if (!result.issues) {
return {
error: null,
value: result.value
};
}
return {
error: formatIssues(result.issues)
};
}
/**
* Create a copy of the object with the updated properties if there is any change
*/
function merge(obj, update) {
if (obj === update || Object.entries(update).every(_ref => {
var [key, value] = _ref;
return obj[key] === value;
})) {
return obj;
}
return Object.assign({}, obj, update);
}
/**
* Transforms object keys using a mapping function.
* Keys mapped to null are filtered out.
*/
function transformKeys(obj, fn) {
var result = {};
for (var [_key, _value2] of Object.entries(obj)) {
var _name = fn(_key);
if (_name !== null) {
result[_name] = _value2;
}
}
return result;
}
/**
* Appends item to array only if not already present.
* Returns original array if item exists, new array if added.
*/
function appendUniqueItem(list, item) {
if (list.includes(item)) {
return list;
}
return list.concat(item);
}
/**
* Maps over array and filters out null results.
*/
function compactMap(list, fn) {
var result = [];
for (var item of list) {
var _value3 = fn(item);
if (_value3 !== null) {
result.push(_value3);
}
}
return result;
}
function generateUniqueKey() {
return Math.trunc(Date.now() * Math.random()).toString(36);
}
/**
* Creates a type-only marker for TypeScript inference.
*
* This function always returns `true` at runtime. It exists
* purely to capture the generic type parameter for compile-time type checking.
* No runtime validation is performed.
*
* Common uses:
* - `isError`: Specify the error shape for type inference
* - `when`: Narrow field metadata to specific shapes for conditional props
*
* **Example: Specify error shape**
* ```ts
* configureForms({
* isError: shape<string[]>(), // errors are string arrays
* });
* ```
*
* **Example: Conditional field metadata**
* ```ts
* extendFieldMetadata(metadata, { when }) {
* return {
* get dateRangePickerProps() {
* return when(metadata, shape<{ start: string; end: string }>(), (m) => ({
* startName: m.getFieldset().start.name,
* endName: m.getFieldset().end.name,
* }));
* },
* };
* }
* ```
*/
function shape() {
return _value => true;
}
/**
* Creates a conditional field metadata property that is only available
* when the field shape matches the specified type.
*/
function when(metadata, _shape, fn) {
return fn(metadata);
}
function isStandardSchemaV1(schema) {
return typeof schema === 'object' && schema !== null && '~standard' in schema && typeof schema['~standard'] === 'object' && schema['~standard'] !== null && 'version' in schema['~standard'] && schema['~standard'].version === 1;
}
function validateStandardSchemaV1(schema, payload) {
var result = schema['~standard'].validate(payload);
if (result instanceof Promise) {
return result.then(actualResult => resolveStandardSchemaResult(actualResult));
}
return resolveStandardSchemaResult(result);
}
export { appendUniqueItem, compactMap, createPathIndexUpdater, generateUniqueKey, getPathArray, isNullable, isNumber, isOptional, isStandardSchemaV1, isString, isUndefined, merge, normalizeValidateResult, resolveSerialize, resolveStandardSchemaResult, resolveValidateResult, shape, transformKeys, updatePathValue, validateStandardSchemaV1, when };