@powerhousedao/powerhouse-vetra-packages 6.2.3-dev.1 → 6.2.3-dev.11

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 (114) hide show
  1. package/dist/browser/assets/{entry-5_Eh4a2Z.js → entry-4ObkElbc.js} +2 -2
  2. package/dist/browser/assets/{projection-entry-5PVbP10h.js → projection-entry-DRGRQCSu.js} +8 -8
  3. package/dist/browser/{button-CuO8Gh3v.js → button-sZQCXeCo.js} +131 -24
  4. package/dist/browser/button-sZQCXeCo.js.map +1 -0
  5. package/dist/browser/chunk-CRPLlQ3x.js +28 -0
  6. package/dist/browser/{dist-BAJ5nRDl.js → dist-D3_ER0Dn.js} +2 -399
  7. package/dist/browser/dist-D3_ER0Dn.js.map +1 -0
  8. package/dist/browser/document-models/index.js +2 -1
  9. package/dist/browser/{documents-J_l59mSV.js → documents-C-lAnv6o.js} +604 -735
  10. package/dist/browser/documents-C-lAnv6o.js.map +1 -0
  11. package/dist/browser/editor-BO_s5gTQ.js +3679 -0
  12. package/dist/browser/editor-BO_s5gTQ.js.map +1 -0
  13. package/dist/browser/{editor-DZP1WlYy.js → editor-DNV-46lY.js} +5 -5
  14. package/dist/browser/{editor-DZP1WlYy.js.map → editor-DNV-46lY.js.map} +1 -1
  15. package/dist/browser/editors/document-model-editor/module.js +1 -1
  16. package/dist/browser/editors/generic-drive-explorer/index.js +4 -5
  17. package/dist/browser/editors/generic-drive-explorer/index.js.map +1 -1
  18. package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
  19. package/dist/browser/folder-view-CzItU0hn.js +957 -0
  20. package/dist/browser/folder-view-CzItU0hn.js.map +1 -0
  21. package/dist/browser/{graphql-editor-Cbkb5KRZ.js → graphql-editor-BMhHl2XP.js} +7 -9
  22. package/dist/browser/{graphql-editor-Cbkb5KRZ.js.map → graphql-editor-BMhHl2XP.js.map} +1 -1
  23. package/dist/{node/hooks-D0DcS3MV.mjs → browser/hooks-Bh1JCohS.js} +2 -2
  24. package/dist/browser/{hooks-KKcNp2X0.js.map → hooks-Bh1JCohS.js.map} +1 -1
  25. package/dist/browser/index.js +120 -20
  26. package/dist/browser/index.js.map +1 -1
  27. package/dist/browser/{json-editor-CN6kPtl1.js → json-editor-DBhkG5TF.js} +3 -4
  28. package/dist/browser/{json-editor-CN6kPtl1.js.map → json-editor-DBhkG5TF.js.map} +1 -1
  29. package/dist/browser/{parser-CkF6Qt8V.js → parser-BBzK7bLd.js} +1 -1
  30. package/dist/browser/{parser-CkF6Qt8V.js.map → parser-BBzK7bLd.js.map} +1 -1
  31. package/dist/browser/{schema-context-ZyeclQwy.js → schema-context-p2bhyog_.js} +3 -3
  32. package/dist/browser/{schema-context-ZyeclQwy.js.map → schema-context-p2bhyog_.js.map} +1 -1
  33. package/dist/browser/src-CVV6HzQZ-D-OQvEkh.js +5151 -0
  34. package/dist/browser/src-CVV6HzQZ-D-OQvEkh.js.map +1 -0
  35. package/dist/browser/state-schemas-DuA5rB1e.js +694 -0
  36. package/dist/browser/state-schemas-DuA5rB1e.js.map +1 -0
  37. package/dist/browser/tslib.es6-CeIASJ2O.js +32 -0
  38. package/dist/browser/tslib.es6-CeIASJ2O.js.map +1 -0
  39. package/dist/node/{button-Da7CxMn7.mjs → button-5bnYEAVq.mjs} +130 -23
  40. package/dist/node/button-5bnYEAVq.mjs.map +1 -0
  41. package/dist/node/chunk-17FXJ3dL.mjs +31 -0
  42. package/dist/node/{dist-CzYOpeXN.mjs → dist-Bf_PIbO7.mjs} +2 -399
  43. package/dist/node/dist-Bf_PIbO7.mjs.map +1 -0
  44. package/dist/node/document-models/index.mjs +2 -1
  45. package/dist/node/documents-XAQfHX5Q.mjs +17 -0
  46. package/dist/node/documents-XAQfHX5Q.mjs.map +1 -0
  47. package/dist/node/editor-BiiLqEe9.mjs +3679 -0
  48. package/dist/node/editor-BiiLqEe9.mjs.map +1 -0
  49. package/dist/node/{editor-Dg2OZEJu.mjs → editor-Cp2TC5MJ.mjs} +5 -5
  50. package/dist/node/{editor-Dg2OZEJu.mjs.map → editor-Cp2TC5MJ.mjs.map} +1 -1
  51. package/dist/node/editors/document-model-editor/module.mjs +1 -1
  52. package/dist/node/editors/generic-drive-explorer/index.mjs +4 -5
  53. package/dist/node/editors/generic-drive-explorer/index.mjs.map +1 -1
  54. package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
  55. package/dist/node/folder-view-m_rH84Nz.mjs +962 -0
  56. package/dist/node/folder-view-m_rH84Nz.mjs.map +1 -0
  57. package/dist/node/{graphql-BfAoPeWM.mjs → graphql-BvV3tC1U.mjs} +2 -2
  58. package/dist/node/{graphql-BfAoPeWM.mjs.map → graphql-BvV3tC1U.mjs.map} +1 -1
  59. package/dist/node/{graphql-editor-DNxebuTn.mjs → graphql-editor-BhF6KN6y.mjs} +6 -7
  60. package/dist/node/{graphql-editor-DNxebuTn.mjs.map → graphql-editor-BhF6KN6y.mjs.map} +1 -1
  61. package/dist/{browser/hooks-KKcNp2X0.js → node/hooks-Di3FASx-.mjs} +2 -2
  62. package/dist/node/{hooks-D0DcS3MV.mjs.map → hooks-Di3FASx-.mjs.map} +1 -1
  63. package/dist/node/index.mjs +142 -21
  64. package/dist/node/index.mjs.map +1 -1
  65. package/dist/node/{json-editor-BpnEn9AS.mjs → json-editor-Cqc0zuz0.mjs} +3 -4
  66. package/dist/node/{json-editor-BpnEn9AS.mjs.map → json-editor-Cqc0zuz0.mjs.map} +1 -1
  67. package/dist/node/{schema-context-DL8jhi_d.mjs → schema-context-mHmP3Cl6.mjs} +3 -3
  68. package/dist/node/{schema-context-DL8jhi_d.mjs.map → schema-context-mHmP3Cl6.mjs.map} +1 -1
  69. package/dist/node/{connect-CeLh6yfj.mjs → src-CVV6HzQZ-CvqjXbXk.mjs} +1829 -11016
  70. package/dist/node/src-CVV6HzQZ-CvqjXbXk.mjs.map +1 -0
  71. package/dist/node/state-schemas-DXG02fMh.mjs +695 -0
  72. package/dist/node/state-schemas-DXG02fMh.mjs.map +1 -0
  73. package/dist/node/{main-B1tRsYOp.mjs → tslib.es6-DdiHgz9e.mjs} +3 -203
  74. package/dist/node/tslib.es6-DdiHgz9e.mjs.map +1 -0
  75. package/package.json +7 -7
  76. package/dist/browser/button-CuO8Gh3v.js.map +0 -1
  77. package/dist/browser/connect-BqgnsniX.js +0 -14322
  78. package/dist/browser/connect-BqgnsniX.js.map +0 -1
  79. package/dist/browser/dist-B4FWbuEM.js +0 -4148
  80. package/dist/browser/dist-B4FWbuEM.js.map +0 -1
  81. package/dist/browser/dist-BAJ5nRDl.js.map +0 -1
  82. package/dist/browser/dist-C-xkNfyD.js +0 -4641
  83. package/dist/browser/dist-C-xkNfyD.js.map +0 -1
  84. package/dist/browser/document-drive-ZQzPQfEL.js +0 -8237
  85. package/dist/browser/document-drive-ZQzPQfEL.js.map +0 -1
  86. package/dist/browser/documents-J_l59mSV.js.map +0 -1
  87. package/dist/browser/editor-BNgF9-uX.js +0 -1809
  88. package/dist/browser/editor-BNgF9-uX.js.map +0 -1
  89. package/dist/browser/folder-view-tx0A96ZI.js +0 -232
  90. package/dist/browser/folder-view-tx0A96ZI.js.map +0 -1
  91. package/dist/browser/lib-ewnRj2dJ.js +0 -209
  92. package/dist/browser/lib-ewnRj2dJ.js.map +0 -1
  93. package/dist/browser/printer-CEYr4JOg.js +0 -604
  94. package/dist/browser/printer-CEYr4JOg.js.map +0 -1
  95. package/dist/browser/state-schemas-CKh98ehP.js +0 -298
  96. package/dist/browser/state-schemas-CKh98ehP.js.map +0 -1
  97. package/dist/node/button-Da7CxMn7.mjs.map +0 -1
  98. package/dist/node/connect-CeLh6yfj.mjs.map +0 -1
  99. package/dist/node/dist-CUFTZwfc.mjs +0 -4649
  100. package/dist/node/dist-CUFTZwfc.mjs.map +0 -1
  101. package/dist/node/dist-CzYOpeXN.mjs.map +0 -1
  102. package/dist/node/dist-DT7jI9ol.mjs +0 -4148
  103. package/dist/node/dist-DT7jI9ol.mjs.map +0 -1
  104. package/dist/node/document-drive-D1NMjQQc.mjs +0 -8254
  105. package/dist/node/document-drive-D1NMjQQc.mjs.map +0 -1
  106. package/dist/node/documents-DCf53bzO.mjs +0 -747
  107. package/dist/node/documents-DCf53bzO.mjs.map +0 -1
  108. package/dist/node/editor-CXQOsbup.mjs +0 -1809
  109. package/dist/node/editor-CXQOsbup.mjs.map +0 -1
  110. package/dist/node/folder-view-DZ0o2-Ef.mjs +0 -232
  111. package/dist/node/folder-view-DZ0o2-Ef.mjs.map +0 -1
  112. package/dist/node/main-B1tRsYOp.mjs.map +0 -1
  113. package/dist/node/state-schemas-CuSHxrn6.mjs +0 -299
  114. package/dist/node/state-schemas-CuSHxrn6.mjs.map +0 -1
