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