@conform-to/dom
Advanced tools
Comparing version 1.0.2 to 1.0.3
@@ -8,7 +8,7 @@ import { getFormAction, getFormEncType, getFormMethod } from './dom'; | ||
export type DefaultValue<Schema> = Schema extends string | number | boolean | Date | bigint | null | undefined ? Schema | string | null | undefined : Schema extends File ? null | undefined : Schema extends Array<infer Item> ? Array<DefaultValue<Item>> | null | undefined : Schema extends Record<string, any> ? { | ||
[Key in keyof Combine<Schema>]?: DefaultValue<Combine<Schema>[Key]>; | ||
[Key in keyof Schema]?: DefaultValue<Schema[Key]>; | ||
} | null | undefined : string | null | undefined; | ||
export type FormValue<Schema> = Schema extends string | number | boolean | Date | bigint | null | undefined ? string | undefined : Schema extends File ? File | undefined : Schema extends File[] ? File | Array<File> | undefined : Schema extends Array<infer Item> ? string | Array<FormValue<Item>> | undefined : Schema extends Record<string, any> ? { | ||
[Key in keyof Combine<Schema>]?: DefaultValue<Combine<Schema>[Key]>; | ||
} | undefined : unknown; | ||
[Key in keyof Schema]?: FormValue<Schema[Key]>; | ||
} | null | undefined : unknown; | ||
declare const error: unique symbol; | ||
@@ -94,2 +94,6 @@ declare const field: unique symbol; | ||
}) => Submission<Schema, FormError, FormValue>; | ||
/** | ||
* To schedule when an intent should be dispatched. | ||
*/ | ||
onSchedule?: (callback: () => void) => void; | ||
}; | ||
@@ -96,0 +100,0 @@ export type SubscriptionSubject = { |
139
form.js
@@ -14,5 +14,3 @@ 'use strict'; | ||
var lastResult = !initialized ? options.lastResult : undefined; | ||
var defaultValue = options.defaultValue ? | ||
// @ts-expect-error | ||
submission.serialize(options.defaultValue) : {}; | ||
var defaultValue = options.defaultValue ? submission.serialize(options.defaultValue) : {}; | ||
var initialValue = (_lastResult$initialVa = lastResult === null || lastResult === void 0 ? void 0 : lastResult.initialValue) !== null && _lastResult$initialVa !== void 0 ? _lastResult$initialVa : defaultValue; | ||
@@ -33,5 +31,3 @@ var result = { | ||
}; | ||
if (lastResult !== null && lastResult !== void 0 && lastResult.intent) { | ||
handleIntent(result, lastResult.intent); | ||
} | ||
handleIntent(result, lastResult === null || lastResult === void 0 ? void 0 : lastResult.intent, lastResult === null || lastResult === void 0 ? void 0 : lastResult.fields); | ||
return result; | ||
@@ -52,12 +48,53 @@ } | ||
} | ||
function handleIntent(meta, intent, initialized) { | ||
function setFieldsValidated(meta, fields) { | ||
for (var _name of Object.keys(meta.error).concat(fields !== null && fields !== void 0 ? fields : [])) { | ||
meta.validated[_name] = true; | ||
} | ||
} | ||
function handleIntent(meta, intent, fields, initialized) { | ||
if (!intent) { | ||
setFieldsValidated(meta, fields); | ||
return; | ||
} | ||
switch (intent.type) { | ||
case 'validate': | ||
{ | ||
if (intent.payload.name) { | ||
meta.validated[intent.payload.name] = true; | ||
} else { | ||
setFieldsValidated(meta, fields); | ||
} | ||
break; | ||
} | ||
case 'update': | ||
{ | ||
if (typeof intent.payload.value !== 'undefined') { | ||
var _intent$payload$name; | ||
var _name = (_intent$payload$name = intent.payload.name) !== null && _intent$payload$name !== void 0 ? _intent$payload$name : ''; | ||
var value = submission.serialize(intent.payload.value); | ||
updateValue(meta, _name, value); | ||
var { | ||
name: _name2, | ||
validated, | ||
value | ||
} = intent.payload; | ||
if (typeof value !== 'undefined') { | ||
updateValue(meta, _name2 !== null && _name2 !== void 0 ? _name2 : '', submission.serialize(value)); | ||
} | ||
if (typeof validated !== 'undefined') { | ||
// Clean up previous validated state | ||
if (_name2) { | ||
submission.setState(meta.validated, _name2, () => undefined); | ||
} else { | ||
meta.validated = {}; | ||
} | ||
if (validated) { | ||
if (formdata.isPlainObject(value) || Array.isArray(value)) { | ||
Object.assign(meta.validated, formdata.flatten(value, { | ||
resolve() { | ||
return true; | ||
}, | ||
prefix: _name2 | ||
})); | ||
} | ||
meta.validated[_name2 !== null && _name2 !== void 0 ? _name2 : ''] = true; | ||
} else if (_name2) { | ||
delete meta.validated[_name2]; | ||
} | ||
} | ||
break; | ||
@@ -67,6 +104,12 @@ } | ||
{ | ||
var _intent$payload$name2; | ||
var _name2 = (_intent$payload$name2 = intent.payload.name) !== null && _intent$payload$name2 !== void 0 ? _intent$payload$name2 : ''; | ||
var _value = formdata.getValue(meta.defaultValue, _name2); | ||
updateValue(meta, _name2, _value); | ||
var _intent$payload$name; | ||
var _name3 = (_intent$payload$name = intent.payload.name) !== null && _intent$payload$name !== void 0 ? _intent$payload$name : ''; | ||
var _value = formdata.getValue(meta.defaultValue, _name3); | ||
updateValue(meta, _name3, _value); | ||
if (_name3) { | ||
submission.setState(meta.validated, _name3, () => undefined); | ||
delete meta.validated[_name3]; | ||
} else { | ||
meta.validated = {}; | ||
} | ||
break; | ||
@@ -84,5 +127,14 @@ } | ||
} | ||
submission.setListState(meta.validated, intent); | ||
meta.validated[intent.payload.name] = true; | ||
break; | ||
} | ||
} | ||
meta.error = Object.entries(meta.error).reduce((result, _ref3) => { | ||
var [name, error] = _ref3; | ||
if (meta.validated[name]) { | ||
result[name] = error; | ||
} | ||
return result; | ||
}, {}); | ||
} | ||
@@ -178,4 +230,4 @@ function updateValue(meta, name, value) { | ||
if (name === '' && key === '' && value) { | ||
return Object.entries(value).reduce((result, _ref3) => { | ||
var [name, value] = _ref3; | ||
return Object.entries(value).reduce((result, _ref4) => { | ||
var [name, value] = _ref4; | ||
if (!shouldDirtyConsider(name)) { | ||
@@ -199,7 +251,7 @@ return result; | ||
var list = prefixes.length === 0 ? names : Array.from(new Set([...Object.keys(prev), ...Object.keys(next)])); | ||
var _loop = function _loop(_name3) { | ||
if (prefixes.length === 0 || names.includes(_name3) || prefixes.some(prefix => formdata.isPrefix(_name3, prefix))) { | ||
var _loop = function _loop(_name4) { | ||
if (prefixes.length === 0 || names.includes(_name4) || prefixes.some(prefix => formdata.isPrefix(_name4, prefix))) { | ||
var _cache$_name; | ||
(_cache$_name = cache[_name3]) !== null && _cache$_name !== void 0 ? _cache$_name : cache[_name3] = compareFn(prev[_name3], next[_name3]); | ||
if (cache[_name3]) { | ||
(_cache$_name = cache[_name4]) !== null && _cache$_name !== void 0 ? _cache$_name : cache[_name4] = compareFn(prev[_name4], next[_name4]); | ||
if (cache[_name4]) { | ||
return { | ||
@@ -212,4 +264,4 @@ v: true | ||
_ret; | ||
for (var _name3 of list) { | ||
_ret = _loop(_name3); | ||
for (var _name4 of list) { | ||
_ret = _loop(_name4); | ||
if (_ret) return _ret.v; | ||
@@ -279,15 +331,2 @@ } | ||
} | ||
function getStateInput(form) { | ||
var element = form.elements.namedItem(submission.STATE); | ||
util.invariant(element === null || dom.isFieldElement(element), "The input name \"".concat(submission.STATE, "\" is reserved by Conform. Please use another name.")); | ||
if (!element) { | ||
var input = document.createElement('input'); | ||
input.type = 'hidden'; | ||
input.name = submission.STATE; | ||
input.value = ''; | ||
form.append(input); | ||
return input; | ||
} | ||
return element; | ||
} | ||
function getSerializedState() { | ||
@@ -302,6 +341,2 @@ return JSON.stringify({ | ||
util.invariant(form === getFormElement(), "The submit event is dispatched by form#".concat(form.id, " instead of form#").concat(latestOptions.formId)); | ||
var input = getStateInput(form); | ||
// To ensure it capturing latest state before parsing | ||
input.value = getSerializedState(); | ||
var formData = formdata.getFormData(form, submitter); | ||
@@ -385,3 +420,3 @@ var result = { | ||
function report(result) { | ||
var _result$error, _result$state$validat, _result$state; | ||
var _result$error, _result$state; | ||
var formElement = getFormElement(); | ||
@@ -392,4 +427,4 @@ if (!result.initialValue) { | ||
} | ||
var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result, _ref4) => { | ||
var [name, newError] = _ref4; | ||
var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result, _ref5) => { | ||
var [name, newError] = _ref5; | ||
var error = newError === null ? meta.error[name] : newError; | ||
@@ -404,12 +439,10 @@ if (error) { | ||
value: result.initialValue, | ||
error, | ||
validated: (_result$state$validat = (_result$state = result.state) === null || _result$state === void 0 ? void 0 : _result$state.validated) !== null && _result$state$validat !== void 0 ? _result$state$validat : {} | ||
validated: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, meta.validated), (_result$state = result.state) === null || _result$state === void 0 ? void 0 : _result$state.validated), | ||
error | ||
}); | ||
if (result.intent) { | ||
handleIntent(update, result.intent, true); | ||
} | ||
handleIntent(update, result.intent, result.fields, true); | ||
updateFormMeta(update); | ||
if (formElement && result.status === 'error') { | ||
for (var element of formElement.elements) { | ||
if (dom.isFieldElement(element) && error[element.name]) { | ||
if (dom.isFieldElement(element) && meta.error[element.name]) { | ||
element.focus(); | ||
@@ -468,8 +501,10 @@ break; | ||
function createFormControl(type) { | ||
var _latestOptions$onSche; | ||
var schedule = (_latestOptions$onSche = latestOptions.onSchedule) !== null && _latestOptions$onSche !== void 0 ? _latestOptions$onSche : callback => callback(); | ||
var control = function control() { | ||
var payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return dispatch({ | ||
return schedule(() => dispatch({ | ||
type, | ||
payload | ||
}); | ||
})); | ||
}; | ||
@@ -476,0 +511,0 @@ return Object.assign(control, { |
@@ -48,5 +48,5 @@ /** | ||
*/ | ||
export declare function normalize<Type extends Record<string, unknown>>(value: Type | null): Type | null | undefined; | ||
export declare function normalize<Type extends Array<unknown>>(value: Type | null): Type | null | undefined; | ||
export declare function normalize(value: unknown): unknown | undefined; | ||
export declare function normalize<Type extends Record<string, unknown>>(value: Type, acceptFile?: boolean): Type | undefined; | ||
export declare function normalize<Type extends Array<unknown>>(value: Type, acceptFile?: boolean): Type | undefined; | ||
export declare function normalize(value: unknown, acceptFile?: boolean): unknown | undefined; | ||
/** | ||
@@ -53,0 +53,0 @@ * Flatten a tree into a dictionary |
@@ -139,5 +139,6 @@ 'use strict'; | ||
function normalize(value) { | ||
var acceptFile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | ||
if (isPlainObject(value)) { | ||
var obj = Object.keys(value).sort().reduce((result, key) => { | ||
var data = normalize(value[key]); | ||
var data = normalize(value[key], acceptFile); | ||
if (typeof data !== 'undefined') { | ||
@@ -157,16 +158,7 @@ result[key] = data; | ||
} | ||
return value.map(normalize); | ||
return value.map(item => normalize(item, acceptFile)); | ||
} | ||
if (typeof value === 'string' && value === '' || value === null || isFile(value) && value.size === 0) { | ||
if (typeof value === 'string' && value === '' || value === null || isFile(value) && (!acceptFile || value.size === 0)) { | ||
return; | ||
} | ||
// We will skip serializing file if the result is sent to the client | ||
if (isFile(value)) { | ||
return Object.assign(value, { | ||
toJSON() { | ||
return; | ||
} | ||
}); | ||
} | ||
return value; | ||
@@ -173,0 +165,0 @@ } |
@@ -6,3 +6,3 @@ { | ||
"license": "MIT", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"main": "index.js", | ||
@@ -9,0 +9,0 @@ "module": "index.mjs", |
@@ -8,6 +8,6 @@ import type { DefaultValue, FieldName, FormValue } from './form'; | ||
payload: Record<string, unknown>; | ||
fields: string[]; | ||
fields: Set<string>; | ||
value?: Value; | ||
error?: Record<string, FormError | null> | null; | ||
state: SubmissionState; | ||
state?: SubmissionState; | ||
}; | ||
@@ -29,2 +29,3 @@ export type Submission<Schema, FormError = string[], FormValue = Schema> = { | ||
initialValue?: Record<string, unknown> | null; | ||
fields?: string[]; | ||
error?: Record<string, FormError | null>; | ||
@@ -31,0 +32,0 @@ state?: SubmissionState; |
@@ -21,5 +21,11 @@ 'use strict'; | ||
var state = body.get(STATE); | ||
var payload = {}; | ||
var fields = []; | ||
util.invariant((typeof intent === 'string' || intent === null) && (typeof state === 'string' || state === null), "The input name \"".concat(INTENT, "\" and \"").concat(STATE, "\" are reserved by Conform. Please use another name for your input.")); | ||
var context = { | ||
payload: {}, | ||
fields: new Set(), | ||
intent: getIntent(intent) | ||
}; | ||
if (state) { | ||
context.state = JSON.parse(state); | ||
} | ||
var _loop = function _loop(next) { | ||
@@ -29,4 +35,4 @@ if (name === INTENT || name === STATE) { | ||
} | ||
fields.push(name); | ||
formdata.setValue(payload, name, prev => { | ||
context.fields.add(name); | ||
formdata.setValue(context.payload, name, prev => { | ||
if (!prev) { | ||
@@ -44,10 +50,3 @@ return next; | ||
} | ||
return { | ||
payload, | ||
intent: getIntent(intent), | ||
state: state ? JSON.parse(state) : { | ||
validated: {} | ||
}, | ||
fields | ||
}; | ||
return context; | ||
} | ||
@@ -59,12 +58,6 @@ function parse(payload, options) { | ||
switch (intent.type) { | ||
case 'validate': | ||
if (intent.payload.name) { | ||
context.state.validated[intent.payload.name] = true; | ||
} | ||
break; | ||
case 'update': | ||
{ | ||
var { | ||
name, | ||
validated | ||
name | ||
} = intent.payload; | ||
@@ -80,23 +73,2 @@ var _value = serialize(intent.payload.value); | ||
} | ||
if (typeof validated !== 'undefined') { | ||
// Clean up previous validated state | ||
if (name) { | ||
setState(context.state.validated, name, () => undefined); | ||
} else { | ||
context.state.validated = {}; | ||
} | ||
if (validated) { | ||
if (formdata.isPlainObject(_value) || Array.isArray(_value)) { | ||
Object.assign(context.state.validated, formdata.flatten(_value, { | ||
resolve() { | ||
return true; | ||
}, | ||
prefix: name | ||
})); | ||
} | ||
context.state.validated[name !== null && name !== void 0 ? name : ''] = true; | ||
} else if (name) { | ||
delete context.state.validated[name]; | ||
} | ||
} | ||
break; | ||
@@ -111,7 +83,4 @@ } | ||
formdata.setValue(context.payload, _name, () => undefined); | ||
setState(context.state.validated, _name, () => undefined); | ||
delete context.state.validated[_name]; | ||
} else { | ||
context.payload = {}; | ||
context.state.validated = {}; | ||
} | ||
@@ -125,4 +94,2 @@ break; | ||
setListValue(context.payload, intent); | ||
setListState(context.state.validated, intent); | ||
context.state.validated[intent.payload.name] = true; | ||
break; | ||
@@ -133,14 +100,6 @@ } | ||
var result = options.resolve(context.payload, intent); | ||
var mergeResolveResult = resolved => { | ||
var error = typeof resolved.error !== 'undefined' ? resolved.error : {}; | ||
if (!intent || intent.type === 'validate' && !intent.payload.name) { | ||
for (var _name2 of [...context.fields, ...Object.keys(error !== null && error !== void 0 ? error : {})]) { | ||
context.state.validated[_name2] = true; | ||
} | ||
} | ||
return createSubmission(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context), {}, { | ||
value: resolved.value, | ||
error: resolved.error | ||
})); | ||
}; | ||
var mergeResolveResult = resolved => createSubmission(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context), {}, { | ||
value: resolved.value, | ||
error: resolved.error | ||
})); | ||
if (result instanceof Promise) { | ||
@@ -172,17 +131,5 @@ return result.then(mergeResolveResult); | ||
function replySubmission(context) { | ||
var _context$intent, _options$formErrors, _normalize; | ||
var _context$intent, _context$intent$paylo, _options$formErrors, _normalize; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
switch ((_context$intent = context.intent) === null || _context$intent === void 0 ? void 0 : _context$intent.type) { | ||
case 'reset': | ||
{ | ||
var _context$intent$paylo; | ||
var name = (_context$intent$paylo = context.intent.payload.name) !== null && _context$intent$paylo !== void 0 ? _context$intent$paylo : ''; | ||
if (name === '') { | ||
return { | ||
initialValue: null | ||
}; | ||
} | ||
} | ||
} | ||
if ('resetForm' in options && options.resetForm) { | ||
if ('resetForm' in options && options.resetForm || ((_context$intent = context.intent) === null || _context$intent === void 0 ? void 0 : _context$intent.type) === 'reset' && ((_context$intent$paylo = context.intent.payload.name) !== null && _context$intent$paylo !== void 0 ? _context$intent$paylo : '') === '') { | ||
return { | ||
@@ -193,26 +140,22 @@ initialValue: null | ||
if ('hideFields' in options && options.hideFields) { | ||
for (var _name3 of options.hideFields) { | ||
var _value2 = formdata.getValue(context.payload, _name3); | ||
for (var name of options.hideFields) { | ||
var _value2 = formdata.getValue(context.payload, name); | ||
if (typeof _value2 !== 'undefined') { | ||
formdata.setValue(context.payload, _name3, () => undefined); | ||
formdata.setValue(context.payload, name, () => undefined); | ||
} | ||
} | ||
} | ||
var submissionError = context.error ? Object.entries(context.error).reduce((result, _ref) => { | ||
var [name, error] = _ref; | ||
if (context.state.validated[name]) { | ||
result[name] = error; | ||
} | ||
return result; | ||
}, {}) : undefined; | ||
var extraError = 'formErrors' in options || 'fieldErrors' in options ? formdata.normalize(_rollupPluginBabelHelpers.objectSpread2({ | ||
'': (_options$formErrors = options.formErrors) !== null && _options$formErrors !== void 0 ? _options$formErrors : null | ||
}, options.fieldErrors)) : null; | ||
var error = submissionError || extraError ? _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, submissionError), extraError) : undefined; | ||
var error = context.error || extraError ? _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context.error), extraError) : undefined; | ||
return { | ||
status: context.intent ? undefined : error ? 'error' : 'success', | ||
intent: context.intent ? context.intent : undefined, | ||
initialValue: (_normalize = formdata.normalize(context.payload)) !== null && _normalize !== void 0 ? _normalize : {}, | ||
initialValue: (_normalize = formdata.normalize(context.payload, | ||
// We can't serialize the file and send it back from the server, but we can preserve it in the client | ||
typeof document !== 'undefined')) !== null && _normalize !== void 0 ? _normalize : {}, | ||
error, | ||
state: context.state | ||
state: context.state, | ||
fields: Array.from(context.fields) | ||
}; | ||
@@ -323,4 +266,4 @@ } | ||
// @ts-expect-error FIXME | ||
return Object.entries(defaultValue).reduce((result, _ref2) => { | ||
var [key, value] = _ref2; | ||
return Object.entries(defaultValue).reduce((result, _ref) => { | ||
var [key, value] = _ref; | ||
// @ts-ignore-error FIXME | ||
@@ -327,0 +270,0 @@ result[key] = serialize(value); |
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
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
103814
2728