@@ -0,0 +1,3679 @@
1
+ import { t as require_graphql } from "./graphql-BvV3tC1U.mjs";
2
+ import { a as Slot, i as Primitive, t as Modal } from "./src-CVV6HzQZ-CvqjXbXk.mjs";
3
+ import { h as twMerge } from "./dist-Bf_PIbO7.mjs";
4
+ import { t as SchemaContextProvider } from "./schema-context-mHmP3Cl6.mjs";
5
+ import { _ as pascalCase, a as compareStringsWithoutWhitespace, c as isEmptyOperationSchema, f as makeOperationInitialDoc, g as constantCase, l as makeEmptyOperationSchema, m as renameSchemaType, n as ensureValidOperationSchemaInputName, o as handleModelNameChange, s as initializeModelSchema, t as Button, u as makeInitialSchemaDoc, v as snakeCase } from "./button-5bnYEAVq.mjs";
6
+ import { addModule, addOperation, addOperationError, deleteModule, deleteOperation, deleteOperationError, generateId, releaseNewVersion, setAuthorName, setAuthorWebsite, setInitialState, setModelDescription, setModelExtension, setModelId, setModelName, setModuleName, setOperationDescription, setOperationErrorName, setOperationName, setOperationSchema, setStateSchema } from "@powerhousedao/shared/document-model";
7
+ import { z } from "zod";
8
+ import * as React$1 from "react";
9
+ import React, { Suspense, forwardRef, lazy, useCallback, useEffect, useId, useImperativeHandle, useRef, useState } from "react";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ import { ConnectSelect, DocumentToolbar, ModalButton } from "@powerhousedao/design-system/connect";
12
+ import { usePHToast, useSelectedDocumentOfType, useSetPHDocumentEditorConfig } from "@powerhousedao/reactor-browser";
13
+ import * as n from "zod/v4/core";
14
+ //#region ../../node_modules/.pnpm/clsx@2.0.0/node_modules/clsx/dist/clsx.mjs
15
+ function r$1(e) {
16
+ var t, f, n = "";
17
+ if ("string" == typeof e || "number" == typeof e) n += e;
18
+ else if ("object" == typeof e) if (Array.isArray(e)) for (t = 0; t < e.length; t++) e[t] && (f = r$1(e[t])) && (n && (n += " "), n += f);
19
+ else for (t in e) e[t] && (n && (n += " "), n += t);
20
+ return n;
21
+ }
22
+ function clsx() {
23
+ for (var e, t, f = 0, n = ""; f < arguments.length;) (e = arguments[f++]) && (t = r$1(e)) && (n && (n += " "), n += t);
24
+ return n;
25
+ }
26
+ //#endregion
27
+ //#region ../../node_modules/.pnpm/class-variance-authority@0.7.0/node_modules/class-variance-authority/dist/index.mjs
28
+ const falsyToString = (value) => typeof value === "boolean" ? "".concat(value) : value === 0 ? "0" : value;
29
+ const cx = clsx;
30
+ const cva = (base, config) => {
31
+ return (props) => {
32
+ var ref;
33
+ if ((config === null || config === void 0 ? void 0 : config.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
34
+ const { variants, defaultVariants } = config;
35
+ const getVariantClassNames = Object.keys(variants).map((variant) => {
36
+ const variantProp = props === null || props === void 0 ? void 0 : props[variant];
37
+ const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
38
+ if (variantProp === null) return null;
39
+ const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
40
+ return variants[variant][variantKey];
41
+ });
42
+ const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
43
+ let [key, value] = param;
44
+ if (value === void 0) return acc;
45
+ acc[key] = value;
46
+ return acc;
47
+ }, {});
48
+ return cx(base, getVariantClassNames, config === null || config === void 0 ? void 0 : (ref = config.compoundVariants) === null || ref === void 0 ? void 0 : ref.reduce((acc, param1) => {
49
+ let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param1;
50
+ return Object.entries(compoundVariantOptions).every((param) => {
51
+ let [key, value] = param;
52
+ return Array.isArray(value) ? value.includes({
53
+ ...defaultVariants,
54
+ ...propsWithoutUndefined
55
+ }[key]) : {
56
+ ...defaultVariants,
57
+ ...propsWithoutUndefined
58
+ }[key] === value;
59
+ }) ? [
60
+ ...acc,
61
+ cvClass,
62
+ cvClassName
63
+ ] : acc;
64
+ }, []), props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
65
+ };
66
+ };
67
+ //#endregion
68
+ //#region ../../node_modules/.pnpm/react-hook-form@7.71.2_react@19.2.6/node_modules/react-hook-form/dist/index.esm.mjs
69
+ var isCheckBoxInput = (element) => element.type === "checkbox";
70
+ var isDateObject = (value) => value instanceof Date;
71
+ var isNullOrUndefined = (value) => value == null;
72
+ const isObjectType = (value) => typeof value === "object";
73
+ var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value);
74
+ var getEventValue = (event) => isObject(event) && event.target ? isCheckBoxInput(event.target) ? event.target.checked : event.target.value : event;
75
+ var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
76
+ var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
77
+ var isPlainObject = (tempObject) => {
78
+ const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
79
+ return isObject(prototypeCopy) && prototypeCopy.hasOwnProperty("isPrototypeOf");
80
+ };
81
+ var isWeb = typeof window !== "undefined" && typeof window.HTMLElement !== "undefined" && typeof document !== "undefined";
82
+ function cloneObject(data) {
83
+ if (data instanceof Date) return new Date(data);
84
+ const isFileListInstance = typeof FileList !== "undefined" && data instanceof FileList;
85
+ if (isWeb && (data instanceof Blob || isFileListInstance)) return data;
86
+ const isArray = Array.isArray(data);
87
+ if (!isArray && !(isObject(data) && isPlainObject(data))) return data;
88
+ const copy = isArray ? [] : Object.create(Object.getPrototypeOf(data));
89
+ for (const key in data) if (Object.prototype.hasOwnProperty.call(data, key)) copy[key] = cloneObject(data[key]);
90
+ return copy;
91
+ }
92
+ var isKey = (value) => /^\w*$/.test(value);
93
+ var isUndefined = (val) => val === void 0;
94
+ var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
95
+ var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/));
96
+ var get = (object, path, defaultValue) => {
97
+ if (!path || !isObject(object)) return defaultValue;
98
+ const result = (isKey(path) ? [path] : stringToPath(path)).reduce((result, key) => isNullOrUndefined(result) ? result : result[key], object);
99
+ return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
100
+ };
101
+ var isBoolean = (value) => typeof value === "boolean";
102
+ var isFunction = (value) => typeof value === "function";
103
+ var set = (object, path, value) => {
104
+ let index = -1;
105
+ const tempPath = isKey(path) ? [path] : stringToPath(path);
106
+ const length = tempPath.length;
107
+ const lastIndex = length - 1;
108
+ while (++index < length) {
109
+ const key = tempPath[index];
110
+ let newValue = value;
111
+ if (index !== lastIndex) {
112
+ const objValue = object[key];
113
+ newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) ? [] : {};
114
+ }
115
+ if (key === "__proto__" || key === "constructor" || key === "prototype") return;
116
+ object[key] = newValue;
117
+ object = object[key];
118
+ }
119
+ };
120
+ const EVENTS = {
121
+ BLUR: "blur",
122
+ FOCUS_OUT: "focusout",
123
+ CHANGE: "change"
124
+ };
125
+ const VALIDATION_MODE = {
126
+ onBlur: "onBlur",
127
+ onChange: "onChange",
128
+ onSubmit: "onSubmit",
129
+ onTouched: "onTouched",
130
+ all: "all"
131
+ };
132
+ const INPUT_VALIDATION_RULES = {
133
+ max: "max",
134
+ min: "min",
135
+ maxLength: "maxLength",
136
+ minLength: "minLength",
137
+ pattern: "pattern",
138
+ required: "required",
139
+ validate: "validate"
140
+ };
141
+ /**
142
+ * Separate context for `control` to prevent unnecessary rerenders.
143
+ * Internal hooks that only need control use this instead of full form context.
144
+ */
145
+ const HookFormControlContext = React.createContext(null);
146
+ HookFormControlContext.displayName = "HookFormControlContext";
147
+ /**
148
+ * @internal Internal hook to access only control from context.
149
+ */
150
+ const useFormControlContext = () => React.useContext(HookFormControlContext);
151
+ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
152
+ const result = { defaultValues: control._defaultValues };
153
+ for (const key in formState) Object.defineProperty(result, key, { get: () => {
154
+ const _key = key;
155
+ if (control._proxyFormState[_key] !== VALIDATION_MODE.all) control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
156
+ localProxyFormState && (localProxyFormState[_key] = true);
157
+ return formState[_key];
158
+ } });
159
+ return result;
160
+ };
161
+ const useIsomorphicLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
162
+ /**
163
+ * This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
164
+ *
165
+ * @remarks
166
+ * [API](https://react-hook-form.com/docs/useformstate) • [Demo](https://codesandbox.io/s/useformstate-75xly)
167
+ *
168
+ * @param props - include options on specify fields to subscribe. {@link UseFormStateReturn}
169
+ *
170
+ * @example
171
+ * ```tsx
172
+ * function App() {
173
+ * const { register, handleSubmit, control } = useForm({
174
+ * defaultValues: {
175
+ * firstName: "firstName"
176
+ * }});
177
+ * const { dirtyFields } = useFormState({
178
+ * control
179
+ * });
180
+ * const onSubmit = (data) => console.log(data);
181
+ *
182
+ * return (
183
+ * <form onSubmit={handleSubmit(onSubmit)}>
184
+ * <input {...register("firstName")} placeholder="First Name" />
185
+ * {dirtyFields.firstName && <p>Field is dirty.</p>}
186
+ * <input type="submit" />
187
+ * </form>
188
+ * );
189
+ * }
190
+ * ```
191
+ */
192
+ function useFormState(props) {
193
+ const formControl = useFormControlContext();
194
+ const { control = formControl, disabled, name, exact } = props || {};
195
+ const [formState, updateFormState] = React.useState(control._formState);
196
+ const _localProxyFormState = React.useRef({
197
+ isDirty: false,
198
+ isLoading: false,
199
+ dirtyFields: false,
200
+ touchedFields: false,
201
+ validatingFields: false,
202
+ isValidating: false,
203
+ isValid: false,
204
+ errors: false
205
+ });
206
+ useIsomorphicLayoutEffect(() => control._subscribe({
207
+ name,
208
+ formState: _localProxyFormState.current,
209
+ exact,
210
+ callback: (formState) => {
211
+ !disabled && updateFormState({
212
+ ...control._formState,
213
+ ...formState
214
+ });
215
+ }
216
+ }), [
217
+ name,
218
+ disabled,
219
+ exact
220
+ ]);
221
+ React.useEffect(() => {
222
+ _localProxyFormState.current.isValid && control._setValid(true);
223
+ }, [control]);
224
+ return React.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
225
+ }
226
+ var isString = (value) => typeof value === "string";
227
+ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
228
+ if (isString(names)) {
229
+ isGlobal && _names.watch.add(names);
230
+ return get(formValues, names, defaultValue);
231
+ }
232
+ if (Array.isArray(names)) return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName), get(formValues, fieldName)));
233
+ isGlobal && (_names.watchAll = true);
234
+ return formValues;
235
+ };
236
+ var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
237
+ function deepEqual(object1, object2, _internal_visited = /* @__PURE__ */ new WeakSet()) {
238
+ if (isPrimitive(object1) || isPrimitive(object2)) return Object.is(object1, object2);
239
+ if (isDateObject(object1) && isDateObject(object2)) return Object.is(object1.getTime(), object2.getTime());
240
+ const keys1 = Object.keys(object1);
241
+ const keys2 = Object.keys(object2);
242
+ if (keys1.length !== keys2.length) return false;
243
+ if (_internal_visited.has(object1) || _internal_visited.has(object2)) return true;
244
+ _internal_visited.add(object1);
245
+ _internal_visited.add(object2);
246
+ for (const key of keys1) {
247
+ const val1 = object1[key];
248
+ if (!keys2.includes(key)) return false;
249
+ if (key !== "ref") {
250
+ const val2 = object2[key];
251
+ if (isDateObject(val1) && isDateObject(val2) || isObject(val1) && isObject(val2) || Array.isArray(val1) && Array.isArray(val2) ? !deepEqual(val1, val2, _internal_visited) : !Object.is(val1, val2)) return false;
252
+ }
253
+ }
254
+ return true;
255
+ }
256
+ /**
257
+ * Custom hook to subscribe to field change and isolate re-rendering at the component level.
258
+ *
259
+ * @remarks
260
+ *
261
+ * [API](https://react-hook-form.com/docs/usewatch) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-usewatch-h9i5e)
262
+ *
263
+ * @example
264
+ * ```tsx
265
+ * const { control } = useForm();
266
+ * const values = useWatch({
267
+ * name: "fieldName"
268
+ * control,
269
+ * })
270
+ * ```
271
+ */
272
+ function useWatch(props) {
273
+ const formControl = useFormControlContext();
274
+ const { control = formControl, name, defaultValue, disabled, exact, compute } = props || {};
275
+ const _defaultValue = React.useRef(defaultValue);
276
+ const _compute = React.useRef(compute);
277
+ const _computeFormValues = React.useRef(void 0);
278
+ const _prevControl = React.useRef(control);
279
+ const _prevName = React.useRef(name);
280
+ _compute.current = compute;
281
+ const [value, updateValue] = React.useState(() => {
282
+ const defaultValue = control._getWatch(name, _defaultValue.current);
283
+ return _compute.current ? _compute.current(defaultValue) : defaultValue;
284
+ });
285
+ const getCurrentOutput = React.useCallback((values) => {
286
+ const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
287
+ return _compute.current ? _compute.current(formValues) : formValues;
288
+ }, [
289
+ control._formValues,
290
+ control._names,
291
+ name
292
+ ]);
293
+ const refreshValue = React.useCallback((values) => {
294
+ if (!disabled) {
295
+ const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
296
+ if (_compute.current) {
297
+ const computedFormValues = _compute.current(formValues);
298
+ if (!deepEqual(computedFormValues, _computeFormValues.current)) {
299
+ updateValue(computedFormValues);
300
+ _computeFormValues.current = computedFormValues;
301
+ }
302
+ } else updateValue(formValues);
303
+ }
304
+ }, [
305
+ control._formValues,
306
+ control._names,
307
+ disabled,
308
+ name
309
+ ]);
310
+ useIsomorphicLayoutEffect(() => {
311
+ if (_prevControl.current !== control || !deepEqual(_prevName.current, name)) {
312
+ _prevControl.current = control;
313
+ _prevName.current = name;
314
+ refreshValue();
315
+ }
316
+ return control._subscribe({
317
+ name,
318
+ formState: { values: true },
319
+ exact,
320
+ callback: (formState) => {
321
+ refreshValue(formState.values);
322
+ }
323
+ });
324
+ }, [
325
+ control,
326
+ exact,
327
+ name,
328
+ refreshValue
329
+ ]);
330
+ React.useEffect(() => control._removeUnmounted());
331
+ const controlChanged = _prevControl.current !== control;
332
+ const prevName = _prevName.current;
333
+ const computedOutput = React.useMemo(() => {
334
+ if (disabled) return null;
335
+ const nameChanged = !controlChanged && !deepEqual(prevName, name);
336
+ return controlChanged || nameChanged ? getCurrentOutput() : null;
337
+ }, [
338
+ disabled,
339
+ controlChanged,
340
+ name,
341
+ prevName,
342
+ getCurrentOutput
343
+ ]);
344
+ return computedOutput !== null ? computedOutput : value;
345
+ }
346
+ /**
347
+ * Custom hook to work with controlled component, this function provide you with both form and field level state. Re-render is isolated at the hook level.
348
+ *
349
+ * @remarks
350
+ * [API](https://react-hook-form.com/docs/usecontroller) • [Demo](https://codesandbox.io/s/usecontroller-0o8px)
351
+ *
352
+ * @param props - the path name to the form field value, and validation rules.
353
+ *
354
+ * @returns field properties, field and form state. {@link UseControllerReturn}
355
+ *
356
+ * @example
357
+ * ```tsx
358
+ * function Input(props) {
359
+ * const { field, fieldState, formState } = useController(props);
360
+ * return (
361
+ * <div>
362
+ * <input {...field} placeholder={props.name} />
363
+ * <p>{fieldState.isTouched && "Touched"}</p>
364
+ * <p>{formState.isSubmitted ? "submitted" : ""}</p>
365
+ * </div>
366
+ * );
367
+ * }
368
+ * ```
369
+ */
370
+ function useController(props) {
371
+ const formControl = useFormControlContext();
372
+ const { name, disabled, control = formControl, shouldUnregister, defaultValue, exact = true } = props;
373
+ const isArrayField = isNameInFieldArray(control._names.array, name);
374
+ const value = useWatch({
375
+ control,
376
+ name,
377
+ defaultValue: React.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [
378
+ control,
379
+ name,
380
+ defaultValue
381
+ ]),
382
+ exact
383
+ });
384
+ const formState = useFormState({
385
+ control,
386
+ name,
387
+ exact
388
+ });
389
+ const _props = React.useRef(props);
390
+ const _previousNameRef = React.useRef(void 0);
391
+ const _registerProps = React.useRef(control.register(name, {
392
+ ...props.rules,
393
+ value,
394
+ ...isBoolean(props.disabled) ? { disabled: props.disabled } : {}
395
+ }));
396
+ _props.current = props;
397
+ const fieldState = React.useMemo(() => Object.defineProperties({}, {
398
+ invalid: {
399
+ enumerable: true,
400
+ get: () => !!get(formState.errors, name)
401
+ },
402
+ isDirty: {
403
+ enumerable: true,
404
+ get: () => !!get(formState.dirtyFields, name)
405
+ },
406
+ isTouched: {
407
+ enumerable: true,
408
+ get: () => !!get(formState.touchedFields, name)
409
+ },
410
+ isValidating: {
411
+ enumerable: true,
412
+ get: () => !!get(formState.validatingFields, name)
413
+ },
414
+ error: {
415
+ enumerable: true,
416
+ get: () => get(formState.errors, name)
417
+ }
418
+ }), [formState, name]);
419
+ const onChange = React.useCallback((event) => _registerProps.current.onChange({
420
+ target: {
421
+ value: getEventValue(event),
422
+ name
423
+ },
424
+ type: EVENTS.CHANGE
425
+ }), [name]);
426
+ const onBlur = React.useCallback(() => _registerProps.current.onBlur({
427
+ target: {
428
+ value: get(control._formValues, name),
429
+ name
430
+ },
431
+ type: EVENTS.BLUR
432
+ }), [name, control._formValues]);
433
+ const ref = React.useCallback((elm) => {
434
+ const field = get(control._fields, name);
435
+ if (field && field._f && elm) field._f.ref = {
436
+ focus: () => isFunction(elm.focus) && elm.focus(),
437
+ select: () => isFunction(elm.select) && elm.select(),
438
+ setCustomValidity: (message) => isFunction(elm.setCustomValidity) && elm.setCustomValidity(message),
439
+ reportValidity: () => isFunction(elm.reportValidity) && elm.reportValidity()
440
+ };
441
+ }, [control._fields, name]);
442
+ const field = React.useMemo(() => ({
443
+ name,
444
+ value,
445
+ ...isBoolean(disabled) || formState.disabled ? { disabled: formState.disabled || disabled } : {},
446
+ onChange,
447
+ onBlur,
448
+ ref
449
+ }), [
450
+ name,
451
+ disabled,
452
+ formState.disabled,
453
+ onChange,
454
+ onBlur,
455
+ ref,
456
+ value
457
+ ]);
458
+ React.useEffect(() => {
459
+ const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
460
+ const previousName = _previousNameRef.current;
461
+ if (previousName && previousName !== name && !isArrayField) control.unregister(previousName);
462
+ control.register(name, {
463
+ ..._props.current.rules,
464
+ ...isBoolean(_props.current.disabled) ? { disabled: _props.current.disabled } : {}
465
+ });
466
+ const updateMounted = (name, value) => {
467
+ const field = get(control._fields, name);
468
+ if (field && field._f) field._f.mount = value;
469
+ };
470
+ updateMounted(name, true);
471
+ if (_shouldUnregisterField) {
472
+ const value = cloneObject(get(control._options.defaultValues, name, _props.current.defaultValue));
473
+ set(control._defaultValues, name, value);
474
+ if (isUndefined(get(control._formValues, name))) set(control._formValues, name, value);
475
+ }
476
+ !isArrayField && control.register(name);
477
+ _previousNameRef.current = name;
478
+ return () => {
479
+ (isArrayField ? _shouldUnregisterField && !control._state.action : _shouldUnregisterField) ? control.unregister(name) : updateMounted(name, false);
480
+ };
481
+ }, [
482
+ name,
483
+ control,
484
+ isArrayField,
485
+ shouldUnregister
486
+ ]);
487
+ React.useEffect(() => {
488
+ control._setDisabledField({
489
+ disabled,
490
+ name
491
+ });
492
+ }, [
493
+ disabled,
494
+ name,
495
+ control
496
+ ]);
497
+ return React.useMemo(() => ({
498
+ field,
499
+ formState,
500
+ fieldState
501
+ }), [
502
+ field,
503
+ formState,
504
+ fieldState
505
+ ]);
506
+ }
507
+ /**
508
+ * Component based on `useController` hook to work with controlled component.
509
+ *
510
+ * @remarks
511
+ * [API](https://react-hook-form.com/docs/usecontroller/controller) • [Demo](https://codesandbox.io/s/react-hook-form-v6-controller-ts-jwyzw) • [Video](https://www.youtube.com/watch?v=N2UNk_UCVyA)
512
+ *
513
+ * @param props - the path name to the form field value, and validation rules.
514
+ *
515
+ * @returns provide field handler functions, field and form state.
516
+ *
517
+ * @example
518
+ * ```tsx
519
+ * function App() {
520
+ * const { control } = useForm<FormValues>({
521
+ * defaultValues: {
522
+ * test: ""
523
+ * }
524
+ * });
525
+ *
526
+ * return (
527
+ * <form>
528
+ * <Controller
529
+ * control={control}
530
+ * name="test"
531
+ * render={({ field: { onChange, onBlur, value, ref }, formState, fieldState }) => (
532
+ * <>
533
+ * <input
534
+ * onChange={onChange} // send value to hook form
535
+ * onBlur={onBlur} // notify when input is touched
536
+ * value={value} // return updated value
537
+ * ref={ref} // set ref for focus management
538
+ * />
539
+ * <p>{formState.isSubmitted ? "submitted" : ""}</p>
540
+ * <p>{fieldState.isTouched ? "touched" : ""}</p>
541
+ * </>
542
+ * )}
543
+ * />
544
+ * </form>
545
+ * );
546
+ * }
547
+ * ```
548
+ */
549
+ const Controller = (props) => props.render(useController(props));
550
+ const HookFormContext = React.createContext(null);
551
+ HookFormContext.displayName = "HookFormContext";
552
+ /**
553
+ * This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop. To be used with {@link FormProvider}.
554
+ *
555
+ * @remarks
556
+ * [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
557
+ *
558
+ * @returns return all useForm methods
559
+ *
560
+ * @example
561
+ * ```tsx
562
+ * function App() {
563
+ * const methods = useForm();
564
+ * const onSubmit = data => console.log(data);
565
+ *
566
+ * return (
567
+ * <FormProvider {...methods} >
568
+ * <form onSubmit={methods.handleSubmit(onSubmit)}>
569
+ * <NestedInput />
570
+ * <input type="submit" />
571
+ * </form>
572
+ * </FormProvider>
573
+ * );
574
+ * }
575
+ *
576
+ * function NestedInput() {
577
+ * const { register } = useFormContext(); // retrieve all hook methods
578
+ * return <input {...register("test")} />;
579
+ * }
580
+ * ```
581
+ */
582
+ const useFormContext = () => React.useContext(HookFormContext);
583
+ /**
584
+ * A provider component that propagates the `useForm` methods to all children components via [React Context](https://react.dev/reference/react/useContext) API. To be used with {@link useFormContext}.
585
+ *
586
+ * @remarks
587
+ * [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
588
+ *
589
+ * @param props - all useForm methods
590
+ *
591
+ * @example
592
+ * ```tsx
593
+ * function App() {
594
+ * const methods = useForm();
595
+ * const onSubmit = data => console.log(data);
596
+ *
597
+ * return (
598
+ * <FormProvider {...methods} >
599
+ * <form onSubmit={methods.handleSubmit(onSubmit)}>
600
+ * <NestedInput />
601
+ * <input type="submit" />
602
+ * </form>
603
+ * </FormProvider>
604
+ * );
605
+ * }
606
+ *
607
+ * function NestedInput() {
608
+ * const { register } = useFormContext(); // retrieve all hook methods
609
+ * return <input {...register("test")} />;
610
+ * }
611
+ * ```
612
+ */
613
+ const FormProvider = (props) => {
614
+ const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe } = props;
615
+ return React.createElement(HookFormContext.Provider, { value: React.useMemo(() => ({
616
+ watch,
617
+ getValues,
618
+ getFieldState,
619
+ setError,
620
+ clearErrors,
621
+ setValue,
622
+ trigger,
623
+ formState,
624
+ resetField,
625
+ reset,
626
+ handleSubmit,
627
+ unregister,
628
+ control,
629
+ register,
630
+ setFocus,
631
+ subscribe
632
+ }), [
633
+ clearErrors,
634
+ control,
635
+ formState,
636
+ getFieldState,
637
+ getValues,
638
+ handleSubmit,
639
+ register,
640
+ reset,
641
+ resetField,
642
+ setError,
643
+ setFocus,
644
+ setValue,
645
+ subscribe,
646
+ trigger,
647
+ unregister,
648
+ watch
649
+ ]) }, React.createElement(HookFormControlContext.Provider, { value: control }, children));
650
+ };
651
+ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria ? {
652
+ ...errors[name],
653
+ types: {
654
+ ...errors[name] && errors[name].types ? errors[name].types : {},
655
+ [type]: message || true
656
+ }
657
+ } : {};
658
+ var convertToArrayPayload = (value) => Array.isArray(value) ? value : [value];
659
+ var createSubject = () => {
660
+ let _observers = [];
661
+ const next = (value) => {
662
+ for (const observer of _observers) observer.next && observer.next(value);
663
+ };
664
+ const subscribe = (observer) => {
665
+ _observers.push(observer);
666
+ return { unsubscribe: () => {
667
+ _observers = _observers.filter((o) => o !== observer);
668
+ } };
669
+ };
670
+ const unsubscribe = () => {
671
+ _observers = [];
672
+ };
673
+ return {
674
+ get observers() {
675
+ return _observers;
676
+ },
677
+ next,
678
+ subscribe,
679
+ unsubscribe
680
+ };
681
+ };
682
+ function extractFormValues(fieldsState, formValues) {
683
+ const values = {};
684
+ for (const key in fieldsState) if (fieldsState.hasOwnProperty(key)) {
685
+ const fieldState = fieldsState[key];
686
+ const fieldValue = formValues[key];
687
+ if (fieldState && isObject(fieldState) && fieldValue) {
688
+ const nestedFieldsState = extractFormValues(fieldState, fieldValue);
689
+ if (isObject(nestedFieldsState)) values[key] = nestedFieldsState;
690
+ } else if (fieldsState[key]) values[key] = fieldValue;
691
+ }
692
+ return values;
693
+ }
694
+ var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
695
+ var isFileInput = (element) => element.type === "file";
696
+ var isHTMLElement = (value) => {
697
+ if (!isWeb) return false;
698
+ const owner = value ? value.ownerDocument : 0;
699
+ return value instanceof (owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement);
700
+ };
701
+ var isMultipleSelect = (element) => element.type === `select-multiple`;
702
+ var isRadioInput = (element) => element.type === "radio";
703
+ var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
704
+ var live = (ref) => isHTMLElement(ref) && ref.isConnected;
705
+ function baseGet(object, updatePath) {
706
+ const length = updatePath.slice(0, -1).length;
707
+ let index = 0;
708
+ while (index < length) object = isUndefined(object) ? index++ : object[updatePath[index++]];
709
+ return object;
710
+ }
711
+ function isEmptyArray(obj) {
712
+ for (const key in obj) if (obj.hasOwnProperty(key) && !isUndefined(obj[key])) return false;
713
+ return true;
714
+ }
715
+ function unset(object, path) {
716
+ const paths = Array.isArray(path) ? path : isKey(path) ? [path] : stringToPath(path);
717
+ const childObject = paths.length === 1 ? object : baseGet(object, paths);
718
+ const index = paths.length - 1;
719
+ const key = paths[index];
720
+ if (childObject) delete childObject[key];
721
+ if (index !== 0 && (isObject(childObject) && isEmptyObject(childObject) || Array.isArray(childObject) && isEmptyArray(childObject))) unset(object, paths.slice(0, -1));
722
+ return object;
723
+ }
724
+ var objectHasFunction = (data) => {
725
+ for (const key in data) if (isFunction(data[key])) return true;
726
+ return false;
727
+ };
728
+ function isTraversable(value) {
729
+ return Array.isArray(value) || isObject(value) && !objectHasFunction(value);
730
+ }
731
+ function markFieldsDirty(data, fields = {}) {
732
+ for (const key in data) {
733
+ const value = data[key];
734
+ if (isTraversable(value)) {
735
+ fields[key] = Array.isArray(value) ? [] : {};
736
+ markFieldsDirty(value, fields[key]);
737
+ } else if (!isUndefined(value)) fields[key] = true;
738
+ }
739
+ return fields;
740
+ }
741
+ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
742
+ if (!dirtyFieldsFromValues) dirtyFieldsFromValues = markFieldsDirty(formValues);
743
+ for (const key in data) {
744
+ const value = data[key];
745
+ if (isTraversable(value)) if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {});
746
+ else getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
747
+ else {
748
+ const formValue = formValues[key];
749
+ dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
750
+ }
751
+ }
752
+ return dirtyFieldsFromValues;
753
+ }
754
+ const defaultResult = {
755
+ value: false,
756
+ isValid: false
757
+ };
758
+ const validResult = {
759
+ value: true,
760
+ isValid: true
761
+ };
762
+ var getCheckboxValue = (options) => {
763
+ if (Array.isArray(options)) {
764
+ if (options.length > 1) {
765
+ const values = options.filter((option) => option && option.checked && !option.disabled).map((option) => option.value);
766
+ return {
767
+ value: values,
768
+ isValid: !!values.length
769
+ };
770
+ }
771
+ return options[0].checked && !options[0].disabled ? options[0].attributes && !isUndefined(options[0].attributes.value) ? isUndefined(options[0].value) || options[0].value === "" ? validResult : {
772
+ value: options[0].value,
773
+ isValid: true
774
+ } : validResult : defaultResult;
775
+ }
776
+ return defaultResult;
777
+ };
778
+ var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isUndefined(value) ? value : valueAsNumber ? value === "" ? NaN : value ? +value : value : valueAsDate && isString(value) ? new Date(value) : setValueAs ? setValueAs(value) : value;
779
+ const defaultReturn = {
780
+ isValid: false,
781
+ value: null
782
+ };
783
+ var getRadioValue = (options) => Array.isArray(options) ? options.reduce((previous, option) => option && option.checked && !option.disabled ? {
784
+ isValid: true,
785
+ value: option.value
786
+ } : previous, defaultReturn) : defaultReturn;
787
+ function getFieldValue(_f) {
788
+ const ref = _f.ref;
789
+ if (isFileInput(ref)) return ref.files;
790
+ if (isRadioInput(ref)) return getRadioValue(_f.refs).value;
791
+ if (isMultipleSelect(ref)) return [...ref.selectedOptions].map(({ value }) => value);
792
+ if (isCheckBoxInput(ref)) return getCheckboxValue(_f.refs).value;
793
+ return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
794
+ }
795
+ var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
796
+ const fields = {};
797
+ for (const name of fieldsNames) {
798
+ const field = get(_fields, name);
799
+ field && set(fields, name, field._f);
800
+ }
801
+ return {
802
+ criteriaMode,
803
+ names: [...fieldsNames],
804
+ fields,
805
+ shouldUseNativeValidation
806
+ };
807
+ };
808
+ var isRegex = (value) => value instanceof RegExp;
809
+ var getRuleValue = (rule) => isUndefined(rule) ? rule : isRegex(rule) ? rule.source : isObject(rule) ? isRegex(rule.value) ? rule.value.source : rule.value : rule;
810
+ var getValidationModes = (mode) => ({
811
+ isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
812
+ isOnBlur: mode === VALIDATION_MODE.onBlur,
813
+ isOnChange: mode === VALIDATION_MODE.onChange,
814
+ isOnAll: mode === VALIDATION_MODE.all,
815
+ isOnTouch: mode === VALIDATION_MODE.onTouched
816
+ });
817
+ const ASYNC_FUNCTION = "AsyncFunction";
818
+ var hasPromiseValidation = (fieldReference) => !!fieldReference && !!fieldReference.validate && !!(isFunction(fieldReference.validate) && fieldReference.validate.constructor.name === ASYNC_FUNCTION || isObject(fieldReference.validate) && Object.values(fieldReference.validate).find((validateFunction) => validateFunction.constructor.name === ASYNC_FUNCTION));
819
+ var hasValidation = (options) => options.mount && (options.required || options.min || options.max || options.maxLength || options.minLength || options.pattern || options.validate);
820
+ var isWatched = (name, _names, isBlurEvent) => !isBlurEvent && (_names.watchAll || _names.watch.has(name) || [..._names.watch].some((watchName) => name.startsWith(watchName) && /^\.\w+/.test(name.slice(watchName.length))));
821
+ const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
822
+ for (const key of fieldsNames || Object.keys(fields)) {
823
+ const field = get(fields, key);
824
+ if (field) {
825
+ const { _f, ...currentField } = field;
826
+ if (_f) {
827
+ if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) return true;
828
+ else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) return true;
829
+ else if (iterateFieldsByAction(currentField, action)) break;
830
+ } else if (isObject(currentField)) {
831
+ if (iterateFieldsByAction(currentField, action)) break;
832
+ }
833
+ }
834
+ }
835
+ };
836
+ function schemaErrorLookup(errors, _fields, name) {
837
+ const error = get(errors, name);
838
+ if (error || isKey(name)) return {
839
+ error,
840
+ name
841
+ };
842
+ const names = name.split(".");
843
+ while (names.length) {
844
+ const fieldName = names.join(".");
845
+ const field = get(_fields, fieldName);
846
+ const foundError = get(errors, fieldName);
847
+ if (field && !Array.isArray(field) && name !== fieldName) return { name };
848
+ if (foundError && foundError.type) return {
849
+ name: fieldName,
850
+ error: foundError
851
+ };
852
+ if (foundError && foundError.root && foundError.root.type) return {
853
+ name: `${fieldName}.root`,
854
+ error: foundError.root
855
+ };
856
+ names.pop();
857
+ }
858
+ return { name };
859
+ }
860
+ var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
861
+ updateFormState(formStateData);
862
+ const { name, ...formState } = formStateData;
863
+ return isEmptyObject(formState) || Object.keys(formState).length >= Object.keys(_proxyFormState).length || Object.keys(formState).find((key) => _proxyFormState[key] === (!isRoot || VALIDATION_MODE.all));
864
+ };
865
+ var shouldSubscribeByName = (name, signalName, exact) => !name || !signalName || name === signalName || convertToArrayPayload(name).some((currentName) => currentName && (exact ? currentName === signalName : currentName.startsWith(signalName) || signalName.startsWith(currentName)));
866
+ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode) => {
867
+ if (mode.isOnAll) return false;
868
+ else if (!isSubmitted && mode.isOnTouch) return !(isTouched || isBlurEvent);
869
+ else if (isSubmitted ? reValidateMode.isOnBlur : mode.isOnBlur) return !isBlurEvent;
870
+ else if (isSubmitted ? reValidateMode.isOnChange : mode.isOnChange) return isBlurEvent;
871
+ return true;
872
+ };
873
+ var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
874
+ var updateFieldArrayRootError = (errors, error, name) => {
875
+ const fieldArrayErrors = convertToArrayPayload(get(errors, name));
876
+ set(fieldArrayErrors, "root", error[name]);
877
+ set(errors, name, fieldArrayErrors);
878
+ return errors;
879
+ };
880
+ function getValidateError(result, ref, type = "validate") {
881
+ if (isString(result) || Array.isArray(result) && result.every(isString) || isBoolean(result) && !result) return {
882
+ type,
883
+ message: isString(result) ? result : "",
884
+ ref
885
+ };
886
+ }
887
+ var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData) ? validationData : {
888
+ value: validationData,
889
+ message: ""
890
+ };
891
+ var validateField = async (field, disabledFieldNames, formValues, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
892
+ const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount } = field._f;
893
+ const inputValue = get(formValues, name);
894
+ if (!mount || disabledFieldNames.has(name)) return {};
895
+ const inputRef = refs ? refs[0] : ref;
896
+ const setCustomValidity = (message) => {
897
+ if (shouldUseNativeValidation && inputRef.reportValidity) {
898
+ inputRef.setCustomValidity(isBoolean(message) ? "" : message || "");
899
+ inputRef.reportValidity();
900
+ }
901
+ };
902
+ const error = {};
903
+ const isRadio = isRadioInput(ref);
904
+ const isCheckBox = isCheckBoxInput(ref);
905
+ const isRadioOrCheckbox = isRadio || isCheckBox;
906
+ const isEmpty = (valueAsNumber || isFileInput(ref)) && isUndefined(ref.value) && isUndefined(inputValue) || isHTMLElement(ref) && ref.value === "" || inputValue === "" || Array.isArray(inputValue) && !inputValue.length;
907
+ const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
908
+ const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
909
+ const message = exceedMax ? maxLengthMessage : minLengthMessage;
910
+ error[name] = {
911
+ type: exceedMax ? maxType : minType,
912
+ message,
913
+ ref,
914
+ ...appendErrorsCurry(exceedMax ? maxType : minType, message)
915
+ };
916
+ };
917
+ if (isFieldArray ? !Array.isArray(inputValue) || !inputValue.length : required && (!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue)) || isBoolean(inputValue) && !inputValue || isCheckBox && !getCheckboxValue(refs).isValid || isRadio && !getRadioValue(refs).isValid)) {
918
+ const { value, message } = isString(required) ? {
919
+ value: !!required,
920
+ message: required
921
+ } : getValueAndMessage(required);
922
+ if (value) {
923
+ error[name] = {
924
+ type: INPUT_VALIDATION_RULES.required,
925
+ message,
926
+ ref: inputRef,
927
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message)
928
+ };
929
+ if (!validateAllFieldCriteria) {
930
+ setCustomValidity(message);
931
+ return error;
932
+ }
933
+ }
934
+ }
935
+ if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
936
+ let exceedMax;
937
+ let exceedMin;
938
+ const maxOutput = getValueAndMessage(max);
939
+ const minOutput = getValueAndMessage(min);
940
+ if (!isNullOrUndefined(inputValue) && !isNaN(inputValue)) {
941
+ const valueNumber = ref.valueAsNumber || (inputValue ? +inputValue : inputValue);
942
+ if (!isNullOrUndefined(maxOutput.value)) exceedMax = valueNumber > maxOutput.value;
943
+ if (!isNullOrUndefined(minOutput.value)) exceedMin = valueNumber < minOutput.value;
944
+ } else {
945
+ const valueDate = ref.valueAsDate || new Date(inputValue);
946
+ const convertTimeToDate = (time) => /* @__PURE__ */ new Date((/* @__PURE__ */ new Date()).toDateString() + " " + time);
947
+ const isTime = ref.type == "time";
948
+ const isWeek = ref.type == "week";
949
+ if (isString(maxOutput.value) && inputValue) exceedMax = isTime ? convertTimeToDate(inputValue) > convertTimeToDate(maxOutput.value) : isWeek ? inputValue > maxOutput.value : valueDate > new Date(maxOutput.value);
950
+ if (isString(minOutput.value) && inputValue) exceedMin = isTime ? convertTimeToDate(inputValue) < convertTimeToDate(minOutput.value) : isWeek ? inputValue < minOutput.value : valueDate < new Date(minOutput.value);
951
+ }
952
+ if (exceedMax || exceedMin) {
953
+ getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
954
+ if (!validateAllFieldCriteria) {
955
+ setCustomValidity(error[name].message);
956
+ return error;
957
+ }
958
+ }
959
+ }
960
+ if ((maxLength || minLength) && !isEmpty && (isString(inputValue) || isFieldArray && Array.isArray(inputValue))) {
961
+ const maxLengthOutput = getValueAndMessage(maxLength);
962
+ const minLengthOutput = getValueAndMessage(minLength);
963
+ const exceedMax = !isNullOrUndefined(maxLengthOutput.value) && inputValue.length > +maxLengthOutput.value;
964
+ const exceedMin = !isNullOrUndefined(minLengthOutput.value) && inputValue.length < +minLengthOutput.value;
965
+ if (exceedMax || exceedMin) {
966
+ getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
967
+ if (!validateAllFieldCriteria) {
968
+ setCustomValidity(error[name].message);
969
+ return error;
970
+ }
971
+ }
972
+ }
973
+ if (pattern && !isEmpty && isString(inputValue)) {
974
+ const { value: patternValue, message } = getValueAndMessage(pattern);
975
+ if (isRegex(patternValue) && !inputValue.match(patternValue)) {
976
+ error[name] = {
977
+ type: INPUT_VALIDATION_RULES.pattern,
978
+ message,
979
+ ref,
980
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message)
981
+ };
982
+ if (!validateAllFieldCriteria) {
983
+ setCustomValidity(message);
984
+ return error;
985
+ }
986
+ }
987
+ }
988
+ if (validate) {
989
+ if (isFunction(validate)) {
990
+ const validateError = getValidateError(await validate(inputValue, formValues), inputRef);
991
+ if (validateError) {
992
+ error[name] = {
993
+ ...validateError,
994
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message)
995
+ };
996
+ if (!validateAllFieldCriteria) {
997
+ setCustomValidity(validateError.message);
998
+ return error;
999
+ }
1000
+ }
1001
+ } else if (isObject(validate)) {
1002
+ let validationResult = {};
1003
+ for (const key in validate) {
1004
+ if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) break;
1005
+ const validateError = getValidateError(await validate[key](inputValue, formValues), inputRef, key);
1006
+ if (validateError) {
1007
+ validationResult = {
1008
+ ...validateError,
1009
+ ...appendErrorsCurry(key, validateError.message)
1010
+ };
1011
+ setCustomValidity(validateError.message);
1012
+ if (validateAllFieldCriteria) error[name] = validationResult;
1013
+ }
1014
+ }
1015
+ if (!isEmptyObject(validationResult)) {
1016
+ error[name] = {
1017
+ ref: inputRef,
1018
+ ...validationResult
1019
+ };
1020
+ if (!validateAllFieldCriteria) return error;
1021
+ }
1022
+ }
1023
+ }
1024
+ setCustomValidity(true);
1025
+ return error;
1026
+ };
1027
+ const defaultOptions = {
1028
+ mode: VALIDATION_MODE.onSubmit,
1029
+ reValidateMode: VALIDATION_MODE.onChange,
1030
+ shouldFocusError: true
1031
+ };
1032
+ function createFormControl(props = {}) {
1033
+ let _options = {
1034
+ ...defaultOptions,
1035
+ ...props
1036
+ };
1037
+ let _formState = {
1038
+ submitCount: 0,
1039
+ isDirty: false,
1040
+ isReady: false,
1041
+ isLoading: isFunction(_options.defaultValues),
1042
+ isValidating: false,
1043
+ isSubmitted: false,
1044
+ isSubmitting: false,
1045
+ isSubmitSuccessful: false,
1046
+ isValid: false,
1047
+ touchedFields: {},
1048
+ dirtyFields: {},
1049
+ validatingFields: {},
1050
+ errors: _options.errors || {},
1051
+ disabled: _options.disabled || false
1052
+ };
1053
+ let _fields = {};
1054
+ let _defaultValues = isObject(_options.defaultValues) || isObject(_options.values) ? cloneObject(_options.defaultValues || _options.values) || {} : {};
1055
+ let _formValues = _options.shouldUnregister ? {} : cloneObject(_defaultValues);
1056
+ let _state = {
1057
+ action: false,
1058
+ mount: false,
1059
+ watch: false,
1060
+ keepIsValid: false
1061
+ };
1062
+ let _names = {
1063
+ mount: /* @__PURE__ */ new Set(),
1064
+ disabled: /* @__PURE__ */ new Set(),
1065
+ unMount: /* @__PURE__ */ new Set(),
1066
+ array: /* @__PURE__ */ new Set(),
1067
+ watch: /* @__PURE__ */ new Set()
1068
+ };
1069
+ let delayErrorCallback;
1070
+ let timer = 0;
1071
+ const defaultProxyFormState = {
1072
+ isDirty: false,
1073
+ dirtyFields: false,
1074
+ validatingFields: false,
1075
+ touchedFields: false,
1076
+ isValidating: false,
1077
+ isValid: false,
1078
+ errors: false
1079
+ };
1080
+ const _proxyFormState = { ...defaultProxyFormState };
1081
+ let _proxySubscribeFormState = { ..._proxyFormState };
1082
+ const _subjects = {
1083
+ array: createSubject(),
1084
+ state: createSubject()
1085
+ };
1086
+ const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
1087
+ const debounce = (callback) => (wait) => {
1088
+ clearTimeout(timer);
1089
+ timer = setTimeout(callback, wait);
1090
+ };
1091
+ const _setValid = async (shouldUpdateValid) => {
1092
+ if (_state.keepIsValid) return;
1093
+ if (!_options.disabled && (_proxyFormState.isValid || _proxySubscribeFormState.isValid || shouldUpdateValid)) {
1094
+ let isValid;
1095
+ if (_options.resolver) {
1096
+ isValid = isEmptyObject((await _runSchema()).errors);
1097
+ _updateIsValidating();
1098
+ } else isValid = await executeBuiltInValidation(_fields, true);
1099
+ if (isValid !== _formState.isValid) _subjects.state.next({ isValid });
1100
+ }
1101
+ };
1102
+ const _updateIsValidating = (names, isValidating) => {
1103
+ if (!_options.disabled && (_proxyFormState.isValidating || _proxyFormState.validatingFields || _proxySubscribeFormState.isValidating || _proxySubscribeFormState.validatingFields)) {
1104
+ (names || Array.from(_names.mount)).forEach((name) => {
1105
+ if (name) isValidating ? set(_formState.validatingFields, name, isValidating) : unset(_formState.validatingFields, name);
1106
+ });
1107
+ _subjects.state.next({
1108
+ validatingFields: _formState.validatingFields,
1109
+ isValidating: !isEmptyObject(_formState.validatingFields)
1110
+ });
1111
+ }
1112
+ };
1113
+ const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
1114
+ if (args && method && !_options.disabled) {
1115
+ _state.action = true;
1116
+ if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
1117
+ const fieldValues = method(get(_fields, name), args.argA, args.argB);
1118
+ shouldSetValues && set(_fields, name, fieldValues);
1119
+ }
1120
+ if (shouldUpdateFieldsAndState && Array.isArray(get(_formState.errors, name))) {
1121
+ const errors = method(get(_formState.errors, name), args.argA, args.argB);
1122
+ shouldSetValues && set(_formState.errors, name, errors);
1123
+ unsetEmptyArray(_formState.errors, name);
1124
+ }
1125
+ if ((_proxyFormState.touchedFields || _proxySubscribeFormState.touchedFields) && shouldUpdateFieldsAndState && Array.isArray(get(_formState.touchedFields, name))) {
1126
+ const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
1127
+ shouldSetValues && set(_formState.touchedFields, name, touchedFields);
1128
+ }
1129
+ if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1130
+ _subjects.state.next({
1131
+ name,
1132
+ isDirty: _getDirty(name, values),
1133
+ dirtyFields: _formState.dirtyFields,
1134
+ errors: _formState.errors,
1135
+ isValid: _formState.isValid
1136
+ });
1137
+ } else set(_formValues, name, values);
1138
+ };
1139
+ const updateErrors = (name, error) => {
1140
+ set(_formState.errors, name, error);
1141
+ _subjects.state.next({ errors: _formState.errors });
1142
+ };
1143
+ const _setErrors = (errors) => {
1144
+ _formState.errors = errors;
1145
+ _subjects.state.next({
1146
+ errors: _formState.errors,
1147
+ isValid: false
1148
+ });
1149
+ };
1150
+ const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
1151
+ const field = get(_fields, name);
1152
+ if (field) {
1153
+ const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
1154
+ isUndefined(defaultValue) || ref && ref.defaultChecked || shouldSkipSetValueAs ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f)) : setFieldValue(name, defaultValue);
1155
+ _state.mount && !_state.action && _setValid();
1156
+ }
1157
+ };
1158
+ const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
1159
+ let shouldUpdateField = false;
1160
+ let isPreviousDirty = false;
1161
+ const output = { name };
1162
+ if (!_options.disabled) {
1163
+ if (!isBlurEvent || shouldDirty) {
1164
+ if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
1165
+ isPreviousDirty = _formState.isDirty;
1166
+ _formState.isDirty = output.isDirty = _getDirty();
1167
+ shouldUpdateField = isPreviousDirty !== output.isDirty;
1168
+ }
1169
+ const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1170
+ isPreviousDirty = !!get(_formState.dirtyFields, name);
1171
+ isCurrentFieldPristine ? unset(_formState.dirtyFields, name) : set(_formState.dirtyFields, name, true);
1172
+ output.dirtyFields = _formState.dirtyFields;
1173
+ shouldUpdateField = shouldUpdateField || (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) && isPreviousDirty !== !isCurrentFieldPristine;
1174
+ }
1175
+ if (isBlurEvent) {
1176
+ const isPreviousFieldTouched = get(_formState.touchedFields, name);
1177
+ if (!isPreviousFieldTouched) {
1178
+ set(_formState.touchedFields, name, isBlurEvent);
1179
+ output.touchedFields = _formState.touchedFields;
1180
+ shouldUpdateField = shouldUpdateField || (_proxyFormState.touchedFields || _proxySubscribeFormState.touchedFields) && isPreviousFieldTouched !== isBlurEvent;
1181
+ }
1182
+ }
1183
+ shouldUpdateField && shouldRender && _subjects.state.next(output);
1184
+ }
1185
+ return shouldUpdateField ? output : {};
1186
+ };
1187
+ const shouldRenderByError = (name, isValid, error, fieldState) => {
1188
+ const previousFieldError = get(_formState.errors, name);
1189
+ const shouldUpdateValid = (_proxyFormState.isValid || _proxySubscribeFormState.isValid) && isBoolean(isValid) && _formState.isValid !== isValid;
1190
+ if (_options.delayError && error) {
1191
+ delayErrorCallback = debounce(() => updateErrors(name, error));
1192
+ delayErrorCallback(_options.delayError);
1193
+ } else {
1194
+ clearTimeout(timer);
1195
+ delayErrorCallback = null;
1196
+ error ? set(_formState.errors, name, error) : unset(_formState.errors, name);
1197
+ }
1198
+ if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) || !isEmptyObject(fieldState) || shouldUpdateValid) {
1199
+ const updatedFormState = {
1200
+ ...fieldState,
1201
+ ...shouldUpdateValid && isBoolean(isValid) ? { isValid } : {},
1202
+ errors: _formState.errors,
1203
+ name
1204
+ };
1205
+ _formState = {
1206
+ ..._formState,
1207
+ ...updatedFormState
1208
+ };
1209
+ _subjects.state.next(updatedFormState);
1210
+ }
1211
+ };
1212
+ const _runSchema = async (name) => {
1213
+ _updateIsValidating(name, true);
1214
+ return await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1215
+ };
1216
+ const executeSchemaAndUpdateState = async (names) => {
1217
+ const { errors } = await _runSchema(names);
1218
+ _updateIsValidating(names);
1219
+ if (names) for (const name of names) {
1220
+ const error = get(errors, name);
1221
+ error ? set(_formState.errors, name, error) : unset(_formState.errors, name);
1222
+ }
1223
+ else _formState.errors = errors;
1224
+ return errors;
1225
+ };
1226
+ const executeBuiltInValidation = async (fields, shouldOnlyCheckValid, context = { valid: true }) => {
1227
+ for (const name in fields) {
1228
+ const field = fields[name];
1229
+ if (field) {
1230
+ const { _f, ...fieldValue } = field;
1231
+ if (_f) {
1232
+ const isFieldArrayRoot = _names.array.has(_f.name);
1233
+ const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1234
+ if (isPromiseFunction && _proxyFormState.validatingFields) _updateIsValidating([_f.name], true);
1235
+ const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1236
+ if (isPromiseFunction && _proxyFormState.validatingFields) _updateIsValidating([_f.name]);
1237
+ if (fieldError[_f.name]) {
1238
+ context.valid = false;
1239
+ if (shouldOnlyCheckValid || props.shouldUseNativeValidation) break;
1240
+ }
1241
+ !shouldOnlyCheckValid && (get(fieldError, _f.name) ? isFieldArrayRoot ? updateFieldArrayRootError(_formState.errors, fieldError, _f.name) : set(_formState.errors, _f.name, fieldError[_f.name]) : unset(_formState.errors, _f.name));
1242
+ }
1243
+ !isEmptyObject(fieldValue) && await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context);
1244
+ }
1245
+ }
1246
+ return context.valid;
1247
+ };
1248
+ const _removeUnmounted = () => {
1249
+ for (const name of _names.unMount) {
1250
+ const field = get(_fields, name);
1251
+ field && (field._f.refs ? field._f.refs.every((ref) => !live(ref)) : !live(field._f.ref)) && unregister(name);
1252
+ }
1253
+ _names.unMount = /* @__PURE__ */ new Set();
1254
+ };
1255
+ const _getDirty = (name, data) => !_options.disabled && (name && data && set(_formValues, name, data), !deepEqual(getValues(), _defaultValues));
1256
+ const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, { ..._state.mount ? _formValues : isUndefined(defaultValue) ? _defaultValues : isString(names) ? { [names]: defaultValue } : defaultValue }, isGlobal, defaultValue);
1257
+ const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
1258
+ const setFieldValue = (name, value, options = {}) => {
1259
+ const field = get(_fields, name);
1260
+ let fieldValue = value;
1261
+ if (field) {
1262
+ const fieldReference = field._f;
1263
+ if (fieldReference) {
1264
+ !fieldReference.disabled && set(_formValues, name, getFieldValueAs(value, fieldReference));
1265
+ fieldValue = isHTMLElement(fieldReference.ref) && isNullOrUndefined(value) ? "" : value;
1266
+ if (isMultipleSelect(fieldReference.ref)) [...fieldReference.ref.options].forEach((optionRef) => optionRef.selected = fieldValue.includes(optionRef.value));
1267
+ else if (fieldReference.refs) if (isCheckBoxInput(fieldReference.ref)) fieldReference.refs.forEach((checkboxRef) => {
1268
+ if (!checkboxRef.defaultChecked || !checkboxRef.disabled) if (Array.isArray(fieldValue)) checkboxRef.checked = !!fieldValue.find((data) => data === checkboxRef.value);
1269
+ else checkboxRef.checked = fieldValue === checkboxRef.value || !!fieldValue;
1270
+ });
1271
+ else fieldReference.refs.forEach((radioRef) => radioRef.checked = radioRef.value === fieldValue);
1272
+ else if (isFileInput(fieldReference.ref)) fieldReference.ref.value = "";
1273
+ else {
1274
+ fieldReference.ref.value = fieldValue;
1275
+ if (!fieldReference.ref.type) _subjects.state.next({
1276
+ name,
1277
+ values: cloneObject(_formValues)
1278
+ });
1279
+ }
1280
+ }
1281
+ }
1282
+ (options.shouldDirty || options.shouldTouch) && updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1283
+ options.shouldValidate && trigger(name);
1284
+ };
1285
+ const setValues = (name, value, options) => {
1286
+ for (const fieldKey in value) {
1287
+ if (!value.hasOwnProperty(fieldKey)) return;
1288
+ const fieldValue = value[fieldKey];
1289
+ const fieldName = name + "." + fieldKey;
1290
+ const field = get(_fields, fieldName);
1291
+ (_names.array.has(name) || isObject(fieldValue) || field && !field._f) && !isDateObject(fieldValue) ? setValues(fieldName, fieldValue, options) : setFieldValue(fieldName, fieldValue, options);
1292
+ }
1293
+ };
1294
+ const setValue = (name, value, options = {}) => {
1295
+ const field = get(_fields, name);
1296
+ const isFieldArray = _names.array.has(name);
1297
+ const cloneValue = cloneObject(value);
1298
+ set(_formValues, name, cloneValue);
1299
+ if (isFieldArray) {
1300
+ _subjects.array.next({
1301
+ name,
1302
+ values: cloneObject(_formValues)
1303
+ });
1304
+ if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields || _proxySubscribeFormState.isDirty || _proxySubscribeFormState.dirtyFields) && options.shouldDirty) _subjects.state.next({
1305
+ name,
1306
+ dirtyFields: getDirtyFields(_defaultValues, _formValues),
1307
+ isDirty: _getDirty(name, cloneValue)
1308
+ });
1309
+ } else field && !field._f && !isNullOrUndefined(cloneValue) ? setValues(name, cloneValue, options) : setFieldValue(name, cloneValue, options);
1310
+ if (isWatched(name, _names)) _subjects.state.next({
1311
+ ..._formState,
1312
+ name,
1313
+ values: cloneObject(_formValues)
1314
+ });
1315
+ else _subjects.state.next({
1316
+ name: _state.mount ? name : void 0,
1317
+ values: cloneObject(_formValues)
1318
+ });
1319
+ };
1320
+ const onChange = async (event) => {
1321
+ _state.mount = true;
1322
+ const target = event.target;
1323
+ let name = target.name;
1324
+ let isFieldValueUpdated = true;
1325
+ const field = get(_fields, name);
1326
+ const _updateIsFieldValueUpdated = (fieldValue) => {
1327
+ isFieldValueUpdated = Number.isNaN(fieldValue) || isDateObject(fieldValue) && isNaN(fieldValue.getTime()) || deepEqual(fieldValue, get(_formValues, name, fieldValue));
1328
+ };
1329
+ const validationModeBeforeSubmit = getValidationModes(_options.mode);
1330
+ const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1331
+ if (field) {
1332
+ let error;
1333
+ let isValid;
1334
+ const fieldValue = target.type ? getFieldValue(field._f) : getEventValue(event);
1335
+ const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1336
+ const shouldSkipValidation = !hasValidation(field._f) && !_options.resolver && !get(_formState.errors, name) && !field._f.deps || skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1337
+ const watched = isWatched(name, _names, isBlurEvent);
1338
+ set(_formValues, name, fieldValue);
1339
+ if (isBlurEvent) {
1340
+ if (!target || !target.readOnly) {
1341
+ field._f.onBlur && field._f.onBlur(event);
1342
+ delayErrorCallback && delayErrorCallback(0);
1343
+ }
1344
+ } else if (field._f.onChange) field._f.onChange(event);
1345
+ const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent);
1346
+ const shouldRender = !isEmptyObject(fieldState) || watched;
1347
+ !isBlurEvent && _subjects.state.next({
1348
+ name,
1349
+ type: event.type,
1350
+ values: cloneObject(_formValues)
1351
+ });
1352
+ if (shouldSkipValidation) {
1353
+ if (_proxyFormState.isValid || _proxySubscribeFormState.isValid) {
1354
+ if (_options.mode === "onBlur") {
1355
+ if (isBlurEvent) _setValid();
1356
+ } else if (!isBlurEvent) _setValid();
1357
+ }
1358
+ return shouldRender && _subjects.state.next({
1359
+ name,
1360
+ ...watched ? {} : fieldState
1361
+ });
1362
+ }
1363
+ !isBlurEvent && watched && _subjects.state.next({ ..._formState });
1364
+ if (_options.resolver) {
1365
+ const { errors } = await _runSchema([name]);
1366
+ _updateIsValidating([name]);
1367
+ _updateIsFieldValueUpdated(fieldValue);
1368
+ if (isFieldValueUpdated) {
1369
+ const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
1370
+ const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
1371
+ error = errorLookupResult.error;
1372
+ name = errorLookupResult.name;
1373
+ isValid = isEmptyObject(errors);
1374
+ }
1375
+ } else {
1376
+ _updateIsValidating([name], true);
1377
+ error = (await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1378
+ _updateIsValidating([name]);
1379
+ _updateIsFieldValueUpdated(fieldValue);
1380
+ if (isFieldValueUpdated) {
1381
+ if (error) isValid = false;
1382
+ else if (_proxyFormState.isValid || _proxySubscribeFormState.isValid) isValid = await executeBuiltInValidation(_fields, true);
1383
+ }
1384
+ }
1385
+ if (isFieldValueUpdated) {
1386
+ field._f.deps && (!Array.isArray(field._f.deps) || field._f.deps.length > 0) && trigger(field._f.deps);
1387
+ shouldRenderByError(name, isValid, error, fieldState);
1388
+ }
1389
+ }
1390
+ };
1391
+ const _focusInput = (ref, key) => {
1392
+ if (get(_formState.errors, key) && ref.focus) {
1393
+ ref.focus();
1394
+ return 1;
1395
+ }
1396
+ };
1397
+ const trigger = async (name, options = {}) => {
1398
+ let isValid;
1399
+ let validationResult;
1400
+ const fieldNames = convertToArrayPayload(name);
1401
+ if (_options.resolver) {
1402
+ const errors = await executeSchemaAndUpdateState(isUndefined(name) ? name : fieldNames);
1403
+ isValid = isEmptyObject(errors);
1404
+ validationResult = name ? !fieldNames.some((name) => get(errors, name)) : isValid;
1405
+ } else if (name) {
1406
+ validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
1407
+ const field = get(_fields, fieldName);
1408
+ return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
1409
+ }))).every(Boolean);
1410
+ !(!validationResult && !_formState.isValid) && _setValid();
1411
+ } else validationResult = isValid = await executeBuiltInValidation(_fields);
1412
+ _subjects.state.next({
1413
+ ...!isString(name) || (_proxyFormState.isValid || _proxySubscribeFormState.isValid) && isValid !== _formState.isValid ? {} : { name },
1414
+ ..._options.resolver || !name ? { isValid } : {},
1415
+ errors: _formState.errors
1416
+ });
1417
+ options.shouldFocus && !validationResult && iterateFieldsByAction(_fields, _focusInput, name ? fieldNames : _names.mount);
1418
+ return validationResult;
1419
+ };
1420
+ const getValues = (fieldNames, config) => {
1421
+ let values = { ..._state.mount ? _formValues : _defaultValues };
1422
+ if (config) values = extractFormValues(config.dirtyFields ? _formState.dirtyFields : _formState.touchedFields, values);
1423
+ return isUndefined(fieldNames) ? values : isString(fieldNames) ? get(values, fieldNames) : fieldNames.map((name) => get(values, name));
1424
+ };
1425
+ const getFieldState = (name, formState) => ({
1426
+ invalid: !!get((formState || _formState).errors, name),
1427
+ isDirty: !!get((formState || _formState).dirtyFields, name),
1428
+ error: get((formState || _formState).errors, name),
1429
+ isValidating: !!get(_formState.validatingFields, name),
1430
+ isTouched: !!get((formState || _formState).touchedFields, name)
1431
+ });
1432
+ const clearErrors = (name) => {
1433
+ const names = name ? convertToArrayPayload(name) : void 0;
1434
+ names === null || names === void 0 || names.forEach((inputName) => unset(_formState.errors, inputName));
1435
+ if (names) names.forEach((inputName) => {
1436
+ _subjects.state.next({
1437
+ name: inputName,
1438
+ errors: _formState.errors
1439
+ });
1440
+ });
1441
+ else _subjects.state.next({ errors: {} });
1442
+ };
1443
+ const setError = (name, error, options) => {
1444
+ const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
1445
+ const { ref: currentRef, message, type, ...restOfErrorTree } = get(_formState.errors, name) || {};
1446
+ set(_formState.errors, name, {
1447
+ ...restOfErrorTree,
1448
+ ...error,
1449
+ ref
1450
+ });
1451
+ _subjects.state.next({
1452
+ name,
1453
+ errors: _formState.errors,
1454
+ isValid: false
1455
+ });
1456
+ options && options.shouldFocus && ref && ref.focus && ref.focus();
1457
+ };
1458
+ const watch = (name, defaultValue) => isFunction(name) ? _subjects.state.subscribe({ next: (payload) => "values" in payload && name(_getWatch(void 0, defaultValue), payload) }) : _getWatch(name, defaultValue, true);
1459
+ const _subscribe = (props) => _subjects.state.subscribe({ next: (formState) => {
1460
+ if (shouldSubscribeByName(props.name, formState.name, props.exact) && shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) props.callback({
1461
+ values: { ..._formValues },
1462
+ ..._formState,
1463
+ ...formState,
1464
+ defaultValues: _defaultValues
1465
+ });
1466
+ } }).unsubscribe;
1467
+ const subscribe = (props) => {
1468
+ _state.mount = true;
1469
+ _proxySubscribeFormState = {
1470
+ ..._proxySubscribeFormState,
1471
+ ...props.formState
1472
+ };
1473
+ return _subscribe({
1474
+ ...props,
1475
+ formState: {
1476
+ ...defaultProxyFormState,
1477
+ ...props.formState
1478
+ }
1479
+ });
1480
+ };
1481
+ const unregister = (name, options = {}) => {
1482
+ for (const fieldName of name ? convertToArrayPayload(name) : _names.mount) {
1483
+ _names.mount.delete(fieldName);
1484
+ _names.array.delete(fieldName);
1485
+ if (!options.keepValue) {
1486
+ unset(_fields, fieldName);
1487
+ unset(_formValues, fieldName);
1488
+ }
1489
+ !options.keepError && unset(_formState.errors, fieldName);
1490
+ !options.keepDirty && unset(_formState.dirtyFields, fieldName);
1491
+ !options.keepTouched && unset(_formState.touchedFields, fieldName);
1492
+ !options.keepIsValidating && unset(_formState.validatingFields, fieldName);
1493
+ !_options.shouldUnregister && !options.keepDefaultValue && unset(_defaultValues, fieldName);
1494
+ }
1495
+ _subjects.state.next({ values: cloneObject(_formValues) });
1496
+ _subjects.state.next({
1497
+ ..._formState,
1498
+ ...!options.keepDirty ? {} : { isDirty: _getDirty() }
1499
+ });
1500
+ !options.keepIsValid && _setValid();
1501
+ };
1502
+ const _setDisabledField = ({ disabled, name }) => {
1503
+ if (isBoolean(disabled) && _state.mount || !!disabled || _names.disabled.has(name)) {
1504
+ const disabledStateChanged = _names.disabled.has(name) !== !!disabled;
1505
+ disabled ? _names.disabled.add(name) : _names.disabled.delete(name);
1506
+ disabledStateChanged && _state.mount && !_state.action && _setValid();
1507
+ }
1508
+ };
1509
+ const register = (name, options = {}) => {
1510
+ let field = get(_fields, name);
1511
+ const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
1512
+ set(_fields, name, {
1513
+ ...field || {},
1514
+ _f: {
1515
+ ...field && field._f ? field._f : { ref: { name } },
1516
+ name,
1517
+ mount: true,
1518
+ ...options
1519
+ }
1520
+ });
1521
+ _names.mount.add(name);
1522
+ if (field) _setDisabledField({
1523
+ disabled: isBoolean(options.disabled) ? options.disabled : _options.disabled,
1524
+ name
1525
+ });
1526
+ else updateValidAndValue(name, true, options.value);
1527
+ return {
1528
+ ...disabledIsDefined ? { disabled: options.disabled || _options.disabled } : {},
1529
+ ..._options.progressive ? {
1530
+ required: !!options.required,
1531
+ min: getRuleValue(options.min),
1532
+ max: getRuleValue(options.max),
1533
+ minLength: getRuleValue(options.minLength),
1534
+ maxLength: getRuleValue(options.maxLength),
1535
+ pattern: getRuleValue(options.pattern)
1536
+ } : {},
1537
+ name,
1538
+ onChange,
1539
+ onBlur: onChange,
1540
+ ref: (ref) => {
1541
+ if (ref) {
1542
+ register(name, options);
1543
+ field = get(_fields, name);
1544
+ const fieldRef = isUndefined(ref.value) ? ref.querySelectorAll ? ref.querySelectorAll("input,select,textarea")[0] || ref : ref : ref;
1545
+ const radioOrCheckbox = isRadioOrCheckbox(fieldRef);
1546
+ const refs = field._f.refs || [];
1547
+ if (radioOrCheckbox ? refs.find((option) => option === fieldRef) : fieldRef === field._f.ref) return;
1548
+ set(_fields, name, { _f: {
1549
+ ...field._f,
1550
+ ...radioOrCheckbox ? {
1551
+ refs: [
1552
+ ...refs.filter(live),
1553
+ fieldRef,
1554
+ ...Array.isArray(get(_defaultValues, name)) ? [{}] : []
1555
+ ],
1556
+ ref: {
1557
+ type: fieldRef.type,
1558
+ name
1559
+ }
1560
+ } : { ref: fieldRef }
1561
+ } });
1562
+ updateValidAndValue(name, false, void 0, fieldRef);
1563
+ } else {
1564
+ field = get(_fields, name, {});
1565
+ if (field._f) field._f.mount = false;
1566
+ (_options.shouldUnregister || options.shouldUnregister) && !(isNameInFieldArray(_names.array, name) && _state.action) && _names.unMount.add(name);
1567
+ }
1568
+ }
1569
+ };
1570
+ };
1571
+ const _focusError = () => _options.shouldFocusError && iterateFieldsByAction(_fields, _focusInput, _names.mount);
1572
+ const _disableForm = (disabled) => {
1573
+ if (isBoolean(disabled)) {
1574
+ _subjects.state.next({ disabled });
1575
+ iterateFieldsByAction(_fields, (ref, name) => {
1576
+ const currentField = get(_fields, name);
1577
+ if (currentField) {
1578
+ ref.disabled = currentField._f.disabled || disabled;
1579
+ if (Array.isArray(currentField._f.refs)) currentField._f.refs.forEach((inputRef) => {
1580
+ inputRef.disabled = currentField._f.disabled || disabled;
1581
+ });
1582
+ }
1583
+ }, 0, false);
1584
+ }
1585
+ };
1586
+ const handleSubmit = (onValid, onInvalid) => async (e) => {
1587
+ let onValidError = void 0;
1588
+ if (e) {
1589
+ e.preventDefault && e.preventDefault();
1590
+ e.persist && e.persist();
1591
+ }
1592
+ let fieldValues = cloneObject(_formValues);
1593
+ _subjects.state.next({ isSubmitting: true });
1594
+ if (_options.resolver) {
1595
+ const { errors, values } = await _runSchema();
1596
+ _updateIsValidating();
1597
+ _formState.errors = errors;
1598
+ fieldValues = cloneObject(values);
1599
+ } else await executeBuiltInValidation(_fields);
1600
+ if (_names.disabled.size) for (const name of _names.disabled) unset(fieldValues, name);
1601
+ unset(_formState.errors, "root");
1602
+ if (isEmptyObject(_formState.errors)) {
1603
+ _subjects.state.next({ errors: {} });
1604
+ try {
1605
+ await onValid(fieldValues, e);
1606
+ } catch (error) {
1607
+ onValidError = error;
1608
+ }
1609
+ } else {
1610
+ if (onInvalid) await onInvalid({ ..._formState.errors }, e);
1611
+ _focusError();
1612
+ setTimeout(_focusError);
1613
+ }
1614
+ _subjects.state.next({
1615
+ isSubmitted: true,
1616
+ isSubmitting: false,
1617
+ isSubmitSuccessful: isEmptyObject(_formState.errors) && !onValidError,
1618
+ submitCount: _formState.submitCount + 1,
1619
+ errors: _formState.errors
1620
+ });
1621
+ if (onValidError) throw onValidError;
1622
+ };
1623
+ const resetField = (name, options = {}) => {
1624
+ if (get(_fields, name)) {
1625
+ if (isUndefined(options.defaultValue)) setValue(name, cloneObject(get(_defaultValues, name)));
1626
+ else {
1627
+ setValue(name, options.defaultValue);
1628
+ set(_defaultValues, name, cloneObject(options.defaultValue));
1629
+ }
1630
+ if (!options.keepTouched) unset(_formState.touchedFields, name);
1631
+ if (!options.keepDirty) {
1632
+ unset(_formState.dirtyFields, name);
1633
+ _formState.isDirty = options.defaultValue ? _getDirty(name, cloneObject(get(_defaultValues, name))) : _getDirty();
1634
+ }
1635
+ if (!options.keepError) {
1636
+ unset(_formState.errors, name);
1637
+ _proxyFormState.isValid && _setValid();
1638
+ }
1639
+ _subjects.state.next({ ..._formState });
1640
+ }
1641
+ };
1642
+ const _reset = (formValues, keepStateOptions = {}) => {
1643
+ const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
1644
+ const cloneUpdatedValues = cloneObject(updatedValues);
1645
+ const isEmptyResetValues = isEmptyObject(formValues);
1646
+ const values = isEmptyResetValues ? _defaultValues : cloneUpdatedValues;
1647
+ if (!keepStateOptions.keepDefaultValues) _defaultValues = updatedValues;
1648
+ if (!keepStateOptions.keepValues) {
1649
+ if (keepStateOptions.keepDirtyValues) {
1650
+ const fieldsToCheck = new Set([..._names.mount, ...Object.keys(getDirtyFields(_defaultValues, _formValues))]);
1651
+ for (const fieldName of Array.from(fieldsToCheck)) {
1652
+ const isDirty = get(_formState.dirtyFields, fieldName);
1653
+ const existingValue = get(_formValues, fieldName);
1654
+ const newValue = get(values, fieldName);
1655
+ if (isDirty && !isUndefined(existingValue)) set(values, fieldName, existingValue);
1656
+ else if (!isDirty && !isUndefined(newValue)) setValue(fieldName, newValue);
1657
+ }
1658
+ } else {
1659
+ if (isWeb && isUndefined(formValues)) for (const name of _names.mount) {
1660
+ const field = get(_fields, name);
1661
+ if (field && field._f) {
1662
+ const fieldReference = Array.isArray(field._f.refs) ? field._f.refs[0] : field._f.ref;
1663
+ if (isHTMLElement(fieldReference)) {
1664
+ const form = fieldReference.closest("form");
1665
+ if (form) {
1666
+ form.reset();
1667
+ break;
1668
+ }
1669
+ }
1670
+ }
1671
+ }
1672
+ if (keepStateOptions.keepFieldsRef) for (const fieldName of _names.mount) setValue(fieldName, get(values, fieldName));
1673
+ else _fields = {};
1674
+ }
1675
+ _formValues = _options.shouldUnregister ? keepStateOptions.keepDefaultValues ? cloneObject(_defaultValues) : {} : cloneObject(values);
1676
+ _subjects.array.next({ values: { ...values } });
1677
+ _subjects.state.next({ values: { ...values } });
1678
+ }
1679
+ _names = {
1680
+ mount: keepStateOptions.keepDirtyValues ? _names.mount : /* @__PURE__ */ new Set(),
1681
+ unMount: /* @__PURE__ */ new Set(),
1682
+ array: /* @__PURE__ */ new Set(),
1683
+ disabled: /* @__PURE__ */ new Set(),
1684
+ watch: /* @__PURE__ */ new Set(),
1685
+ watchAll: false,
1686
+ focus: ""
1687
+ };
1688
+ _state.mount = !_proxyFormState.isValid || !!keepStateOptions.keepIsValid || !!keepStateOptions.keepDirtyValues || !_options.shouldUnregister && !isEmptyObject(values);
1689
+ _state.watch = !!_options.shouldUnregister;
1690
+ _state.keepIsValid = !!keepStateOptions.keepIsValid;
1691
+ _state.action = false;
1692
+ if (!keepStateOptions.keepErrors) _formState.errors = {};
1693
+ _subjects.state.next({
1694
+ submitCount: keepStateOptions.keepSubmitCount ? _formState.submitCount : 0,
1695
+ isDirty: isEmptyResetValues ? false : keepStateOptions.keepDirty ? _formState.isDirty : !!(keepStateOptions.keepDefaultValues && !deepEqual(formValues, _defaultValues)),
1696
+ isSubmitted: keepStateOptions.keepIsSubmitted ? _formState.isSubmitted : false,
1697
+ dirtyFields: isEmptyResetValues ? {} : keepStateOptions.keepDirtyValues ? keepStateOptions.keepDefaultValues && _formValues ? getDirtyFields(_defaultValues, _formValues) : _formState.dirtyFields : keepStateOptions.keepDefaultValues && formValues ? getDirtyFields(_defaultValues, formValues) : keepStateOptions.keepDirty ? _formState.dirtyFields : {},
1698
+ touchedFields: keepStateOptions.keepTouched ? _formState.touchedFields : {},
1699
+ errors: keepStateOptions.keepErrors ? _formState.errors : {},
1700
+ isSubmitSuccessful: keepStateOptions.keepIsSubmitSuccessful ? _formState.isSubmitSuccessful : false,
1701
+ isSubmitting: false,
1702
+ defaultValues: _defaultValues
1703
+ });
1704
+ };
1705
+ const reset = (formValues, keepStateOptions) => _reset(isFunction(formValues) ? formValues(_formValues) : formValues, {
1706
+ ..._options.resetOptions,
1707
+ ...keepStateOptions
1708
+ });
1709
+ const setFocus = (name, options = {}) => {
1710
+ const field = get(_fields, name);
1711
+ const fieldReference = field && field._f;
1712
+ if (fieldReference) {
1713
+ const fieldRef = fieldReference.refs ? fieldReference.refs[0] : fieldReference.ref;
1714
+ if (fieldRef.focus) setTimeout(() => {
1715
+ fieldRef.focus();
1716
+ options.shouldSelect && isFunction(fieldRef.select) && fieldRef.select();
1717
+ });
1718
+ }
1719
+ };
1720
+ const _setFormState = (updatedFormState) => {
1721
+ _formState = {
1722
+ ..._formState,
1723
+ ...updatedFormState
1724
+ };
1725
+ };
1726
+ const _resetDefaultValues = () => isFunction(_options.defaultValues) && _options.defaultValues().then((values) => {
1727
+ reset(values, _options.resetOptions);
1728
+ _subjects.state.next({ isLoading: false });
1729
+ });
1730
+ const methods = {
1731
+ control: {
1732
+ register,
1733
+ unregister,
1734
+ getFieldState,
1735
+ handleSubmit,
1736
+ setError,
1737
+ _subscribe,
1738
+ _runSchema,
1739
+ _updateIsValidating,
1740
+ _focusError,
1741
+ _getWatch,
1742
+ _getDirty,
1743
+ _setValid,
1744
+ _setFieldArray,
1745
+ _setDisabledField,
1746
+ _setErrors,
1747
+ _getFieldArray,
1748
+ _reset,
1749
+ _resetDefaultValues,
1750
+ _removeUnmounted,
1751
+ _disableForm,
1752
+ _subjects,
1753
+ _proxyFormState,
1754
+ get _fields() {
1755
+ return _fields;
1756
+ },
1757
+ get _formValues() {
1758
+ return _formValues;
1759
+ },
1760
+ get _state() {
1761
+ return _state;
1762
+ },
1763
+ set _state(value) {
1764
+ _state = value;
1765
+ },
1766
+ get _defaultValues() {
1767
+ return _defaultValues;
1768
+ },
1769
+ get _names() {
1770
+ return _names;
1771
+ },
1772
+ set _names(value) {
1773
+ _names = value;
1774
+ },
1775
+ get _formState() {
1776
+ return _formState;
1777
+ },
1778
+ get _options() {
1779
+ return _options;
1780
+ },
1781
+ set _options(value) {
1782
+ _options = {
1783
+ ..._options,
1784
+ ...value
1785
+ };
1786
+ }
1787
+ },
1788
+ subscribe,
1789
+ trigger,
1790
+ register,
1791
+ handleSubmit,
1792
+ watch,
1793
+ setValue,
1794
+ getValues,
1795
+ reset,
1796
+ resetField,
1797
+ clearErrors,
1798
+ unregister,
1799
+ setError,
1800
+ setFocus,
1801
+ getFieldState
1802
+ };
1803
+ return {
1804
+ ...methods,
1805
+ formControl: methods
1806
+ };
1807
+ }
1808
+ /**
1809
+ * Custom hook to manage the entire form.
1810
+ *
1811
+ * @remarks
1812
+ * [API](https://react-hook-form.com/docs/useform) • [Demo](https://codesandbox.io/s/react-hook-form-get-started-ts-5ksmm) • [Video](https://www.youtube.com/watch?v=RkXv4AXXC_4)
1813
+ *
1814
+ * @param props - form configuration and validation parameters.
1815
+ *
1816
+ * @returns methods - individual functions to manage the form state. {@link UseFormReturn}
1817
+ *
1818
+ * @example
1819
+ * ```tsx
1820
+ * function App() {
1821
+ * const { register, handleSubmit, watch, formState: { errors } } = useForm();
1822
+ * const onSubmit = data => console.log(data);
1823
+ *
1824
+ * console.log(watch("example"));
1825
+ *
1826
+ * return (
1827
+ * <form onSubmit={handleSubmit(onSubmit)}>
1828
+ * <input defaultValue="test" {...register("example")} />
1829
+ * <input {...register("exampleRequired", { required: true })} />
1830
+ * {errors.exampleRequired && <span>This field is required</span>}
1831
+ * <button>Submit</button>
1832
+ * </form>
1833
+ * );
1834
+ * }
1835
+ * ```
1836
+ */
1837
+ function useForm(props = {}) {
1838
+ const _formControl = React.useRef(void 0);
1839
+ const _values = React.useRef(void 0);
1840
+ const [formState, updateFormState] = React.useState({
1841
+ isDirty: false,
1842
+ isValidating: false,
1843
+ isLoading: isFunction(props.defaultValues),
1844
+ isSubmitted: false,
1845
+ isSubmitting: false,
1846
+ isSubmitSuccessful: false,
1847
+ isValid: false,
1848
+ submitCount: 0,
1849
+ dirtyFields: {},
1850
+ touchedFields: {},
1851
+ validatingFields: {},
1852
+ errors: props.errors || {},
1853
+ disabled: props.disabled || false,
1854
+ isReady: false,
1855
+ defaultValues: isFunction(props.defaultValues) ? void 0 : props.defaultValues
1856
+ });
1857
+ if (!_formControl.current) if (props.formControl) {
1858
+ _formControl.current = {
1859
+ ...props.formControl,
1860
+ formState
1861
+ };
1862
+ if (props.defaultValues && !isFunction(props.defaultValues)) props.formControl.reset(props.defaultValues, props.resetOptions);
1863
+ } else {
1864
+ const { formControl, ...rest } = createFormControl(props);
1865
+ _formControl.current = {
1866
+ ...rest,
1867
+ formState
1868
+ };
1869
+ }
1870
+ const control = _formControl.current.control;
1871
+ control._options = props;
1872
+ useIsomorphicLayoutEffect(() => {
1873
+ const sub = control._subscribe({
1874
+ formState: control._proxyFormState,
1875
+ callback: () => updateFormState({ ...control._formState }),
1876
+ reRenderRoot: true
1877
+ });
1878
+ updateFormState((data) => ({
1879
+ ...data,
1880
+ isReady: true
1881
+ }));
1882
+ control._formState.isReady = true;
1883
+ return sub;
1884
+ }, [control]);
1885
+ React.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
1886
+ React.useEffect(() => {
1887
+ if (props.mode) control._options.mode = props.mode;
1888
+ if (props.reValidateMode) control._options.reValidateMode = props.reValidateMode;
1889
+ }, [
1890
+ control,
1891
+ props.mode,
1892
+ props.reValidateMode
1893
+ ]);
1894
+ React.useEffect(() => {
1895
+ if (props.errors) {
1896
+ control._setErrors(props.errors);
1897
+ control._focusError();
1898
+ }
1899
+ }, [control, props.errors]);
1900
+ React.useEffect(() => {
1901
+ props.shouldUnregister && control._subjects.state.next({ values: control._getWatch() });
1902
+ }, [control, props.shouldUnregister]);
1903
+ React.useEffect(() => {
1904
+ if (control._proxyFormState.isDirty) {
1905
+ const isDirty = control._getDirty();
1906
+ if (isDirty !== formState.isDirty) control._subjects.state.next({ isDirty });
1907
+ }
1908
+ }, [control, formState.isDirty]);
1909
+ React.useEffect(() => {
1910
+ var _a;
1911
+ if (props.values && !deepEqual(props.values, _values.current)) {
1912
+ control._reset(props.values, {
1913
+ keepFieldsRef: true,
1914
+ ...control._options.resetOptions
1915
+ });
1916
+ if (!((_a = control._options.resetOptions) === null || _a === void 0 ? void 0 : _a.keepIsValid)) control._setValid();
1917
+ _values.current = props.values;
1918
+ updateFormState((state) => ({ ...state }));
1919
+ } else control._resetDefaultValues();
1920
+ }, [control, props.values]);
1921
+ React.useEffect(() => {
1922
+ if (!control._state.mount) {
1923
+ control._setValid();
1924
+ control._state.mount = true;
1925
+ }
1926
+ if (control._state.watch) {
1927
+ control._state.watch = false;
1928
+ control._subjects.state.next({ ...control._formState });
1929
+ }
1930
+ control._removeUnmounted();
1931
+ });
1932
+ _formControl.current.formState = React.useMemo(() => getProxyFormState(formState, control), [control, formState]);
1933
+ return _formControl.current;
1934
+ }
1935
+ //#endregion
1936
+ //#region editors/document-model-editor/components/divider.tsx
1937
+ function Divider({ className, size = "sm", margin = "md" }) {
1938
+ function getSize() {
1939
+ if (size === "sm") return "h-px";
1940
+ if (size === "md") return "h-1";
1941
+ return "h-1.5";
1942
+ }
1943
+ function getMargin() {
1944
+ if (margin === "sm") return "my-4";
1945
+ if (margin === "md") return "my-6";
1946
+ return "my-8";
1947
+ }
1948
+ return /* @__PURE__ */ jsx("div", { className: twMerge("bg-secondary", getSize(), getMargin(), className) });
1949
+ }
1950
+ //#endregion
1951
+ //#region ../../node_modules/.pnpm/@hookform+resolvers@5.2.2_react-hook-form@7.71.2_react@19.2.6_/node_modules/@hookform/resolvers/dist/resolvers.mjs
1952
+ const r = (t, r, o) => {
1953
+ if (t && "reportValidity" in t) {
1954
+ const s = get(o, r);
1955
+ t.setCustomValidity(s && s.message || ""), t.reportValidity();
1956
+ }
1957
+ }, o = (e, t) => {
1958
+ for (const o in t.fields) {
1959
+ const s = t.fields[o];
1960
+ s && s.ref && "reportValidity" in s.ref ? r(s.ref, o, e) : s && s.refs && s.refs.forEach((t) => r(t, o, e));
1961
+ }
1962
+ }, s$1 = (r, s) => {
1963
+ s.shouldUseNativeValidation && o(r, s);
1964
+ const n = {};
1965
+ for (const o in r) {
1966
+ const f = get(s.fields, o), c = Object.assign(r[o] || {}, { ref: f && f.ref });
1967
+ if (i$1(s.names || Object.keys(r), o)) {
1968
+ const r = Object.assign({}, get(n, o));
1969
+ set(r, "root", c), set(n, o, r);
1970
+ } else set(n, o, c);
1971
+ }
1972
+ return n;
1973
+ }, i$1 = (e, t) => {
1974
+ const r = n$1(t);
1975
+ return e.some((e) => n$1(e).match(`^${r}\\.\\d+`));
1976
+ };
1977
+ function n$1(e) {
1978
+ return e.replace(/\]|\[/g, "");
1979
+ }
1980
+ //#endregion
1981
+ //#region ../../node_modules/.pnpm/@hookform+resolvers@5.2.2_react-hook-form@7.71.2_react@19.2.6_/node_modules/@hookform/resolvers/zod/dist/zod.mjs
1982
+ function t(r, e) {
1983
+ try {
1984
+ var o = r();
1985
+ } catch (r) {
1986
+ return e(r);
1987
+ }
1988
+ return o && o.then ? o.then(void 0, e) : o;
1989
+ }
1990
+ function s(r, e) {
1991
+ for (var n = {}; r.length;) {
1992
+ var t = r[0], s = t.code, i = t.message, a = t.path.join(".");
1993
+ if (!n[a]) if ("unionErrors" in t) {
1994
+ var u = t.unionErrors[0].errors[0];
1995
+ n[a] = {
1996
+ message: u.message,
1997
+ type: u.code
1998
+ };
1999
+ } else n[a] = {
2000
+ message: i,
2001
+ type: s
2002
+ };
2003
+ if ("unionErrors" in t && t.unionErrors.forEach(function(e) {
2004
+ return e.errors.forEach(function(e) {
2005
+ return r.push(e);
2006
+ });
2007
+ }), e) {
2008
+ var c = n[a].types, f = c && c[t.code];
2009
+ n[a] = appendErrors(a, e, n, s, f ? [].concat(f, t.message) : t.message);
2010
+ }
2011
+ r.shift();
2012
+ }
2013
+ return n;
2014
+ }
2015
+ function i(r, e) {
2016
+ for (var n = {}; r.length;) {
2017
+ var t = r[0], s = t.code, i = t.message, a = t.path.join(".");
2018
+ if (!n[a]) if ("invalid_union" === t.code && t.errors.length > 0) {
2019
+ var u = t.errors[0][0];
2020
+ n[a] = {
2021
+ message: u.message,
2022
+ type: u.code
2023
+ };
2024
+ } else n[a] = {
2025
+ message: i,
2026
+ type: s
2027
+ };
2028
+ if ("invalid_union" === t.code && t.errors.forEach(function(e) {
2029
+ return e.forEach(function(e) {
2030
+ return r.push(e);
2031
+ });
2032
+ }), e) {
2033
+ var c = n[a].types, f = c && c[t.code];
2034
+ n[a] = appendErrors(a, e, n, s, f ? [].concat(f, t.message) : t.message);
2035
+ }
2036
+ r.shift();
2037
+ }
2038
+ return n;
2039
+ }
2040
+ function a(o$1, a, u) {
2041
+ if (void 0 === u && (u = {}), function(r) {
2042
+ return "_def" in r && "object" == typeof r._def && "typeName" in r._def;
2043
+ }(o$1)) return function(n, i, c) {
2044
+ try {
2045
+ return Promise.resolve(t(function() {
2046
+ return Promise.resolve(o$1["sync" === u.mode ? "parse" : "parseAsync"](n, a)).then(function(e) {
2047
+ return c.shouldUseNativeValidation && o({}, c), {
2048
+ errors: {},
2049
+ values: u.raw ? Object.assign({}, n) : e
2050
+ };
2051
+ });
2052
+ }, function(r) {
2053
+ if (function(r) {
2054
+ return Array.isArray(null == r ? void 0 : r.issues);
2055
+ }(r)) return {
2056
+ values: {},
2057
+ errors: s$1(s(r.errors, !c.shouldUseNativeValidation && "all" === c.criteriaMode), c)
2058
+ };
2059
+ throw r;
2060
+ }));
2061
+ } catch (r) {
2062
+ return Promise.reject(r);
2063
+ }
2064
+ };
2065
+ if (function(r) {
2066
+ return "_zod" in r && "object" == typeof r._zod;
2067
+ }(o$1)) return function(s, c, f) {
2068
+ try {
2069
+ return Promise.resolve(t(function() {
2070
+ return Promise.resolve(("sync" === u.mode ? n.parse : n.parseAsync)(o$1, s, a)).then(function(e) {
2071
+ return f.shouldUseNativeValidation && o({}, f), {
2072
+ errors: {},
2073
+ values: u.raw ? Object.assign({}, s) : e
2074
+ };
2075
+ });
2076
+ }, function(r) {
2077
+ if (function(r) {
2078
+ return r instanceof n.$ZodError;
2079
+ }(r)) return {
2080
+ values: {},
2081
+ errors: s$1(i(r.issues, !f.shouldUseNativeValidation && "all" === f.criteriaMode), f)
2082
+ };
2083
+ throw r;
2084
+ }));
2085
+ } catch (r) {
2086
+ return Promise.reject(r);
2087
+ }
2088
+ };
2089
+ throw new Error("Invalid input: not a Zod schema");
2090
+ }
2091
+ //#endregion
2092
+ //#region editors/document-model-editor/schemas/inputs.ts
2093
+ const isUppercase = (value) => !/\p{Ll}/u.test(value);
2094
+ const isLowercase = (value) => !/\p{Lu}/u.test(value);
2095
+ function createNameSchema(options = {}) {
2096
+ const { required = false, allowEmpty = false, unique = [] } = options;
2097
+ const baseSchema = allowEmpty ? z.string() : z.string().min(1);
2098
+ const uniqueRefinement = baseSchema.refine((value) => {
2099
+ if (!value && allowEmpty) return true;
2100
+ return !unique.map((n) => n.toLowerCase()).includes(value.replace(/^\s+|\s+$/g, "_").toLowerCase());
2101
+ }, { message: "Item with this name already exists" });
2102
+ if (!required) return unique.length > 0 ? z.string().optional().refine((value) => {
2103
+ if (value === void 0) return true;
2104
+ if (!value && allowEmpty) return true;
2105
+ return !unique.map((n) => n.toLowerCase()).includes(value.replace(/^\s+|\s+$/g, "_").toLowerCase());
2106
+ }, { message: "Item with this name already exists" }) : z.string().optional();
2107
+ return unique.length > 0 ? uniqueRefinement : baseSchema;
2108
+ }
2109
+ function createConstantCaseSchema(options = {}) {
2110
+ return createNameSchema(options).transform((value) => value ? value.toUpperCase() : value).refine((value) => !value || isUppercase(value), { message: "Must be uppercase" });
2111
+ }
2112
+ function createLowercaseSnakeCaseSchema(options = {}) {
2113
+ return createNameSchema(options).transform((value) => value ? value.toLowerCase() : value).refine((value) => !value || isLowercase(value), { message: "Must be lowercase" });
2114
+ }
2115
+ function toLowercaseSnakeCase(value, options = {}) {
2116
+ return createLowercaseSnakeCaseSchema(options).parse(snakeCase(value));
2117
+ }
2118
+ function toConstantCase(value, options = {}) {
2119
+ return createConstantCaseSchema(options).parse(constantCase(value));
2120
+ }
2121
+ z.object({
2122
+ name: createNameSchema({ allowEmpty: true }),
2123
+ website: z.union([z.url(), z.literal("")]).optional().default("")
2124
+ }).default({
2125
+ name: "",
2126
+ website: ""
2127
+ });
2128
+ //#endregion
2129
+ //#region editors/document-model-editor/context/form-context.ts
2130
+ const FormFieldContext = React.createContext({});
2131
+ const FormItemContext = React.createContext({});
2132
+ //#endregion
2133
+ //#region editors/document-model-editor/hooks/useFormField.ts
2134
+ const useFormField = () => {
2135
+ const fieldContext = React.useContext(FormFieldContext);
2136
+ const itemContext = React.useContext(FormItemContext);
2137
+ const { getFieldState, formState } = useFormContext();
2138
+ const fieldState = getFieldState(fieldContext.name, formState);
2139
+ if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
2140
+ const { id } = itemContext;
2141
+ return {
2142
+ id,
2143
+ name: fieldContext.name,
2144
+ formItemId: `${id}-form-item`,
2145
+ formDescriptionId: `${id}-form-item-description`,
2146
+ formMessageId: `${id}-form-item-message`,
2147
+ ...fieldState
2148
+ };
2149
+ };
2150
+ //#endregion
2151
+ //#region ../../node_modules/.pnpm/@radix-ui+react-label@2.1.8_@types+react-dom@19.2.3_@types+react@19.2.14__@types+react@_8d35ec453e0b59eefe06771bb1432577/node_modules/@radix-ui/react-label/dist/index.mjs
2152
+ var NAME = "Label";
2153
+ var Label$1 = React$1.forwardRef((props, forwardedRef) => {
2154
+ return /* @__PURE__ */ jsx(Primitive.label, {
2155
+ ...props,
2156
+ ref: forwardedRef,
2157
+ onMouseDown: (event) => {
2158
+ if (event.target.closest("button, input, select, textarea")) return;
2159
+ props.onMouseDown?.(event);
2160
+ if (!event.defaultPrevented && event.detail > 1) event.preventDefault();
2161
+ }
2162
+ });
2163
+ });
2164
+ Label$1.displayName = NAME;
2165
+ var Root = Label$1;
2166
+ //#endregion
2167
+ //#region editors/document-model-editor/components/label.tsx
2168
+ const labelVariants = cva("text-sm leading-none font-medium peer-disabled:disabled-effect");
2169
+ const Label = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(Root, {
2170
+ ref,
2171
+ className: twMerge(labelVariants(), className),
2172
+ ...props
2173
+ }));
2174
+ Label.displayName = Root.displayName;
2175
+ //#endregion
2176
+ //#region editors/document-model-editor/components/form.tsx
2177
+ const Form = FormProvider;
2178
+ const FormField = ({ ...props }) => {
2179
+ return /* @__PURE__ */ jsx(FormFieldContext.Provider, {
2180
+ value: { name: props.name },
2181
+ children: /* @__PURE__ */ jsx(Controller, { ...props })
2182
+ });
2183
+ };
2184
+ const FormItem = React$1.forwardRef(({ className, ...props }, ref) => {
2185
+ const id = React$1.useId();
2186
+ return /* @__PURE__ */ jsx(FormItemContext.Provider, {
2187
+ value: { id },
2188
+ children: /* @__PURE__ */ jsx("div", {
2189
+ ref,
2190
+ className,
2191
+ ...props
2192
+ })
2193
+ });
2194
+ });
2195
+ FormItem.displayName = "FormItem";
2196
+ const FormLabel = React$1.forwardRef(({ className, ...props }, ref) => {
2197
+ const { error, formItemId } = useFormField();
2198
+ return /* @__PURE__ */ jsx(Label, {
2199
+ ref,
2200
+ className: twMerge(error && "text-destructive", className),
2201
+ htmlFor: formItemId,
2202
+ ...props
2203
+ });
2204
+ });
2205
+ FormLabel.displayName = "FormLabel";
2206
+ const FormControl = React$1.forwardRef(({ ...props }, ref) => {
2207
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
2208
+ return /* @__PURE__ */ jsx(Slot, {
2209
+ ref,
2210
+ id: formItemId,
2211
+ "aria-describedby": !error ? formDescriptionId : `${formDescriptionId} ${formMessageId}`,
2212
+ "aria-invalid": !!error,
2213
+ ...props
2214
+ });
2215
+ });
2216
+ FormControl.displayName = "FormControl";
2217
+ const FormDescription = React$1.forwardRef(({ className, ...props }, ref) => {
2218
+ const { formDescriptionId } = useFormField();
2219
+ return /* @__PURE__ */ jsx("p", {
2220
+ ref,
2221
+ id: formDescriptionId,
2222
+ className: twMerge("text-sm text-foreground", className),
2223
+ ...props
2224
+ });
2225
+ });
2226
+ FormDescription.displayName = "FormDescription";
2227
+ const FormMessage = React$1.forwardRef(({ className, children, ...props }, ref) => {
2228
+ const { error, formMessageId } = useFormField();
2229
+ const body = error ? String(error.message) : children;
2230
+ if (!body) return null;
2231
+ return /* @__PURE__ */ jsx("p", {
2232
+ ref,
2233
+ id: formMessageId,
2234
+ className: twMerge("text-sm font-medium text-destructive", className),
2235
+ ...props,
2236
+ children: body
2237
+ });
2238
+ });
2239
+ FormMessage.displayName = "FormMessage";
2240
+ //#endregion
2241
+ //#region editors/document-model-editor/components/text-area.tsx
2242
+ const Textarea = forwardRef(({ className, ...props }, ref) => {
2243
+ const textareaRef = useRef(null);
2244
+ const adjustHeight = useCallback((textarea) => {
2245
+ textarea.style.height = "auto";
2246
+ const newHeight = Math.max(textarea.scrollHeight, textarea.offsetHeight);
2247
+ textarea.style.height = `${newHeight}px`;
2248
+ }, []);
2249
+ const handleInput = useCallback((e) => {
2250
+ adjustHeight(e.currentTarget);
2251
+ }, [adjustHeight]);
2252
+ React$1.useEffect(() => {
2253
+ if (textareaRef.current) adjustHeight(textareaRef.current);
2254
+ }, [adjustHeight]);
2255
+ useImperativeHandle(ref, () => ({
2256
+ focus: () => textareaRef.current?.focus(),
2257
+ element: textareaRef.current
2258
+ }));
2259
+ return /* @__PURE__ */ jsx("textarea", {
2260
+ ...props,
2261
+ className: twMerge("min-h-10 w-full resize-none rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none disabled:disabled-effect", className),
2262
+ ref: textareaRef,
2263
+ onInput: handleInput
2264
+ });
2265
+ });
2266
+ Textarea.displayName = "Textarea";
2267
+ //#endregion
2268
+ //#region editors/document-model-editor/components/text-field.tsx
2269
+ const TextField = forwardRef(({ name, value, onSubmit, label, placeholder, unique, className = "", rows = 1, focusOnMount = false, required = false, allowEmpty = false, shouldReset = false, onChange }, ref) => {
2270
+ const textareaRef = useRef(null);
2271
+ const id = useId();
2272
+ useEffect(() => {
2273
+ if (focusOnMount && textareaRef.current) textareaRef.current.focus();
2274
+ }, [focusOnMount]);
2275
+ const form = useForm({
2276
+ resolver: a(z.object({ [name]: createNameSchema({
2277
+ required,
2278
+ allowEmpty,
2279
+ unique
2280
+ }) })),
2281
+ defaultValues: { [name]: value ?? "" }
2282
+ });
2283
+ const handleSubmit = useCallback((values) => {
2284
+ const newValue = values[name];
2285
+ if (newValue === void 0 || value === newValue) return;
2286
+ onSubmit(newValue);
2287
+ if (shouldReset) form.reset({ [name]: "" });
2288
+ }, [
2289
+ name,
2290
+ value,
2291
+ onSubmit,
2292
+ form,
2293
+ shouldReset
2294
+ ]);
2295
+ const handleBlur = useCallback(async () => {
2296
+ const currentValue = form.getValues()[name] ?? "";
2297
+ if (value === null || value === void 0) {
2298
+ if (!currentValue || currentValue.trim() === "") return;
2299
+ }
2300
+ if (compareStringsWithoutWhitespace(currentValue, value ?? "")) return;
2301
+ try {
2302
+ await form.trigger();
2303
+ if (form.formState.isValid) await form.handleSubmit(handleSubmit)();
2304
+ } catch (_e) {}
2305
+ }, [
2306
+ form,
2307
+ handleSubmit,
2308
+ name,
2309
+ value
2310
+ ]);
2311
+ const onEnterKeyDown = useCallback((e) => {
2312
+ if (e.key === "Enter") {
2313
+ e.preventDefault();
2314
+ e.target.blur();
2315
+ }
2316
+ }, []);
2317
+ const handleChange = useCallback((e) => {
2318
+ const newValue = e.target.value;
2319
+ onChange?.(newValue);
2320
+ }, [onChange]);
2321
+ useImperativeHandle(ref, () => ({ focus: () => textareaRef.current?.focus() }));
2322
+ useEffect(() => {
2323
+ form.reset({ [name]: value ?? "" });
2324
+ }, [
2325
+ form,
2326
+ name,
2327
+ value
2328
+ ]);
2329
+ return /* @__PURE__ */ jsx(Form, {
2330
+ ...form,
2331
+ children: /* @__PURE__ */ jsx(FormField, {
2332
+ control: form.control,
2333
+ name,
2334
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, {
2335
+ className: "grid h-full grid-rows-[auto,1fr] gap-2 overflow-visible",
2336
+ children: [
2337
+ !!label && /* @__PURE__ */ jsx(FormLabel, {
2338
+ htmlFor: name,
2339
+ className: "text-sm font-medium text-foreground",
2340
+ children: label
2341
+ }),
2342
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(Textarea, {
2343
+ ...field,
2344
+ id,
2345
+ name,
2346
+ ref: (node) => {
2347
+ if (node) {
2348
+ field.ref(node.element);
2349
+ textareaRef.current = node;
2350
+ }
2351
+ },
2352
+ placeholder,
2353
+ onBlur: () => void handleBlur(),
2354
+ onChange: (e) => {
2355
+ field.onChange(e);
2356
+ handleChange(e);
2357
+ },
2358
+ onKeyDown: onEnterKeyDown,
2359
+ rows,
2360
+ className
2361
+ }) }),
2362
+ /* @__PURE__ */ jsx(FormMessage, {})
2363
+ ]
2364
+ })
2365
+ })
2366
+ });
2367
+ });
2368
+ TextField.displayName = "TextField";
2369
+ z.object({
2370
+ name: z.string(),
2371
+ documentType: z.string(),
2372
+ extension: z.string().optional().default(""),
2373
+ description: z.string(),
2374
+ authorName: z.string(),
2375
+ authorWebsite: z.string()
2376
+ });
2377
+ function ModelMetadata(props) {
2378
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(ModelNameForm, { ...props }), /* @__PURE__ */ jsx("div", {
2379
+ className: "flex h-full flex-col gap-4",
2380
+ children: /* @__PURE__ */ jsxs("div", {
2381
+ className: "grid flex-1 grid-cols-3 items-start gap-4",
2382
+ children: [/* @__PURE__ */ jsxs("div", {
2383
+ className: "col-span-2 flex h-full flex-col gap-4",
2384
+ children: [/* @__PURE__ */ jsx("div", {
2385
+ className: "shrink-0",
2386
+ children: /* @__PURE__ */ jsx(DocumentTypeForm, { ...props })
2387
+ }), /* @__PURE__ */ jsx("div", {
2388
+ className: "min-h-0 flex-1",
2389
+ children: /* @__PURE__ */ jsx(DescriptionForm, { ...props })
2390
+ })]
2391
+ }), /* @__PURE__ */ jsxs("div", {
2392
+ className: "col-span-1 flex flex-col gap-4",
2393
+ children: [
2394
+ /* @__PURE__ */ jsx(AuthorNameForm, { ...props }),
2395
+ /* @__PURE__ */ jsx(AuthorWebsiteForm, { ...props }),
2396
+ /* @__PURE__ */ jsx(ModelExtensionForm, { ...props })
2397
+ ]
2398
+ })]
2399
+ })
2400
+ })] });
2401
+ }
2402
+ function ModelNameForm(props) {
2403
+ const { name, globalStateSchema, localStateSchema, setModelName, setStateSchema } = props;
2404
+ return /* @__PURE__ */ jsx(TextField, {
2405
+ name: "name",
2406
+ value: name,
2407
+ onSubmit: useCallback((newName) => {
2408
+ if (name === newName) return;
2409
+ setModelName(newName);
2410
+ if (!!!globalStateSchema) {
2411
+ setStateSchema(makeInitialSchemaDoc(newName, "global"), "global");
2412
+ return;
2413
+ }
2414
+ setStateSchema(renameSchemaType(globalStateSchema, name, newName, "global"), "global");
2415
+ if (localStateSchema) setStateSchema(renameSchemaType(localStateSchema, name, newName, "local"), "local");
2416
+ handleModelNameChange({
2417
+ oldName: name,
2418
+ newName,
2419
+ globalStateSchema,
2420
+ localStateSchema,
2421
+ setStateSchema
2422
+ });
2423
+ }, [
2424
+ name,
2425
+ globalStateSchema,
2426
+ localStateSchema,
2427
+ setStateSchema,
2428
+ setModelName
2429
+ ]),
2430
+ placeholder: "Model name",
2431
+ className: "border-none pl-0 text-xl font-bold text-foreground",
2432
+ required: true,
2433
+ focusOnMount: true
2434
+ });
2435
+ }
2436
+ function DocumentTypeForm(props) {
2437
+ const { documentType, setModelId } = props;
2438
+ return /* @__PURE__ */ jsx(TextField, {
2439
+ label: "Document Type *",
2440
+ name: "powerhouse/document-model",
2441
+ value: documentType,
2442
+ onSubmit: setModelId,
2443
+ placeholder: "Document Type",
2444
+ required: true
2445
+ });
2446
+ }
2447
+ function ModelExtensionForm(props) {
2448
+ const { extension, setModelExtension } = props;
2449
+ return /* @__PURE__ */ jsx(TextField, {
2450
+ name: "extension",
2451
+ value: extension,
2452
+ onSubmit: setModelExtension,
2453
+ label: "Model Extension",
2454
+ placeholder: "Example .phdm",
2455
+ allowEmpty: true
2456
+ });
2457
+ }
2458
+ function DescriptionForm(props) {
2459
+ const { description, setModelDescription } = props;
2460
+ return /* @__PURE__ */ jsx(TextField, {
2461
+ name: "description",
2462
+ label: "Model Description",
2463
+ value: description,
2464
+ onSubmit: setModelDescription,
2465
+ placeholder: "Describe your document to others",
2466
+ allowEmpty: true,
2467
+ className: "h-full"
2468
+ });
2469
+ }
2470
+ function AuthorNameForm(props) {
2471
+ const { authorName, setAuthorName } = props;
2472
+ return /* @__PURE__ */ jsx(TextField, {
2473
+ name: "authorName",
2474
+ value: authorName,
2475
+ onSubmit: setAuthorName,
2476
+ label: "Author Name",
2477
+ placeholder: "Username or organisation",
2478
+ allowEmpty: true
2479
+ });
2480
+ }
2481
+ function AuthorWebsiteForm(props) {
2482
+ const { authorWebsite, setAuthorWebsite } = props;
2483
+ return /* @__PURE__ */ jsx(TextField, {
2484
+ name: "authorWebsite",
2485
+ value: authorWebsite,
2486
+ label: "Website URL",
2487
+ onSubmit: (newAuthorWebsite) => {
2488
+ if (!!authorWebsite && !newAuthorWebsite) return;
2489
+ setAuthorWebsite(newAuthorWebsite);
2490
+ },
2491
+ placeholder: "https://www.powerhouse.inc/",
2492
+ allowEmpty: true
2493
+ });
2494
+ }
2495
+ //#endregion
2496
+ //#region editors/document-model-editor/components/module-form.tsx
2497
+ function ModuleForm({ module, onAddModule, updateModuleName, modules = [] }) {
2498
+ const isEdit = !!module;
2499
+ const moduleNames = modules.map((m) => m.name);
2500
+ const handleSubmit = async (name) => {
2501
+ const formattedName = toLowercaseSnakeCase(name);
2502
+ if (!formattedName.length) return;
2503
+ if (isEdit) {
2504
+ if (formattedName !== module.name) updateModuleName(module.id, formattedName);
2505
+ } else await onAddModule(formattedName);
2506
+ };
2507
+ return /* @__PURE__ */ jsx(TextField, {
2508
+ name: "name",
2509
+ label: isEdit ? "Module name *" : "Add module *",
2510
+ value: module?.name,
2511
+ onSubmit: (name) => void handleSubmit(name),
2512
+ placeholder: "Add module",
2513
+ unique: moduleNames,
2514
+ shouldReset: !isEdit,
2515
+ required: true
2516
+ }, module?.id ?? "new");
2517
+ }
2518
+ //#endregion
2519
+ //#region editors/document-model-editor/components/operation-form.tsx
2520
+ function OperationForm({ operation, module, focusOnMount, allOperationNames, onAddOperationAndInitialSchema, updateOperationName, deleteOperation }) {
2521
+ const isEdit = !!operation;
2522
+ const handleSubmit = async (name) => {
2523
+ if (isEdit && name === "") {
2524
+ deleteOperation(operation.id);
2525
+ return;
2526
+ }
2527
+ const formattedName = toConstantCase(name);
2528
+ if (isEdit) {
2529
+ if (formattedName !== operation.name) updateOperationName(operation.id, formattedName);
2530
+ } else await onAddOperationAndInitialSchema(module.id, formattedName);
2531
+ };
2532
+ const handleChange = (value) => {
2533
+ if (isEdit && value === "") deleteOperation(operation.id);
2534
+ };
2535
+ return /* @__PURE__ */ jsx(TextField, {
2536
+ name: "name",
2537
+ value: operation?.name,
2538
+ label: isEdit ? "Operation name *" : "Add operation *",
2539
+ onSubmit: (name) => void handleSubmit(name),
2540
+ onChange: handleChange,
2541
+ placeholder: "Add operation",
2542
+ required: !isEdit,
2543
+ allowEmpty: !isEdit,
2544
+ shouldReset: !isEdit,
2545
+ focusOnMount,
2546
+ unique: allOperationNames
2547
+ });
2548
+ }
2549
+ //#endregion
2550
+ //#region editors/document-model-editor/components/operation-description-form.tsx
2551
+ function OperationDescriptionForm({ operation, focusOnMount, setOperationDescription }) {
2552
+ const textFieldRef = useRef(null);
2553
+ useEffect(() => {
2554
+ if (focusOnMount && textFieldRef.current) textFieldRef.current.focus();
2555
+ }, [focusOnMount]);
2556
+ return /* @__PURE__ */ jsx(TextField, {
2557
+ ref: textFieldRef,
2558
+ name: "description",
2559
+ value: operation.description,
2560
+ onSubmit: (newDescription) => setOperationDescription(operation.id, newDescription),
2561
+ label: "Operation description",
2562
+ allowEmpty: true,
2563
+ placeholder: "Operation Description"
2564
+ });
2565
+ }
2566
+ //#endregion
2567
+ //#region editors/document-model-editor/components/operation-error-form.tsx
2568
+ function OperationErrorForm({ operation, error, focusOnMount, onSubmit, onAddOperationError, deleteOperationError, setOperationErrorName }) {
2569
+ const textFieldRef = useRef(null);
2570
+ const isEdit = !!error;
2571
+ const allOperationErrorNames = operation.errors.map((o) => o.name).filter((n) => n !== null);
2572
+ const handleSubmit = (name) => {
2573
+ if (isEdit && name === "") {
2574
+ deleteOperationError(error.id);
2575
+ return;
2576
+ }
2577
+ const formattedName = pascalCase(name);
2578
+ if (isEdit) setOperationErrorName(operation.id, error.id, formattedName);
2579
+ else onAddOperationError(operation.id, formattedName);
2580
+ onSubmit?.();
2581
+ };
2582
+ const handleChange = (value) => {
2583
+ if (isEdit && value === "") deleteOperationError(error.id);
2584
+ };
2585
+ return /* @__PURE__ */ jsx(TextField, {
2586
+ ref: textFieldRef,
2587
+ name: "name",
2588
+ value: error?.name,
2589
+ onSubmit: handleSubmit,
2590
+ onChange: handleChange,
2591
+ placeholder: "Add exception",
2592
+ required: !isEdit,
2593
+ allowEmpty: !isEdit,
2594
+ shouldReset: !isEdit,
2595
+ unique: allOperationErrorNames,
2596
+ focusOnMount
2597
+ });
2598
+ }
2599
+ //#endregion
2600
+ //#region editors/document-model-editor/components/operation-errors.tsx
2601
+ function OperationErrors({ operation, addOperationError, deleteOperationError, setOperationErrorName }) {
2602
+ const addErrorFormId = useId();
2603
+ const [shouldFocusAddForm, setShouldFocusAddForm] = useState(false);
2604
+ const onAddOperationError = useCallback(async (operationId, error) => {
2605
+ const errorId = await addOperationError(operationId, error);
2606
+ if (errorId) setShouldFocusAddForm(true);
2607
+ return errorId;
2608
+ }, [addOperationError, setShouldFocusAddForm]);
2609
+ const onAddOperationErrorSubmit = useCallback(() => setShouldFocusAddForm(false), [setShouldFocusAddForm]);
2610
+ return /* @__PURE__ */ jsxs("ul", {
2611
+ className: "ml-4 list-disc",
2612
+ children: [operation.errors.map((error) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(OperationErrorForm, {
2613
+ error,
2614
+ operation,
2615
+ onAddOperationError,
2616
+ deleteOperationError,
2617
+ setOperationErrorName
2618
+ }) }, error.id)), /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(OperationErrorForm, {
2619
+ operation,
2620
+ onAddOperationError,
2621
+ deleteOperationError,
2622
+ setOperationErrorName,
2623
+ focusOnMount: shouldFocusAddForm,
2624
+ onSubmit: onAddOperationErrorSubmit
2625
+ }, `${addErrorFormId}-${shouldFocusAddForm}`) })]
2626
+ });
2627
+ }
2628
+ //#endregion
2629
+ //#region editors/document-model-editor/components/operation.tsx
2630
+ const GraphqlEditor = lazy(() => import("./graphql-editor-BhF6KN6y.mjs"));
2631
+ function Operation(props) {
2632
+ const { operation, module, allOperationNames, lastCreatedOperationId, onAddOperationAndInitialSchema, updateOperationName, deleteOperation, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired } = props;
2633
+ const noInputRequired = isEmptyOperationSchema(operation.schema);
2634
+ const handleToggleNoInput = useCallback((checked) => toggleNoInputRequired(operation.id, checked), [operation.id, toggleNoInputRequired]);
2635
+ const handleUpdateDocument = useCallback((newDoc) => updateOperationSchema(operation.id, newDoc), [operation.id, updateOperationSchema]);
2636
+ const customLinter = useCallback((doc) => operation.name ? ensureValidOperationSchemaInputName(doc, operation.name) : [], [operation.name]);
2637
+ return /* @__PURE__ */ jsxs("div", {
2638
+ className: "mt-4 grid grid-cols-2 gap-x-12",
2639
+ style: {
2640
+ gridTemplateAreas: `
2641
+ "left editor"
2642
+ "errors editor"
2643
+ `,
2644
+ gridTemplateRows: "auto 1fr"
2645
+ },
2646
+ children: [
2647
+ /* @__PURE__ */ jsxs("div", {
2648
+ className: "flex flex-col gap-2",
2649
+ style: { gridArea: "left" },
2650
+ children: [/* @__PURE__ */ jsx(OperationForm, {
2651
+ operation,
2652
+ onAddOperationAndInitialSchema,
2653
+ updateOperationName,
2654
+ deleteOperation,
2655
+ module,
2656
+ allOperationNames
2657
+ }), /* @__PURE__ */ jsx(OperationDescriptionForm, {
2658
+ operation,
2659
+ focusOnMount: operation.id === lastCreatedOperationId,
2660
+ setOperationDescription
2661
+ })]
2662
+ }),
2663
+ /* @__PURE__ */ jsxs("div", {
2664
+ className: "relative top-8",
2665
+ style: { gridArea: "editor" },
2666
+ children: [/* @__PURE__ */ jsxs("label", {
2667
+ className: "mb-2 flex cursor-pointer items-center gap-2",
2668
+ children: [/* @__PURE__ */ jsx("input", {
2669
+ type: "checkbox",
2670
+ checked: noInputRequired,
2671
+ onChange: (e) => handleToggleNoInput(e.target.checked),
2672
+ className: "size-4 rounded-sm border-border"
2673
+ }), /* @__PURE__ */ jsx("span", {
2674
+ className: "text-sm text-foreground",
2675
+ children: "Operation with no inputs"
2676
+ })]
2677
+ }), !noInputRequired && /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(GraphqlEditor, {
2678
+ doc: operation.schema ?? "",
2679
+ updateDocumentInModel: handleUpdateDocument,
2680
+ customLinter
2681
+ }) })]
2682
+ }),
2683
+ /* @__PURE__ */ jsxs("div", {
2684
+ style: { gridArea: "errors" },
2685
+ children: [/* @__PURE__ */ jsx("h3", {
2686
+ className: "my-2 text-sm font-medium text-foreground",
2687
+ children: "Reducer Exceptions"
2688
+ }), /* @__PURE__ */ jsx(OperationErrors, {
2689
+ operation,
2690
+ addOperationError,
2691
+ deleteOperationError,
2692
+ setOperationErrorName
2693
+ })]
2694
+ })
2695
+ ]
2696
+ });
2697
+ }
2698
+ //#endregion
2699
+ //#region editors/document-model-editor/components/operations.tsx
2700
+ function Operations({ module, allOperations, shouldFocusNewOperation, updateOperationName, deleteOperation, addOperationAndInitialSchema, addOperationError, deleteOperationError, setOperationErrorName, updateOperationSchema, setOperationDescription, toggleNoInputRequired }) {
2701
+ const [lastCreatedOperationId, setLastCreatedOperationId] = useState(null);
2702
+ const addOperationFormId = useId();
2703
+ const allOperationNames = allOperations.map((o) => o.name).filter((n) => n !== null);
2704
+ const onAddOperationAndInitialSchema = useCallback(async (moduleId, name) => {
2705
+ const operationId = await addOperationAndInitialSchema(moduleId, name);
2706
+ if (operationId) setLastCreatedOperationId(operationId);
2707
+ return operationId;
2708
+ }, [addOperationAndInitialSchema, setLastCreatedOperationId]);
2709
+ return /* @__PURE__ */ jsxs("div", { children: [module.operations.map((operation) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Operation, {
2710
+ operation,
2711
+ module,
2712
+ lastCreatedOperationId,
2713
+ allOperationNames,
2714
+ addOperationError,
2715
+ deleteOperationError,
2716
+ setOperationErrorName,
2717
+ onAddOperationAndInitialSchema,
2718
+ updateOperationName,
2719
+ deleteOperation,
2720
+ updateOperationSchema,
2721
+ setOperationDescription,
2722
+ toggleNoInputRequired
2723
+ }) }, operation.id)), /* @__PURE__ */ jsx("div", {
2724
+ className: "mt-6 w-1/2 pr-6",
2725
+ children: /* @__PURE__ */ jsx(OperationForm, {
2726
+ onAddOperationAndInitialSchema,
2727
+ updateOperationName,
2728
+ deleteOperation,
2729
+ module,
2730
+ allOperationNames,
2731
+ focusOnMount: shouldFocusNewOperation
2732
+ }, addOperationFormId)
2733
+ })] });
2734
+ }
2735
+ //#endregion
2736
+ //#region editors/document-model-editor/components/module.tsx
2737
+ function Module(props) {
2738
+ const { module, modules, allOperations, lastCreatedModuleId, onAddModule, updateModuleName, deleteModule, updateOperationName, deleteOperation, addOperationAndInitialSchema, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired } = props;
2739
+ return /* @__PURE__ */ jsxs("div", {
2740
+ className: "relative rounded-3xl bg-muted p-6",
2741
+ children: [/* @__PURE__ */ jsxs("div", {
2742
+ className: "mb-2 w-1/2 pr-6",
2743
+ children: [/* @__PURE__ */ jsx(ModuleForm, {
2744
+ modules,
2745
+ module,
2746
+ onAddModule,
2747
+ updateModuleName
2748
+ }), !!module && /* @__PURE__ */ jsx("button", {
2749
+ "aria-label": "Delete module",
2750
+ tabIndex: -1,
2751
+ className: "absolute top-1 right-1 p-2 text-foreground transition-colors hover:hover-effect",
2752
+ onClick: () => {
2753
+ deleteModule(module.id);
2754
+ },
2755
+ children: /* @__PURE__ */ jsx("svg", {
2756
+ className: "size-6",
2757
+ viewBox: "0 0 24 24",
2758
+ fill: "currentcolor",
2759
+ children: /* @__PURE__ */ jsx("path", {
2760
+ fillRule: "evenodd",
2761
+ clipRule: "evenodd",
2762
+ d: "M16.9993 8.51506L15.4844 7L11.9994 10.4852L8.51497 7.00057L7 8.51562L10.4844 12.0003L7.00056 15.4843L8.51552 16.9994L11.9994 13.5153L15.4838 17L16.9988 15.4849L13.5144 12.0003L16.9993 8.51506Z"
2763
+ })
2764
+ })
2765
+ })]
2766
+ }), !!module && /* @__PURE__ */ jsx(Operations, {
2767
+ module,
2768
+ allOperations,
2769
+ shouldFocusNewOperation: module.id === lastCreatedModuleId,
2770
+ updateOperationName,
2771
+ deleteOperation,
2772
+ addOperationAndInitialSchema,
2773
+ updateOperationSchema,
2774
+ setOperationDescription,
2775
+ addOperationError,
2776
+ deleteOperationError,
2777
+ setOperationErrorName,
2778
+ toggleNoInputRequired
2779
+ })]
2780
+ });
2781
+ }
2782
+ //#endregion
2783
+ //#region editors/document-model-editor/components/modules.tsx
2784
+ function Modules({ modules, allOperations, addModule, updateModuleName, deleteModule, updateOperationName, deleteOperation, addOperationAndInitialSchema, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired }) {
2785
+ const [lastCreatedModuleId, setLastCreatedModuleId] = useState(null);
2786
+ const focusTrapRef = useRef(null);
2787
+ const onAddModule = useCallback(async (name) => {
2788
+ const moduleId = await addModule(name);
2789
+ if (moduleId) {
2790
+ setLastCreatedModuleId(moduleId);
2791
+ focusTrapRef.current?.focus();
2792
+ }
2793
+ return moduleId;
2794
+ }, [addModule, setLastCreatedModuleId]);
2795
+ return /* @__PURE__ */ jsxs("div", {
2796
+ className: "flex flex-col gap-2",
2797
+ children: [
2798
+ modules.map((module) => /* @__PURE__ */ jsx(Module, {
2799
+ module,
2800
+ modules,
2801
+ allOperations,
2802
+ lastCreatedModuleId,
2803
+ onAddModule,
2804
+ updateModuleName,
2805
+ deleteModule,
2806
+ updateOperationName,
2807
+ deleteOperation,
2808
+ addOperationAndInitialSchema,
2809
+ updateOperationSchema,
2810
+ setOperationDescription,
2811
+ addOperationError,
2812
+ deleteOperationError,
2813
+ setOperationErrorName,
2814
+ toggleNoInputRequired
2815
+ }, module.id)),
2816
+ /* @__PURE__ */ jsx(Module, {
2817
+ modules,
2818
+ allOperations,
2819
+ lastCreatedModuleId,
2820
+ onAddModule,
2821
+ updateModuleName,
2822
+ deleteModule,
2823
+ updateOperationName,
2824
+ deleteOperation,
2825
+ addOperationAndInitialSchema,
2826
+ updateOperationSchema,
2827
+ setOperationDescription,
2828
+ addOperationError,
2829
+ deleteOperationError,
2830
+ setOperationErrorName,
2831
+ toggleNoInputRequired
2832
+ }, "add-module"),
2833
+ /* @__PURE__ */ jsx("div", {
2834
+ ref: focusTrapRef,
2835
+ tabIndex: 0,
2836
+ className: "size-0 overflow-hidden",
2837
+ "aria-hidden": "true"
2838
+ })
2839
+ ]
2840
+ });
2841
+ }
2842
+ //#endregion
2843
+ //#region editors/document-model-editor/components/version-controls.tsx
2844
+ const compactButtonStyle$1 = "min-h-0 min-w-0 flex-none rounded-lg px-6 py-1.5 text-sm whitespace-nowrap";
2845
+ function VersionControls(props) {
2846
+ const { specifications, viewedVersion, onViewVersion, onReleaseNewVersion } = props;
2847
+ const [showReleaseModal, setShowReleaseModal] = useState(false);
2848
+ const latestVersion = specifications[specifications.length - 1].version;
2849
+ const nextVersion = latestVersion + 1;
2850
+ return /* @__PURE__ */ jsxs("div", {
2851
+ className: "mb-4 flex items-center justify-between gap-4",
2852
+ children: [
2853
+ /* @__PURE__ */ jsxs("div", {
2854
+ className: "flex items-center gap-2",
2855
+ children: [/* @__PURE__ */ jsxs("span", {
2856
+ className: "rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground",
2857
+ "data-testid": "model-version-badge",
2858
+ children: ["Version ", viewedVersion]
2859
+ }), specifications.length >= 2 && /* @__PURE__ */ jsx("div", {
2860
+ "aria-label": "Document model version",
2861
+ "data-testid": "model-version-switcher",
2862
+ children: /* @__PURE__ */ jsx(ConnectSelect, {
2863
+ absolutePositionMenu: true,
2864
+ containerClassName: "z-10 [&_svg]:size-4",
2865
+ id: "model-version-switcher",
2866
+ itemClassName: "gap-1 px-2 py-1 font-mono text-xs leading-none [&_p:empty]:hidden",
2867
+ items: specifications.map((spec) => ({
2868
+ value: String(spec.version),
2869
+ displayValue: /* @__PURE__ */ jsx("span", {
2870
+ className: "normal-case",
2871
+ children: spec.version === latestVersion ? `v${spec.version} (latest)` : `v${spec.version} (frozen)`
2872
+ })
2873
+ })),
2874
+ listClassName: "border border-t-0 border-border shadow-md",
2875
+ menuClassName: "min-w-0 pr-1.5",
2876
+ onChange: (value) => {
2877
+ const version = Number(value);
2878
+ onViewVersion(version === latestVersion ? "latest" : version);
2879
+ },
2880
+ value: String(viewedVersion)
2881
+ })
2882
+ })]
2883
+ }),
2884
+ /* @__PURE__ */ jsx(Button, {
2885
+ className: "inline-flex h-8 items-center justify-center py-0",
2886
+ "data-testid": "release-new-version-button",
2887
+ onClick: () => setShowReleaseModal(true),
2888
+ type: "button",
2889
+ children: "Release new version"
2890
+ }),
2891
+ /* @__PURE__ */ jsx(Modal, {
2892
+ open: showReleaseModal,
2893
+ onOpenChange: (status) => {
2894
+ if (!status) setShowReleaseModal(false);
2895
+ },
2896
+ children: /* @__PURE__ */ jsxs("div", {
2897
+ className: "w-[440px] p-6",
2898
+ children: [
2899
+ /* @__PURE__ */ jsxs("div", {
2900
+ className: "pb-2 text-2xl font-bold text-foreground",
2901
+ children: ["Release version ", nextVersion]
2902
+ }),
2903
+ /* @__PURE__ */ jsxs("div", {
2904
+ className: "my-4 rounded-md bg-background p-4 text-left text-sm text-foreground",
2905
+ children: [/* @__PURE__ */ jsxs("p", { children: [
2906
+ "Version ",
2907
+ latestVersion,
2908
+ " will be frozen as-is. Version",
2909
+ " ",
2910
+ nextVersion,
2911
+ " starts as an identical copy, and all further edits apply to version ",
2912
+ nextVersion,
2913
+ "."
2914
+ ] }), /* @__PURE__ */ jsxs("p", {
2915
+ className: "mt-3",
2916
+ children: [
2917
+ "Existing version ",
2918
+ latestVersion,
2919
+ " documents will be upgradeable once you define the migration."
2920
+ ]
2921
+ })]
2922
+ }),
2923
+ /* @__PURE__ */ jsxs("div", {
2924
+ className: "mt-4 flex justify-between gap-3",
2925
+ children: [/* @__PURE__ */ jsx(ModalButton, {
2926
+ className: compactButtonStyle$1,
2927
+ onClick: () => setShowReleaseModal(false),
2928
+ variant: "cancel",
2929
+ children: "Cancel"
2930
+ }), /* @__PURE__ */ jsxs(ModalButton, {
2931
+ className: compactButtonStyle$1,
2932
+ "data-testid": "confirm-release-button",
2933
+ onClick: () => {
2934
+ setShowReleaseModal(false);
2935
+ onReleaseNewVersion();
2936
+ },
2937
+ variant: "confirm",
2938
+ children: ["Release version ", nextVersion]
2939
+ })]
2940
+ })
2941
+ ]
2942
+ })
2943
+ })
2944
+ ]
2945
+ });
2946
+ }
2947
+ function FrozenVersionBanner(props) {
2948
+ const { viewedVersion, latestVersion } = props;
2949
+ return /* @__PURE__ */ jsxs("div", {
2950
+ className: "mb-4 rounded-md border border-border bg-muted p-3 text-sm text-foreground",
2951
+ "data-testid": "frozen-version-banner",
2952
+ children: [
2953
+ "Version ",
2954
+ viewedVersion,
2955
+ " is frozen. You're viewing it read-only. Edits go to version ",
2956
+ latestVersion,
2957
+ "."
2958
+ ]
2959
+ });
2960
+ }
2961
+ //#endregion
2962
+ //#region editors/document-model-editor/components/version-advisory-modal.tsx
2963
+ const compactButtonStyle = "min-h-0 min-w-0 flex-none rounded-lg px-4 py-1.5 text-sm whitespace-nowrap";
2964
+ function FieldDiffList(props) {
2965
+ const { label, fields } = props;
2966
+ if (fields.length === 0) return null;
2967
+ return /* @__PURE__ */ jsxs("div", {
2968
+ className: "mt-3",
2969
+ children: [/* @__PURE__ */ jsx("p", {
2970
+ className: "mb-1.5",
2971
+ children: label
2972
+ }), /* @__PURE__ */ jsx("div", {
2973
+ className: "flex flex-col items-start gap-1",
2974
+ children: fields.map((field) => /* @__PURE__ */ jsx("span", {
2975
+ className: "rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground",
2976
+ children: field
2977
+ }, field))
2978
+ })]
2979
+ });
2980
+ }
2981
+ function VersionAdvisoryModal(props) {
2982
+ const { prompt, onReleaseFirst, onKeepEditing, onCancel } = props;
2983
+ if (!prompt) return null;
2984
+ const { version, reason, diff } = prompt;
2985
+ const nextVersion = version + 1;
2986
+ return /* @__PURE__ */ jsx(Modal, {
2987
+ open: true,
2988
+ onOpenChange: (status) => {
2989
+ if (!status) onCancel();
2990
+ },
2991
+ children: /* @__PURE__ */ jsxs("div", {
2992
+ className: "w-[440px] p-6",
2993
+ "data-testid": "version-advisory-modal",
2994
+ children: [
2995
+ /* @__PURE__ */ jsxs("div", {
2996
+ className: "pb-2 text-2xl font-bold text-foreground",
2997
+ children: [
2998
+ "Is version ",
2999
+ version,
3000
+ " of this model already in use?"
3001
+ ]
3002
+ }),
3003
+ /* @__PURE__ */ jsxs("div", {
3004
+ className: "my-4 rounded-md bg-background p-4 text-left text-sm text-foreground",
3005
+ children: [
3006
+ /* @__PURE__ */ jsxs("p", { children: [
3007
+ reason,
3008
+ " Documents that were already created with version ",
3009
+ version,
3010
+ " ",
3011
+ "may stop working correctly."
3012
+ ] }),
3013
+ diff && /* @__PURE__ */ jsxs(Fragment, { children: [
3014
+ /* @__PURE__ */ jsx(FieldDiffList, {
3015
+ fields: diff.addedFields,
3016
+ label: "New fields:"
3017
+ }),
3018
+ /* @__PURE__ */ jsx(FieldDiffList, {
3019
+ fields: diff.removedFields,
3020
+ label: "Removed fields:"
3021
+ }),
3022
+ /* @__PURE__ */ jsx(FieldDiffList, {
3023
+ fields: diff.changedFields,
3024
+ label: "Changed fields:"
3025
+ })
3026
+ ] }),
3027
+ /* @__PURE__ */ jsxs("p", {
3028
+ className: "mt-3",
3029
+ children: [
3030
+ "If others are already using version ",
3031
+ version,
3032
+ ", release version",
3033
+ " ",
3034
+ nextVersion,
3035
+ " first. Your change will go into version ",
3036
+ nextVersion,
3037
+ ", and existing documents can be updated safely."
3038
+ ]
3039
+ })
3040
+ ]
3041
+ }),
3042
+ /* @__PURE__ */ jsxs("div", {
3043
+ className: "mt-4 flex flex-col gap-2",
3044
+ children: [/* @__PURE__ */ jsx(ModalButton, {
3045
+ className: compactButtonStyle,
3046
+ "data-testid": "advisory-release-first",
3047
+ onClick: onReleaseFirst,
3048
+ variant: "confirm",
3049
+ children: `It's in use — release v${nextVersion} first`
3050
+ }), /* @__PURE__ */ jsxs(ModalButton, {
3051
+ className: compactButtonStyle,
3052
+ "data-testid": "advisory-keep-editing",
3053
+ onClick: onKeepEditing,
3054
+ variant: "cancel",
3055
+ children: ["Still in development — keep editing v", version]
3056
+ })]
3057
+ })
3058
+ ]
3059
+ })
3060
+ });
3061
+ }
3062
+ //#endregion
3063
+ //#region editors/document-model-editor/config.ts
3064
+ const editorConfig = { isExternalControlsEnabled: false };
3065
+ //#endregion
3066
+ //#region editors/document-model-editor/hooks/useDocumentModelDocument.ts
3067
+ function useSelectedDocumentModelDocument() {
3068
+ return useSelectedDocumentOfType("powerhouse/document-model");
3069
+ }
3070
+ //#endregion
3071
+ //#region editors/document-model-editor/utils/change-classification.ts
3072
+ var import_graphql = require_graphql();
3073
+ function isShapeTypeNode(node) {
3074
+ return node.kind === import_graphql.Kind.OBJECT_TYPE_DEFINITION || node.kind === import_graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION || node.kind === import_graphql.Kind.ENUM_TYPE_DEFINITION;
3075
+ }
3076
+ function collectTypeFields(doc) {
3077
+ const types = /* @__PURE__ */ new Map();
3078
+ for (const definition of doc.definitions) {
3079
+ if (!isShapeTypeNode(definition)) continue;
3080
+ const fields = /* @__PURE__ */ new Map();
3081
+ if (definition.kind === import_graphql.Kind.ENUM_TYPE_DEFINITION) for (const value of definition.values ?? []) fields.set(value.name.value, "value");
3082
+ else for (const field of definition.fields ?? []) fields.set(field.name.value, (0, import_graphql.print)(field.type));
3083
+ types.set(definition.name.value, fields);
3084
+ }
3085
+ return types;
3086
+ }
3087
+ function escapeRegExp(value) {
3088
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3089
+ }
3090
+ function replaceTypeName(printedType, oldName, newName) {
3091
+ return printedType.replace(new RegExp(`\\b${escapeRegExp(oldName)}\\b`, "g"), newName);
3092
+ }
3093
+ function typeSignature(name, fields) {
3094
+ return [...fields.entries()].map(([field, type]) => `${field}:${replaceTypeName(type, name, "__SELF__")}`).sort().join("|");
3095
+ }
3096
+ function detectTypeRenames(oldTypes, newTypes) {
3097
+ const renames = /* @__PURE__ */ new Map();
3098
+ const removed = [...oldTypes.keys()].filter((name) => !newTypes.has(name));
3099
+ const added = new Set([...newTypes.keys()].filter((name) => !oldTypes.has(name)));
3100
+ for (const oldName of removed) {
3101
+ const oldSignature = typeSignature(oldName, oldTypes.get(oldName));
3102
+ for (const newName of added) if (typeSignature(newName, newTypes.get(newName)) === oldSignature) {
3103
+ renames.set(oldName, newName);
3104
+ added.delete(newName);
3105
+ break;
3106
+ }
3107
+ }
3108
+ return renames;
3109
+ }
3110
+ function flattenFields(types, renames) {
3111
+ const fields = /* @__PURE__ */ new Map();
3112
+ for (const [typeName, typeFields] of types) {
3113
+ const resolvedTypeName = renames.get(typeName) ?? typeName;
3114
+ for (const [fieldName, printedType] of typeFields) {
3115
+ let resolvedType = printedType;
3116
+ for (const [oldName, newName] of renames) resolvedType = replaceTypeName(resolvedType, oldName, newName);
3117
+ fields.set(`${resolvedTypeName}.${fieldName}`, resolvedType);
3118
+ }
3119
+ }
3120
+ return fields;
3121
+ }
3122
+ function hasShapeChange(diff) {
3123
+ return diff.addedFields.length > 0 || diff.removedFields.length > 0 || diff.changedFields.length > 0;
3124
+ }
3125
+ function diffSdlShapes(oldSdl, newSdl) {
3126
+ const empty = {
3127
+ addedFields: [],
3128
+ removedFields: [],
3129
+ changedFields: []
3130
+ };
3131
+ let oldDoc;
3132
+ let newDoc;
3133
+ try {
3134
+ oldDoc = (0, import_graphql.parse)(oldSdl);
3135
+ newDoc = (0, import_graphql.parse)(newSdl);
3136
+ } catch {
3137
+ return empty;
3138
+ }
3139
+ const oldTypes = collectTypeFields(oldDoc);
3140
+ const newTypes = collectTypeFields(newDoc);
3141
+ const oldFields = flattenFields(oldTypes, detectTypeRenames(oldTypes, newTypes));
3142
+ const newFields = flattenFields(newTypes, /* @__PURE__ */ new Map());
3143
+ const diff = {
3144
+ addedFields: [],
3145
+ removedFields: [],
3146
+ changedFields: []
3147
+ };
3148
+ for (const [key, newType] of newFields) {
3149
+ const oldType = oldFields.get(key);
3150
+ if (oldType === void 0) diff.addedFields.push(key);
3151
+ else if (oldType !== newType) diff.changedFields.push(`${key}: ${oldType} → ${newType}`);
3152
+ }
3153
+ for (const key of oldFields.keys()) if (!newFields.has(key)) diff.removedFields.push(key);
3154
+ return diff;
3155
+ }
3156
+ const SAFE = { kind: "safe" };
3157
+ function isBlank(value) {
3158
+ return !value || !value.trim() || value.trim() === "{}";
3159
+ }
3160
+ /**
3161
+ * True for a blank SDL, or an SDL whose types contain nothing but the
3162
+ * `_placeholder` field the editor seeds new state/operation schemas with
3163
+ * (see `makeInitialSchemaDoc` / `makeOperationInitialDoc` in ./helpers.ts).
3164
+ * Replacing a placeholder-only schema with real fields is a user's first
3165
+ * edit on a brand-new model, not a version-relevant change.
3166
+ */
3167
+ function isPlaceholderOnlySchema(sdl) {
3168
+ if (isBlank(sdl)) return true;
3169
+ let doc;
3170
+ try {
3171
+ doc = (0, import_graphql.parse)(sdl);
3172
+ } catch {
3173
+ return false;
3174
+ }
3175
+ return [...collectTypeFields(doc).values()].every((fields) => fields.size === 0 || fields.size === 1 && fields.has("_placeholder"));
3176
+ }
3177
+ function findOperation(spec, operationId) {
3178
+ for (const module of spec.modules) {
3179
+ const operation = module.operations.find((op) => op.id === operationId);
3180
+ if (operation) return operation;
3181
+ }
3182
+ }
3183
+ function addedSinceLastRelease(operationId, previousSpec) {
3184
+ return previousSpec !== void 0 && !findOperation(previousSpec, operationId);
3185
+ }
3186
+ function classifySetStateSchema(input, latestSpec) {
3187
+ const currentSchema = input.scope === "local" ? latestSpec.state.local.schema : latestSpec.state.global.schema;
3188
+ if (isPlaceholderOnlySchema(currentSchema)) return SAFE;
3189
+ const diff = diffSdlShapes(currentSchema, input.schema);
3190
+ if (!hasShapeChange(diff)) return SAFE;
3191
+ return {
3192
+ kind: "version-relevant",
3193
+ reason: input.scope === "local" ? `You're changing the local fields that version ${latestSpec.version} documents store.` : `You're changing the fields that version ${latestSpec.version} documents store.`,
3194
+ diff
3195
+ };
3196
+ }
3197
+ /**
3198
+ * The editor pre-fills a fresh model's initial value from the placeholder
3199
+ * schema, so a value that is blank or carries only the `_placeholder` key is
3200
+ * still being initialized rather than changed.
3201
+ */
3202
+ function isPlaceholderOnlyInitialValue(value) {
3203
+ if (isBlank(value)) return true;
3204
+ let parsed;
3205
+ try {
3206
+ parsed = JSON.parse(value);
3207
+ } catch {
3208
+ return false;
3209
+ }
3210
+ if (typeof parsed !== "object" || parsed === null) return false;
3211
+ return Object.keys(parsed).every((key) => key === "_placeholder");
3212
+ }
3213
+ function classifySetInitialState(input, latestSpec) {
3214
+ const currentValue = input.scope === "local" ? latestSpec.state.local.initialValue : latestSpec.state.global.initialValue;
3215
+ if (isPlaceholderOnlyInitialValue(currentValue)) return SAFE;
3216
+ if (compareStringsWithoutWhitespace(currentValue, input.initialValue)) return SAFE;
3217
+ return {
3218
+ kind: "version-relevant",
3219
+ reason: `You're changing the starting content that version ${latestSpec.version} documents are built on.`
3220
+ };
3221
+ }
3222
+ function classifyOperationChange(action, operationId, latestSpec, previousSpec) {
3223
+ if (addedSinceLastRelease(operationId, previousSpec)) return SAFE;
3224
+ const operation = findOperation(latestSpec, operationId);
3225
+ if (!operation) return SAFE;
3226
+ const operationLabel = operation.name || "an operation";
3227
+ switch (action.type) {
3228
+ case "DELETE_OPERATION": return {
3229
+ kind: "version-relevant",
3230
+ reason: `You're removing the "${operationLabel}" operation from version ${latestSpec.version}.`
3231
+ };
3232
+ case "SET_OPERATION_NAME":
3233
+ if (isBlank(operation.name)) return SAFE;
3234
+ return {
3235
+ kind: "version-relevant",
3236
+ reason: `You're renaming the "${operationLabel}" operation in version ${latestSpec.version}.`
3237
+ };
3238
+ case "SET_OPERATION_SCHEMA": {
3239
+ if (isPlaceholderOnlySchema(operation.schema ?? "")) return SAFE;
3240
+ if (isBlank(action.input.schema)) return {
3241
+ kind: "version-relevant",
3242
+ reason: `You're changing the information that the "${operationLabel}" operation accepts in version ${latestSpec.version}.`
3243
+ };
3244
+ const diff = diffSdlShapes(operation.schema ?? "", action.input.schema ?? "");
3245
+ if (!hasShapeChange(diff)) return SAFE;
3246
+ return {
3247
+ kind: "version-relevant",
3248
+ reason: `You're changing the information that the "${operationLabel}" operation accepts in version ${latestSpec.version}.`,
3249
+ diff
3250
+ };
3251
+ }
3252
+ default: return SAFE;
3253
+ }
3254
+ }
3255
+ function classifyDeleteModule(moduleId, latestSpec, previousSpec) {
3256
+ const module = latestSpec.modules.find((candidate) => candidate.id === moduleId);
3257
+ if (!module || module.operations.length === 0) return SAFE;
3258
+ if (module.operations.every((operation) => addedSinceLastRelease(operation.id, previousSpec))) return SAFE;
3259
+ return {
3260
+ kind: "version-relevant",
3261
+ reason: `You're removing the "${module.name}" module and all of its operations from version ${latestSpec.version}.`
3262
+ };
3263
+ }
3264
+ /**
3265
+ * Classifies a document-model action as version-relevant (would break
3266
+ * documents created with the current version) or safe. `previousSpec` is the
3267
+ * last released specification, used to exempt operations added since the
3268
+ * release.
3269
+ */
3270
+ function classifyDocumentModelAction(action, latestSpec, previousSpec) {
3271
+ switch (action.type) {
3272
+ case "SET_STATE_SCHEMA": return classifySetStateSchema(action.input, latestSpec);
3273
+ case "SET_INITIAL_STATE": return classifySetInitialState(action.input, latestSpec);
3274
+ case "DELETE_OPERATION":
3275
+ case "SET_OPERATION_NAME":
3276
+ case "SET_OPERATION_SCHEMA": return classifyOperationChange(action, action.input.id, latestSpec, previousSpec);
3277
+ case "DELETE_MODULE": return classifyDeleteModule(action.input.id, latestSpec, previousSpec);
3278
+ default: return SAFE;
3279
+ }
3280
+ }
3281
+ /**
3282
+ * Pure decision core of the version advisory: given the actions about to be
3283
+ * dispatched, decide whether to dispatch immediately or prompt the user.
3284
+ */
3285
+ function decideDispatch(actions, latestSpec, previousSpec, hasSessionChoice) {
3286
+ if (hasSessionChoice) return { kind: "dispatch" };
3287
+ for (const action of actions) {
3288
+ const classification = classifyDocumentModelAction(action, latestSpec, previousSpec);
3289
+ if (classification.kind === "version-relevant") return {
3290
+ kind: "prompt",
3291
+ reason: classification.reason,
3292
+ diff: classification.diff
3293
+ };
3294
+ }
3295
+ return { kind: "dispatch" };
3296
+ }
3297
+ //#endregion
3298
+ //#region editors/document-model-editor/hooks/useVersionAdvisory.ts
3299
+ /**
3300
+ * Versions the user has confirmed as "still in development" (or that were
3301
+ * just created via an explicit release) for this browser session. Keyed by
3302
+ * `${documentId}:${version}`. Deliberately in-memory: a publisher returning
3303
+ * in a later session is asked again, which is when the reminder matters.
3304
+ */
3305
+ const sessionVersionChoices = /* @__PURE__ */ new Set();
3306
+ function useVersionAdvisory(args) {
3307
+ const { documentId, latestSpec, previousSpec, dispatch, onReleaseError } = args;
3308
+ const [prompt, setPrompt] = useState(void 0);
3309
+ const pendingRef = useRef(void 0);
3310
+ const choiceKey = `${documentId}:${latestSpec.version}`;
3311
+ const guardedDispatch = (...dispatchArgs) => {
3312
+ const [action] = dispatchArgs;
3313
+ const decision = decideDispatch((Array.isArray(action) ? action : [action]).filter((candidate) => candidate !== void 0), latestSpec, previousSpec, sessionVersionChoices.has(choiceKey));
3314
+ if (decision.kind === "dispatch") {
3315
+ dispatch(...dispatchArgs);
3316
+ return;
3317
+ }
3318
+ pendingRef.current = dispatchArgs;
3319
+ setPrompt({
3320
+ version: latestSpec.version,
3321
+ reason: decision.reason,
3322
+ diff: decision.diff
3323
+ });
3324
+ };
3325
+ const flushPending = () => {
3326
+ const pending = pendingRef.current;
3327
+ pendingRef.current = void 0;
3328
+ if (pending) dispatch(...pending);
3329
+ };
3330
+ const releaseFirst = () => {
3331
+ setPrompt(void 0);
3332
+ if (!pendingRef.current) return;
3333
+ dispatch(releaseNewVersion(), (errors) => {
3334
+ if (errors.length > 0) {
3335
+ pendingRef.current = void 0;
3336
+ onReleaseError?.(errors[0].message);
3337
+ }
3338
+ }, () => {
3339
+ if (!pendingRef.current) return;
3340
+ sessionVersionChoices.add(`${documentId}:${latestSpec.version + 1}`);
3341
+ flushPending();
3342
+ });
3343
+ };
3344
+ const keepEditing = () => {
3345
+ sessionVersionChoices.add(choiceKey);
3346
+ setPrompt(void 0);
3347
+ flushPending();
3348
+ };
3349
+ const cancelAdvisory = () => {
3350
+ pendingRef.current = void 0;
3351
+ setPrompt(void 0);
3352
+ };
3353
+ const markVersionInDevelopment = (version) => {
3354
+ sessionVersionChoices.add(`${documentId}:${version}`);
3355
+ };
3356
+ return {
3357
+ guardedDispatch,
3358
+ prompt,
3359
+ releaseFirst,
3360
+ keepEditing,
3361
+ cancelAdvisory,
3362
+ markVersionInDevelopment
3363
+ };
3364
+ }
3365
+ //#endregion
3366
+ //#region editors/document-model-editor/editor.tsx
3367
+ const StateSchemas = lazy(() => import("./state-schemas-DXG02fMh.mjs"));
3368
+ const noopSetStateSchema = () => void 0;
3369
+ const noopSetInitialState = () => void 0;
3370
+ function Editor() {
3371
+ useSetPHDocumentEditorConfig(editorConfig);
3372
+ const toast = usePHToast();
3373
+ const [document, dispatch] = useSelectedDocumentModelDocument();
3374
+ const [scope, setScope] = useState("global");
3375
+ const documentNodeName = document.header.name;
3376
+ const { name: modelName, id: documentType, extension, description, author: { name: authorName, website: authorWebsite } } = document.state.global;
3377
+ const specifications = document.state.global.specifications;
3378
+ const latestSpec = specifications[specifications.length - 1];
3379
+ const previousSpec = specifications.length >= 2 ? specifications[specifications.length - 2] : void 0;
3380
+ const [viewedVersion, setViewedVersion] = useState("latest");
3381
+ const viewedSpec = viewedVersion === "latest" ? latestSpec : specifications.find((spec) => spec.version === viewedVersion) ?? latestSpec;
3382
+ const isViewingFrozenVersion = viewedSpec.version !== latestSpec.version;
3383
+ const { state: { global: { schema: globalStateSchema, initialValue: globalStateInitialValue }, local: { schema: localStateSchema, initialValue: localStateInitialValue } }, modules } = viewedSpec;
3384
+ const operations = modules.flatMap((module) => module.operations);
3385
+ const { state: { global: { schema: latestGlobalStateSchema, initialValue: latestGlobalStateInitialValue }, local: { schema: latestLocalStateSchema, initialValue: latestLocalStateInitialValue } }, modules: latestModules } = latestSpec;
3386
+ const latestOperations = latestModules.flatMap((module) => module.operations);
3387
+ const shouldSetInitialName = useRef(!modelName && !!documentNodeName && latestOperations.length === 0);
3388
+ useEffect(() => {
3389
+ if (!shouldSetInitialName.current || !documentNodeName) return;
3390
+ const initialSchemaDoc = initializeModelSchema(documentNodeName);
3391
+ dispatch([setModelName({ name: documentNodeName }), setStateSchema({
3392
+ schema: initialSchemaDoc,
3393
+ scope: "global"
3394
+ })]);
3395
+ shouldSetInitialName.current = false;
3396
+ }, [documentNodeName, dispatch]);
3397
+ const { guardedDispatch, prompt, releaseFirst, keepEditing, cancelAdvisory, markVersionInDevelopment } = useVersionAdvisory({
3398
+ documentId: document.header.id,
3399
+ latestSpec,
3400
+ previousSpec,
3401
+ dispatch,
3402
+ onReleaseError: (message) => {
3403
+ if (toast) toast(message, { type: "connect-warning" });
3404
+ }
3405
+ });
3406
+ const handleReleaseNewVersion = () => {
3407
+ const nextVersion = latestSpec.version + 1;
3408
+ dispatch(releaseNewVersion(), (errors) => {
3409
+ if (errors.length > 0 && toast) toast(errors[0].message, { type: "connect-warning" });
3410
+ }, () => {
3411
+ markVersionInDevelopment(nextVersion);
3412
+ setViewedVersion("latest");
3413
+ });
3414
+ };
3415
+ const operationSchemasSdl = operations.flatMap((operation) => operation.schema ?? []).join("\n");
3416
+ const handleSetModelId = (id) => {
3417
+ if (compareStringsWithoutWhitespace(id, documentType)) return;
3418
+ guardedDispatch([setModelId({ id })]);
3419
+ };
3420
+ const handleSetModelDescription = (newDescription) => {
3421
+ if (compareStringsWithoutWhitespace(newDescription, description)) return;
3422
+ guardedDispatch(setModelDescription({ description: newDescription }));
3423
+ };
3424
+ const handleSetModelExtension = (newExtension) => {
3425
+ if (compareStringsWithoutWhitespace(newExtension, extension)) return;
3426
+ guardedDispatch(setModelExtension({ extension: newExtension }));
3427
+ };
3428
+ const handleSetModelName = (newName) => {
3429
+ if (compareStringsWithoutWhitespace(newName, modelName)) return;
3430
+ guardedDispatch(setModelName({ name: newName }));
3431
+ };
3432
+ const handleSetAuthorName = (newAuthorName) => {
3433
+ if (compareStringsWithoutWhitespace(newAuthorName, authorName)) return;
3434
+ guardedDispatch(setAuthorName({ authorName: newAuthorName }));
3435
+ };
3436
+ const handleSetAuthorWebsite = (newAuthorWebsite) => {
3437
+ if (compareStringsWithoutWhitespace(newAuthorWebsite, authorWebsite ?? "")) return;
3438
+ guardedDispatch(setAuthorWebsite({ authorWebsite: newAuthorWebsite }));
3439
+ };
3440
+ const handleSetStateSchema = (newSchema, scope) => {
3441
+ if (compareStringsWithoutWhitespace(newSchema, scope === "global" ? latestGlobalStateSchema : latestLocalStateSchema)) return;
3442
+ guardedDispatch(setStateSchema({
3443
+ schema: newSchema,
3444
+ scope
3445
+ }));
3446
+ };
3447
+ const handleSetInitialState = (newInitialValue, scope) => {
3448
+ if (compareStringsWithoutWhitespace(newInitialValue, scope === "global" ? latestGlobalStateInitialValue : latestLocalStateInitialValue)) return;
3449
+ guardedDispatch(setInitialState({
3450
+ initialValue: newInitialValue,
3451
+ scope
3452
+ }));
3453
+ };
3454
+ const handleAddModule = (name) => {
3455
+ return new Promise((resolve) => {
3456
+ try {
3457
+ if (latestModules.some((module) => compareStringsWithoutWhitespace(module.name, name))) {
3458
+ resolve(void 0);
3459
+ return;
3460
+ }
3461
+ const id = generateId();
3462
+ guardedDispatch(addModule({
3463
+ id,
3464
+ name
3465
+ }));
3466
+ resolve(id);
3467
+ } catch (error) {
3468
+ console.error("Failed to add module:", error);
3469
+ resolve(void 0);
3470
+ }
3471
+ });
3472
+ };
3473
+ const handleSetModuleName = (id, name) => {
3474
+ if (latestModules.some((module) => compareStringsWithoutWhitespace(module.name, name))) return;
3475
+ guardedDispatch(setModuleName({
3476
+ id,
3477
+ name
3478
+ }));
3479
+ };
3480
+ const handleDeleteModule = (id) => {
3481
+ guardedDispatch(deleteModule({ id }));
3482
+ };
3483
+ const handleAddOperation = (moduleId, name) => {
3484
+ return new Promise((resolve) => {
3485
+ const id = generateId();
3486
+ guardedDispatch(addOperation({
3487
+ id,
3488
+ moduleId,
3489
+ name,
3490
+ scope
3491
+ }), (errors) => {
3492
+ if (errors.length > 0) {
3493
+ if (toast) toast(errors[0].message, { type: "connect-warning" });
3494
+ resolve(void 0);
3495
+ } else resolve(id);
3496
+ }, () => resolve(id));
3497
+ });
3498
+ };
3499
+ const handleSetOperationName = (id, name) => {
3500
+ guardedDispatch(setOperationName({
3501
+ id,
3502
+ name
3503
+ }), (errors) => {
3504
+ if (errors.length > 0 && toast) toast(errors[0].message, { type: "connect-warning" });
3505
+ });
3506
+ };
3507
+ const handleSetOperationSchema = (id, newSchema) => {
3508
+ const operation = latestOperations.find((operation) => operation.id === id);
3509
+ if (operation?.schema && compareStringsWithoutWhitespace(newSchema, operation.schema)) return;
3510
+ guardedDispatch(setOperationSchema({
3511
+ id,
3512
+ schema: newSchema
3513
+ }));
3514
+ };
3515
+ const handleToggleNoInputRequired = (id, noInputRequired) => {
3516
+ const operation = latestOperations.find((op) => op.id === id);
3517
+ if (!operation?.name) return;
3518
+ if (noInputRequired) guardedDispatch(setOperationSchema({
3519
+ id,
3520
+ schema: makeEmptyOperationSchema(operation.name)
3521
+ }));
3522
+ else guardedDispatch(setOperationSchema({
3523
+ id,
3524
+ schema: makeOperationInitialDoc(operation.name)
3525
+ }));
3526
+ };
3527
+ const handleSetOperationDescription = (id, newDescription) => {
3528
+ if (compareStringsWithoutWhitespace(latestOperations.find((operation) => operation.id === id)?.description ?? "", newDescription)) return;
3529
+ guardedDispatch(setOperationDescription({
3530
+ id,
3531
+ description: newDescription
3532
+ }));
3533
+ };
3534
+ const handleDeleteOperation = (id) => {
3535
+ guardedDispatch(deleteOperation({ id }));
3536
+ };
3537
+ const handleAddOperationError = (operationId, errorName) => {
3538
+ return new Promise((resolve) => {
3539
+ try {
3540
+ if ((latestOperations.find((operation) => operation.id === operationId)?.errors.map((error) => error.name).filter(Boolean) ?? []).some((name) => compareStringsWithoutWhitespace(name, errorName))) {
3541
+ resolve(void 0);
3542
+ return;
3543
+ }
3544
+ const id = generateId();
3545
+ guardedDispatch(addOperationError({
3546
+ id,
3547
+ operationId,
3548
+ errorName,
3549
+ errorCode: pascalCase(errorName)
3550
+ }));
3551
+ resolve(id);
3552
+ } catch (error) {
3553
+ console.error("Failed to add operation error:", error);
3554
+ resolve(void 0);
3555
+ }
3556
+ });
3557
+ };
3558
+ const handleDeleteOperationError = (id) => {
3559
+ guardedDispatch(deleteOperationError({ id }));
3560
+ };
3561
+ const handleSetOperationErrorName = (operationId, errorId, errorName) => {
3562
+ if ((latestOperations.find((operation) => operation.id === operationId)?.errors.map((error) => error.name).filter(Boolean) ?? []).some((name) => compareStringsWithoutWhitespace(name, errorName))) return;
3563
+ guardedDispatch(setOperationErrorName({
3564
+ id: errorId,
3565
+ errorName
3566
+ }));
3567
+ };
3568
+ const addOperationAndInitialSchema = async (moduleId, name) => {
3569
+ try {
3570
+ const id = await handleAddOperation(moduleId, name);
3571
+ if (!id) return void 0;
3572
+ try {
3573
+ handleSetOperationSchema(id, makeOperationInitialDoc(name));
3574
+ return id;
3575
+ } catch (error) {
3576
+ console.error("Failed to update operation schema:", error);
3577
+ return;
3578
+ }
3579
+ } catch (error) {
3580
+ console.error("Failed to add operation and schema:", error);
3581
+ return;
3582
+ }
3583
+ };
3584
+ return /* @__PURE__ */ jsxs("main", {
3585
+ className: "min-h-dvh bg-background p-6",
3586
+ children: [
3587
+ /* @__PURE__ */ jsx(DocumentToolbar, {}),
3588
+ /* @__PURE__ */ jsx(SchemaContextProvider, {
3589
+ globalStateSchemaSdl: globalStateSchema,
3590
+ localStateSchemaSdl: localStateSchema,
3591
+ operationSchemasSdl,
3592
+ children: /* @__PURE__ */ jsxs("div", {
3593
+ className: "mx-auto max-w-6xl px-4 pt-8",
3594
+ children: [
3595
+ /* @__PURE__ */ jsx(VersionControls, {
3596
+ specifications,
3597
+ viewedVersion: viewedSpec.version,
3598
+ onViewVersion: setViewedVersion,
3599
+ onReleaseNewVersion: handleReleaseNewVersion
3600
+ }),
3601
+ /* @__PURE__ */ jsx(ModelMetadata, {
3602
+ name: modelName,
3603
+ documentType,
3604
+ extension,
3605
+ description,
3606
+ authorName,
3607
+ authorWebsite: authorWebsite ?? "",
3608
+ globalStateSchema: latestGlobalStateSchema,
3609
+ localStateSchema: latestLocalStateSchema,
3610
+ setModelId: handleSetModelId,
3611
+ setModelDescription: handleSetModelDescription,
3612
+ setModelExtension: handleSetModelExtension,
3613
+ setModelName: handleSetModelName,
3614
+ setAuthorName: handleSetAuthorName,
3615
+ setAuthorWebsite: handleSetAuthorWebsite,
3616
+ setStateSchema: handleSetStateSchema
3617
+ }),
3618
+ /* @__PURE__ */ jsx(Divider, {}),
3619
+ isViewingFrozenVersion && /* @__PURE__ */ jsx(FrozenVersionBanner, {
3620
+ latestVersion: latestSpec.version,
3621
+ viewedVersion: viewedSpec.version
3622
+ }),
3623
+ /* @__PURE__ */ jsxs("div", {
3624
+ className: isViewingFrozenVersion ? "pointer-events-none opacity-80 select-none" : void 0,
3625
+ inert: isViewingFrozenVersion || void 0,
3626
+ children: [
3627
+ /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(StateSchemas, {
3628
+ modelName,
3629
+ globalStateSchema,
3630
+ globalStateInitialValue,
3631
+ localStateSchema,
3632
+ localStateInitialValue,
3633
+ setStateSchema: isViewingFrozenVersion ? noopSetStateSchema : handleSetStateSchema,
3634
+ setInitialState: isViewingFrozenVersion ? noopSetInitialState : handleSetInitialState,
3635
+ currentScope: scope,
3636
+ onScopeChange: setScope
3637
+ }) }),
3638
+ /* @__PURE__ */ jsx(Divider, {}),
3639
+ /* @__PURE__ */ jsxs("h3", {
3640
+ className: "mb-6 text-lg text-foreground capitalize",
3641
+ children: [scope, " Operations"]
3642
+ }),
3643
+ /* @__PURE__ */ jsx(Modules, {
3644
+ modules: modules.map((module) => ({
3645
+ ...module,
3646
+ operations: module.operations.filter((op) => op.scope === scope)
3647
+ })),
3648
+ allOperations: operations,
3649
+ addModule: handleAddModule,
3650
+ updateModuleName: handleSetModuleName,
3651
+ deleteModule: handleDeleteModule,
3652
+ updateOperationName: handleSetOperationName,
3653
+ updateOperationSchema: handleSetOperationSchema,
3654
+ setOperationDescription: handleSetOperationDescription,
3655
+ deleteOperation: handleDeleteOperation,
3656
+ addOperationError: handleAddOperationError,
3657
+ deleteOperationError: handleDeleteOperationError,
3658
+ setOperationErrorName: handleSetOperationErrorName,
3659
+ addOperationAndInitialSchema,
3660
+ toggleNoInputRequired: handleToggleNoInputRequired
3661
+ })
3662
+ ]
3663
+ })
3664
+ ]
3665
+ })
3666
+ }),
3667
+ /* @__PURE__ */ jsx(VersionAdvisoryModal, {
3668
+ prompt,
3669
+ onReleaseFirst: releaseFirst,
3670
+ onKeepEditing: keepEditing,
3671
+ onCancel: cancelAdvisory
3672
+ })
3673
+ ]
3674
+ });
3675
+ }
3676
+ //#endregion
3677
+ export { Editor as default };
3678
+
3679
+ //# sourceMappingURL=editor-BiiLqEe9.mjs.map