@reformer/core 11.0.0-beta.6 → 11.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +7 -3
  2. package/dist/behaviors.js +216 -179
  3. package/dist/create-model-BBRHhHwK.js +30 -0
  4. package/dist/en-CjAqn7h0.js +41 -0
  5. package/dist/form/behaviors/collections.d.ts +14 -1
  6. package/dist/form/behaviors/context.d.ts +18 -2
  7. package/dist/form/behaviors/index.d.ts +3 -1
  8. package/dist/form/behaviors/internals.d.ts +9 -1
  9. package/dist/form/behaviors/schema-operators.d.ts +76 -0
  10. package/dist/form/behaviors/types.d.ts +15 -3
  11. package/dist/form/create-core-form.d.ts +5 -3
  12. package/dist/form/create-form.d.ts +28 -53
  13. package/dist/form/form-bundle.d.ts +136 -0
  14. package/dist/form/index.d.ts +6 -1
  15. package/dist/form/nodes/field-node.d.ts +2 -2
  16. package/dist/form/nodes/group-node.d.ts +1 -1
  17. package/dist/form/nodes/model-array-node.d.ts +10 -5
  18. package/dist/form/schema-controller.d.ts +137 -0
  19. package/dist/form/schema-subtree.d.ts +28 -0
  20. package/dist/form/signal-node-registry.d.ts +22 -16
  21. package/dist/form/types/contracts.d.ts +6 -0
  22. package/dist/form/types/deep-schema.d.ts +2 -2
  23. package/dist/form/types/form-proxy.d.ts +1 -1
  24. package/dist/form/types/schema-node.d.ts +37 -12
  25. package/dist/form/types/validation-schema.d.ts +13 -1
  26. package/dist/form/validation/context.d.ts +6 -1
  27. package/dist/form/validation/index.d.ts +1 -1
  28. package/dist/form/validation/operators.d.ts +74 -7
  29. package/dist/form/validation/types.d.ts +2 -1
  30. package/dist/form/validators/validation-error.d.ts +8 -0
  31. package/dist/i18n/descriptor.d.ts +54 -0
  32. package/dist/i18n/en.json.d.ts +45 -0
  33. package/dist/i18n/loader.d.ts +71 -0
  34. package/dist/i18n/locale-store.d.ts +39 -0
  35. package/dist/i18n/locale.d.ts +90 -0
  36. package/dist/i18n/message-format.d.ts +116 -0
  37. package/dist/i18n/resolve-localized.d.ts +17 -0
  38. package/dist/i18n/ru.json.d.ts +45 -0
  39. package/dist/i18n/translator.d.ts +50 -0
  40. package/dist/i18n/validation-message.d.ts +18 -0
  41. package/dist/i18n.d.ts +31 -0
  42. package/dist/i18n.js +303 -0
  43. package/dist/index-BrNkQj1y.js +105 -0
  44. package/dist/index.js +737 -743
  45. package/dist/loader-Dv_Hl7JC.js +216 -0
  46. package/dist/locale/en.d.ts +2 -0
  47. package/dist/locale/en.js +5 -0
  48. package/dist/locale/en.json +42 -0
  49. package/dist/locale/index.d.ts +18 -0
  50. package/dist/locale/ru.d.ts +2 -0
  51. package/dist/locale/ru.js +41 -0
  52. package/dist/locale/ru.json +42 -0
  53. package/dist/locale.d.ts +2 -0
  54. package/dist/locale.js +9 -0
  55. package/dist/model/create-model.d.ts +17 -3
  56. package/dist/model/index.d.ts +8 -3
  57. package/dist/model/model-nodes.d.ts +67 -4
  58. package/dist/model/model-signals-proxy.d.ts +33 -1
  59. package/dist/model/model-value-proxy.d.ts +76 -0
  60. package/dist/model/types.d.ts +26 -9
  61. package/dist/model-value-proxy-caTmAiUd.js +419 -0
  62. package/dist/model.js +21 -17
  63. package/dist/node-BeV_lV5i.js +100 -0
  64. package/dist/platforms/react/form-bundle-context.d.ts +27 -0
  65. package/dist/platforms/react/hooks/types.d.ts +6 -3
  66. package/dist/platforms/react/hooks/useFormControlValue.d.ts +2 -1
  67. package/dist/platforms/react/i18n/context.d.ts +13 -0
  68. package/dist/platforms/react/i18n/hooks.d.ts +59 -0
  69. package/dist/platforms/react/i18n/provider.d.ts +52 -0
  70. package/dist/platforms/react/index.d.ts +1 -0
  71. package/dist/strategy-DgzELWno.js +204 -0
  72. package/dist/validation-error-B-U3RsV0.js +11 -0
  73. package/dist/validation.js +7 -6
  74. package/dist/validators/email.js +5 -8
  75. package/dist/validators/future-date.js +8 -11
  76. package/dist/validators/integer.js +4 -7
  77. package/dist/validators/is-date.js +5 -8
  78. package/dist/validators/is-number.js +4 -7
  79. package/dist/validators/max-age.js +8 -11
  80. package/dist/validators/max-date.js +8 -11
  81. package/dist/validators/max-length.js +5 -8
  82. package/dist/validators/max.js +4 -7
  83. package/dist/validators/min-age.js +8 -11
  84. package/dist/validators/min-date.js +8 -11
  85. package/dist/validators/min-length.js +5 -8
  86. package/dist/validators/min.js +4 -7
  87. package/dist/validators/multiple-of.js +5 -8
  88. package/dist/validators/non-negative.js +4 -7
  89. package/dist/validators/non-zero.js +4 -7
  90. package/dist/validators/past-date.js +8 -11
  91. package/dist/validators/pattern.js +5 -8
  92. package/dist/validators/phone.js +6 -9
  93. package/dist/validators/required.js +4 -7
  94. package/dist/validators/url.js +9 -14
  95. package/dist/validators.js +84 -106
  96. package/docs/llms/03-api-signatures.md +10 -4
  97. package/docs/llms/09-formschema.md +5 -5
  98. package/docs/llms/10-arrays.md +52 -3
  99. package/docs/llms/16-ui-components.md +2 -2
  100. package/docs/llms/18-conditional-fields.md +1 -1
  101. package/docs/llms/21-array-operations.md +26 -0
  102. package/docs/llms/28-submit-and-reset.md +3 -3
  103. package/docs/llms/29-async-preload.md +4 -4
  104. package/docs/llms/33-validation-strategy.md +2 -2
  105. package/docs/llms/34-i18n.md +272 -0
  106. package/docs/llms/35-unified-contract.md +246 -0
  107. package/llms-index.json +1 -1
  108. package/llms.txt +2746 -229
  109. package/package.json +22 -3
  110. package/dist/create-model-Dxh9cfLp.js +0 -97
  111. package/dist/model-signals-proxy-mV3WGdlO.js +0 -233
  112. package/dist/node-DGEFMTQu.js +0 -18
  113. package/dist/strategy-DA3JwxsR.js +0 -170
@@ -0,0 +1,100 @@
1
+ import { signal as o, effect as a } from "@preact/signals-core";
2
+ import { b as f, i as c, f as u } from "./model-value-proxy-caTmAiUd.js";
3
+ import { g as d } from "./signal-node-registry-tiwel-TV.js";
4
+ import { d as l } from "./behaviors-value-C7dSEhCc.js";
5
+ function p() {
6
+ const e = /* @__PURE__ */ new Map();
7
+ return {
8
+ hiddenOverrides: /* @__PURE__ */ new Map(),
9
+ propsOverrides: /* @__PURE__ */ new Map(),
10
+ refRegistry: /* @__PURE__ */ new Map(),
11
+ conditionRegistry: /* @__PURE__ */ new Map(),
12
+ effectRegistry: [],
13
+ callbackRegistry: /* @__PURE__ */ new Map(),
14
+ lifecycleRegistry: /* @__PURE__ */ new Map(),
15
+ version: o(0),
16
+ versionFor(t) {
17
+ let r = e.get(t);
18
+ return r || (r = o(0), e.set(t, r)), r;
19
+ }
20
+ };
21
+ }
22
+ function g(e = p()) {
23
+ const t = (r) => {
24
+ e.version.value++, e.versionFor(r).value++;
25
+ };
26
+ return {
27
+ __overrideMaps: e,
28
+ node: (r) => ({
29
+ setHidden(n) {
30
+ return e.hiddenOverrides.set(r, n), t(r), this;
31
+ },
32
+ resetHidden() {
33
+ return e.hiddenOverrides.delete(r), t(r), this;
34
+ },
35
+ patchProps(n) {
36
+ return e.propsOverrides.set(r, {
37
+ ...e.propsOverrides.get(r) ?? {},
38
+ ...n
39
+ }), t(r), this;
40
+ },
41
+ resetProps() {
42
+ return e.propsOverrides.delete(r), t(r), this;
43
+ },
44
+ getRef() {
45
+ let n = e.refRegistry.get(r);
46
+ return n || (n = { current: null }, e.refRegistry.set(r, n)), n;
47
+ },
48
+ __selector: r,
49
+ __overrideMaps: e
50
+ })
51
+ };
52
+ }
53
+ function S() {
54
+ const e = /* @__PURE__ */ new WeakMap();
55
+ return {
56
+ scopeOf(t) {
57
+ let r = e.get(t);
58
+ return r || (r = g(), e.set(t, r)), r;
59
+ }
60
+ };
61
+ }
62
+ function s(e, t, r) {
63
+ if (e == null || typeof e != "object" || f(e) || c(e) || u(e) || e.$$typeof !== void 0 || r.has(e)) return;
64
+ if (r.add(e), Array.isArray(e)) {
65
+ for (const i of e) s(i, t, r);
66
+ return;
67
+ }
68
+ const n = e.selector;
69
+ typeof n == "string" && t.add(n);
70
+ for (const i of Object.values(e)) s(i, t, r);
71
+ }
72
+ function b(e, t) {
73
+ const r = /* @__PURE__ */ new Set();
74
+ return s(t, r, /* @__PURE__ */ new WeakSet()), [.../* @__PURE__ */ new Set([
75
+ ...e.hiddenOverrides.keys(),
76
+ ...e.propsOverrides.keys(),
77
+ ...e.conditionRegistry.keys(),
78
+ ...e.callbackRegistry.keys(),
79
+ ...e.lifecycleRegistry.keys()
80
+ ])].filter((i) => !r.has(i));
81
+ }
82
+ function y(e, t, r) {
83
+ return a(() => {
84
+ const n = t(), i = d(e);
85
+ i && l(() => {
86
+ n ? i.enable() : (i.disable(), r?.resetOnDisable && i.reset());
87
+ });
88
+ });
89
+ }
90
+ function M(e, t, r) {
91
+ return y(e, () => !t(), r);
92
+ }
93
+ export {
94
+ g as a,
95
+ p as b,
96
+ S as c,
97
+ M as d,
98
+ y as e,
99
+ b as u
100
+ };
@@ -0,0 +1,27 @@
1
+ import { FormBundle } from '../../form/form-bundle';
2
+ /**
3
+ * Контекст сборки. Значение — бандл `createForm`; вне рендерера — `null`.
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * <FormBundleContext.Provider value={bundle}>
8
+ * <MyWizard />
9
+ * </FormBundleContext.Provider>
10
+ * ```
11
+ */
12
+ export declare const FormBundleContext: import('react').Context<FormBundle<any> | null>;
13
+ /**
14
+ * Бандл сборки, внутри которой отрисован компонент; `null` — компонент стоит вне рендерера
15
+ * (например, визард в разметке React-руками получает форму и валидацию пропсами).
16
+ *
17
+ * @typeParam T - Форма данных модели.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * function StepFooter() {
22
+ * const bundle = useFormBundleContext<CreditForm>();
23
+ * return <button onClick={() => bundle?.validation?.validateAll()}>Проверить</button>;
24
+ * }
25
+ * ```
26
+ */
27
+ export declare function useFormBundleContext<T = unknown>(): FormBundle<T> | null;
@@ -15,6 +15,7 @@ import { ValidationError } from '../../../form/types/index';
15
15
  *
16
16
  * function TextField({ control }: Props) {
17
17
  * const state = useFormControl(control);
18
+ * const message = useValidationMessage(); // из '@reformer/core/i18n'
18
19
  *
19
20
  * return (
20
21
  * <div>
@@ -24,7 +25,7 @@ import { ValidationError } from '../../../form/types/index';
24
25
  * onChange={e => control.setValue(e.target.value)}
25
26
  * />
26
27
  * {state.shouldShowError && state.errors[0] && (
27
- * <span className="error">{state.errors[0].message}</span>
28
+ * <span className="error">{message(state.errors[0])}</span>
28
29
  * )}
29
30
  * </div>
30
31
  * );
@@ -89,11 +90,12 @@ export interface FieldControlState<T> {
89
90
  * @example
90
91
  * ```tsx
91
92
  * const { errors } = useFormControl(field);
93
+ * const message = useValidationMessage(); // из '@reformer/core/i18n'
92
94
  *
93
95
  * return (
94
96
  * <ul className="error-list">
95
97
  * {errors.map((error, i) => (
96
- * <li key={i}>{error.message}</li>
98
+ * <li key={i}>{message(error)}</li>
97
99
  * ))}
98
100
  * </ul>
99
101
  * );
@@ -152,12 +154,13 @@ export interface FieldControlState<T> {
152
154
  * @example
153
155
  * ```tsx
154
156
  * const { shouldShowError, errors } = useFormControl(field);
157
+ * const message = useValidationMessage(); // из '@reformer/core/i18n'
155
158
  *
156
159
  * return (
157
160
  * <div>
158
161
  * <input {...props} />
159
162
  * {shouldShowError && (
160
- * <span className="error">{errors[0]?.message}</span>
163
+ * <span className="error">{message(errors[0])}</span>
161
164
  * )}
162
165
  * </div>
163
166
  * );
@@ -134,6 +134,7 @@ import { FormValue } from '../../../form/types/index';
134
134
  * // Основной редактор использует useFormControl для полного состояния
135
135
  * function MarkdownEditor({ control }: MarkdownEditorProps) {
136
136
  * const { value, shouldShowError, errors } = useFormControl(control);
137
+ * const message = useValidationMessage(); // из '@reformer/core/i18n'
137
138
  *
138
139
  * return (
139
140
  * <div className="editor-container">
@@ -141,7 +142,7 @@ import { FormValue } from '../../../form/types/index';
141
142
  * value={value}
142
143
  * onChange={e => control.setValue(e.target.value)}
143
144
  * />
144
- * {shouldShowError && <span className="error">{errors[0]?.message}</span>}
145
+ * {shouldShowError && <span className="error">{message(errors[0])}</span>}
145
146
  *
146
147
  * {/* Preview обновляется только при изменении value *}
147
148
  * <MarkdownPreview control={control} />
@@ -0,0 +1,13 @@
1
+ import { I18nHandle } from '../../../i18n/translator';
2
+ /** Имя контекста и одновременно маркер, по которому страж ищет его копии в сборках. */
3
+ export declare const I18N_CONTEXT_MARKER = "ReformerI18nContext";
4
+ /** Что видит компонент: ручка активной локали и состояние её загрузки. */
5
+ export interface I18nContextValue extends I18nHandle {
6
+ /** Идёт загрузка другого языка; на экране пока прежний. Без загрузчика всегда `false`. */
7
+ readonly pending: boolean;
8
+ /** Ошибка последней загрузки языка. */
9
+ readonly error: unknown;
10
+ }
11
+ /** Значение контекста для локали: ручка плюс состояние загрузки. */
12
+ export declare function contextValue(handle: I18nHandle, pending: boolean, error: unknown): I18nContextValue;
13
+ export declare const I18nContext: import('react').Context<I18nContextValue>;
@@ -0,0 +1,59 @@
1
+ import { ValidationError } from '../../../form/types/contracts';
2
+ import { Messages } from '../../../i18n/locale';
3
+ import { MessageValues } from '../../../i18n/message-format';
4
+ import { I18nContextValue } from './context';
5
+ /**
6
+ * Активная локаль: перевод ключей приложения, форматирование чисел, дат и размеров, состояние
7
+ * загрузки языка. Без провайдера — английский с пустым словарём.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * function LangBadge() {
12
+ * const { code, pending, t } = useI18n();
13
+ * return <span aria-busy={pending}>{t('app.language')}: {code}</span>;
14
+ * }
15
+ * ```
16
+ */
17
+ export declare function useI18n(): I18nContextValue;
18
+ /**
19
+ * Переводчик пакета: ищет ключ в локали провайдера, а при промахе берёт встроенную английскую
20
+ * таблицу этого пакета. Так пакет говорит по-английски без провайдера и не зависит от того, знает
21
+ * ли локаль его ключи. Тип ключа выводится из таблицы — опечатка в ключе не скомпилируется.
22
+ *
23
+ * `defaults` должен быть стабильной ссылкой (импорт JSON-модуля), иначе переводчик будет
24
+ * пересоздаваться на каждый рендер.
25
+ *
26
+ * @param defaults - Встроенная английская таблица пакета.
27
+ * @returns Функция `(ключ, значения?) => строка`; её идентичность меняется вместе с локалью.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * import en from './locale/en.json';
32
+ *
33
+ * const useKitMessages = () => useMessages(en);
34
+ *
35
+ * function ClearButton() {
36
+ * const t = useKitMessages();
37
+ * return <button aria-label={t('kit.select.clear')} />;
38
+ * }
39
+ * ```
40
+ */
41
+ export declare function useMessages<D extends Messages>(defaults: D): (key: keyof D & string, values?: MessageValues) => string;
42
+ /**
43
+ * Резолвер текста ошибки валидации по активной локали: `messageKey` автора → явное `message` →
44
+ * словарь локали по коду → встроенный английский → код. Идентичность функции меняется вместе с
45
+ * локалью, поэтому показанные ошибки переводятся при смене языка без повторной валидации.
46
+ *
47
+ * `FormField` из `@reformer/cdk` использует его сам; вызывайте напрямую, если рисуете ошибки
48
+ * своим компонентом.
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * function FieldErrors({ control }: { control: FieldNode<string> }) {
53
+ * const message = useValidationMessage();
54
+ * const { errors } = useFormControl(control);
55
+ * return <>{errors.map((error) => <span key={error.code}>{message(error)}</span>)}</>;
56
+ * }
57
+ * ```
58
+ */
59
+ export declare function useValidationMessage(): (error: ValidationError) => string;
@@ -0,0 +1,52 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ import { FormLocale } from '../../../i18n/locale';
3
+ import { LocaleLoad } from '../../../i18n/locale-store';
4
+ /** Режим «готовая локаль». */
5
+ export interface I18nStaticProviderProps {
6
+ /** Локаль. Смена объекта переключает язык сразу. */
7
+ locale: FormLocale;
8
+ children?: ReactNode;
9
+ }
10
+ /** Режим «провайдер грузит сам». */
11
+ export interface I18nLoadingProviderProps {
12
+ /** Код языка. Смена кода запускает загрузку; до её конца на экране прежний язык. */
13
+ lang: string;
14
+ /** Загрузчик локалей — обычно результат `createLocaleLoader`. */
15
+ load: LocaleLoad;
16
+ /**
17
+ * Что показать, пока не загружена самая первая локаль. По умолчанию — ничего: иначе на кадр
18
+ * мелькнул бы встроенный английский. Если локаль уже в кэше загрузчика (`load.preload(lang)`
19
+ * до монтирования), первый рендер синхронный и `fallback` не показывается.
20
+ */
21
+ fallback?: ReactNode;
22
+ /** Отказ загрузки. Язык на экране при этом не меняется. */
23
+ onError?: (error: unknown, lang: string) => void;
24
+ children?: ReactNode;
25
+ }
26
+ export type I18nProviderProps = I18nStaticProviderProps | I18nLoadingProviderProps;
27
+ /**
28
+ * Провайдер локализации для подписей компонентов, ошибок валидации и авторских подписей формы.
29
+ * Без провайдера компоненты говорят встроенным английским.
30
+ *
31
+ * При смене `lang` на экране остаётся прежний язык, пока новый не загрузится (`useI18n().pending`
32
+ * — для индикатора). При быстром переключении применяется только последний запрос. Вложенный
33
+ * провайдер заменяет локаль для своего поддерева целиком.
34
+ *
35
+ * @example Провайдер грузит локаль сам
36
+ * ```tsx
37
+ * const [lang, setLang] = useState('ru');
38
+ *
39
+ * <I18nProvider lang={lang} load={loadLocale}>
40
+ * <LangSwitch value={lang} onChange={setLang} />
41
+ * <CreditForm />
42
+ * </I18nProvider>
43
+ * ```
44
+ *
45
+ * @example Готовая локаль — SSR и тесты
46
+ * ```tsx
47
+ * import { ru } from '@reformer/ui-kit/locale/ru';
48
+ *
49
+ * <I18nProvider locale={ru}><CreditForm /></I18nProvider>
50
+ * ```
51
+ */
52
+ export declare function I18nProvider(props: I18nProviderProps): ReactElement | null;
@@ -20,6 +20,7 @@ export { useFormValidation } from './hooks/use-form-validation';
20
20
  export type { UseFormValidationArgs, UseFormValidationResult } from './hooks/use-form-validation';
21
21
  export { useFormBundle } from './hooks/use-form-bundle';
22
22
  export type { FormBundleLike } from './hooks/use-form-bundle';
23
+ export { FormBundleContext, useFormBundleContext } from './form-bundle-context';
23
24
  export type { FieldControlState, ArrayControlState } from './hooks/types';
24
25
  export { getFieldAdapter, bindFieldProps, FIELD_WRAPPER_ONLY_PROPS, } from './field-binding/field-adapter';
25
26
  export type { FieldAdapter, FieldAdapterCarrier, FieldSeam } from './field-binding/field-adapter';
@@ -0,0 +1,204 @@
1
+ import { g as W, m as E, h as $ } from "./model-value-proxy-caTmAiUd.js";
2
+ import { signal as O, effect as P } from "@preact/signals-core";
3
+ import { a as V } from "./create-model-BBRHhHwK.js";
4
+ import { g as h } from "./signal-node-registry-tiwel-TV.js";
5
+ let p = null;
6
+ function A(e, r) {
7
+ const t = p;
8
+ p = e;
9
+ try {
10
+ return r();
11
+ } finally {
12
+ p = t;
13
+ }
14
+ }
15
+ function c(e) {
16
+ if (!p)
17
+ throw new Error(
18
+ `[@reformer/core/validation] "${e}" вызван вне схемы валидации — операторы валидации можно вызывать только внутри прогона validateModel(...) (напрямую или через apply/each).`
19
+ );
20
+ return p;
21
+ }
22
+ function m(e, r) {
23
+ let t = e.errors.get(r);
24
+ return t || e.errors.set(r, t = []), t;
25
+ }
26
+ const y = (e) => e.whenStack.every((r) => r());
27
+ function _(e, r) {
28
+ const t = c("validate"), n = m(t, e);
29
+ if (!y(t)) return;
30
+ const o = e.peek();
31
+ for (const a of r) {
32
+ const i = a(o, t.model, t.root);
33
+ i && n.push(i);
34
+ }
35
+ }
36
+ function j(e, r) {
37
+ const t = c("validateAsync"), n = m(t, e);
38
+ if (!y(t)) return;
39
+ const o = e.peek(), a = t.signal;
40
+ for (const i of r)
41
+ t.pending.push(
42
+ i(o, { signal: a }).then(
43
+ (s) => {
44
+ s && !a.aborted && n.push(s);
45
+ },
46
+ () => {
47
+ }
48
+ )
49
+ );
50
+ }
51
+ function z(e, r) {
52
+ const t = c("validateWhen");
53
+ t.whenStack.push(e);
54
+ try {
55
+ r();
56
+ } finally {
57
+ t.whenStack.pop();
58
+ }
59
+ }
60
+ function G(e, r) {
61
+ const t = c("cross"), n = m(t, e);
62
+ if (!y(t)) return;
63
+ const o = r(t.model.get());
64
+ o && n.push(o);
65
+ }
66
+ function F(e, r, t) {
67
+ const n = r;
68
+ A(
69
+ { ...e, model: n },
70
+ () => t({ model: n })
71
+ );
72
+ }
73
+ function M(e, r) {
74
+ const t = $(r);
75
+ if (!t)
76
+ throw new TypeError(
77
+ `[@reformer/core/validation] ${e}: ожидался массив под-форм модели — \`model.$.<массив>\`. Массив примитивов — одно значение поля, его проверяют целиком: \`validate(model.$.<массив>, [...])\`.`
78
+ );
79
+ return E(t);
80
+ }
81
+ function I(e, r) {
82
+ const t = c("applyEach"), n = M("applyEach", e), o = n.length;
83
+ for (let a = 0; a < o; a++) F(t, n.at(a), r);
84
+ }
85
+ function J(e, r) {
86
+ c("each");
87
+ const t = M("each", e), n = t.length;
88
+ for (let o = 0; o < n; o++) r(t.at(o));
89
+ }
90
+ function K(...e) {
91
+ const r = c("apply");
92
+ if (typeof e[0] == "function") {
93
+ for (const o of e) o({ model: r.model });
94
+ return;
95
+ }
96
+ const [t, n] = e;
97
+ for (const o of Array.isArray(t) ? t : [t]) {
98
+ const a = W(o);
99
+ if (!a)
100
+ throw new TypeError(
101
+ "[@reformer/core/validation] apply: ожидалась группа модели — `model.$.<группа>`. Массив под-форм подключают через `applyEach`."
102
+ );
103
+ F(r, E(a), n);
104
+ }
105
+ }
106
+ function Q(e) {
107
+ return e;
108
+ }
109
+ const x = /* @__PURE__ */ new WeakMap();
110
+ function C(e, r) {
111
+ let t = x.get(e);
112
+ t || x.set(e, t = /* @__PURE__ */ new WeakMap());
113
+ let n = t.get(r);
114
+ return n || t.set(r, n = { fields: /* @__PURE__ */ new Set(), ac: null }), n;
115
+ }
116
+ const L = (e) => {
117
+ for (const r of e.values()) for (const t of r) if (t.severity !== "warning") return !0;
118
+ return !1;
119
+ };
120
+ function H(e) {
121
+ return e.aborted ? Promise.resolve() : new Promise((r) => {
122
+ e.addEventListener("abort", () => r(), { once: !0 });
123
+ });
124
+ }
125
+ async function q(e, r, t) {
126
+ const n = C(e, r);
127
+ n.ac?.abort();
128
+ const o = new AbortController();
129
+ n.ac = o;
130
+ const a = {
131
+ model: e,
132
+ root: e,
133
+ errors: /* @__PURE__ */ new Map(),
134
+ pending: [],
135
+ whenStack: [],
136
+ signal: o.signal
137
+ };
138
+ if (A(a, () => r({ model: e })), a.pending.length && await Promise.race([Promise.all(a.pending), H(o.signal)]), o.signal.aborted) return !1;
139
+ const i = new Set(a.errors.keys());
140
+ for (const s of n.fields) i.has(s) || h(s)?.setErrors([]);
141
+ for (const s of i) h(s)?.setErrors(a.errors.get(s) ?? []);
142
+ if (t?.touch) for (const s of i) h(s)?.markAsTouched();
143
+ return n.fields = i, !L(a.errors);
144
+ }
145
+ function U(e, r, t = {}) {
146
+ const { strategy: n = "submit", debounce: o = 0, liveAfterSubmit: a = "change" } = t, i = O(!1);
147
+ let s = 0, w = !1, u, l;
148
+ const b = async (f) => {
149
+ s++, i.value = !0;
150
+ try {
151
+ return await q(e, r, { touch: f });
152
+ } finally {
153
+ --s === 0 && (i.value = !1);
154
+ }
155
+ }, g = () => {
156
+ b(!1);
157
+ }, T = () => {
158
+ if (!o) {
159
+ g();
160
+ return;
161
+ }
162
+ l && clearTimeout(l), l = setTimeout(g, o);
163
+ }, k = (f, d) => {
164
+ let S = !0;
165
+ return P(() => {
166
+ if (V(e, f), S) {
167
+ S = !1;
168
+ return;
169
+ }
170
+ n === "afterFirstSubmit" && !w || d();
171
+ });
172
+ }, v = {
173
+ async validate() {
174
+ return w = !0, b(!0);
175
+ },
176
+ start() {
177
+ if (u) return () => v.dispose();
178
+ const f = n === "afterFirstSubmit" ? a : n;
179
+ return f === "change" ? u = k((d) => void d.value, T) : f === "blur" && (u = k((d) => void h(d)?.touched.value, g)), () => v.dispose();
180
+ },
181
+ dispose() {
182
+ l && (clearTimeout(l), l = void 0), u?.(), u = void 0;
183
+ },
184
+ get isValidating() {
185
+ return i.value;
186
+ },
187
+ get validating() {
188
+ return i;
189
+ }
190
+ };
191
+ return v;
192
+ }
193
+ export {
194
+ j as a,
195
+ z as b,
196
+ G as c,
197
+ K as d,
198
+ J as e,
199
+ I as f,
200
+ Q as g,
201
+ q as h,
202
+ U as i,
203
+ _ as v
204
+ };
@@ -0,0 +1,11 @@
1
+ function m(s, e, a) {
2
+ const r = {
3
+ code: s,
4
+ message: e?.message ?? "",
5
+ params: a === void 0 ? e?.params : { ...a, ...e?.params }
6
+ };
7
+ return e?.messageKey !== void 0 && (r.messageKey = e.messageKey), r;
8
+ }
9
+ export {
10
+ m as v
11
+ };
@@ -1,12 +1,13 @@
1
- import { d as s, h as d, c as i, f as l, e as t, v as o, a as c, g as n, b as r } from "./strategy-DA3JwxsR.js";
1
+ import { d as s, f as i, i as d, c as l, g as t, e as c, v as o, a as h, h as n, b as p } from "./strategy-DgzELWno.js";
2
2
  export {
3
3
  s as apply,
4
+ i as applyEach,
4
5
  d as createFormValidation,
5
- i as cross,
6
- l as defineValidationSchema,
7
- t as each,
6
+ l as cross,
7
+ t as defineValidationSchema,
8
+ c as each,
8
9
  o as validate,
9
- c as validateAsync,
10
+ h as validateAsync,
10
11
  n as validateModel,
11
- r as validateWhen
12
+ p as validateWhen
12
13
  };
@@ -1,11 +1,8 @@
1
- const s = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2
- function n(e) {
3
- return (r) => r ? s.test(r) ? null : {
4
- code: "email",
5
- message: e?.message ?? "invalid",
6
- params: e?.params
7
- } : null;
1
+ import { v as n } from "../validation-error-B-U3RsV0.js";
2
+ const i = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
3
+ function o(t) {
4
+ return (r) => r ? i.test(r) ? null : n("email", t) : null;
8
5
  }
9
6
  export {
10
- n as email
7
+ o as email
11
8
  };
@@ -1,19 +1,16 @@
1
- import { p as s, n as l, g as o } from "../date-utils-dTT_x_Be.js";
2
- function i(a) {
1
+ import { p as e, n as i, g as l } from "../date-utils-dTT_x_Be.js";
2
+ import { v as u } from "../validation-error-B-U3RsV0.js";
3
+ function f(n) {
3
4
  return (r) => {
4
5
  if (r == null || r === "")
5
6
  return null;
6
- const e = s(r);
7
- if (e === null)
7
+ const t = e(r);
8
+ if (t === null)
8
9
  return null;
9
- const n = l(e), t = o();
10
- return n < t ? {
11
- code: "date_past",
12
- message: a?.message ?? "invalid",
13
- params: a?.params
14
- } : null;
10
+ const o = i(t), a = l();
11
+ return o < a ? u("date_past", n) : null;
15
12
  };
16
13
  }
17
14
  export {
18
- i as futureDate
15
+ f as futureDate
19
16
  };
@@ -1,10 +1,7 @@
1
- function n(e) {
2
- return (r) => r == null || typeof r != "number" || isNaN(r) || Number.isInteger(r) ? null : {
3
- code: "integer",
4
- message: e?.message ?? "invalid",
5
- params: e?.params
6
- };
1
+ import { v as t } from "../validation-error-B-U3RsV0.js";
2
+ function e(n) {
3
+ return (r) => r == null || typeof r != "number" || isNaN(r) || Number.isInteger(r) ? null : t("integer", n);
7
4
  }
8
5
  export {
9
- n as integer
6
+ e as integer
10
7
  };
@@ -1,11 +1,8 @@
1
- import { p as a } from "../date-utils-dTT_x_Be.js";
2
- function t(e) {
3
- return (r) => r == null || r === "" ? null : a(r) === null ? {
4
- code: "date_invalid",
5
- message: e?.message ?? "invalid",
6
- params: e?.params
7
- } : null;
1
+ import { p as t } from "../date-utils-dTT_x_Be.js";
2
+ import { v as i } from "../validation-error-B-U3RsV0.js";
3
+ function l(n) {
4
+ return (r) => r == null || r === "" ? null : t(r) === null ? i("date_invalid", n) : null;
8
5
  }
9
6
  export {
10
- t as isDate
7
+ l as isDate
11
8
  };
@@ -1,10 +1,7 @@
1
- function n(e) {
2
- return (r) => r == null ? null : typeof r != "number" || isNaN(r) ? {
3
- code: "isNumber",
4
- message: e?.message ?? "invalid",
5
- params: e?.params
6
- } : null;
1
+ import { v as i } from "../validation-error-B-U3RsV0.js";
2
+ function o(n) {
3
+ return (r) => r == null ? null : typeof r != "number" || isNaN(r) ? i("isNumber", n) : null;
7
4
  }
8
5
  export {
9
- n as isNumber
6
+ o as isNumber
10
7
  };