@powerhousedao/powerhouse-vetra-packages 6.2.3-dev.5 → 6.2.3-dev.50

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 (117) hide show
  1. package/dist/browser/assets/{entry-5_Eh4a2Z.js → entry-E7pSm84X.js} +111 -7
  2. package/dist/browser/assets/{projection-entry-5PVbP10h.js → projection-entry-UE4mfnXc.js} +99 -21
  3. package/dist/browser/document-models/index.js +2 -1
  4. package/dist/browser/{documents-J_l59mSV.js → documents-CRzouuNR.js} +631 -752
  5. package/dist/browser/documents-CRzouuNR.js.map +1 -0
  6. package/dist/browser/editor-C7KBR_ar.js +4676 -0
  7. package/dist/browser/editor-C7KBR_ar.js.map +1 -0
  8. package/dist/browser/{editor-Cbl_EDjI.js → editor-CiR6XQBO.js} +4 -5
  9. package/dist/browser/{editor-Cbl_EDjI.js.map → editor-CiR6XQBO.js.map} +1 -1
  10. package/dist/browser/editors/document-model-editor/module.js +1 -1
  11. package/dist/browser/editors/document-model-editor/module.js.map +1 -1
  12. package/dist/browser/editors/generic-drive-explorer/index.js +81 -65
  13. package/dist/browser/editors/generic-drive-explorer/index.js.map +1 -1
  14. package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
  15. package/dist/browser/editors/generic-drive-explorer/module.js.map +1 -1
  16. package/dist/browser/folder-view-DSgXN79D.js +4409 -0
  17. package/dist/browser/folder-view-DSgXN79D.js.map +1 -0
  18. package/dist/browser/{graphql-editor-BcL3-Zha.js → graphql-editor-Cgi5UOrF.js} +98 -88
  19. package/dist/browser/graphql-editor-Cgi5UOrF.js.map +1 -0
  20. package/dist/{node/hooks-D0DcS3MV.mjs → browser/hooks-eQxBX7g4.js} +824 -444
  21. package/dist/browser/{hooks-KKcNp2X0.js.map → hooks-eQxBX7g4.js.map} +1 -1
  22. package/dist/browser/index.js +137 -34
  23. package/dist/browser/index.js.map +1 -1
  24. package/dist/browser/{json-editor-DHXQRIN5.js → json-editor-DfRD-pfk.js} +8 -9
  25. package/dist/browser/{json-editor-DHXQRIN5.js.map → json-editor-DfRD-pfk.js.map} +1 -1
  26. package/dist/browser/{parser-CkF6Qt8V.js → parser-DtbeHA3H.js} +7 -6
  27. package/dist/browser/{parser-CkF6Qt8V.js.map → parser-DtbeHA3H.js.map} +1 -1
  28. package/dist/browser/rolldown-runtime-DC62tzP2.js +33 -0
  29. package/dist/browser/src-CrUksCLW-B2dkRdgq.js +5254 -0
  30. package/dist/browser/src-CrUksCLW-B2dkRdgq.js.map +1 -0
  31. package/dist/browser/state-schemas-B5Bk_l1s.js +696 -0
  32. package/dist/browser/state-schemas-B5Bk_l1s.js.map +1 -0
  33. package/dist/browser/tslib.es6-Cno80yFJ.js +32 -0
  34. package/dist/browser/tslib.es6-Cno80yFJ.js.map +1 -0
  35. package/dist/node/document-models/index.mjs +2 -1
  36. package/dist/node/documents-D70S9PZL.mjs +17 -0
  37. package/dist/node/documents-D70S9PZL.mjs.map +1 -0
  38. package/dist/node/editor-96sMeumV.mjs +4597 -0
  39. package/dist/node/editor-96sMeumV.mjs.map +1 -0
  40. package/dist/node/{editor-DG1q4Y55.mjs → editor-wqvKwcO5.mjs} +4 -5
  41. package/dist/node/{editor-DG1q4Y55.mjs.map → editor-wqvKwcO5.mjs.map} +1 -1
  42. package/dist/node/editors/document-model-editor/module.mjs +1 -1
  43. package/dist/node/editors/document-model-editor/module.mjs.map +1 -1
  44. package/dist/node/editors/generic-drive-explorer/index.mjs +26 -21
  45. package/dist/node/editors/generic-drive-explorer/index.mjs.map +1 -1
  46. package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
  47. package/dist/node/editors/generic-drive-explorer/module.mjs.map +1 -1
  48. package/dist/node/folder-view-ktfv2Cvw.mjs +4409 -0
  49. package/dist/node/folder-view-ktfv2Cvw.mjs.map +1 -0
  50. package/dist/node/{graphql-BfAoPeWM.mjs → graphql-Dp4j7rmx.mjs} +50 -49
  51. package/dist/node/{graphql-BfAoPeWM.mjs.map → graphql-Dp4j7rmx.mjs.map} +1 -1
  52. package/dist/node/{graphql-editor-B-XIb6az.mjs → graphql-editor-CBJXEY_C.mjs} +77 -63
  53. package/dist/node/graphql-editor-CBJXEY_C.mjs.map +1 -0
  54. package/dist/{browser/hooks-KKcNp2X0.js → node/hooks-C2b46djt.mjs} +824 -444
  55. package/dist/node/{hooks-D0DcS3MV.mjs.map → hooks-C2b46djt.mjs.map} +1 -1
  56. package/dist/node/index.mjs +158 -35
  57. package/dist/node/index.mjs.map +1 -1
  58. package/dist/node/{json-editor-DB0vi6tV.mjs → json-editor-DaqHARBD.mjs} +8 -9
  59. package/dist/node/{json-editor-DB0vi6tV.mjs.map → json-editor-DaqHARBD.mjs.map} +1 -1
  60. package/dist/node/{schema-context-DL8jhi_d.mjs → schema-context-CojjnSE6.mjs} +6 -5
  61. package/dist/node/schema-context-CojjnSE6.mjs.map +1 -0
  62. package/dist/node/src-CrUksCLW-TvF37aMo.mjs +5935 -0
  63. package/dist/node/src-CrUksCLW-TvF37aMo.mjs.map +1 -0
  64. package/dist/node/state-schemas-BHuo0GPl.mjs +698 -0
  65. package/dist/node/state-schemas-BHuo0GPl.mjs.map +1 -0
  66. package/dist/node/{main-B1tRsYOp.mjs → tslib.es6-VORZjfk3.mjs} +40 -202
  67. package/dist/node/tslib.es6-VORZjfk3.mjs.map +1 -0
  68. package/package.json +12 -11
  69. package/dist/browser/button-CuO8Gh3v.js +0 -696
  70. package/dist/browser/button-CuO8Gh3v.js.map +0 -1
  71. package/dist/browser/connect-BtHSAuSc.js +0 -14328
  72. package/dist/browser/connect-BtHSAuSc.js.map +0 -1
  73. package/dist/browser/dist-B4FWbuEM.js +0 -4148
  74. package/dist/browser/dist-B4FWbuEM.js.map +0 -1
  75. package/dist/browser/dist-BAJ5nRDl.js +0 -2711
  76. package/dist/browser/dist-BAJ5nRDl.js.map +0 -1
  77. package/dist/browser/dist-D69hfRZN.js +0 -4641
  78. package/dist/browser/dist-D69hfRZN.js.map +0 -1
  79. package/dist/browser/document-drive-BEXJ-rHp.js +0 -8277
  80. package/dist/browser/document-drive-BEXJ-rHp.js.map +0 -1
  81. package/dist/browser/documents-J_l59mSV.js.map +0 -1
  82. package/dist/browser/editor-mNThkZOv.js +0 -1809
  83. package/dist/browser/editor-mNThkZOv.js.map +0 -1
  84. package/dist/browser/folder-view-D8AkN1Oj.js +0 -232
  85. package/dist/browser/folder-view-D8AkN1Oj.js.map +0 -1
  86. package/dist/browser/graphql-editor-BcL3-Zha.js.map +0 -1
  87. package/dist/browser/lib-ewnRj2dJ.js +0 -209
  88. package/dist/browser/lib-ewnRj2dJ.js.map +0 -1
  89. package/dist/browser/printer-CEYr4JOg.js +0 -604
  90. package/dist/browser/printer-CEYr4JOg.js.map +0 -1
  91. package/dist/browser/schema-context-ZyeclQwy.js +0 -69
  92. package/dist/browser/schema-context-ZyeclQwy.js.map +0 -1
  93. package/dist/browser/state-schemas-C4F8lReN.js +0 -298
  94. package/dist/browser/state-schemas-C4F8lReN.js.map +0 -1
  95. package/dist/node/button-Da7CxMn7.mjs +0 -678
  96. package/dist/node/button-Da7CxMn7.mjs.map +0 -1
  97. package/dist/node/connect-B6IQsY6u.mjs +0 -15022
  98. package/dist/node/connect-B6IQsY6u.mjs.map +0 -1
  99. package/dist/node/dist-CzYOpeXN.mjs +0 -2711
  100. package/dist/node/dist-CzYOpeXN.mjs.map +0 -1
  101. package/dist/node/dist-DT7jI9ol.mjs +0 -4148
  102. package/dist/node/dist-DT7jI9ol.mjs.map +0 -1
  103. package/dist/node/dist-hd-KLWy7.mjs +0 -4649
  104. package/dist/node/dist-hd-KLWy7.mjs.map +0 -1
  105. package/dist/node/document-drive-CkV9NvD7.mjs +0 -8294
  106. package/dist/node/document-drive-CkV9NvD7.mjs.map +0 -1
  107. package/dist/node/documents-DCf53bzO.mjs +0 -747
  108. package/dist/node/documents-DCf53bzO.mjs.map +0 -1
  109. package/dist/node/editor-C93fdI28.mjs +0 -1809
  110. package/dist/node/editor-C93fdI28.mjs.map +0 -1
  111. package/dist/node/folder-view-BGabHV7H.mjs +0 -232
  112. package/dist/node/folder-view-BGabHV7H.mjs.map +0 -1
  113. package/dist/node/graphql-editor-B-XIb6az.mjs.map +0 -1
  114. package/dist/node/main-B1tRsYOp.mjs.map +0 -1
  115. package/dist/node/schema-context-DL8jhi_d.mjs.map +0 -1
  116. package/dist/node/state-schemas-BGsgtEG1.mjs +0 -299
  117. package/dist/node/state-schemas-BGsgtEG1.mjs.map +0 -1
@@ -0,0 +1,4597 @@
1
+ import { i as __exportAll } from "./tslib.es6-VORZjfk3.mjs";
2
+ import { t as require_graphql } from "./graphql-Dp4j7rmx.mjs";
3
+ import { i as Primitive, m as twMerge, t as Modal } from "./src-CrUksCLW-TvF37aMo.mjs";
4
+ import { n as safeParseSdl, t as SchemaContextProvider } from "./schema-context-CojjnSE6.mjs";
5
+ 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";
6
+ import { z } from "zod";
7
+ import * as React$1 from "react";
8
+ import React, { Suspense, forwardRef, lazy, useCallback, useEffect, useId, useImperativeHandle, useRef, useState } from "react";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { ConnectSelect, DocumentToolbar, ModalButton } from "@powerhousedao/design-system/connect";
11
+ import { usePHToast, useSelectedDocumentOfType, useSetPHDocumentEditorConfig } from "@powerhousedao/reactor-browser";
12
+ import { getPHCustomScalarByTypeName } from "@powerhousedao/document-engineering/graphql";
13
+ import * as n from "zod/v4/core";
14
+ //#region ../../node_modules/.pnpm/@radix-ui+react-compose-refs@1.1.3_@types+react@19.2.14_react@19.2.6/node_modules/@radix-ui/react-compose-refs/dist/index.mjs
15
+ var import_graphql = require_graphql();
16
+ function setRef(ref, value) {
17
+ if (typeof ref === "function") return ref(value);
18
+ else if (ref !== null && ref !== void 0) ref.current = value;
19
+ }
20
+ function composeRefs(...refs) {
21
+ return (node) => {
22
+ let hasCleanup = false;
23
+ const cleanups = refs.map((ref) => {
24
+ const cleanup = setRef(ref, node);
25
+ if (!hasCleanup && typeof cleanup == "function") hasCleanup = true;
26
+ return cleanup;
27
+ });
28
+ if (hasCleanup) return () => {
29
+ for (let i = 0; i < cleanups.length; i++) {
30
+ const cleanup = cleanups[i];
31
+ if (typeof cleanup == "function") cleanup();
32
+ else setRef(refs[i], null);
33
+ }
34
+ };
35
+ };
36
+ }
37
+ function useComposedRefs(...refs) {
38
+ return React$1.useCallback(composeRefs(...refs), refs);
39
+ }
40
+ //#endregion
41
+ //#region ../../node_modules/.pnpm/@radix-ui+react-slot@1.3.0_@types+react@19.2.14_react@19.2.6/node_modules/@radix-ui/react-slot/dist/index.mjs
42
+ // @__NO_SIDE_EFFECTS__
43
+ function createSlot(ownerName) {
44
+ const Slot2 = React$1.forwardRef((props, forwardedRef) => {
45
+ let { children, ...slotProps } = props;
46
+ let slottableElement = null;
47
+ let hasSlottable = false;
48
+ const newChildren = [];
49
+ if (isLazyComponent(children) && typeof use === "function") children = use(children._payload);
50
+ React$1.Children.forEach(children, (maybeSlottable) => {
51
+ if (isSlottable(maybeSlottable)) {
52
+ hasSlottable = true;
53
+ const slottable = maybeSlottable;
54
+ let child = "child" in slottable.props ? slottable.props.child : slottable.props.children;
55
+ if (isLazyComponent(child) && typeof use === "function") child = use(child._payload);
56
+ slottableElement = getSlottableElementFromSlottable(slottable, child);
57
+ newChildren.push(slottableElement?.props?.children);
58
+ } else newChildren.push(maybeSlottable);
59
+ });
60
+ if (slottableElement) slottableElement = React$1.cloneElement(slottableElement, void 0, newChildren);
61
+ else if (!hasSlottable && React$1.Children.count(children) === 1 && React$1.isValidElement(children)) slottableElement = children;
62
+ const slottableElementRef = slottableElement ? getElementRef(slottableElement) : void 0;
63
+ const composedRef = useComposedRefs(forwardedRef, slottableElementRef);
64
+ if (!slottableElement) {
65
+ if (children || children === 0) throw new Error(hasSlottable ? createSlottableError(ownerName) : createSlotError(ownerName));
66
+ return children;
67
+ }
68
+ const mergedProps = mergeProps(slotProps, slottableElement.props ?? {});
69
+ if (slottableElement.type !== React$1.Fragment) mergedProps.ref = forwardedRef ? composedRef : slottableElementRef;
70
+ return React$1.cloneElement(slottableElement, mergedProps);
71
+ });
72
+ Slot2.displayName = `${ownerName}.Slot`;
73
+ return Slot2;
74
+ }
75
+ var Slot = /* @__PURE__ */ createSlot("Slot");
76
+ var SLOTTABLE_IDENTIFIER = Symbol.for("radix.slottable");
77
+ var getSlottableElementFromSlottable = (slottable, child) => {
78
+ if ("child" in slottable.props) {
79
+ const child2 = slottable.props.child;
80
+ if (!React$1.isValidElement(child2)) return null;
81
+ return React$1.cloneElement(child2, void 0, slottable.props.children(child2.props.children));
82
+ }
83
+ return React$1.isValidElement(child) ? child : null;
84
+ };
85
+ function mergeProps(slotProps, childProps) {
86
+ const overrideProps = { ...childProps };
87
+ for (const propName in childProps) {
88
+ const slotPropValue = slotProps[propName];
89
+ const childPropValue = childProps[propName];
90
+ if (/^on[A-Z]/.test(propName)) {
91
+ if (slotPropValue && childPropValue) overrideProps[propName] = (...args) => {
92
+ const result = childPropValue(...args);
93
+ slotPropValue(...args);
94
+ return result;
95
+ };
96
+ else if (slotPropValue) overrideProps[propName] = slotPropValue;
97
+ } else if (propName === "style") overrideProps[propName] = {
98
+ ...slotPropValue,
99
+ ...childPropValue
100
+ };
101
+ else if (propName === "className") overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
102
+ }
103
+ return {
104
+ ...slotProps,
105
+ ...overrideProps
106
+ };
107
+ }
108
+ function getElementRef(element) {
109
+ let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
110
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
111
+ if (mayWarn) return element.ref;
112
+ getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
113
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
114
+ if (mayWarn) return element.props.ref;
115
+ return element.props.ref || element.ref;
116
+ }
117
+ function isSlottable(child) {
118
+ return React$1.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
119
+ }
120
+ var REACT_LAZY_TYPE = Symbol.for("react.lazy");
121
+ function isLazyComponent(element) {
122
+ return element != null && typeof element === "object" && "$$typeof" in element && element.$$typeof === REACT_LAZY_TYPE && "_payload" in element && isPromiseLike(element._payload);
123
+ }
124
+ function isPromiseLike(value) {
125
+ return typeof value === "object" && value !== null && "then" in value;
126
+ }
127
+ var createSlotError = (ownerName) => {
128
+ return `${ownerName} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`;
129
+ };
130
+ var createSlottableError = (ownerName) => {
131
+ return `${ownerName} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`;
132
+ };
133
+ var use = React$1[" use ".trim().toString()];
134
+ //#endregion
135
+ //#region ../../node_modules/.pnpm/clsx@2.0.0/node_modules/clsx/dist/clsx.mjs
136
+ function r$1(e) {
137
+ var t, f, n = "";
138
+ if ("string" == typeof e || "number" == typeof e) n += e;
139
+ 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);
140
+ else for (t in e) e[t] && (n && (n += " "), n += t);
141
+ return n;
142
+ }
143
+ function clsx() {
144
+ for (var e, t, f = 0, n = ""; f < arguments.length;) (e = arguments[f++]) && (t = r$1(e)) && (n && (n += " "), n += t);
145
+ return n;
146
+ }
147
+ //#endregion
148
+ //#region ../../node_modules/.pnpm/class-variance-authority@0.7.0/node_modules/class-variance-authority/dist/index.mjs
149
+ const falsyToString = (value) => typeof value === "boolean" ? "".concat(value) : value === 0 ? "0" : value;
150
+ const cx = clsx;
151
+ const cva = (base, config) => {
152
+ return (props) => {
153
+ var ref;
154
+ 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);
155
+ const { variants, defaultVariants } = config;
156
+ const getVariantClassNames = Object.keys(variants).map((variant) => {
157
+ const variantProp = props === null || props === void 0 ? void 0 : props[variant];
158
+ const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
159
+ if (variantProp === null) return null;
160
+ const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
161
+ return variants[variant][variantKey];
162
+ });
163
+ const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
164
+ let [key, value] = param;
165
+ if (value === void 0) return acc;
166
+ acc[key] = value;
167
+ return acc;
168
+ }, {});
169
+ const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (ref = config.compoundVariants) === null || ref === void 0 ? void 0 : ref.reduce((acc, param1) => {
170
+ let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param1;
171
+ return Object.entries(compoundVariantOptions).every((param) => {
172
+ let [key, value] = param;
173
+ return Array.isArray(value) ? value.includes({
174
+ ...defaultVariants,
175
+ ...propsWithoutUndefined
176
+ }[key]) : {
177
+ ...defaultVariants,
178
+ ...propsWithoutUndefined
179
+ }[key] === value;
180
+ }) ? [
181
+ ...acc,
182
+ cvClass,
183
+ cvClassName
184
+ ] : acc;
185
+ }, []);
186
+ return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
187
+ };
188
+ };
189
+ //#endregion
190
+ //#region ../../node_modules/.pnpm/react-hook-form@7.71.2_react@19.2.6/node_modules/react-hook-form/dist/index.esm.mjs
191
+ var isCheckBoxInput = (element) => element.type === "checkbox";
192
+ var isDateObject = (value) => value instanceof Date;
193
+ var isNullOrUndefined = (value) => value == null;
194
+ const isObjectType$1 = (value) => typeof value === "object";
195
+ var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType$1(value) && !isDateObject(value);
196
+ var getEventValue = (event) => isObject(event) && event.target ? isCheckBoxInput(event.target) ? event.target.checked : event.target.value : event;
197
+ var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
198
+ var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
199
+ var isPlainObject = (tempObject) => {
200
+ const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
201
+ return isObject(prototypeCopy) && prototypeCopy.hasOwnProperty("isPrototypeOf");
202
+ };
203
+ var isWeb = typeof window !== "undefined" && typeof window.HTMLElement !== "undefined" && typeof document !== "undefined";
204
+ function cloneObject(data) {
205
+ if (data instanceof Date) return new Date(data);
206
+ const isFileListInstance = typeof FileList !== "undefined" && data instanceof FileList;
207
+ if (isWeb && (data instanceof Blob || isFileListInstance)) return data;
208
+ const isArray = Array.isArray(data);
209
+ if (!isArray && !(isObject(data) && isPlainObject(data))) return data;
210
+ const copy = isArray ? [] : Object.create(Object.getPrototypeOf(data));
211
+ for (const key in data) if (Object.prototype.hasOwnProperty.call(data, key)) copy[key] = cloneObject(data[key]);
212
+ return copy;
213
+ }
214
+ var isKey = (value) => /^\w*$/.test(value);
215
+ var isUndefined = (val) => val === void 0;
216
+ var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
217
+ var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/));
218
+ var get = (object, path, defaultValue) => {
219
+ if (!path || !isObject(object)) return defaultValue;
220
+ const result = (isKey(path) ? [path] : stringToPath(path)).reduce((result, key) => isNullOrUndefined(result) ? result : result[key], object);
221
+ return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
222
+ };
223
+ var isBoolean = (value) => typeof value === "boolean";
224
+ var isFunction = (value) => typeof value === "function";
225
+ var set = (object, path, value) => {
226
+ let index = -1;
227
+ const tempPath = isKey(path) ? [path] : stringToPath(path);
228
+ const length = tempPath.length;
229
+ const lastIndex = length - 1;
230
+ while (++index < length) {
231
+ const key = tempPath[index];
232
+ let newValue = value;
233
+ if (index !== lastIndex) {
234
+ const objValue = object[key];
235
+ newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) ? [] : {};
236
+ }
237
+ if (key === "__proto__" || key === "constructor" || key === "prototype") return;
238
+ object[key] = newValue;
239
+ object = object[key];
240
+ }
241
+ };
242
+ const EVENTS = {
243
+ BLUR: "blur",
244
+ FOCUS_OUT: "focusout",
245
+ CHANGE: "change"
246
+ };
247
+ const VALIDATION_MODE = {
248
+ onBlur: "onBlur",
249
+ onChange: "onChange",
250
+ onSubmit: "onSubmit",
251
+ onTouched: "onTouched",
252
+ all: "all"
253
+ };
254
+ const INPUT_VALIDATION_RULES = {
255
+ max: "max",
256
+ min: "min",
257
+ maxLength: "maxLength",
258
+ minLength: "minLength",
259
+ pattern: "pattern",
260
+ required: "required",
261
+ validate: "validate"
262
+ };
263
+ /**
264
+ * Separate context for `control` to prevent unnecessary rerenders.
265
+ * Internal hooks that only need control use this instead of full form context.
266
+ */
267
+ const HookFormControlContext = React.createContext(null);
268
+ HookFormControlContext.displayName = "HookFormControlContext";
269
+ /**
270
+ * @internal Internal hook to access only control from context.
271
+ */
272
+ const useFormControlContext = () => React.useContext(HookFormControlContext);
273
+ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
274
+ const result = { defaultValues: control._defaultValues };
275
+ for (const key in formState) Object.defineProperty(result, key, { get: () => {
276
+ const _key = key;
277
+ if (control._proxyFormState[_key] !== VALIDATION_MODE.all) control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
278
+ localProxyFormState && (localProxyFormState[_key] = true);
279
+ return formState[_key];
280
+ } });
281
+ return result;
282
+ };
283
+ const useIsomorphicLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
284
+ /**
285
+ * 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.
286
+ *
287
+ * @remarks
288
+ * [API](https://react-hook-form.com/docs/useformstate) • [Demo](https://codesandbox.io/s/useformstate-75xly)
289
+ *
290
+ * @param props - include options on specify fields to subscribe. {@link UseFormStateReturn}
291
+ *
292
+ * @example
293
+ * ```tsx
294
+ * function App() {
295
+ * const { register, handleSubmit, control } = useForm({
296
+ * defaultValues: {
297
+ * firstName: "firstName"
298
+ * }});
299
+ * const { dirtyFields } = useFormState({
300
+ * control
301
+ * });
302
+ * const onSubmit = (data) => console.log(data);
303
+ *
304
+ * return (
305
+ * <form onSubmit={handleSubmit(onSubmit)}>
306
+ * <input {...register("firstName")} placeholder="First Name" />
307
+ * {dirtyFields.firstName && <p>Field is dirty.</p>}
308
+ * <input type="submit" />
309
+ * </form>
310
+ * );
311
+ * }
312
+ * ```
313
+ */
314
+ function useFormState(props) {
315
+ const formControl = useFormControlContext();
316
+ const { control = formControl, disabled, name, exact } = props || {};
317
+ const [formState, updateFormState] = React.useState(control._formState);
318
+ const _localProxyFormState = React.useRef({
319
+ isDirty: false,
320
+ isLoading: false,
321
+ dirtyFields: false,
322
+ touchedFields: false,
323
+ validatingFields: false,
324
+ isValidating: false,
325
+ isValid: false,
326
+ errors: false
327
+ });
328
+ useIsomorphicLayoutEffect(() => control._subscribe({
329
+ name,
330
+ formState: _localProxyFormState.current,
331
+ exact,
332
+ callback: (formState) => {
333
+ !disabled && updateFormState({
334
+ ...control._formState,
335
+ ...formState
336
+ });
337
+ }
338
+ }), [
339
+ name,
340
+ disabled,
341
+ exact
342
+ ]);
343
+ React.useEffect(() => {
344
+ _localProxyFormState.current.isValid && control._setValid(true);
345
+ }, [control]);
346
+ return React.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
347
+ }
348
+ var isString = (value) => typeof value === "string";
349
+ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
350
+ if (isString(names)) {
351
+ isGlobal && _names.watch.add(names);
352
+ return get(formValues, names, defaultValue);
353
+ }
354
+ if (Array.isArray(names)) return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName), get(formValues, fieldName)));
355
+ isGlobal && (_names.watchAll = true);
356
+ return formValues;
357
+ };
358
+ var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType$1(value);
359
+ function deepEqual(object1, object2, _internal_visited = /* @__PURE__ */ new WeakSet()) {
360
+ if (isPrimitive(object1) || isPrimitive(object2)) return Object.is(object1, object2);
361
+ if (isDateObject(object1) && isDateObject(object2)) return Object.is(object1.getTime(), object2.getTime());
362
+ const keys1 = Object.keys(object1);
363
+ const keys2 = Object.keys(object2);
364
+ if (keys1.length !== keys2.length) return false;
365
+ if (_internal_visited.has(object1) || _internal_visited.has(object2)) return true;
366
+ _internal_visited.add(object1);
367
+ _internal_visited.add(object2);
368
+ for (const key of keys1) {
369
+ const val1 = object1[key];
370
+ if (!keys2.includes(key)) return false;
371
+ if (key !== "ref") {
372
+ const val2 = object2[key];
373
+ 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;
374
+ }
375
+ }
376
+ return true;
377
+ }
378
+ /**
379
+ * Custom hook to subscribe to field change and isolate re-rendering at the component level.
380
+ *
381
+ * @remarks
382
+ *
383
+ * [API](https://react-hook-form.com/docs/usewatch) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-usewatch-h9i5e)
384
+ *
385
+ * @example
386
+ * ```tsx
387
+ * const { control } = useForm();
388
+ * const values = useWatch({
389
+ * name: "fieldName"
390
+ * control,
391
+ * })
392
+ * ```
393
+ */
394
+ function useWatch(props) {
395
+ const formControl = useFormControlContext();
396
+ const { control = formControl, name, defaultValue, disabled, exact, compute } = props || {};
397
+ const _defaultValue = React.useRef(defaultValue);
398
+ const _compute = React.useRef(compute);
399
+ const _computeFormValues = React.useRef(void 0);
400
+ const _prevControl = React.useRef(control);
401
+ const _prevName = React.useRef(name);
402
+ _compute.current = compute;
403
+ const [value, updateValue] = React.useState(() => {
404
+ const defaultValue = control._getWatch(name, _defaultValue.current);
405
+ return _compute.current ? _compute.current(defaultValue) : defaultValue;
406
+ });
407
+ const getCurrentOutput = React.useCallback((values) => {
408
+ const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
409
+ return _compute.current ? _compute.current(formValues) : formValues;
410
+ }, [
411
+ control._formValues,
412
+ control._names,
413
+ name
414
+ ]);
415
+ const refreshValue = React.useCallback((values) => {
416
+ if (!disabled) {
417
+ const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
418
+ if (_compute.current) {
419
+ const computedFormValues = _compute.current(formValues);
420
+ if (!deepEqual(computedFormValues, _computeFormValues.current)) {
421
+ updateValue(computedFormValues);
422
+ _computeFormValues.current = computedFormValues;
423
+ }
424
+ } else updateValue(formValues);
425
+ }
426
+ }, [
427
+ control._formValues,
428
+ control._names,
429
+ disabled,
430
+ name
431
+ ]);
432
+ useIsomorphicLayoutEffect(() => {
433
+ if (_prevControl.current !== control || !deepEqual(_prevName.current, name)) {
434
+ _prevControl.current = control;
435
+ _prevName.current = name;
436
+ refreshValue();
437
+ }
438
+ return control._subscribe({
439
+ name,
440
+ formState: { values: true },
441
+ exact,
442
+ callback: (formState) => {
443
+ refreshValue(formState.values);
444
+ }
445
+ });
446
+ }, [
447
+ control,
448
+ exact,
449
+ name,
450
+ refreshValue
451
+ ]);
452
+ React.useEffect(() => control._removeUnmounted());
453
+ const controlChanged = _prevControl.current !== control;
454
+ const prevName = _prevName.current;
455
+ const computedOutput = React.useMemo(() => {
456
+ if (disabled) return null;
457
+ const nameChanged = !controlChanged && !deepEqual(prevName, name);
458
+ return controlChanged || nameChanged ? getCurrentOutput() : null;
459
+ }, [
460
+ disabled,
461
+ controlChanged,
462
+ name,
463
+ prevName,
464
+ getCurrentOutput
465
+ ]);
466
+ return computedOutput !== null ? computedOutput : value;
467
+ }
468
+ /**
469
+ * 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.
470
+ *
471
+ * @remarks
472
+ * [API](https://react-hook-form.com/docs/usecontroller) • [Demo](https://codesandbox.io/s/usecontroller-0o8px)
473
+ *
474
+ * @param props - the path name to the form field value, and validation rules.
475
+ *
476
+ * @returns field properties, field and form state. {@link UseControllerReturn}
477
+ *
478
+ * @example
479
+ * ```tsx
480
+ * function Input(props) {
481
+ * const { field, fieldState, formState } = useController(props);
482
+ * return (
483
+ * <div>
484
+ * <input {...field} placeholder={props.name} />
485
+ * <p>{fieldState.isTouched && "Touched"}</p>
486
+ * <p>{formState.isSubmitted ? "submitted" : ""}</p>
487
+ * </div>
488
+ * );
489
+ * }
490
+ * ```
491
+ */
492
+ function useController(props) {
493
+ const formControl = useFormControlContext();
494
+ const { name, disabled, control = formControl, shouldUnregister, defaultValue, exact = true } = props;
495
+ const isArrayField = isNameInFieldArray(control._names.array, name);
496
+ const value = useWatch({
497
+ control,
498
+ name,
499
+ defaultValue: React.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [
500
+ control,
501
+ name,
502
+ defaultValue
503
+ ]),
504
+ exact
505
+ });
506
+ const formState = useFormState({
507
+ control,
508
+ name,
509
+ exact
510
+ });
511
+ const _props = React.useRef(props);
512
+ const _previousNameRef = React.useRef(void 0);
513
+ const _registerProps = React.useRef(control.register(name, {
514
+ ...props.rules,
515
+ value,
516
+ ...isBoolean(props.disabled) ? { disabled: props.disabled } : {}
517
+ }));
518
+ _props.current = props;
519
+ const fieldState = React.useMemo(() => Object.defineProperties({}, {
520
+ invalid: {
521
+ enumerable: true,
522
+ get: () => !!get(formState.errors, name)
523
+ },
524
+ isDirty: {
525
+ enumerable: true,
526
+ get: () => !!get(formState.dirtyFields, name)
527
+ },
528
+ isTouched: {
529
+ enumerable: true,
530
+ get: () => !!get(formState.touchedFields, name)
531
+ },
532
+ isValidating: {
533
+ enumerable: true,
534
+ get: () => !!get(formState.validatingFields, name)
535
+ },
536
+ error: {
537
+ enumerable: true,
538
+ get: () => get(formState.errors, name)
539
+ }
540
+ }), [formState, name]);
541
+ const onChange = React.useCallback((event) => _registerProps.current.onChange({
542
+ target: {
543
+ value: getEventValue(event),
544
+ name
545
+ },
546
+ type: EVENTS.CHANGE
547
+ }), [name]);
548
+ const onBlur = React.useCallback(() => _registerProps.current.onBlur({
549
+ target: {
550
+ value: get(control._formValues, name),
551
+ name
552
+ },
553
+ type: EVENTS.BLUR
554
+ }), [name, control._formValues]);
555
+ const ref = React.useCallback((elm) => {
556
+ const field = get(control._fields, name);
557
+ if (field && field._f && elm) field._f.ref = {
558
+ focus: () => isFunction(elm.focus) && elm.focus(),
559
+ select: () => isFunction(elm.select) && elm.select(),
560
+ setCustomValidity: (message) => isFunction(elm.setCustomValidity) && elm.setCustomValidity(message),
561
+ reportValidity: () => isFunction(elm.reportValidity) && elm.reportValidity()
562
+ };
563
+ }, [control._fields, name]);
564
+ const field = React.useMemo(() => ({
565
+ name,
566
+ value,
567
+ ...isBoolean(disabled) || formState.disabled ? { disabled: formState.disabled || disabled } : {},
568
+ onChange,
569
+ onBlur,
570
+ ref
571
+ }), [
572
+ name,
573
+ disabled,
574
+ formState.disabled,
575
+ onChange,
576
+ onBlur,
577
+ ref,
578
+ value
579
+ ]);
580
+ React.useEffect(() => {
581
+ const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
582
+ const previousName = _previousNameRef.current;
583
+ if (previousName && previousName !== name && !isArrayField) control.unregister(previousName);
584
+ control.register(name, {
585
+ ..._props.current.rules,
586
+ ...isBoolean(_props.current.disabled) ? { disabled: _props.current.disabled } : {}
587
+ });
588
+ const updateMounted = (name, value) => {
589
+ const field = get(control._fields, name);
590
+ if (field && field._f) field._f.mount = value;
591
+ };
592
+ updateMounted(name, true);
593
+ if (_shouldUnregisterField) {
594
+ const value = cloneObject(get(control._options.defaultValues, name, _props.current.defaultValue));
595
+ set(control._defaultValues, name, value);
596
+ if (isUndefined(get(control._formValues, name))) set(control._formValues, name, value);
597
+ }
598
+ !isArrayField && control.register(name);
599
+ _previousNameRef.current = name;
600
+ return () => {
601
+ (isArrayField ? _shouldUnregisterField && !control._state.action : _shouldUnregisterField) ? control.unregister(name) : updateMounted(name, false);
602
+ };
603
+ }, [
604
+ name,
605
+ control,
606
+ isArrayField,
607
+ shouldUnregister
608
+ ]);
609
+ React.useEffect(() => {
610
+ control._setDisabledField({
611
+ disabled,
612
+ name
613
+ });
614
+ }, [
615
+ disabled,
616
+ name,
617
+ control
618
+ ]);
619
+ return React.useMemo(() => ({
620
+ field,
621
+ formState,
622
+ fieldState
623
+ }), [
624
+ field,
625
+ formState,
626
+ fieldState
627
+ ]);
628
+ }
629
+ /**
630
+ * Component based on `useController` hook to work with controlled component.
631
+ *
632
+ * @remarks
633
+ * [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)
634
+ *
635
+ * @param props - the path name to the form field value, and validation rules.
636
+ *
637
+ * @returns provide field handler functions, field and form state.
638
+ *
639
+ * @example
640
+ * ```tsx
641
+ * function App() {
642
+ * const { control } = useForm<FormValues>({
643
+ * defaultValues: {
644
+ * test: ""
645
+ * }
646
+ * });
647
+ *
648
+ * return (
649
+ * <form>
650
+ * <Controller
651
+ * control={control}
652
+ * name="test"
653
+ * render={({ field: { onChange, onBlur, value, ref }, formState, fieldState }) => (
654
+ * <>
655
+ * <input
656
+ * onChange={onChange} // send value to hook form
657
+ * onBlur={onBlur} // notify when input is touched
658
+ * value={value} // return updated value
659
+ * ref={ref} // set ref for focus management
660
+ * />
661
+ * <p>{formState.isSubmitted ? "submitted" : ""}</p>
662
+ * <p>{fieldState.isTouched ? "touched" : ""}</p>
663
+ * </>
664
+ * )}
665
+ * />
666
+ * </form>
667
+ * );
668
+ * }
669
+ * ```
670
+ */
671
+ const Controller = (props) => props.render(useController(props));
672
+ const HookFormContext = React.createContext(null);
673
+ HookFormContext.displayName = "HookFormContext";
674
+ /**
675
+ * 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}.
676
+ *
677
+ * @remarks
678
+ * [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
679
+ *
680
+ * @returns return all useForm methods
681
+ *
682
+ * @example
683
+ * ```tsx
684
+ * function App() {
685
+ * const methods = useForm();
686
+ * const onSubmit = data => console.log(data);
687
+ *
688
+ * return (
689
+ * <FormProvider {...methods} >
690
+ * <form onSubmit={methods.handleSubmit(onSubmit)}>
691
+ * <NestedInput />
692
+ * <input type="submit" />
693
+ * </form>
694
+ * </FormProvider>
695
+ * );
696
+ * }
697
+ *
698
+ * function NestedInput() {
699
+ * const { register } = useFormContext(); // retrieve all hook methods
700
+ * return <input {...register("test")} />;
701
+ * }
702
+ * ```
703
+ */
704
+ const useFormContext = () => React.useContext(HookFormContext);
705
+ /**
706
+ * 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}.
707
+ *
708
+ * @remarks
709
+ * [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
710
+ *
711
+ * @param props - all useForm methods
712
+ *
713
+ * @example
714
+ * ```tsx
715
+ * function App() {
716
+ * const methods = useForm();
717
+ * const onSubmit = data => console.log(data);
718
+ *
719
+ * return (
720
+ * <FormProvider {...methods} >
721
+ * <form onSubmit={methods.handleSubmit(onSubmit)}>
722
+ * <NestedInput />
723
+ * <input type="submit" />
724
+ * </form>
725
+ * </FormProvider>
726
+ * );
727
+ * }
728
+ *
729
+ * function NestedInput() {
730
+ * const { register } = useFormContext(); // retrieve all hook methods
731
+ * return <input {...register("test")} />;
732
+ * }
733
+ * ```
734
+ */
735
+ const FormProvider = (props) => {
736
+ const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe } = props;
737
+ return React.createElement(HookFormContext.Provider, { value: React.useMemo(() => ({
738
+ watch,
739
+ getValues,
740
+ getFieldState,
741
+ setError,
742
+ clearErrors,
743
+ setValue,
744
+ trigger,
745
+ formState,
746
+ resetField,
747
+ reset,
748
+ handleSubmit,
749
+ unregister,
750
+ control,
751
+ register,
752
+ setFocus,
753
+ subscribe
754
+ }), [
755
+ clearErrors,
756
+ control,
757
+ formState,
758
+ getFieldState,
759
+ getValues,
760
+ handleSubmit,
761
+ register,
762
+ reset,
763
+ resetField,
764
+ setError,
765
+ setFocus,
766
+ setValue,
767
+ subscribe,
768
+ trigger,
769
+ unregister,
770
+ watch
771
+ ]) }, React.createElement(HookFormControlContext.Provider, { value: control }, children));
772
+ };
773
+ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria ? {
774
+ ...errors[name],
775
+ types: {
776
+ ...errors[name] && errors[name].types ? errors[name].types : {},
777
+ [type]: message || true
778
+ }
779
+ } : {};
780
+ var convertToArrayPayload = (value) => Array.isArray(value) ? value : [value];
781
+ var createSubject = () => {
782
+ let _observers = [];
783
+ const next = (value) => {
784
+ for (const observer of _observers) observer.next && observer.next(value);
785
+ };
786
+ const subscribe = (observer) => {
787
+ _observers.push(observer);
788
+ return { unsubscribe: () => {
789
+ _observers = _observers.filter((o) => o !== observer);
790
+ } };
791
+ };
792
+ const unsubscribe = () => {
793
+ _observers = [];
794
+ };
795
+ return {
796
+ get observers() {
797
+ return _observers;
798
+ },
799
+ next,
800
+ subscribe,
801
+ unsubscribe
802
+ };
803
+ };
804
+ function extractFormValues(fieldsState, formValues) {
805
+ const values = {};
806
+ for (const key in fieldsState) if (fieldsState.hasOwnProperty(key)) {
807
+ const fieldState = fieldsState[key];
808
+ const fieldValue = formValues[key];
809
+ if (fieldState && isObject(fieldState) && fieldValue) {
810
+ const nestedFieldsState = extractFormValues(fieldState, fieldValue);
811
+ if (isObject(nestedFieldsState)) values[key] = nestedFieldsState;
812
+ } else if (fieldsState[key]) values[key] = fieldValue;
813
+ }
814
+ return values;
815
+ }
816
+ var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
817
+ var isFileInput = (element) => element.type === "file";
818
+ var isHTMLElement = (value) => {
819
+ if (!isWeb) return false;
820
+ const owner = value ? value.ownerDocument : 0;
821
+ return value instanceof (owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement);
822
+ };
823
+ var isMultipleSelect = (element) => element.type === `select-multiple`;
824
+ var isRadioInput = (element) => element.type === "radio";
825
+ var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
826
+ var live = (ref) => isHTMLElement(ref) && ref.isConnected;
827
+ function baseGet(object, updatePath) {
828
+ const length = updatePath.slice(0, -1).length;
829
+ let index = 0;
830
+ while (index < length) object = isUndefined(object) ? index++ : object[updatePath[index++]];
831
+ return object;
832
+ }
833
+ function isEmptyArray(obj) {
834
+ for (const key in obj) if (obj.hasOwnProperty(key) && !isUndefined(obj[key])) return false;
835
+ return true;
836
+ }
837
+ function unset(object, path) {
838
+ const paths = Array.isArray(path) ? path : isKey(path) ? [path] : stringToPath(path);
839
+ const childObject = paths.length === 1 ? object : baseGet(object, paths);
840
+ const index = paths.length - 1;
841
+ const key = paths[index];
842
+ if (childObject) delete childObject[key];
843
+ if (index !== 0 && (isObject(childObject) && isEmptyObject(childObject) || Array.isArray(childObject) && isEmptyArray(childObject))) unset(object, paths.slice(0, -1));
844
+ return object;
845
+ }
846
+ var objectHasFunction = (data) => {
847
+ for (const key in data) if (isFunction(data[key])) return true;
848
+ return false;
849
+ };
850
+ function isTraversable(value) {
851
+ return Array.isArray(value) || isObject(value) && !objectHasFunction(value);
852
+ }
853
+ function markFieldsDirty(data, fields = {}) {
854
+ for (const key in data) {
855
+ const value = data[key];
856
+ if (isTraversable(value)) {
857
+ fields[key] = Array.isArray(value) ? [] : {};
858
+ markFieldsDirty(value, fields[key]);
859
+ } else if (!isUndefined(value)) fields[key] = true;
860
+ }
861
+ return fields;
862
+ }
863
+ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
864
+ if (!dirtyFieldsFromValues) dirtyFieldsFromValues = markFieldsDirty(formValues);
865
+ for (const key in data) {
866
+ const value = data[key];
867
+ if (isTraversable(value)) {
868
+ if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {});
869
+ else getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
870
+ } else {
871
+ const formValue = formValues[key];
872
+ dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
873
+ }
874
+ }
875
+ return dirtyFieldsFromValues;
876
+ }
877
+ const defaultResult = {
878
+ value: false,
879
+ isValid: false
880
+ };
881
+ const validResult = {
882
+ value: true,
883
+ isValid: true
884
+ };
885
+ var getCheckboxValue = (options) => {
886
+ if (Array.isArray(options)) {
887
+ if (options.length > 1) {
888
+ const values = options.filter((option) => option && option.checked && !option.disabled).map((option) => option.value);
889
+ return {
890
+ value: values,
891
+ isValid: !!values.length
892
+ };
893
+ }
894
+ return options[0].checked && !options[0].disabled ? options[0].attributes && !isUndefined(options[0].attributes.value) ? isUndefined(options[0].value) || options[0].value === "" ? validResult : {
895
+ value: options[0].value,
896
+ isValid: true
897
+ } : validResult : defaultResult;
898
+ }
899
+ return defaultResult;
900
+ };
901
+ 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;
902
+ const defaultReturn = {
903
+ isValid: false,
904
+ value: null
905
+ };
906
+ var getRadioValue = (options) => Array.isArray(options) ? options.reduce((previous, option) => option && option.checked && !option.disabled ? {
907
+ isValid: true,
908
+ value: option.value
909
+ } : previous, defaultReturn) : defaultReturn;
910
+ function getFieldValue(_f) {
911
+ const ref = _f.ref;
912
+ if (isFileInput(ref)) return ref.files;
913
+ if (isRadioInput(ref)) return getRadioValue(_f.refs).value;
914
+ if (isMultipleSelect(ref)) return [...ref.selectedOptions].map(({ value }) => value);
915
+ if (isCheckBoxInput(ref)) return getCheckboxValue(_f.refs).value;
916
+ return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
917
+ }
918
+ var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
919
+ const fields = {};
920
+ for (const name of fieldsNames) {
921
+ const field = get(_fields, name);
922
+ field && set(fields, name, field._f);
923
+ }
924
+ return {
925
+ criteriaMode,
926
+ names: [...fieldsNames],
927
+ fields,
928
+ shouldUseNativeValidation
929
+ };
930
+ };
931
+ var isRegex = (value) => value instanceof RegExp;
932
+ var getRuleValue = (rule) => isUndefined(rule) ? rule : isRegex(rule) ? rule.source : isObject(rule) ? isRegex(rule.value) ? rule.value.source : rule.value : rule;
933
+ var getValidationModes = (mode) => ({
934
+ isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
935
+ isOnBlur: mode === VALIDATION_MODE.onBlur,
936
+ isOnChange: mode === VALIDATION_MODE.onChange,
937
+ isOnAll: mode === VALIDATION_MODE.all,
938
+ isOnTouch: mode === VALIDATION_MODE.onTouched
939
+ });
940
+ const ASYNC_FUNCTION = "AsyncFunction";
941
+ 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));
942
+ var hasValidation = (options) => options.mount && (options.required || options.min || options.max || options.maxLength || options.minLength || options.pattern || options.validate);
943
+ 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))));
944
+ const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
945
+ for (const key of fieldsNames || Object.keys(fields)) {
946
+ const field = get(fields, key);
947
+ if (field) {
948
+ const { _f, ...currentField } = field;
949
+ if (_f) {
950
+ if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) return true;
951
+ else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) return true;
952
+ else if (iterateFieldsByAction(currentField, action)) break;
953
+ } else if (isObject(currentField)) {
954
+ if (iterateFieldsByAction(currentField, action)) break;
955
+ }
956
+ }
957
+ }
958
+ };
959
+ function schemaErrorLookup(errors, _fields, name) {
960
+ const error = get(errors, name);
961
+ if (error || isKey(name)) return {
962
+ error,
963
+ name
964
+ };
965
+ const names = name.split(".");
966
+ while (names.length) {
967
+ const fieldName = names.join(".");
968
+ const field = get(_fields, fieldName);
969
+ const foundError = get(errors, fieldName);
970
+ if (field && !Array.isArray(field) && name !== fieldName) return { name };
971
+ if (foundError && foundError.type) return {
972
+ name: fieldName,
973
+ error: foundError
974
+ };
975
+ if (foundError && foundError.root && foundError.root.type) return {
976
+ name: `${fieldName}.root`,
977
+ error: foundError.root
978
+ };
979
+ names.pop();
980
+ }
981
+ return { name };
982
+ }
983
+ var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
984
+ updateFormState(formStateData);
985
+ const { name, ...formState } = formStateData;
986
+ return isEmptyObject(formState) || Object.keys(formState).length >= Object.keys(_proxyFormState).length || Object.keys(formState).find((key) => _proxyFormState[key] === (!isRoot || VALIDATION_MODE.all));
987
+ };
988
+ var shouldSubscribeByName = (name, signalName, exact) => !name || !signalName || name === signalName || convertToArrayPayload(name).some((currentName) => currentName && (exact ? currentName === signalName : currentName.startsWith(signalName) || signalName.startsWith(currentName)));
989
+ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode) => {
990
+ if (mode.isOnAll) return false;
991
+ else if (!isSubmitted && mode.isOnTouch) return !(isTouched || isBlurEvent);
992
+ else if (isSubmitted ? reValidateMode.isOnBlur : mode.isOnBlur) return !isBlurEvent;
993
+ else if (isSubmitted ? reValidateMode.isOnChange : mode.isOnChange) return isBlurEvent;
994
+ return true;
995
+ };
996
+ var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
997
+ var updateFieldArrayRootError = (errors, error, name) => {
998
+ const fieldArrayErrors = convertToArrayPayload(get(errors, name));
999
+ set(fieldArrayErrors, "root", error[name]);
1000
+ set(errors, name, fieldArrayErrors);
1001
+ return errors;
1002
+ };
1003
+ function getValidateError(result, ref, type = "validate") {
1004
+ if (isString(result) || Array.isArray(result) && result.every(isString) || isBoolean(result) && !result) return {
1005
+ type,
1006
+ message: isString(result) ? result : "",
1007
+ ref
1008
+ };
1009
+ }
1010
+ var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData) ? validationData : {
1011
+ value: validationData,
1012
+ message: ""
1013
+ };
1014
+ var validateField = async (field, disabledFieldNames, formValues, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
1015
+ const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount } = field._f;
1016
+ const inputValue = get(formValues, name);
1017
+ if (!mount || disabledFieldNames.has(name)) return {};
1018
+ const inputRef = refs ? refs[0] : ref;
1019
+ const setCustomValidity = (message) => {
1020
+ if (shouldUseNativeValidation && inputRef.reportValidity) {
1021
+ inputRef.setCustomValidity(isBoolean(message) ? "" : message || "");
1022
+ inputRef.reportValidity();
1023
+ }
1024
+ };
1025
+ const error = {};
1026
+ const isRadio = isRadioInput(ref);
1027
+ const isCheckBox = isCheckBoxInput(ref);
1028
+ const isRadioOrCheckbox = isRadio || isCheckBox;
1029
+ const isEmpty = (valueAsNumber || isFileInput(ref)) && isUndefined(ref.value) && isUndefined(inputValue) || isHTMLElement(ref) && ref.value === "" || inputValue === "" || Array.isArray(inputValue) && !inputValue.length;
1030
+ const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
1031
+ const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
1032
+ const message = exceedMax ? maxLengthMessage : minLengthMessage;
1033
+ error[name] = {
1034
+ type: exceedMax ? maxType : minType,
1035
+ message,
1036
+ ref,
1037
+ ...appendErrorsCurry(exceedMax ? maxType : minType, message)
1038
+ };
1039
+ };
1040
+ if (isFieldArray ? !Array.isArray(inputValue) || !inputValue.length : required && (!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue)) || isBoolean(inputValue) && !inputValue || isCheckBox && !getCheckboxValue(refs).isValid || isRadio && !getRadioValue(refs).isValid)) {
1041
+ const { value, message } = isString(required) ? {
1042
+ value: !!required,
1043
+ message: required
1044
+ } : getValueAndMessage(required);
1045
+ if (value) {
1046
+ error[name] = {
1047
+ type: INPUT_VALIDATION_RULES.required,
1048
+ message,
1049
+ ref: inputRef,
1050
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message)
1051
+ };
1052
+ if (!validateAllFieldCriteria) {
1053
+ setCustomValidity(message);
1054
+ return error;
1055
+ }
1056
+ }
1057
+ }
1058
+ if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
1059
+ let exceedMax;
1060
+ let exceedMin;
1061
+ const maxOutput = getValueAndMessage(max);
1062
+ const minOutput = getValueAndMessage(min);
1063
+ if (!isNullOrUndefined(inputValue) && !isNaN(inputValue)) {
1064
+ const valueNumber = ref.valueAsNumber || (inputValue ? +inputValue : inputValue);
1065
+ if (!isNullOrUndefined(maxOutput.value)) exceedMax = valueNumber > maxOutput.value;
1066
+ if (!isNullOrUndefined(minOutput.value)) exceedMin = valueNumber < minOutput.value;
1067
+ } else {
1068
+ const valueDate = ref.valueAsDate || new Date(inputValue);
1069
+ const convertTimeToDate = (time) => /* @__PURE__ */ new Date((/* @__PURE__ */ new Date()).toDateString() + " " + time);
1070
+ const isTime = ref.type == "time";
1071
+ const isWeek = ref.type == "week";
1072
+ if (isString(maxOutput.value) && inputValue) exceedMax = isTime ? convertTimeToDate(inputValue) > convertTimeToDate(maxOutput.value) : isWeek ? inputValue > maxOutput.value : valueDate > new Date(maxOutput.value);
1073
+ if (isString(minOutput.value) && inputValue) exceedMin = isTime ? convertTimeToDate(inputValue) < convertTimeToDate(minOutput.value) : isWeek ? inputValue < minOutput.value : valueDate < new Date(minOutput.value);
1074
+ }
1075
+ if (exceedMax || exceedMin) {
1076
+ getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
1077
+ if (!validateAllFieldCriteria) {
1078
+ setCustomValidity(error[name].message);
1079
+ return error;
1080
+ }
1081
+ }
1082
+ }
1083
+ if ((maxLength || minLength) && !isEmpty && (isString(inputValue) || isFieldArray && Array.isArray(inputValue))) {
1084
+ const maxLengthOutput = getValueAndMessage(maxLength);
1085
+ const minLengthOutput = getValueAndMessage(minLength);
1086
+ const exceedMax = !isNullOrUndefined(maxLengthOutput.value) && inputValue.length > +maxLengthOutput.value;
1087
+ const exceedMin = !isNullOrUndefined(minLengthOutput.value) && inputValue.length < +minLengthOutput.value;
1088
+ if (exceedMax || exceedMin) {
1089
+ getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
1090
+ if (!validateAllFieldCriteria) {
1091
+ setCustomValidity(error[name].message);
1092
+ return error;
1093
+ }
1094
+ }
1095
+ }
1096
+ if (pattern && !isEmpty && isString(inputValue)) {
1097
+ const { value: patternValue, message } = getValueAndMessage(pattern);
1098
+ if (isRegex(patternValue) && !inputValue.match(patternValue)) {
1099
+ error[name] = {
1100
+ type: INPUT_VALIDATION_RULES.pattern,
1101
+ message,
1102
+ ref,
1103
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message)
1104
+ };
1105
+ if (!validateAllFieldCriteria) {
1106
+ setCustomValidity(message);
1107
+ return error;
1108
+ }
1109
+ }
1110
+ }
1111
+ if (validate) {
1112
+ if (isFunction(validate)) {
1113
+ const validateError = getValidateError(await validate(inputValue, formValues), inputRef);
1114
+ if (validateError) {
1115
+ error[name] = {
1116
+ ...validateError,
1117
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message)
1118
+ };
1119
+ if (!validateAllFieldCriteria) {
1120
+ setCustomValidity(validateError.message);
1121
+ return error;
1122
+ }
1123
+ }
1124
+ } else if (isObject(validate)) {
1125
+ let validationResult = {};
1126
+ for (const key in validate) {
1127
+ if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) break;
1128
+ const validateError = getValidateError(await validate[key](inputValue, formValues), inputRef, key);
1129
+ if (validateError) {
1130
+ validationResult = {
1131
+ ...validateError,
1132
+ ...appendErrorsCurry(key, validateError.message)
1133
+ };
1134
+ setCustomValidity(validateError.message);
1135
+ if (validateAllFieldCriteria) error[name] = validationResult;
1136
+ }
1137
+ }
1138
+ if (!isEmptyObject(validationResult)) {
1139
+ error[name] = {
1140
+ ref: inputRef,
1141
+ ...validationResult
1142
+ };
1143
+ if (!validateAllFieldCriteria) return error;
1144
+ }
1145
+ }
1146
+ }
1147
+ setCustomValidity(true);
1148
+ return error;
1149
+ };
1150
+ const defaultOptions = {
1151
+ mode: VALIDATION_MODE.onSubmit,
1152
+ reValidateMode: VALIDATION_MODE.onChange,
1153
+ shouldFocusError: true
1154
+ };
1155
+ function createFormControl(props = {}) {
1156
+ let _options = {
1157
+ ...defaultOptions,
1158
+ ...props
1159
+ };
1160
+ let _formState = {
1161
+ submitCount: 0,
1162
+ isDirty: false,
1163
+ isReady: false,
1164
+ isLoading: isFunction(_options.defaultValues),
1165
+ isValidating: false,
1166
+ isSubmitted: false,
1167
+ isSubmitting: false,
1168
+ isSubmitSuccessful: false,
1169
+ isValid: false,
1170
+ touchedFields: {},
1171
+ dirtyFields: {},
1172
+ validatingFields: {},
1173
+ errors: _options.errors || {},
1174
+ disabled: _options.disabled || false
1175
+ };
1176
+ let _fields = {};
1177
+ let _defaultValues = isObject(_options.defaultValues) || isObject(_options.values) ? cloneObject(_options.defaultValues || _options.values) || {} : {};
1178
+ let _formValues = _options.shouldUnregister ? {} : cloneObject(_defaultValues);
1179
+ let _state = {
1180
+ action: false,
1181
+ mount: false,
1182
+ watch: false,
1183
+ keepIsValid: false
1184
+ };
1185
+ let _names = {
1186
+ mount: /* @__PURE__ */ new Set(),
1187
+ disabled: /* @__PURE__ */ new Set(),
1188
+ unMount: /* @__PURE__ */ new Set(),
1189
+ array: /* @__PURE__ */ new Set(),
1190
+ watch: /* @__PURE__ */ new Set()
1191
+ };
1192
+ let delayErrorCallback;
1193
+ let timer = 0;
1194
+ const defaultProxyFormState = {
1195
+ isDirty: false,
1196
+ dirtyFields: false,
1197
+ validatingFields: false,
1198
+ touchedFields: false,
1199
+ isValidating: false,
1200
+ isValid: false,
1201
+ errors: false
1202
+ };
1203
+ const _proxyFormState = { ...defaultProxyFormState };
1204
+ let _proxySubscribeFormState = { ..._proxyFormState };
1205
+ const _subjects = {
1206
+ array: createSubject(),
1207
+ state: createSubject()
1208
+ };
1209
+ const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
1210
+ const debounce = (callback) => (wait) => {
1211
+ clearTimeout(timer);
1212
+ timer = setTimeout(callback, wait);
1213
+ };
1214
+ const _setValid = async (shouldUpdateValid) => {
1215
+ if (_state.keepIsValid) return;
1216
+ if (!_options.disabled && (_proxyFormState.isValid || _proxySubscribeFormState.isValid || shouldUpdateValid)) {
1217
+ let isValid;
1218
+ if (_options.resolver) {
1219
+ isValid = isEmptyObject((await _runSchema()).errors);
1220
+ _updateIsValidating();
1221
+ } else isValid = await executeBuiltInValidation(_fields, true);
1222
+ if (isValid !== _formState.isValid) _subjects.state.next({ isValid });
1223
+ }
1224
+ };
1225
+ const _updateIsValidating = (names, isValidating) => {
1226
+ if (!_options.disabled && (_proxyFormState.isValidating || _proxyFormState.validatingFields || _proxySubscribeFormState.isValidating || _proxySubscribeFormState.validatingFields)) {
1227
+ (names || Array.from(_names.mount)).forEach((name) => {
1228
+ if (name) isValidating ? set(_formState.validatingFields, name, isValidating) : unset(_formState.validatingFields, name);
1229
+ });
1230
+ _subjects.state.next({
1231
+ validatingFields: _formState.validatingFields,
1232
+ isValidating: !isEmptyObject(_formState.validatingFields)
1233
+ });
1234
+ }
1235
+ };
1236
+ const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
1237
+ if (args && method && !_options.disabled) {
1238
+ _state.action = true;
1239
+ if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
1240
+ const fieldValues = method(get(_fields, name), args.argA, args.argB);
1241
+ shouldSetValues && set(_fields, name, fieldValues);
1242
+ }
1243
+ if (shouldUpdateFieldsAndState && Array.isArray(get(_formState.errors, name))) {
1244
+ const errors = method(get(_formState.errors, name), args.argA, args.argB);
1245
+ shouldSetValues && set(_formState.errors, name, errors);
1246
+ unsetEmptyArray(_formState.errors, name);
1247
+ }
1248
+ if ((_proxyFormState.touchedFields || _proxySubscribeFormState.touchedFields) && shouldUpdateFieldsAndState && Array.isArray(get(_formState.touchedFields, name))) {
1249
+ const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
1250
+ shouldSetValues && set(_formState.touchedFields, name, touchedFields);
1251
+ }
1252
+ if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1253
+ _subjects.state.next({
1254
+ name,
1255
+ isDirty: _getDirty(name, values),
1256
+ dirtyFields: _formState.dirtyFields,
1257
+ errors: _formState.errors,
1258
+ isValid: _formState.isValid
1259
+ });
1260
+ } else set(_formValues, name, values);
1261
+ };
1262
+ const updateErrors = (name, error) => {
1263
+ set(_formState.errors, name, error);
1264
+ _subjects.state.next({ errors: _formState.errors });
1265
+ };
1266
+ const _setErrors = (errors) => {
1267
+ _formState.errors = errors;
1268
+ _subjects.state.next({
1269
+ errors: _formState.errors,
1270
+ isValid: false
1271
+ });
1272
+ };
1273
+ const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
1274
+ const field = get(_fields, name);
1275
+ if (field) {
1276
+ const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
1277
+ isUndefined(defaultValue) || ref && ref.defaultChecked || shouldSkipSetValueAs ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f)) : setFieldValue(name, defaultValue);
1278
+ _state.mount && !_state.action && _setValid();
1279
+ }
1280
+ };
1281
+ const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
1282
+ let shouldUpdateField = false;
1283
+ let isPreviousDirty = false;
1284
+ const output = { name };
1285
+ if (!_options.disabled) {
1286
+ if (!isBlurEvent || shouldDirty) {
1287
+ if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
1288
+ isPreviousDirty = _formState.isDirty;
1289
+ _formState.isDirty = output.isDirty = _getDirty();
1290
+ shouldUpdateField = isPreviousDirty !== output.isDirty;
1291
+ }
1292
+ const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1293
+ isPreviousDirty = !!get(_formState.dirtyFields, name);
1294
+ isCurrentFieldPristine ? unset(_formState.dirtyFields, name) : set(_formState.dirtyFields, name, true);
1295
+ output.dirtyFields = _formState.dirtyFields;
1296
+ shouldUpdateField = shouldUpdateField || (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) && isPreviousDirty !== !isCurrentFieldPristine;
1297
+ }
1298
+ if (isBlurEvent) {
1299
+ const isPreviousFieldTouched = get(_formState.touchedFields, name);
1300
+ if (!isPreviousFieldTouched) {
1301
+ set(_formState.touchedFields, name, isBlurEvent);
1302
+ output.touchedFields = _formState.touchedFields;
1303
+ shouldUpdateField = shouldUpdateField || (_proxyFormState.touchedFields || _proxySubscribeFormState.touchedFields) && isPreviousFieldTouched !== isBlurEvent;
1304
+ }
1305
+ }
1306
+ shouldUpdateField && shouldRender && _subjects.state.next(output);
1307
+ }
1308
+ return shouldUpdateField ? output : {};
1309
+ };
1310
+ const shouldRenderByError = (name, isValid, error, fieldState) => {
1311
+ const previousFieldError = get(_formState.errors, name);
1312
+ const shouldUpdateValid = (_proxyFormState.isValid || _proxySubscribeFormState.isValid) && isBoolean(isValid) && _formState.isValid !== isValid;
1313
+ if (_options.delayError && error) {
1314
+ delayErrorCallback = debounce(() => updateErrors(name, error));
1315
+ delayErrorCallback(_options.delayError);
1316
+ } else {
1317
+ clearTimeout(timer);
1318
+ delayErrorCallback = null;
1319
+ error ? set(_formState.errors, name, error) : unset(_formState.errors, name);
1320
+ }
1321
+ if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) || !isEmptyObject(fieldState) || shouldUpdateValid) {
1322
+ const updatedFormState = {
1323
+ ...fieldState,
1324
+ ...shouldUpdateValid && isBoolean(isValid) ? { isValid } : {},
1325
+ errors: _formState.errors,
1326
+ name
1327
+ };
1328
+ _formState = {
1329
+ ..._formState,
1330
+ ...updatedFormState
1331
+ };
1332
+ _subjects.state.next(updatedFormState);
1333
+ }
1334
+ };
1335
+ const _runSchema = async (name) => {
1336
+ _updateIsValidating(name, true);
1337
+ return await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1338
+ };
1339
+ const executeSchemaAndUpdateState = async (names) => {
1340
+ const { errors } = await _runSchema(names);
1341
+ _updateIsValidating(names);
1342
+ if (names) for (const name of names) {
1343
+ const error = get(errors, name);
1344
+ error ? set(_formState.errors, name, error) : unset(_formState.errors, name);
1345
+ }
1346
+ else _formState.errors = errors;
1347
+ return errors;
1348
+ };
1349
+ const executeBuiltInValidation = async (fields, shouldOnlyCheckValid, context = { valid: true }) => {
1350
+ for (const name in fields) {
1351
+ const field = fields[name];
1352
+ if (field) {
1353
+ const { _f, ...fieldValue } = field;
1354
+ if (_f) {
1355
+ const isFieldArrayRoot = _names.array.has(_f.name);
1356
+ const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1357
+ if (isPromiseFunction && _proxyFormState.validatingFields) _updateIsValidating([_f.name], true);
1358
+ const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1359
+ if (isPromiseFunction && _proxyFormState.validatingFields) _updateIsValidating([_f.name]);
1360
+ if (fieldError[_f.name]) {
1361
+ context.valid = false;
1362
+ if (shouldOnlyCheckValid || props.shouldUseNativeValidation) break;
1363
+ }
1364
+ !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));
1365
+ }
1366
+ !isEmptyObject(fieldValue) && await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context);
1367
+ }
1368
+ }
1369
+ return context.valid;
1370
+ };
1371
+ const _removeUnmounted = () => {
1372
+ for (const name of _names.unMount) {
1373
+ const field = get(_fields, name);
1374
+ field && (field._f.refs ? field._f.refs.every((ref) => !live(ref)) : !live(field._f.ref)) && unregister(name);
1375
+ }
1376
+ _names.unMount = /* @__PURE__ */ new Set();
1377
+ };
1378
+ const _getDirty = (name, data) => !_options.disabled && (name && data && set(_formValues, name, data), !deepEqual(getValues(), _defaultValues));
1379
+ const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, { ..._state.mount ? _formValues : isUndefined(defaultValue) ? _defaultValues : isString(names) ? { [names]: defaultValue } : defaultValue }, isGlobal, defaultValue);
1380
+ const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
1381
+ const setFieldValue = (name, value, options = {}) => {
1382
+ const field = get(_fields, name);
1383
+ let fieldValue = value;
1384
+ if (field) {
1385
+ const fieldReference = field._f;
1386
+ if (fieldReference) {
1387
+ !fieldReference.disabled && set(_formValues, name, getFieldValueAs(value, fieldReference));
1388
+ fieldValue = isHTMLElement(fieldReference.ref) && isNullOrUndefined(value) ? "" : value;
1389
+ if (isMultipleSelect(fieldReference.ref)) [...fieldReference.ref.options].forEach((optionRef) => optionRef.selected = fieldValue.includes(optionRef.value));
1390
+ else if (fieldReference.refs) {
1391
+ if (isCheckBoxInput(fieldReference.ref)) fieldReference.refs.forEach((checkboxRef) => {
1392
+ if (!checkboxRef.defaultChecked || !checkboxRef.disabled) {
1393
+ if (Array.isArray(fieldValue)) checkboxRef.checked = !!fieldValue.find((data) => data === checkboxRef.value);
1394
+ else checkboxRef.checked = fieldValue === checkboxRef.value || !!fieldValue;
1395
+ }
1396
+ });
1397
+ else fieldReference.refs.forEach((radioRef) => radioRef.checked = radioRef.value === fieldValue);
1398
+ } else if (isFileInput(fieldReference.ref)) fieldReference.ref.value = "";
1399
+ else {
1400
+ fieldReference.ref.value = fieldValue;
1401
+ if (!fieldReference.ref.type) _subjects.state.next({
1402
+ name,
1403
+ values: cloneObject(_formValues)
1404
+ });
1405
+ }
1406
+ }
1407
+ }
1408
+ (options.shouldDirty || options.shouldTouch) && updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1409
+ options.shouldValidate && trigger(name);
1410
+ };
1411
+ const setValues = (name, value, options) => {
1412
+ for (const fieldKey in value) {
1413
+ if (!value.hasOwnProperty(fieldKey)) return;
1414
+ const fieldValue = value[fieldKey];
1415
+ const fieldName = name + "." + fieldKey;
1416
+ const field = get(_fields, fieldName);
1417
+ (_names.array.has(name) || isObject(fieldValue) || field && !field._f) && !isDateObject(fieldValue) ? setValues(fieldName, fieldValue, options) : setFieldValue(fieldName, fieldValue, options);
1418
+ }
1419
+ };
1420
+ const setValue = (name, value, options = {}) => {
1421
+ const field = get(_fields, name);
1422
+ const isFieldArray = _names.array.has(name);
1423
+ const cloneValue = cloneObject(value);
1424
+ set(_formValues, name, cloneValue);
1425
+ if (isFieldArray) {
1426
+ _subjects.array.next({
1427
+ name,
1428
+ values: cloneObject(_formValues)
1429
+ });
1430
+ if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields || _proxySubscribeFormState.isDirty || _proxySubscribeFormState.dirtyFields) && options.shouldDirty) _subjects.state.next({
1431
+ name,
1432
+ dirtyFields: getDirtyFields(_defaultValues, _formValues),
1433
+ isDirty: _getDirty(name, cloneValue)
1434
+ });
1435
+ } else field && !field._f && !isNullOrUndefined(cloneValue) ? setValues(name, cloneValue, options) : setFieldValue(name, cloneValue, options);
1436
+ if (isWatched(name, _names)) _subjects.state.next({
1437
+ ..._formState,
1438
+ name,
1439
+ values: cloneObject(_formValues)
1440
+ });
1441
+ else _subjects.state.next({
1442
+ name: _state.mount ? name : void 0,
1443
+ values: cloneObject(_formValues)
1444
+ });
1445
+ };
1446
+ const onChange = async (event) => {
1447
+ _state.mount = true;
1448
+ const target = event.target;
1449
+ let name = target.name;
1450
+ let isFieldValueUpdated = true;
1451
+ const field = get(_fields, name);
1452
+ const _updateIsFieldValueUpdated = (fieldValue) => {
1453
+ isFieldValueUpdated = Number.isNaN(fieldValue) || isDateObject(fieldValue) && isNaN(fieldValue.getTime()) || deepEqual(fieldValue, get(_formValues, name, fieldValue));
1454
+ };
1455
+ const validationModeBeforeSubmit = getValidationModes(_options.mode);
1456
+ const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1457
+ if (field) {
1458
+ let error;
1459
+ let isValid;
1460
+ const fieldValue = target.type ? getFieldValue(field._f) : getEventValue(event);
1461
+ const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1462
+ const shouldSkipValidation = !hasValidation(field._f) && !_options.resolver && !get(_formState.errors, name) && !field._f.deps || skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1463
+ const watched = isWatched(name, _names, isBlurEvent);
1464
+ set(_formValues, name, fieldValue);
1465
+ if (isBlurEvent) {
1466
+ if (!target || !target.readOnly) {
1467
+ field._f.onBlur && field._f.onBlur(event);
1468
+ delayErrorCallback && delayErrorCallback(0);
1469
+ }
1470
+ } else if (field._f.onChange) field._f.onChange(event);
1471
+ const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent);
1472
+ const shouldRender = !isEmptyObject(fieldState) || watched;
1473
+ !isBlurEvent && _subjects.state.next({
1474
+ name,
1475
+ type: event.type,
1476
+ values: cloneObject(_formValues)
1477
+ });
1478
+ if (shouldSkipValidation) {
1479
+ if (_proxyFormState.isValid || _proxySubscribeFormState.isValid) {
1480
+ if (_options.mode === "onBlur") {
1481
+ if (isBlurEvent) _setValid();
1482
+ } else if (!isBlurEvent) _setValid();
1483
+ }
1484
+ return shouldRender && _subjects.state.next({
1485
+ name,
1486
+ ...watched ? {} : fieldState
1487
+ });
1488
+ }
1489
+ !isBlurEvent && watched && _subjects.state.next({ ..._formState });
1490
+ if (_options.resolver) {
1491
+ const { errors } = await _runSchema([name]);
1492
+ _updateIsValidating([name]);
1493
+ _updateIsFieldValueUpdated(fieldValue);
1494
+ if (isFieldValueUpdated) {
1495
+ const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
1496
+ const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
1497
+ error = errorLookupResult.error;
1498
+ name = errorLookupResult.name;
1499
+ isValid = isEmptyObject(errors);
1500
+ }
1501
+ } else {
1502
+ _updateIsValidating([name], true);
1503
+ error = (await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1504
+ _updateIsValidating([name]);
1505
+ _updateIsFieldValueUpdated(fieldValue);
1506
+ if (isFieldValueUpdated) {
1507
+ if (error) isValid = false;
1508
+ else if (_proxyFormState.isValid || _proxySubscribeFormState.isValid) isValid = await executeBuiltInValidation(_fields, true);
1509
+ }
1510
+ }
1511
+ if (isFieldValueUpdated) {
1512
+ field._f.deps && (!Array.isArray(field._f.deps) || field._f.deps.length > 0) && trigger(field._f.deps);
1513
+ shouldRenderByError(name, isValid, error, fieldState);
1514
+ }
1515
+ }
1516
+ };
1517
+ const _focusInput = (ref, key) => {
1518
+ if (get(_formState.errors, key) && ref.focus) {
1519
+ ref.focus();
1520
+ return 1;
1521
+ }
1522
+ };
1523
+ const trigger = async (name, options = {}) => {
1524
+ let isValid;
1525
+ let validationResult;
1526
+ const fieldNames = convertToArrayPayload(name);
1527
+ if (_options.resolver) {
1528
+ const errors = await executeSchemaAndUpdateState(isUndefined(name) ? name : fieldNames);
1529
+ isValid = isEmptyObject(errors);
1530
+ validationResult = name ? !fieldNames.some((name) => get(errors, name)) : isValid;
1531
+ } else if (name) {
1532
+ validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
1533
+ const field = get(_fields, fieldName);
1534
+ return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
1535
+ }))).every(Boolean);
1536
+ (validationResult || _formState.isValid) && _setValid();
1537
+ } else validationResult = isValid = await executeBuiltInValidation(_fields);
1538
+ _subjects.state.next({
1539
+ ...!isString(name) || (_proxyFormState.isValid || _proxySubscribeFormState.isValid) && isValid !== _formState.isValid ? {} : { name },
1540
+ ..._options.resolver || !name ? { isValid } : {},
1541
+ errors: _formState.errors
1542
+ });
1543
+ options.shouldFocus && !validationResult && iterateFieldsByAction(_fields, _focusInput, name ? fieldNames : _names.mount);
1544
+ return validationResult;
1545
+ };
1546
+ const getValues = (fieldNames, config) => {
1547
+ let values = { ..._state.mount ? _formValues : _defaultValues };
1548
+ if (config) values = extractFormValues(config.dirtyFields ? _formState.dirtyFields : _formState.touchedFields, values);
1549
+ return isUndefined(fieldNames) ? values : isString(fieldNames) ? get(values, fieldNames) : fieldNames.map((name) => get(values, name));
1550
+ };
1551
+ const getFieldState = (name, formState) => ({
1552
+ invalid: !!get((formState || _formState).errors, name),
1553
+ isDirty: !!get((formState || _formState).dirtyFields, name),
1554
+ error: get((formState || _formState).errors, name),
1555
+ isValidating: !!get(_formState.validatingFields, name),
1556
+ isTouched: !!get((formState || _formState).touchedFields, name)
1557
+ });
1558
+ const clearErrors = (name) => {
1559
+ const names = name ? convertToArrayPayload(name) : void 0;
1560
+ names === null || names === void 0 || names.forEach((inputName) => unset(_formState.errors, inputName));
1561
+ if (names) names.forEach((inputName) => {
1562
+ _subjects.state.next({
1563
+ name: inputName,
1564
+ errors: _formState.errors
1565
+ });
1566
+ });
1567
+ else _subjects.state.next({ errors: {} });
1568
+ };
1569
+ const setError = (name, error, options) => {
1570
+ const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
1571
+ const { ref: currentRef, message, type, ...restOfErrorTree } = get(_formState.errors, name) || {};
1572
+ set(_formState.errors, name, {
1573
+ ...restOfErrorTree,
1574
+ ...error,
1575
+ ref
1576
+ });
1577
+ _subjects.state.next({
1578
+ name,
1579
+ errors: _formState.errors,
1580
+ isValid: false
1581
+ });
1582
+ options && options.shouldFocus && ref && ref.focus && ref.focus();
1583
+ };
1584
+ const watch = (name, defaultValue) => isFunction(name) ? _subjects.state.subscribe({ next: (payload) => "values" in payload && name(_getWatch(void 0, defaultValue), payload) }) : _getWatch(name, defaultValue, true);
1585
+ const _subscribe = (props) => _subjects.state.subscribe({ next: (formState) => {
1586
+ if (shouldSubscribeByName(props.name, formState.name, props.exact) && shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) props.callback({
1587
+ values: { ..._formValues },
1588
+ ..._formState,
1589
+ ...formState,
1590
+ defaultValues: _defaultValues
1591
+ });
1592
+ } }).unsubscribe;
1593
+ const subscribe = (props) => {
1594
+ _state.mount = true;
1595
+ _proxySubscribeFormState = {
1596
+ ..._proxySubscribeFormState,
1597
+ ...props.formState
1598
+ };
1599
+ return _subscribe({
1600
+ ...props,
1601
+ formState: {
1602
+ ...defaultProxyFormState,
1603
+ ...props.formState
1604
+ }
1605
+ });
1606
+ };
1607
+ const unregister = (name, options = {}) => {
1608
+ for (const fieldName of name ? convertToArrayPayload(name) : _names.mount) {
1609
+ _names.mount.delete(fieldName);
1610
+ _names.array.delete(fieldName);
1611
+ if (!options.keepValue) {
1612
+ unset(_fields, fieldName);
1613
+ unset(_formValues, fieldName);
1614
+ }
1615
+ !options.keepError && unset(_formState.errors, fieldName);
1616
+ !options.keepDirty && unset(_formState.dirtyFields, fieldName);
1617
+ !options.keepTouched && unset(_formState.touchedFields, fieldName);
1618
+ !options.keepIsValidating && unset(_formState.validatingFields, fieldName);
1619
+ !_options.shouldUnregister && !options.keepDefaultValue && unset(_defaultValues, fieldName);
1620
+ }
1621
+ _subjects.state.next({ values: cloneObject(_formValues) });
1622
+ _subjects.state.next({
1623
+ ..._formState,
1624
+ ...!options.keepDirty ? {} : { isDirty: _getDirty() }
1625
+ });
1626
+ !options.keepIsValid && _setValid();
1627
+ };
1628
+ const _setDisabledField = ({ disabled, name }) => {
1629
+ if (isBoolean(disabled) && _state.mount || !!disabled || _names.disabled.has(name)) {
1630
+ const disabledStateChanged = _names.disabled.has(name) !== !!disabled;
1631
+ disabled ? _names.disabled.add(name) : _names.disabled.delete(name);
1632
+ disabledStateChanged && _state.mount && !_state.action && _setValid();
1633
+ }
1634
+ };
1635
+ const register = (name, options = {}) => {
1636
+ let field = get(_fields, name);
1637
+ const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
1638
+ set(_fields, name, {
1639
+ ...field || {},
1640
+ _f: {
1641
+ ...field && field._f ? field._f : { ref: { name } },
1642
+ name,
1643
+ mount: true,
1644
+ ...options
1645
+ }
1646
+ });
1647
+ _names.mount.add(name);
1648
+ if (field) _setDisabledField({
1649
+ disabled: isBoolean(options.disabled) ? options.disabled : _options.disabled,
1650
+ name
1651
+ });
1652
+ else updateValidAndValue(name, true, options.value);
1653
+ return {
1654
+ ...disabledIsDefined ? { disabled: options.disabled || _options.disabled } : {},
1655
+ ..._options.progressive ? {
1656
+ required: !!options.required,
1657
+ min: getRuleValue(options.min),
1658
+ max: getRuleValue(options.max),
1659
+ minLength: getRuleValue(options.minLength),
1660
+ maxLength: getRuleValue(options.maxLength),
1661
+ pattern: getRuleValue(options.pattern)
1662
+ } : {},
1663
+ name,
1664
+ onChange,
1665
+ onBlur: onChange,
1666
+ ref: (ref) => {
1667
+ if (ref) {
1668
+ register(name, options);
1669
+ field = get(_fields, name);
1670
+ const fieldRef = isUndefined(ref.value) ? ref.querySelectorAll ? ref.querySelectorAll("input,select,textarea")[0] || ref : ref : ref;
1671
+ const radioOrCheckbox = isRadioOrCheckbox(fieldRef);
1672
+ const refs = field._f.refs || [];
1673
+ if (radioOrCheckbox ? refs.find((option) => option === fieldRef) : fieldRef === field._f.ref) return;
1674
+ set(_fields, name, { _f: {
1675
+ ...field._f,
1676
+ ...radioOrCheckbox ? {
1677
+ refs: [
1678
+ ...refs.filter(live),
1679
+ fieldRef,
1680
+ ...Array.isArray(get(_defaultValues, name)) ? [{}] : []
1681
+ ],
1682
+ ref: {
1683
+ type: fieldRef.type,
1684
+ name
1685
+ }
1686
+ } : { ref: fieldRef }
1687
+ } });
1688
+ updateValidAndValue(name, false, void 0, fieldRef);
1689
+ } else {
1690
+ field = get(_fields, name, {});
1691
+ if (field._f) field._f.mount = false;
1692
+ (_options.shouldUnregister || options.shouldUnregister) && !(isNameInFieldArray(_names.array, name) && _state.action) && _names.unMount.add(name);
1693
+ }
1694
+ }
1695
+ };
1696
+ };
1697
+ const _focusError = () => _options.shouldFocusError && iterateFieldsByAction(_fields, _focusInput, _names.mount);
1698
+ const _disableForm = (disabled) => {
1699
+ if (isBoolean(disabled)) {
1700
+ _subjects.state.next({ disabled });
1701
+ iterateFieldsByAction(_fields, (ref, name) => {
1702
+ const currentField = get(_fields, name);
1703
+ if (currentField) {
1704
+ ref.disabled = currentField._f.disabled || disabled;
1705
+ if (Array.isArray(currentField._f.refs)) currentField._f.refs.forEach((inputRef) => {
1706
+ inputRef.disabled = currentField._f.disabled || disabled;
1707
+ });
1708
+ }
1709
+ }, 0, false);
1710
+ }
1711
+ };
1712
+ const handleSubmit = (onValid, onInvalid) => async (e) => {
1713
+ let onValidError = void 0;
1714
+ if (e) {
1715
+ e.preventDefault && e.preventDefault();
1716
+ e.persist && e.persist();
1717
+ }
1718
+ let fieldValues = cloneObject(_formValues);
1719
+ _subjects.state.next({ isSubmitting: true });
1720
+ if (_options.resolver) {
1721
+ const { errors, values } = await _runSchema();
1722
+ _updateIsValidating();
1723
+ _formState.errors = errors;
1724
+ fieldValues = cloneObject(values);
1725
+ } else await executeBuiltInValidation(_fields);
1726
+ if (_names.disabled.size) for (const name of _names.disabled) unset(fieldValues, name);
1727
+ unset(_formState.errors, "root");
1728
+ if (isEmptyObject(_formState.errors)) {
1729
+ _subjects.state.next({ errors: {} });
1730
+ try {
1731
+ await onValid(fieldValues, e);
1732
+ } catch (error) {
1733
+ onValidError = error;
1734
+ }
1735
+ } else {
1736
+ if (onInvalid) await onInvalid({ ..._formState.errors }, e);
1737
+ _focusError();
1738
+ setTimeout(_focusError);
1739
+ }
1740
+ _subjects.state.next({
1741
+ isSubmitted: true,
1742
+ isSubmitting: false,
1743
+ isSubmitSuccessful: isEmptyObject(_formState.errors) && !onValidError,
1744
+ submitCount: _formState.submitCount + 1,
1745
+ errors: _formState.errors
1746
+ });
1747
+ if (onValidError) throw onValidError;
1748
+ };
1749
+ const resetField = (name, options = {}) => {
1750
+ if (get(_fields, name)) {
1751
+ if (isUndefined(options.defaultValue)) setValue(name, cloneObject(get(_defaultValues, name)));
1752
+ else {
1753
+ setValue(name, options.defaultValue);
1754
+ set(_defaultValues, name, cloneObject(options.defaultValue));
1755
+ }
1756
+ if (!options.keepTouched) unset(_formState.touchedFields, name);
1757
+ if (!options.keepDirty) {
1758
+ unset(_formState.dirtyFields, name);
1759
+ _formState.isDirty = options.defaultValue ? _getDirty(name, cloneObject(get(_defaultValues, name))) : _getDirty();
1760
+ }
1761
+ if (!options.keepError) {
1762
+ unset(_formState.errors, name);
1763
+ _proxyFormState.isValid && _setValid();
1764
+ }
1765
+ _subjects.state.next({ ..._formState });
1766
+ }
1767
+ };
1768
+ const _reset = (formValues, keepStateOptions = {}) => {
1769
+ const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
1770
+ const cloneUpdatedValues = cloneObject(updatedValues);
1771
+ const isEmptyResetValues = isEmptyObject(formValues);
1772
+ const values = isEmptyResetValues ? _defaultValues : cloneUpdatedValues;
1773
+ if (!keepStateOptions.keepDefaultValues) _defaultValues = updatedValues;
1774
+ if (!keepStateOptions.keepValues) {
1775
+ if (keepStateOptions.keepDirtyValues) {
1776
+ const fieldsToCheck = /* @__PURE__ */ new Set([..._names.mount, ...Object.keys(getDirtyFields(_defaultValues, _formValues))]);
1777
+ for (const fieldName of Array.from(fieldsToCheck)) {
1778
+ const isDirty = get(_formState.dirtyFields, fieldName);
1779
+ const existingValue = get(_formValues, fieldName);
1780
+ const newValue = get(values, fieldName);
1781
+ if (isDirty && !isUndefined(existingValue)) set(values, fieldName, existingValue);
1782
+ else if (!isDirty && !isUndefined(newValue)) setValue(fieldName, newValue);
1783
+ }
1784
+ } else {
1785
+ if (isWeb && isUndefined(formValues)) for (const name of _names.mount) {
1786
+ const field = get(_fields, name);
1787
+ if (field && field._f) {
1788
+ const fieldReference = Array.isArray(field._f.refs) ? field._f.refs[0] : field._f.ref;
1789
+ if (isHTMLElement(fieldReference)) {
1790
+ const form = fieldReference.closest("form");
1791
+ if (form) {
1792
+ form.reset();
1793
+ break;
1794
+ }
1795
+ }
1796
+ }
1797
+ }
1798
+ if (keepStateOptions.keepFieldsRef) for (const fieldName of _names.mount) setValue(fieldName, get(values, fieldName));
1799
+ else _fields = {};
1800
+ }
1801
+ _formValues = _options.shouldUnregister ? keepStateOptions.keepDefaultValues ? cloneObject(_defaultValues) : {} : cloneObject(values);
1802
+ _subjects.array.next({ values: { ...values } });
1803
+ _subjects.state.next({ values: { ...values } });
1804
+ }
1805
+ _names = {
1806
+ mount: keepStateOptions.keepDirtyValues ? _names.mount : /* @__PURE__ */ new Set(),
1807
+ unMount: /* @__PURE__ */ new Set(),
1808
+ array: /* @__PURE__ */ new Set(),
1809
+ disabled: /* @__PURE__ */ new Set(),
1810
+ watch: /* @__PURE__ */ new Set(),
1811
+ watchAll: false,
1812
+ focus: ""
1813
+ };
1814
+ _state.mount = !_proxyFormState.isValid || !!keepStateOptions.keepIsValid || !!keepStateOptions.keepDirtyValues || !_options.shouldUnregister && !isEmptyObject(values);
1815
+ _state.watch = !!_options.shouldUnregister;
1816
+ _state.keepIsValid = !!keepStateOptions.keepIsValid;
1817
+ _state.action = false;
1818
+ if (!keepStateOptions.keepErrors) _formState.errors = {};
1819
+ _subjects.state.next({
1820
+ submitCount: keepStateOptions.keepSubmitCount ? _formState.submitCount : 0,
1821
+ isDirty: isEmptyResetValues ? false : keepStateOptions.keepDirty ? _formState.isDirty : !!(keepStateOptions.keepDefaultValues && !deepEqual(formValues, _defaultValues)),
1822
+ isSubmitted: keepStateOptions.keepIsSubmitted ? _formState.isSubmitted : false,
1823
+ dirtyFields: isEmptyResetValues ? {} : keepStateOptions.keepDirtyValues ? keepStateOptions.keepDefaultValues && _formValues ? getDirtyFields(_defaultValues, _formValues) : _formState.dirtyFields : keepStateOptions.keepDefaultValues && formValues ? getDirtyFields(_defaultValues, formValues) : keepStateOptions.keepDirty ? _formState.dirtyFields : {},
1824
+ touchedFields: keepStateOptions.keepTouched ? _formState.touchedFields : {},
1825
+ errors: keepStateOptions.keepErrors ? _formState.errors : {},
1826
+ isSubmitSuccessful: keepStateOptions.keepIsSubmitSuccessful ? _formState.isSubmitSuccessful : false,
1827
+ isSubmitting: false,
1828
+ defaultValues: _defaultValues
1829
+ });
1830
+ };
1831
+ const reset = (formValues, keepStateOptions) => _reset(isFunction(formValues) ? formValues(_formValues) : formValues, {
1832
+ ..._options.resetOptions,
1833
+ ...keepStateOptions
1834
+ });
1835
+ const setFocus = (name, options = {}) => {
1836
+ const field = get(_fields, name);
1837
+ const fieldReference = field && field._f;
1838
+ if (fieldReference) {
1839
+ const fieldRef = fieldReference.refs ? fieldReference.refs[0] : fieldReference.ref;
1840
+ if (fieldRef.focus) setTimeout(() => {
1841
+ fieldRef.focus();
1842
+ options.shouldSelect && isFunction(fieldRef.select) && fieldRef.select();
1843
+ });
1844
+ }
1845
+ };
1846
+ const _setFormState = (updatedFormState) => {
1847
+ _formState = {
1848
+ ..._formState,
1849
+ ...updatedFormState
1850
+ };
1851
+ };
1852
+ const _resetDefaultValues = () => isFunction(_options.defaultValues) && _options.defaultValues().then((values) => {
1853
+ reset(values, _options.resetOptions);
1854
+ _subjects.state.next({ isLoading: false });
1855
+ });
1856
+ const methods = {
1857
+ control: {
1858
+ register,
1859
+ unregister,
1860
+ getFieldState,
1861
+ handleSubmit,
1862
+ setError,
1863
+ _subscribe,
1864
+ _runSchema,
1865
+ _updateIsValidating,
1866
+ _focusError,
1867
+ _getWatch,
1868
+ _getDirty,
1869
+ _setValid,
1870
+ _setFieldArray,
1871
+ _setDisabledField,
1872
+ _setErrors,
1873
+ _getFieldArray,
1874
+ _reset,
1875
+ _resetDefaultValues,
1876
+ _removeUnmounted,
1877
+ _disableForm,
1878
+ _subjects,
1879
+ _proxyFormState,
1880
+ get _fields() {
1881
+ return _fields;
1882
+ },
1883
+ get _formValues() {
1884
+ return _formValues;
1885
+ },
1886
+ get _state() {
1887
+ return _state;
1888
+ },
1889
+ set _state(value) {
1890
+ _state = value;
1891
+ },
1892
+ get _defaultValues() {
1893
+ return _defaultValues;
1894
+ },
1895
+ get _names() {
1896
+ return _names;
1897
+ },
1898
+ set _names(value) {
1899
+ _names = value;
1900
+ },
1901
+ get _formState() {
1902
+ return _formState;
1903
+ },
1904
+ get _options() {
1905
+ return _options;
1906
+ },
1907
+ set _options(value) {
1908
+ _options = {
1909
+ ..._options,
1910
+ ...value
1911
+ };
1912
+ }
1913
+ },
1914
+ subscribe,
1915
+ trigger,
1916
+ register,
1917
+ handleSubmit,
1918
+ watch,
1919
+ setValue,
1920
+ getValues,
1921
+ reset,
1922
+ resetField,
1923
+ clearErrors,
1924
+ unregister,
1925
+ setError,
1926
+ setFocus,
1927
+ getFieldState
1928
+ };
1929
+ return {
1930
+ ...methods,
1931
+ formControl: methods
1932
+ };
1933
+ }
1934
+ /**
1935
+ * Custom hook to manage the entire form.
1936
+ *
1937
+ * @remarks
1938
+ * [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)
1939
+ *
1940
+ * @param props - form configuration and validation parameters.
1941
+ *
1942
+ * @returns methods - individual functions to manage the form state. {@link UseFormReturn}
1943
+ *
1944
+ * @example
1945
+ * ```tsx
1946
+ * function App() {
1947
+ * const { register, handleSubmit, watch, formState: { errors } } = useForm();
1948
+ * const onSubmit = data => console.log(data);
1949
+ *
1950
+ * console.log(watch("example"));
1951
+ *
1952
+ * return (
1953
+ * <form onSubmit={handleSubmit(onSubmit)}>
1954
+ * <input defaultValue="test" {...register("example")} />
1955
+ * <input {...register("exampleRequired", { required: true })} />
1956
+ * {errors.exampleRequired && <span>This field is required</span>}
1957
+ * <button>Submit</button>
1958
+ * </form>
1959
+ * );
1960
+ * }
1961
+ * ```
1962
+ */
1963
+ function useForm(props = {}) {
1964
+ const _formControl = React.useRef(void 0);
1965
+ const _values = React.useRef(void 0);
1966
+ const [formState, updateFormState] = React.useState({
1967
+ isDirty: false,
1968
+ isValidating: false,
1969
+ isLoading: isFunction(props.defaultValues),
1970
+ isSubmitted: false,
1971
+ isSubmitting: false,
1972
+ isSubmitSuccessful: false,
1973
+ isValid: false,
1974
+ submitCount: 0,
1975
+ dirtyFields: {},
1976
+ touchedFields: {},
1977
+ validatingFields: {},
1978
+ errors: props.errors || {},
1979
+ disabled: props.disabled || false,
1980
+ isReady: false,
1981
+ defaultValues: isFunction(props.defaultValues) ? void 0 : props.defaultValues
1982
+ });
1983
+ if (!_formControl.current) {
1984
+ if (props.formControl) {
1985
+ _formControl.current = {
1986
+ ...props.formControl,
1987
+ formState
1988
+ };
1989
+ if (props.defaultValues && !isFunction(props.defaultValues)) props.formControl.reset(props.defaultValues, props.resetOptions);
1990
+ } else {
1991
+ const { formControl, ...rest } = createFormControl(props);
1992
+ _formControl.current = {
1993
+ ...rest,
1994
+ formState
1995
+ };
1996
+ }
1997
+ }
1998
+ const control = _formControl.current.control;
1999
+ control._options = props;
2000
+ useIsomorphicLayoutEffect(() => {
2001
+ const sub = control._subscribe({
2002
+ formState: control._proxyFormState,
2003
+ callback: () => updateFormState({ ...control._formState }),
2004
+ reRenderRoot: true
2005
+ });
2006
+ updateFormState((data) => ({
2007
+ ...data,
2008
+ isReady: true
2009
+ }));
2010
+ control._formState.isReady = true;
2011
+ return sub;
2012
+ }, [control]);
2013
+ React.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
2014
+ React.useEffect(() => {
2015
+ if (props.mode) control._options.mode = props.mode;
2016
+ if (props.reValidateMode) control._options.reValidateMode = props.reValidateMode;
2017
+ }, [
2018
+ control,
2019
+ props.mode,
2020
+ props.reValidateMode
2021
+ ]);
2022
+ React.useEffect(() => {
2023
+ if (props.errors) {
2024
+ control._setErrors(props.errors);
2025
+ control._focusError();
2026
+ }
2027
+ }, [control, props.errors]);
2028
+ React.useEffect(() => {
2029
+ props.shouldUnregister && control._subjects.state.next({ values: control._getWatch() });
2030
+ }, [control, props.shouldUnregister]);
2031
+ React.useEffect(() => {
2032
+ if (control._proxyFormState.isDirty) {
2033
+ const isDirty = control._getDirty();
2034
+ if (isDirty !== formState.isDirty) control._subjects.state.next({ isDirty });
2035
+ }
2036
+ }, [control, formState.isDirty]);
2037
+ React.useEffect(() => {
2038
+ var _a;
2039
+ if (props.values && !deepEqual(props.values, _values.current)) {
2040
+ control._reset(props.values, {
2041
+ keepFieldsRef: true,
2042
+ ...control._options.resetOptions
2043
+ });
2044
+ if (!((_a = control._options.resetOptions) === null || _a === void 0 ? void 0 : _a.keepIsValid)) control._setValid();
2045
+ _values.current = props.values;
2046
+ updateFormState((state) => ({ ...state }));
2047
+ } else control._resetDefaultValues();
2048
+ }, [control, props.values]);
2049
+ React.useEffect(() => {
2050
+ if (!control._state.mount) {
2051
+ control._setValid();
2052
+ control._state.mount = true;
2053
+ }
2054
+ if (control._state.watch) {
2055
+ control._state.watch = false;
2056
+ control._subjects.state.next({ ...control._formState });
2057
+ }
2058
+ control._removeUnmounted();
2059
+ });
2060
+ _formControl.current.formState = React.useMemo(() => getProxyFormState(formState, control), [control, formState]);
2061
+ return _formControl.current;
2062
+ }
2063
+ //#endregion
2064
+ //#region ../../node_modules/.pnpm/change-case@5.4.4/node_modules/change-case/dist/index.js
2065
+ const SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
2066
+ const SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
2067
+ const SPLIT_SEPARATE_NUMBER_RE = /(\d)\p{Ll}|(\p{L})\d/u;
2068
+ const DEFAULT_STRIP_REGEXP = /[^\p{L}\d]+/giu;
2069
+ const SPLIT_REPLACE_VALUE = "$1\0$2";
2070
+ const DEFAULT_PREFIX_SUFFIX_CHARACTERS = "";
2071
+ /**
2072
+ * Split any cased input strings into an array of words.
2073
+ */
2074
+ function split(value) {
2075
+ let result = value.trim();
2076
+ result = result.replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE).replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE);
2077
+ result = result.replace(DEFAULT_STRIP_REGEXP, "\0");
2078
+ let start = 0;
2079
+ let end = result.length;
2080
+ while (result.charAt(start) === "\0") start++;
2081
+ if (start === end) return [];
2082
+ while (result.charAt(end - 1) === "\0") end--;
2083
+ return result.slice(start, end).split(/\0/g);
2084
+ }
2085
+ /**
2086
+ * Split the input string into an array of words, separating numbers.
2087
+ */
2088
+ function splitSeparateNumbers(value) {
2089
+ const words = split(value);
2090
+ for (let i = 0; i < words.length; i++) {
2091
+ const word = words[i];
2092
+ const match = SPLIT_SEPARATE_NUMBER_RE.exec(word);
2093
+ if (match) {
2094
+ const offset = match.index + (match[1] ?? match[2]).length;
2095
+ words.splice(i, 1, word.slice(0, offset), word.slice(offset));
2096
+ }
2097
+ }
2098
+ return words;
2099
+ }
2100
+ /**
2101
+ * Convert a string to space separated lower case (`foo bar`).
2102
+ */
2103
+ function noCase(input, options) {
2104
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
2105
+ return prefix + words.map(lowerFactory(options?.locale)).join(options?.delimiter ?? " ") + suffix;
2106
+ }
2107
+ /**
2108
+ * Convert a string to pascal case (`FooBar`).
2109
+ */
2110
+ function pascalCase(input, options) {
2111
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
2112
+ const lower = lowerFactory(options?.locale);
2113
+ const upper = upperFactory(options?.locale);
2114
+ const transform = options?.mergeAmbiguousCharacters ? capitalCaseTransformFactory(lower, upper) : pascalCaseTransformFactory(lower, upper);
2115
+ return prefix + words.map(transform).join(options?.delimiter ?? "") + suffix;
2116
+ }
2117
+ /**
2118
+ * Convert a string to constant case (`FOO_BAR`).
2119
+ */
2120
+ function constantCase(input, options) {
2121
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
2122
+ return prefix + words.map(upperFactory(options?.locale)).join(options?.delimiter ?? "_") + suffix;
2123
+ }
2124
+ /**
2125
+ * Convert a string to path case (`Foo bar`).
2126
+ */
2127
+ function sentenceCase(input, options) {
2128
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
2129
+ const lower = lowerFactory(options?.locale);
2130
+ const transform = capitalCaseTransformFactory(lower, upperFactory(options?.locale));
2131
+ return prefix + words.map((word, index) => {
2132
+ if (index === 0) return transform(word);
2133
+ return lower(word);
2134
+ }).join(options?.delimiter ?? " ") + suffix;
2135
+ }
2136
+ /**
2137
+ * Convert a string to snake case (`foo_bar`).
2138
+ */
2139
+ function snakeCase(input, options) {
2140
+ return noCase(input, {
2141
+ delimiter: "_",
2142
+ ...options
2143
+ });
2144
+ }
2145
+ function lowerFactory(locale) {
2146
+ return locale === false ? (input) => input.toLowerCase() : (input) => input.toLocaleLowerCase(locale);
2147
+ }
2148
+ function upperFactory(locale) {
2149
+ return locale === false ? (input) => input.toUpperCase() : (input) => input.toLocaleUpperCase(locale);
2150
+ }
2151
+ function capitalCaseTransformFactory(lower, upper) {
2152
+ return (word) => `${upper(word[0])}${lower(word.slice(1))}`;
2153
+ }
2154
+ function pascalCaseTransformFactory(lower, upper) {
2155
+ return (word, index) => {
2156
+ const char0 = word[0];
2157
+ return (index > 0 && char0 >= "0" && char0 <= "9" ? "_" + char0 : upper(char0)) + lower(word.slice(1));
2158
+ };
2159
+ }
2160
+ function splitPrefixSuffix(input, options = {}) {
2161
+ const splitFn = options.split ?? (options.separateNumbers ? splitSeparateNumbers : split);
2162
+ const prefixCharacters = options.prefixCharacters ?? DEFAULT_PREFIX_SUFFIX_CHARACTERS;
2163
+ const suffixCharacters = options.suffixCharacters ?? DEFAULT_PREFIX_SUFFIX_CHARACTERS;
2164
+ let prefixIndex = 0;
2165
+ let suffixIndex = input.length;
2166
+ while (prefixIndex < input.length) {
2167
+ const char = input.charAt(prefixIndex);
2168
+ if (!prefixCharacters.includes(char)) break;
2169
+ prefixIndex++;
2170
+ }
2171
+ while (suffixIndex > prefixIndex) {
2172
+ const index = suffixIndex - 1;
2173
+ const char = input.charAt(index);
2174
+ if (!suffixCharacters.includes(char)) break;
2175
+ suffixIndex = index;
2176
+ }
2177
+ return [
2178
+ input.slice(0, prefixIndex),
2179
+ splitFn(input.slice(prefixIndex, suffixIndex)),
2180
+ input.slice(suffixIndex)
2181
+ ];
2182
+ }
2183
+ //#endregion
2184
+ //#region editors/document-model-editor/constants/graphql-kinds.ts
2185
+ const STRING_GQL_PRIMITIVE_NAME = "String";
2186
+ const BOOLEAN_GQL_PRIMITIVE_NAME = "Boolean";
2187
+ const FLOAT_GQL_PRIMITIVE_NAME = "Float";
2188
+ const gqlPrimitiveNodeNamesList = [
2189
+ STRING_GQL_PRIMITIVE_NAME,
2190
+ BOOLEAN_GQL_PRIMITIVE_NAME,
2191
+ "Int",
2192
+ FLOAT_GQL_PRIMITIVE_NAME,
2193
+ "ID"
2194
+ ];
2195
+ //#endregion
2196
+ //#region editors/document-model-editor/utils/helpers.ts
2197
+ function makeStateSchemaNameForScope(modelName, scope) {
2198
+ const modelNamePascalCase = pascalCase(modelName);
2199
+ const scopePascalCase = pascalCase(scope);
2200
+ return scopePascalCase === "Global" ? `${modelNamePascalCase}State` : `${modelNamePascalCase}${scopePascalCase}State`;
2201
+ }
2202
+ function makeInitialSchemaDoc(modelName, scope) {
2203
+ return `type ${makeStateSchemaNameForScope(modelName, scope)} {
2204
+ "Add your ${scope} state fields here"
2205
+ _placeholder: String
2206
+ }`;
2207
+ }
2208
+ function makeOperationInitialDoc(name) {
2209
+ return `input ${pascalCase(name)}Input {
2210
+ "Add your inputs here"
2211
+ _placeholder: String
2212
+ }`;
2213
+ }
2214
+ function makeEmptyOperationSchema(operationName) {
2215
+ return `input ${pascalCase(operationName)}Input {\n _empty: Boolean\n}`;
2216
+ }
2217
+ function isEmptyOperationSchema(schema) {
2218
+ if (!schema) return false;
2219
+ return /_empty:\s*Boolean/.test(schema) && !schema.replace(/_empty:\s*Boolean/, "").match(/\w+:\s*\w+/);
2220
+ }
2221
+ function safeParseJsonRecord(json) {
2222
+ try {
2223
+ return JSON.parse(json);
2224
+ } catch (_error) {
2225
+ return null;
2226
+ }
2227
+ }
2228
+ function makeMinimalObjectForStateType(args) {
2229
+ const { sharedSchemaDocumentNode, stateTypeDefinitionNode, existingValue } = args;
2230
+ const existingValueObject = safeParseJsonRecord(existingValue);
2231
+ if (!existingValueObject) return existingValue;
2232
+ const stateTypeDefinitionFields = stateTypeDefinitionNode.fields;
2233
+ if (!stateTypeDefinitionFields?.length) return existingValue;
2234
+ const minimalObject = makeMinimalValuesForObjectFields({
2235
+ schemaDocumentNode: sharedSchemaDocumentNode,
2236
+ fieldDefinitionNodes: stateTypeDefinitionFields,
2237
+ existingValueObject,
2238
+ visitedTypes: /* @__PURE__ */ new Set([stateTypeDefinitionNode.name.value])
2239
+ });
2240
+ return JSON.stringify(minimalObject, null, 2);
2241
+ }
2242
+ function makeMinimalValuesForObjectFields(args) {
2243
+ const { schemaDocumentNode, existingValueObject, fieldDefinitionNodes, visitedTypes } = args;
2244
+ const newJson = {};
2245
+ for (const astNode of fieldDefinitionNodes) {
2246
+ const fieldName = getASTNodeName(astNode);
2247
+ if (!fieldName) continue;
2248
+ const minimalValue = makeMinimalValueForASTNode({
2249
+ fieldName,
2250
+ astNode,
2251
+ schemaDocumentNode,
2252
+ existingValueObject,
2253
+ visitedTypes
2254
+ });
2255
+ newJson[astNode.name.value] = minimalValue;
2256
+ }
2257
+ return newJson;
2258
+ }
2259
+ function makeMinimalValueForASTNode(args) {
2260
+ const { fieldName, astNode, schemaDocumentNode, existingValueObject, visitedTypes } = args;
2261
+ const existingFieldValue = existingValueObject?.[fieldName];
2262
+ let node = astNode;
2263
+ if (isFieldDefinitionNode(astNode)) node = getASTNodeTypeNode(node);
2264
+ const isNonNull = isNonNullNode(node);
2265
+ if (isNonNull) node = getASTNodeTypeNode(node);
2266
+ if (isListTypeNode(node)) return makeMinimalValueForGqlListNode(node, existingFieldValue, isNonNull, schemaDocumentNode, visitedTypes);
2267
+ if (isGqlPrimitiveNode(node)) return makeMinimalValueForGQLPrimitiveNode(node, existingFieldValue, isNonNull);
2268
+ const namedTypeDefinitionNode = getNamedTypeDefinitionNode(node, schemaDocumentNode);
2269
+ if (isEnumTypeDefinitionNode(namedTypeDefinitionNode)) return makeMinimalValueForGqlEnum(namedTypeDefinitionNode, existingFieldValue, isNonNull);
2270
+ if (isScalarTypeDefinitionNode(namedTypeDefinitionNode)) return makeMinimalValueForGqlScalar(namedTypeDefinitionNode, existingFieldValue, isNonNull);
2271
+ if (isUnionTypeDefinitionNode(namedTypeDefinitionNode)) return makeMinimalValueForGqlUnion(namedTypeDefinitionNode, existingFieldValue, schemaDocumentNode, existingValueObject, isNonNull, visitedTypes);
2272
+ if (isObjectTypeDefinitionNode(namedTypeDefinitionNode)) return makeMinimalValueForGqlObject(namedTypeDefinitionNode, schemaDocumentNode, existingValueObject, existingFieldValue, isNonNull, visitedTypes);
2273
+ return existingFieldValue;
2274
+ }
2275
+ function isFieldDefinitionNode(astNodeTypeNode) {
2276
+ if (!astNodeTypeNode) return false;
2277
+ return astNodeTypeNode.kind === import_graphql.Kind.FIELD_DEFINITION;
2278
+ }
2279
+ function isNonNullNode(astNode) {
2280
+ if (!astNode) return false;
2281
+ return astNode.kind === import_graphql.Kind.NON_NULL_TYPE;
2282
+ }
2283
+ function isGqlPrimitiveNode(astNodeTypeNode) {
2284
+ if (!astNodeTypeNode) return false;
2285
+ const name = getASTNodeName(astNodeTypeNode);
2286
+ return gqlPrimitiveNodeNamesList.includes(name);
2287
+ }
2288
+ function isListTypeNode(astNodeTypeNode) {
2289
+ if (!astNodeTypeNode) return false;
2290
+ return astNodeTypeNode.kind === import_graphql.Kind.LIST_TYPE;
2291
+ }
2292
+ function isEnumTypeDefinitionNode(definitionNode) {
2293
+ if (!definitionNode) return false;
2294
+ return definitionNode.kind === import_graphql.Kind.ENUM_TYPE_DEFINITION;
2295
+ }
2296
+ function isScalarTypeDefinitionNode(definitionNode) {
2297
+ if (!definitionNode) return false;
2298
+ return definitionNode.kind === import_graphql.Kind.SCALAR_TYPE_DEFINITION;
2299
+ }
2300
+ function isUnionTypeDefinitionNode(definitionNode) {
2301
+ if (!definitionNode) return false;
2302
+ return definitionNode.kind === import_graphql.Kind.UNION_TYPE_DEFINITION;
2303
+ }
2304
+ function isObjectTypeDefinitionNode(definitionNode) {
2305
+ if (!definitionNode) return false;
2306
+ return definitionNode.kind === import_graphql.Kind.OBJECT_TYPE_DEFINITION;
2307
+ }
2308
+ function getASTNodeName(astNode) {
2309
+ if (!astNode) return null;
2310
+ if (!("name" in astNode)) return null;
2311
+ if (!astNode.name) return null;
2312
+ if (!("value" in astNode.name)) return null;
2313
+ return astNode.name.value;
2314
+ }
2315
+ function getASTNodeTypeNode(astNode) {
2316
+ if (!astNode) return null;
2317
+ if (!("type" in astNode)) return null;
2318
+ return astNode.type;
2319
+ }
2320
+ function makeMinimalValueForGQLPrimitiveNode(primitiveTypeNode, existingFieldValue, isNonNull) {
2321
+ const name = getASTNodeName(primitiveTypeNode);
2322
+ if (!name) return null;
2323
+ switch (name) {
2324
+ case "ID":
2325
+ if (z.string().safeParse(existingFieldValue).success) return existingFieldValue;
2326
+ return isNonNull ? "placeholder-id" : null;
2327
+ case BOOLEAN_GQL_PRIMITIVE_NAME:
2328
+ if (z.boolean().safeParse(existingFieldValue).success) return existingFieldValue;
2329
+ return isNonNull ? false : null;
2330
+ case "Int":
2331
+ if (z.number().safeParse(existingFieldValue).success) return existingFieldValue;
2332
+ return isNonNull ? 0 : null;
2333
+ case FLOAT_GQL_PRIMITIVE_NAME:
2334
+ if (z.number().safeParse(existingFieldValue).success) return existingFieldValue;
2335
+ return isNonNull ? 0 : null;
2336
+ case STRING_GQL_PRIMITIVE_NAME:
2337
+ if (z.string().safeParse(existingFieldValue).success) return existingFieldValue;
2338
+ return isNonNull ? "" : null;
2339
+ }
2340
+ return isNonNull ? existingFieldValue : null;
2341
+ }
2342
+ function makeMinimalValueForGqlEnum(namedTypeDefinitionNode, existingFieldValue, isNonNull) {
2343
+ const enumValues = namedTypeDefinitionNode.values?.map((value) => value.name.value) ?? [];
2344
+ if (typeof existingFieldValue === "string" && enumValues.includes(existingFieldValue)) return existingFieldValue;
2345
+ if (isNonNull) return enumValues[0];
2346
+ return null;
2347
+ }
2348
+ function makeMinimalValueForGqlScalar(scalarTypeDefinitionNode, existingFieldValue, isNonNull) {
2349
+ if (!isNonNull && !existingFieldValue) return null;
2350
+ const name = getASTNodeName(scalarTypeDefinitionNode);
2351
+ if (!name) {
2352
+ console.error("No name for scalar type definition node", scalarTypeDefinitionNode);
2353
+ return null;
2354
+ }
2355
+ const scalar = getPHCustomScalarByTypeName(name);
2356
+ if (!scalar) return null;
2357
+ if (scalar.schema.safeParse(existingFieldValue).success) return existingFieldValue;
2358
+ if (!isNonNull) return null;
2359
+ const minimalValue = scalar.getDefaultValue?.();
2360
+ if (minimalValue) return minimalValue;
2361
+ return existingFieldValue;
2362
+ }
2363
+ function makeMinimalValueForGqlUnion(namedTypeDefinitionNode, existingFieldValue, schemaDocumentNode, existingValueObject, isNonNull, visitedTypes) {
2364
+ if (!isNonNull && !existingFieldValue) return null;
2365
+ if (!namedTypeDefinitionNode.types?.length) return null;
2366
+ const firstNamedTypeDefinitionNode = namedTypeDefinitionNode.types?.at(0);
2367
+ if (!firstNamedTypeDefinitionNode) return null;
2368
+ const firstNamedTypeObjectDefinitionNode = getNamedTypeDefinitionNode(firstNamedTypeDefinitionNode, schemaDocumentNode);
2369
+ if (!isObjectTypeDefinitionNode(firstNamedTypeObjectDefinitionNode)) return null;
2370
+ return makeMinimalValueForGqlObject(firstNamedTypeObjectDefinitionNode, schemaDocumentNode, existingValueObject, existingFieldValue, isNonNull, visitedTypes);
2371
+ }
2372
+ function makeMinimalValueForGqlListNode(listTypeNode, existingFieldValue, isNonNull, schemaDocumentNode, visitedTypes) {
2373
+ if (!isNonNull && !Array.isArray(existingFieldValue)) return null;
2374
+ if (isNonNull && !Array.isArray(existingFieldValue)) return [];
2375
+ return existingFieldValue.map((item, index) => makeMinimalValueForASTNode({
2376
+ fieldName: String(index),
2377
+ astNode: listTypeNode.type,
2378
+ schemaDocumentNode,
2379
+ existingValueObject: { [index]: item },
2380
+ visitedTypes
2381
+ }));
2382
+ }
2383
+ function makeMinimalValueForGqlObject(objectTypeDefinitionNode, schemaDocumentNode, _existingValueObject, existingFieldValue, isNonNull, visitedTypes) {
2384
+ const typeName = objectTypeDefinitionNode.name.value;
2385
+ if (visitedTypes?.has(typeName)) return null;
2386
+ if (!isNonNull && !existingFieldValue) return null;
2387
+ const fields = objectTypeDefinitionNode.fields;
2388
+ if (!fields?.length) return {};
2389
+ const newVisitedTypes = new Set(visitedTypes);
2390
+ newVisitedTypes.add(typeName);
2391
+ return makeMinimalValuesForObjectFields({
2392
+ schemaDocumentNode,
2393
+ existingValueObject: existingFieldValue && typeof existingFieldValue === "object" && !Array.isArray(existingFieldValue) ? existingFieldValue : null,
2394
+ fieldDefinitionNodes: fields,
2395
+ visitedTypes: newVisitedTypes
2396
+ });
2397
+ }
2398
+ function getNamedTypeDefinitionNode(astNodeTypeNode, schemaDocumentNode) {
2399
+ if (!astNodeTypeNode) return null;
2400
+ const name = getASTNodeName(astNodeTypeNode);
2401
+ if (!name) return null;
2402
+ const definitionNode = schemaDocumentNode.definitions.find((def) => "kind" in def && "name" in def && def.name?.value === name);
2403
+ if (!definitionNode) return null;
2404
+ return definitionNode;
2405
+ }
2406
+ function removeWhitespace(str) {
2407
+ return str.replace(/\s+|\\n|\\t/g, "").toLowerCase();
2408
+ }
2409
+ function compareStringsWithoutWhitespace(str1, str2) {
2410
+ if (str1 === null || str2 === null || str1 === void 0 || str2 === void 0) return false;
2411
+ return removeWhitespace(str1) === removeWhitespace(str2);
2412
+ }
2413
+ function renameSchemaType(sdl, oldName, newName, scope) {
2414
+ const typeSuffix = scope === "global" ? "State" : "LocalState";
2415
+ const oldTypeName = `${pascalCase(oldName)}${typeSuffix}`;
2416
+ const newTypeName = `${pascalCase(newName)}${typeSuffix}`;
2417
+ const ast = safeParseSdl(sdl);
2418
+ if (!ast) return sdl;
2419
+ const updatedAst = (0, import_graphql.visit)(ast, { ObjectTypeDefinition: (node) => {
2420
+ if (node.name.value === oldTypeName) return {
2421
+ ...node,
2422
+ name: {
2423
+ ...node.name,
2424
+ value: newTypeName
2425
+ }
2426
+ };
2427
+ } });
2428
+ return (0, import_graphql.print)(updatedAst);
2429
+ }
2430
+ function initializeModelSchema(modelName) {
2431
+ return makeInitialSchemaDoc(modelName, "global");
2432
+ }
2433
+ function updateModelSchemaNames(params) {
2434
+ const { oldName, newName, globalStateSchema, localStateSchema, setStateSchema } = params;
2435
+ setStateSchema(renameSchemaType(globalStateSchema, oldName, newName, "global"), "global");
2436
+ if (localStateSchema) setStateSchema(renameSchemaType(localStateSchema, oldName, newName, "local"), "local");
2437
+ }
2438
+ function handleModelNameChange(params) {
2439
+ const { newName, globalStateSchema, setStateSchema } = params;
2440
+ if (!!!globalStateSchema) {
2441
+ setStateSchema(initializeModelSchema(newName), "global");
2442
+ return;
2443
+ }
2444
+ updateModelSchemaNames(params);
2445
+ }
2446
+ function validateStateObject(sharedSchemaDocumentNode, stateTypeDefinitionNode, stateValue) {
2447
+ let stateObjectJson;
2448
+ try {
2449
+ stateObjectJson = JSON.parse(stateValue);
2450
+ } catch (error) {
2451
+ return [new Error("Invalid JSON object", { cause: error })];
2452
+ }
2453
+ const typeDefByName = indexTypeDefinitions(sharedSchemaDocumentNode);
2454
+ const stateTypeName = stateTypeDefinitionNode.name.value;
2455
+ if (!typeDefByName.has(stateTypeName)) return [/* @__PURE__ */ new Error(`State type "${stateTypeName}" was not found in sharedSchemaDocumentNode`)];
2456
+ const inputSuffix = "Input";
2457
+ const generatedInputDefs = generateInputTypesForObjectTree(stateTypeName, typeDefByName, inputSuffix);
2458
+ const augmentedDoc = {
2459
+ ...sharedSchemaDocumentNode,
2460
+ definitions: [...sharedSchemaDocumentNode.definitions, ...generatedInputDefs]
2461
+ };
2462
+ let schema;
2463
+ try {
2464
+ schema = (0, import_graphql.buildASTSchema)(augmentedDoc, { assumeValidSDL: false });
2465
+ } catch (e) {
2466
+ return [new Error("Failed to build schema from SDL", { cause: e })];
2467
+ }
2468
+ const inputTypeName = `${stateTypeName}${inputSuffix}`;
2469
+ const opDoc = (0, import_graphql.parse)(`query($v: ${inputTypeName}!) { __typename }`);
2470
+ const op = (0, import_graphql.getOperationAST)(opDoc);
2471
+ if (!op) return [/* @__PURE__ */ new Error("Failed to create validation operation AST")];
2472
+ const { errors } = (0, import_graphql.getVariableValues)(schema, op.variableDefinitions ?? [], { v: stateObjectJson });
2473
+ const recursiveTypeErrors = detectRecursiveTypes(stateTypeDefinitionNode, typeDefByName);
2474
+ const recursiveFieldNames = new Set(recursiveTypeErrors.map((e) => e.field));
2475
+ const validationErrors = errors ? graphQLErrorsToStateValidationErrors(errors).filter((e) => {
2476
+ if (e instanceof StateValidationError && e.kind === "NON_NULL") {
2477
+ const rootField = e.path[0];
2478
+ if (typeof rootField === "string" && recursiveFieldNames.has(rootField)) return false;
2479
+ }
2480
+ return true;
2481
+ }) : [];
2482
+ validationErrors.unshift(...recursiveTypeErrors);
2483
+ const missingOptionalErrors = detectMissingOptionalFields(sharedSchemaDocumentNode, stateTypeDefinitionNode, stateObjectJson);
2484
+ validationErrors.push(...missingOptionalErrors);
2485
+ return validationErrors;
2486
+ }
2487
+ /**
2488
+ * Indexes object/input/enum/scalar/interface/union type definition nodes by name.
2489
+ * Note: only AST definitions that have a "name" field are indexed.
2490
+ */
2491
+ function indexTypeDefinitions(doc) {
2492
+ const map = /* @__PURE__ */ new Map();
2493
+ for (const def of doc.definitions) if (def.kind === import_graphql.Kind.OBJECT_TYPE_DEFINITION || def.kind === import_graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION || def.kind === import_graphql.Kind.ENUM_TYPE_DEFINITION || def.kind === import_graphql.Kind.SCALAR_TYPE_DEFINITION || def.kind === import_graphql.Kind.INTERFACE_TYPE_DEFINITION || def.kind === import_graphql.Kind.UNION_TYPE_DEFINITION || def.kind === import_graphql.Kind.OBJECT_TYPE_EXTENSION || def.kind === import_graphql.Kind.INPUT_OBJECT_TYPE_EXTENSION || def.kind === import_graphql.Kind.ENUM_TYPE_EXTENSION || def.kind === import_graphql.Kind.INTERFACE_TYPE_EXTENSION || def.kind === import_graphql.Kind.UNION_TYPE_EXTENSION) {
2494
+ const name = def.name.value;
2495
+ if (!map.has(name)) map.set(name, def);
2496
+ }
2497
+ return map;
2498
+ }
2499
+ /**
2500
+ * Generates InputObjectTypeDefinitionNode(s) for a root object type and any nested
2501
+ * object types reachable via fields, converting object references to their *Input equivalents*.
2502
+ */
2503
+ function generateInputTypesForObjectTree(rootObjectTypeName, typeDefByName, inputSuffix) {
2504
+ const generated = /* @__PURE__ */ new Map();
2505
+ const visiting = /* @__PURE__ */ new Set();
2506
+ const ensureInputForObject = (objectTypeName) => {
2507
+ const inputName = `${objectTypeName}${inputSuffix}`;
2508
+ if (generated.has(inputName)) return;
2509
+ if (visiting.has(objectTypeName)) return;
2510
+ visiting.add(objectTypeName);
2511
+ const def = typeDefByName.get(objectTypeName);
2512
+ if (!def) throw new import_graphql.GraphQLError(`Unknown referenced type "${objectTypeName}"`);
2513
+ if (def.kind !== import_graphql.Kind.OBJECT_TYPE_DEFINITION && def.kind !== import_graphql.Kind.OBJECT_TYPE_EXTENSION) throw new import_graphql.GraphQLError(`Type "${objectTypeName}" is not an object type; cannot generate input from kind "${def.kind}"`);
2514
+ const objDef = def;
2515
+ const inputFields = objDef.fields?.map((f) => {
2516
+ return {
2517
+ kind: import_graphql.Kind.INPUT_VALUE_DEFINITION,
2518
+ name: f.name,
2519
+ description: f.description,
2520
+ directives: [],
2521
+ type: convertOutputTypeNodeToInputTypeNode(f.type, typeDefByName, inputSuffix, ensureInputForObject),
2522
+ defaultValue: void 0
2523
+ };
2524
+ }) ?? [];
2525
+ const inputDef = {
2526
+ kind: import_graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION,
2527
+ name: {
2528
+ kind: import_graphql.Kind.NAME,
2529
+ value: inputName
2530
+ },
2531
+ description: objDef.description,
2532
+ directives: [],
2533
+ fields: inputFields
2534
+ };
2535
+ generated.set(inputName, inputDef);
2536
+ visiting.delete(objectTypeName);
2537
+ };
2538
+ ensureInputForObject(rootObjectTypeName);
2539
+ return Array.from(generated.values());
2540
+ }
2541
+ function convertOutputTypeNodeToInputTypeNode(typeNode, typeDefByName, inputSuffix, ensureInputForObject) {
2542
+ switch (typeNode.kind) {
2543
+ case import_graphql.Kind.NON_NULL_TYPE: return {
2544
+ kind: import_graphql.Kind.NON_NULL_TYPE,
2545
+ type: convertOutputTypeNodeToInputTypeNode(typeNode.type, typeDefByName, inputSuffix, ensureInputForObject)
2546
+ };
2547
+ case import_graphql.Kind.LIST_TYPE: return {
2548
+ kind: import_graphql.Kind.LIST_TYPE,
2549
+ type: convertOutputTypeNodeToInputTypeNode(typeNode.type, typeDefByName, inputSuffix, ensureInputForObject)
2550
+ };
2551
+ case import_graphql.Kind.NAMED_TYPE: {
2552
+ const named = typeNode;
2553
+ const name = named.name.value;
2554
+ const def = typeDefByName.get(name);
2555
+ if (def?.kind === import_graphql.Kind.OBJECT_TYPE_DEFINITION || def?.kind === import_graphql.Kind.OBJECT_TYPE_EXTENSION) {
2556
+ ensureInputForObject(name);
2557
+ return {
2558
+ kind: import_graphql.Kind.NAMED_TYPE,
2559
+ name: {
2560
+ kind: import_graphql.Kind.NAME,
2561
+ value: `${name}${inputSuffix}`
2562
+ }
2563
+ };
2564
+ }
2565
+ if (!def || def.kind === import_graphql.Kind.SCALAR_TYPE_DEFINITION || def.kind === import_graphql.Kind.ENUM_TYPE_DEFINITION || def.kind === import_graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION || def.kind === import_graphql.Kind.INPUT_OBJECT_TYPE_EXTENSION) return named;
2566
+ if (def.kind === import_graphql.Kind.INTERFACE_TYPE_DEFINITION || def.kind === import_graphql.Kind.UNION_TYPE_DEFINITION) throw new import_graphql.GraphQLError(`Type "${name}" (${def.kind}) cannot be used in an input type`);
2567
+ throw new import_graphql.GraphQLError(`Unsupported named type "${name}" of kind "${def.kind}"`);
2568
+ }
2569
+ default: throw new import_graphql.GraphQLError(`Unsupported TypeNode kind: ${JSON.stringify(typeNode)}`);
2570
+ }
2571
+ }
2572
+ var StateValidationError = class extends Error {
2573
+ payload;
2574
+ originalMessage;
2575
+ constructor(payload, originalMessage) {
2576
+ super(payload.kind);
2577
+ this.name = "StateValidationError";
2578
+ this.payload = payload;
2579
+ this.originalMessage = originalMessage;
2580
+ Object.setPrototypeOf(this, new.target.prototype);
2581
+ }
2582
+ get kind() {
2583
+ return this.payload.kind;
2584
+ }
2585
+ get path() {
2586
+ return this.payload.path;
2587
+ }
2588
+ get field() {
2589
+ return this.payload.field;
2590
+ }
2591
+ };
2592
+ function extractInputPath(message) {
2593
+ const match = message.match(/at\s+"([^"]+)"/);
2594
+ if (!match) return [];
2595
+ const parts = match[1].split(".").filter(Boolean);
2596
+ return (parts[0] === "v" ? parts.slice(1) : parts).map((p) => /^\d+$/.test(p) ? Number(p) : p);
2597
+ }
2598
+ const RE_MISSING_REQUIRED_FIELD = /Field "([^"]+)" of required type "([^"]+)" was not provided\./;
2599
+ const RE_UNKNOWN_FIELD = /Field "([^"]+)" is not defined by type "([^"]+)"\.(?: Did you mean "([^"]+)"\?)?/;
2600
+ function extractMissingRequiredField(message) {
2601
+ const m = message.match(RE_MISSING_REQUIRED_FIELD);
2602
+ if (!m) return null;
2603
+ return {
2604
+ field: m[1],
2605
+ expectedType: m[2]
2606
+ };
2607
+ }
2608
+ function extractUnknownField(message) {
2609
+ const m = message.match(RE_UNKNOWN_FIELD);
2610
+ if (!m) return null;
2611
+ return {
2612
+ field: m[1],
2613
+ typeName: m[2],
2614
+ didYouMean: m[3]
2615
+ };
2616
+ }
2617
+ function lastFieldFromPath(path) {
2618
+ for (let i = path.length - 1; i >= 0; i--) if (typeof path[i] === "string") return path[i];
2619
+ }
2620
+ function extractExpectedType(message) {
2621
+ let m = message.match(/Expected non-nullable type "([^"]+)"/);
2622
+ if (m?.[1]) return m[1];
2623
+ m = message.match(/Expected type "([^"]+)"/);
2624
+ if (m?.[1]) return m[1];
2625
+ m = message.match(/;\s*([_A-Za-z][_0-9A-Za-z]*)\s+cannot represent/i);
2626
+ if (m?.[1]) return m[1];
2627
+ }
2628
+ function graphQLErrorsToStateValidationErrors(errors) {
2629
+ const out = [];
2630
+ for (const e of errors) {
2631
+ const originalMessage = e.message;
2632
+ const missing = extractMissingRequiredField(originalMessage);
2633
+ if (missing) {
2634
+ out.push(new StateValidationError({
2635
+ kind: "MISSING",
2636
+ path: [missing.field],
2637
+ field: missing.field,
2638
+ expectedType: missing.expectedType
2639
+ }, originalMessage));
2640
+ continue;
2641
+ }
2642
+ const unknown = extractUnknownField(originalMessage);
2643
+ if (unknown) {
2644
+ out.push(new StateValidationError({
2645
+ kind: "UNKNOWN_FIELD",
2646
+ path: [unknown.field],
2647
+ field: unknown.field,
2648
+ didYouMean: unknown.didYouMean
2649
+ }, originalMessage));
2650
+ continue;
2651
+ }
2652
+ const path = extractInputPath(originalMessage);
2653
+ const field = lastFieldFromPath(path) ?? "value";
2654
+ const expectedType = extractExpectedType(originalMessage);
2655
+ if (originalMessage.includes("Expected non-nullable type") && originalMessage.includes("not to be null")) {
2656
+ out.push(new StateValidationError({
2657
+ kind: "NON_NULL",
2658
+ path,
2659
+ field,
2660
+ expectedType
2661
+ }, originalMessage));
2662
+ continue;
2663
+ }
2664
+ if (originalMessage.includes("cannot represent") || originalMessage.includes("Expected type")) {
2665
+ out.push(new StateValidationError({
2666
+ kind: "TYPE",
2667
+ path,
2668
+ field,
2669
+ expectedType,
2670
+ details: originalMessage
2671
+ }, originalMessage));
2672
+ continue;
2673
+ }
2674
+ out.push(new StateValidationError({
2675
+ kind: "TYPE",
2676
+ path,
2677
+ field,
2678
+ details: originalMessage
2679
+ }, originalMessage));
2680
+ }
2681
+ return out;
2682
+ }
2683
+ /**
2684
+ * Finds all fields defined in the schema that are missing from the state object.
2685
+ * Returns information about each missing field including whether it's required.
2686
+ */
2687
+ function findMissingFields(sharedSchemaDocumentNode, rootTypeNode, value, basePath = []) {
2688
+ let stateObjectJson;
2689
+ try {
2690
+ stateObjectJson = typeof value === "string" ? JSON.parse(value) : value;
2691
+ } catch {
2692
+ return [];
2693
+ }
2694
+ const typeByName = indexObjectTypes(sharedSchemaDocumentNode);
2695
+ const missingFields = [];
2696
+ for (const field of rootTypeNode.fields ?? []) {
2697
+ const fieldName = field.name.value;
2698
+ const fieldPath = [...basePath, fieldName];
2699
+ const isRequired = field.type.kind === import_graphql.Kind.NON_NULL_TYPE;
2700
+ const underlyingType = isRequired ? field.type.type : field.type;
2701
+ if (!(fieldName in stateObjectJson)) {
2702
+ missingFields.push({
2703
+ fieldName,
2704
+ path: fieldPath,
2705
+ isRequired,
2706
+ type: underlyingType
2707
+ });
2708
+ continue;
2709
+ }
2710
+ const namedType = unwrapNamedType(field.type);
2711
+ const childType = namedType ? typeByName.get(namedType) : void 0;
2712
+ if (childType && typeof stateObjectJson[fieldName] === "object" && stateObjectJson[fieldName] !== null && !Array.isArray(stateObjectJson[fieldName])) {
2713
+ const nestedMissing = findMissingFields(sharedSchemaDocumentNode, childType, stateObjectJson[fieldName], fieldPath);
2714
+ missingFields.push(...nestedMissing);
2715
+ }
2716
+ }
2717
+ return missingFields;
2718
+ }
2719
+ /**
2720
+ * Detects optional fields defined in the schema that are missing from the state object.
2721
+ * Returns StateValidationError[] for each missing optional field.
2722
+ */
2723
+ function detectMissingOptionalFields(sharedSchemaDocumentNode, rootTypeNode, value) {
2724
+ return findMissingFields(sharedSchemaDocumentNode, rootTypeNode, value).filter((field) => !field.isRequired).map((field) => new StateValidationError({
2725
+ kind: "MISSING_OPTIONAL",
2726
+ path: field.path,
2727
+ field: field.fieldName,
2728
+ expectedType: typeNodeToString(field.type)
2729
+ }));
2730
+ }
2731
+ /**
2732
+ * Detects fields that have recursive types (types that reference themselves directly or indirectly).
2733
+ * Returns a RECURSIVE_TYPE error for each field that contains a recursive type.
2734
+ */
2735
+ function detectRecursiveTypes(stateTypeDefinitionNode, typeDefByName) {
2736
+ const errors = [];
2737
+ for (const field of stateTypeDefinitionNode.fields ?? []) {
2738
+ const fieldName = field.name.value;
2739
+ const namedTypeName = getNamedTypeName(field.type);
2740
+ if (!namedTypeName) continue;
2741
+ if (isRecursiveType(namedTypeName, typeDefByName, /* @__PURE__ */ new Set())) errors.push(new StateValidationError({
2742
+ kind: "RECURSIVE_TYPE",
2743
+ path: [fieldName],
2744
+ field: fieldName,
2745
+ typeName: namedTypeName
2746
+ }));
2747
+ }
2748
+ return errors;
2749
+ }
2750
+ /**
2751
+ * Gets the named type name from a TypeNode, unwrapping NonNull and List types.
2752
+ */
2753
+ function getNamedTypeName(typeNode) {
2754
+ if (typeNode.kind === import_graphql.Kind.NAMED_TYPE) return typeNode.name.value;
2755
+ if (typeNode.kind === import_graphql.Kind.NON_NULL_TYPE || typeNode.kind === import_graphql.Kind.LIST_TYPE) return getNamedTypeName(typeNode.type);
2756
+ return null;
2757
+ }
2758
+ /**
2759
+ * Checks if a type is recursive (references itself directly or indirectly through required fields).
2760
+ */
2761
+ function isRecursiveType(typeName, typeDefByName, visitedTypes) {
2762
+ if (visitedTypes.has(typeName)) return true;
2763
+ const typeDef = typeDefByName.get(typeName);
2764
+ if (!typeDef || typeDef.kind !== import_graphql.Kind.OBJECT_TYPE_DEFINITION) return false;
2765
+ visitedTypes.add(typeName);
2766
+ for (const field of typeDef.fields ?? []) {
2767
+ if (field.type.kind !== import_graphql.Kind.NON_NULL_TYPE) continue;
2768
+ const innerType = field.type.type;
2769
+ let fieldTypeName = null;
2770
+ if (innerType.kind === import_graphql.Kind.NAMED_TYPE) fieldTypeName = innerType.name.value;
2771
+ else if (innerType.kind === import_graphql.Kind.LIST_TYPE) fieldTypeName = getNamedTypeName(innerType);
2772
+ if (fieldTypeName && isRecursiveType(fieldTypeName, typeDefByName, visitedTypes)) return true;
2773
+ }
2774
+ visitedTypes.delete(typeName);
2775
+ return false;
2776
+ }
2777
+ /**
2778
+ * Converts a TypeNode to its string representation (e.g., "String", "Int!", "[String]!")
2779
+ */
2780
+ function typeNodeToString(typeNode) {
2781
+ switch (typeNode.kind) {
2782
+ case import_graphql.Kind.NAMED_TYPE: return typeNode.name.value;
2783
+ case import_graphql.Kind.NON_NULL_TYPE: return `${typeNodeToString(typeNode.type)}!`;
2784
+ case import_graphql.Kind.LIST_TYPE: return `[${typeNodeToString(typeNode.type)}]`;
2785
+ }
2786
+ }
2787
+ function indexObjectTypes(doc) {
2788
+ const map = /* @__PURE__ */ new Map();
2789
+ for (const def of doc.definitions) if (def.kind === import_graphql.Kind.OBJECT_TYPE_DEFINITION) map.set(def.name.value, def);
2790
+ return map;
2791
+ }
2792
+ function unwrapNamedType(typeNode) {
2793
+ if (typeNode.kind === import_graphql.Kind.NAMED_TYPE) return typeNode.name.value;
2794
+ if (typeNode.kind === import_graphql.Kind.NON_NULL_TYPE) return unwrapNamedType(typeNode.type);
2795
+ if (typeNode.kind === import_graphql.Kind.LIST_TYPE) return unwrapNamedType(typeNode.type);
2796
+ }
2797
+ //#endregion
2798
+ //#region editors/document-model-editor/utils/linting.ts
2799
+ function ensureDocumentContainsNodeWithNameAndType(doc, nodeName, nodeType) {
2800
+ const parsedDoc = safeParseSdl(doc);
2801
+ if (!parsedDoc) return true;
2802
+ return parsedDoc.definitions.some((def) => {
2803
+ return def.kind === import_graphql.Kind[nodeType] && "name" in def && def.name?.value === nodeName;
2804
+ });
2805
+ }
2806
+ function createNodeTypeAndNameDiagnostic(doc, errorMessage) {
2807
+ const parsedDoc = safeParseSdl(doc);
2808
+ if (!parsedDoc) return void 0;
2809
+ const firstNode = parsedDoc.definitions[0];
2810
+ const nameNode = "name" in firstNode ? firstNode.name : null;
2811
+ return {
2812
+ from: nameNode?.loc?.start ?? firstNode.loc?.start ?? 0,
2813
+ to: nameNode?.loc?.end ?? firstNode.loc?.end ?? 0,
2814
+ severity: "error",
2815
+ message: errorMessage
2816
+ };
2817
+ }
2818
+ function ensureValidStateSchemaName(doc, modelName, scope) {
2819
+ if (!safeParseSdl(doc)) return [];
2820
+ const requiredTypeName = makeStateSchemaNameForScope(modelName, scope);
2821
+ if (!ensureDocumentContainsNodeWithNameAndType(doc, requiredTypeName, "OBJECT_TYPE_DEFINITION")) return [createNodeTypeAndNameDiagnostic(doc, `${sentenceCase(scope)} state schema must be named ${requiredTypeName}`)].filter((d) => d !== void 0);
2822
+ return [];
2823
+ }
2824
+ function ensureValidOperationSchemaInputName(doc, operationName) {
2825
+ if (!doc || !safeParseSdl(doc)) return [];
2826
+ const requiredTypeName = `${pascalCase(operationName)}Input`;
2827
+ if (!ensureDocumentContainsNodeWithNameAndType(doc, requiredTypeName, "INPUT_OBJECT_TYPE_DEFINITION")) return [createNodeTypeAndNameDiagnostic(doc, `Operation schema must contain an input type named ${requiredTypeName}`)].filter((d) => d !== void 0);
2828
+ return [];
2829
+ }
2830
+ //#endregion
2831
+ //#region editors/document-model-editor/components/button.tsx
2832
+ const Button = forwardRef((props, ref) => {
2833
+ const { className, ...rest } = props;
2834
+ return /* @__PURE__ */ jsx("button", {
2835
+ ref,
2836
+ ...rest,
2837
+ className: twMerge("h-10 rounded-md border border-border bg-background px-4 py-2 text-sm font-medium whitespace-nowrap text-foreground transition-colors hover:hover-effect focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:disabled-effect", className)
2838
+ });
2839
+ });
2840
+ //#endregion
2841
+ //#region editors/document-model-editor/components/divider.tsx
2842
+ function Divider({ className, size = "sm", margin = "md" }) {
2843
+ function getSize() {
2844
+ if (size === "sm") return "h-px";
2845
+ if (size === "md") return "h-1";
2846
+ return "h-1.5";
2847
+ }
2848
+ function getMargin() {
2849
+ if (margin === "sm") return "my-4";
2850
+ if (margin === "md") return "my-6";
2851
+ return "my-8";
2852
+ }
2853
+ const sizeClass = getSize();
2854
+ const marginClass = getMargin();
2855
+ return /* @__PURE__ */ jsx("div", { className: twMerge("bg-secondary", sizeClass, marginClass, className) });
2856
+ }
2857
+ //#endregion
2858
+ //#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
2859
+ const r = (t, r, o) => {
2860
+ if (t && "reportValidity" in t) {
2861
+ const s = get(o, r);
2862
+ t.setCustomValidity(s && s.message || ""), t.reportValidity();
2863
+ }
2864
+ };
2865
+ const o = (e, t) => {
2866
+ for (const o in t.fields) {
2867
+ const s = t.fields[o];
2868
+ s && s.ref && "reportValidity" in s.ref ? r(s.ref, o, e) : s && s.refs && s.refs.forEach((t) => r(t, o, e));
2869
+ }
2870
+ };
2871
+ const s$1 = (r, s) => {
2872
+ s.shouldUseNativeValidation && o(r, s);
2873
+ const n = {};
2874
+ for (const o in r) {
2875
+ const f = get(s.fields, o), c = Object.assign(r[o] || {}, { ref: f && f.ref });
2876
+ if (i$1(s.names || Object.keys(r), o)) {
2877
+ const r = Object.assign({}, get(n, o));
2878
+ set(r, "root", c), set(n, o, r);
2879
+ } else set(n, o, c);
2880
+ }
2881
+ return n;
2882
+ };
2883
+ const i$1 = (e, t) => {
2884
+ const r = n$1(t);
2885
+ return e.some((e) => n$1(e).match(`^${r}\\.\\d+`));
2886
+ };
2887
+ function n$1(e) {
2888
+ return e.replace(/\]|\[/g, "");
2889
+ }
2890
+ //#endregion
2891
+ //#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
2892
+ function t(r, e) {
2893
+ try {
2894
+ var o = r();
2895
+ } catch (r) {
2896
+ return e(r);
2897
+ }
2898
+ return o && o.then ? o.then(void 0, e) : o;
2899
+ }
2900
+ function s(r, e) {
2901
+ for (var n = {}; r.length;) {
2902
+ var t = r[0], s = t.code, i = t.message, a = t.path.join(".");
2903
+ if (!n[a]) if ("unionErrors" in t) {
2904
+ var u = t.unionErrors[0].errors[0];
2905
+ n[a] = {
2906
+ message: u.message,
2907
+ type: u.code
2908
+ };
2909
+ } else n[a] = {
2910
+ message: i,
2911
+ type: s
2912
+ };
2913
+ if ("unionErrors" in t && t.unionErrors.forEach(function(e) {
2914
+ return e.errors.forEach(function(e) {
2915
+ return r.push(e);
2916
+ });
2917
+ }), e) {
2918
+ var c = n[a].types, f = c && c[t.code];
2919
+ n[a] = appendErrors(a, e, n, s, f ? [].concat(f, t.message) : t.message);
2920
+ }
2921
+ r.shift();
2922
+ }
2923
+ return n;
2924
+ }
2925
+ function i(r, e) {
2926
+ for (var n = {}; r.length;) {
2927
+ var t = r[0], s = t.code, i = t.message, a = t.path.join(".");
2928
+ if (!n[a]) if ("invalid_union" === t.code && t.errors.length > 0) {
2929
+ var u = t.errors[0][0];
2930
+ n[a] = {
2931
+ message: u.message,
2932
+ type: u.code
2933
+ };
2934
+ } else n[a] = {
2935
+ message: i,
2936
+ type: s
2937
+ };
2938
+ if ("invalid_union" === t.code && t.errors.forEach(function(e) {
2939
+ return e.forEach(function(e) {
2940
+ return r.push(e);
2941
+ });
2942
+ }), e) {
2943
+ var c = n[a].types, f = c && c[t.code];
2944
+ n[a] = appendErrors(a, e, n, s, f ? [].concat(f, t.message) : t.message);
2945
+ }
2946
+ r.shift();
2947
+ }
2948
+ return n;
2949
+ }
2950
+ function a(o$1, a, u) {
2951
+ if (void 0 === u && (u = {}), function(r) {
2952
+ return "_def" in r && "object" == typeof r._def && "typeName" in r._def;
2953
+ }(o$1)) return function(n, i, c) {
2954
+ try {
2955
+ return Promise.resolve(t(function() {
2956
+ return Promise.resolve(o$1["sync" === u.mode ? "parse" : "parseAsync"](n, a)).then(function(e) {
2957
+ return c.shouldUseNativeValidation && o({}, c), {
2958
+ errors: {},
2959
+ values: u.raw ? Object.assign({}, n) : e
2960
+ };
2961
+ });
2962
+ }, function(r) {
2963
+ if (function(r) {
2964
+ return Array.isArray(null == r ? void 0 : r.issues);
2965
+ }(r)) return {
2966
+ values: {},
2967
+ errors: s$1(s(r.errors, !c.shouldUseNativeValidation && "all" === c.criteriaMode), c)
2968
+ };
2969
+ throw r;
2970
+ }));
2971
+ } catch (r) {
2972
+ return Promise.reject(r);
2973
+ }
2974
+ };
2975
+ if (function(r) {
2976
+ return "_zod" in r && "object" == typeof r._zod;
2977
+ }(o$1)) return function(s, c, f) {
2978
+ try {
2979
+ return Promise.resolve(t(function() {
2980
+ return Promise.resolve(("sync" === u.mode ? n.parse : n.parseAsync)(o$1, s, a)).then(function(e) {
2981
+ return f.shouldUseNativeValidation && o({}, f), {
2982
+ errors: {},
2983
+ values: u.raw ? Object.assign({}, s) : e
2984
+ };
2985
+ });
2986
+ }, function(r) {
2987
+ if (function(r) {
2988
+ return r instanceof n.$ZodError;
2989
+ }(r)) return {
2990
+ values: {},
2991
+ errors: s$1(i(r.issues, !f.shouldUseNativeValidation && "all" === f.criteriaMode), f)
2992
+ };
2993
+ throw r;
2994
+ }));
2995
+ } catch (r) {
2996
+ return Promise.reject(r);
2997
+ }
2998
+ };
2999
+ throw new Error("Invalid input: not a Zod schema");
3000
+ }
3001
+ //#endregion
3002
+ //#region editors/document-model-editor/schemas/inputs.ts
3003
+ const isUppercase = (value) => !/\p{Ll}/u.test(value);
3004
+ const isLowercase = (value) => !/\p{Lu}/u.test(value);
3005
+ function createNameSchema(options = {}) {
3006
+ const { required = false, allowEmpty = false, unique = [] } = options;
3007
+ const baseSchema = allowEmpty ? z.string() : z.string().min(1);
3008
+ const uniqueRefinement = baseSchema.refine((value) => {
3009
+ if (!value && allowEmpty) return true;
3010
+ return !unique.map((n) => n.toLowerCase()).includes(value.replace(/^\s+|\s+$/g, "_").toLowerCase());
3011
+ }, { message: "Item with this name already exists" });
3012
+ if (!required) return unique.length > 0 ? z.string().optional().refine((value) => {
3013
+ if (value === void 0) return true;
3014
+ if (!value && allowEmpty) return true;
3015
+ return !unique.map((n) => n.toLowerCase()).includes(value.replace(/^\s+|\s+$/g, "_").toLowerCase());
3016
+ }, { message: "Item with this name already exists" }) : z.string().optional();
3017
+ return unique.length > 0 ? uniqueRefinement : baseSchema;
3018
+ }
3019
+ function createConstantCaseSchema(options = {}) {
3020
+ return createNameSchema(options).transform((value) => value ? value.toUpperCase() : value).refine((value) => !value || isUppercase(value), { message: "Must be uppercase" });
3021
+ }
3022
+ function createLowercaseSnakeCaseSchema(options = {}) {
3023
+ return createNameSchema(options).transform((value) => value ? value.toLowerCase() : value).refine((value) => !value || isLowercase(value), { message: "Must be lowercase" });
3024
+ }
3025
+ function toLowercaseSnakeCase(value, options = {}) {
3026
+ return createLowercaseSnakeCaseSchema(options).parse(snakeCase(value));
3027
+ }
3028
+ function toConstantCase(value, options = {}) {
3029
+ return createConstantCaseSchema(options).parse(constantCase(value));
3030
+ }
3031
+ z.object({
3032
+ name: createNameSchema({ allowEmpty: true }),
3033
+ website: z.union([z.url(), z.literal("")]).optional().default("")
3034
+ }).default({
3035
+ name: "",
3036
+ website: ""
3037
+ });
3038
+ //#endregion
3039
+ //#region editors/document-model-editor/context/form-context.ts
3040
+ const FormFieldContext = React.createContext({});
3041
+ const FormItemContext = React.createContext({});
3042
+ //#endregion
3043
+ //#region editors/document-model-editor/hooks/useFormField.ts
3044
+ const useFormField = () => {
3045
+ const fieldContext = React.useContext(FormFieldContext);
3046
+ const itemContext = React.useContext(FormItemContext);
3047
+ const { getFieldState, formState } = useFormContext();
3048
+ const fieldState = getFieldState(fieldContext.name, formState);
3049
+ if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
3050
+ const { id } = itemContext;
3051
+ return {
3052
+ id,
3053
+ name: fieldContext.name,
3054
+ formItemId: `${id}-form-item`,
3055
+ formDescriptionId: `${id}-form-item-description`,
3056
+ formMessageId: `${id}-form-item-message`,
3057
+ ...fieldState
3058
+ };
3059
+ };
3060
+ //#endregion
3061
+ //#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
3062
+ var NAME = "Label";
3063
+ var Label$1 = React$1.forwardRef((props, forwardedRef) => {
3064
+ return /* @__PURE__ */ jsx(Primitive.label, {
3065
+ ...props,
3066
+ ref: forwardedRef,
3067
+ onMouseDown: (event) => {
3068
+ if (event.target.closest("button, input, select, textarea")) return;
3069
+ props.onMouseDown?.(event);
3070
+ if (!event.defaultPrevented && event.detail > 1) event.preventDefault();
3071
+ }
3072
+ });
3073
+ });
3074
+ Label$1.displayName = NAME;
3075
+ var Root = Label$1;
3076
+ //#endregion
3077
+ //#region editors/document-model-editor/components/label.tsx
3078
+ const labelVariants = cva("text-sm leading-none font-medium peer-disabled:disabled-effect");
3079
+ const Label = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(Root, {
3080
+ ref,
3081
+ className: twMerge(labelVariants(), className),
3082
+ ...props
3083
+ }));
3084
+ Label.displayName = Root.displayName;
3085
+ //#endregion
3086
+ //#region editors/document-model-editor/components/form.tsx
3087
+ const Form = FormProvider;
3088
+ const FormField = ({ ...props }) => {
3089
+ return /* @__PURE__ */ jsx(FormFieldContext.Provider, {
3090
+ value: { name: props.name },
3091
+ children: /* @__PURE__ */ jsx(Controller, { ...props })
3092
+ });
3093
+ };
3094
+ const FormItem = React$1.forwardRef(({ className, ...props }, ref) => {
3095
+ const id = React$1.useId();
3096
+ return /* @__PURE__ */ jsx(FormItemContext.Provider, {
3097
+ value: { id },
3098
+ children: /* @__PURE__ */ jsx("div", {
3099
+ ref,
3100
+ className,
3101
+ ...props
3102
+ })
3103
+ });
3104
+ });
3105
+ FormItem.displayName = "FormItem";
3106
+ const FormLabel = React$1.forwardRef(({ className, ...props }, ref) => {
3107
+ const { error, formItemId } = useFormField();
3108
+ return /* @__PURE__ */ jsx(Label, {
3109
+ ref,
3110
+ className: twMerge(error && "text-destructive", className),
3111
+ htmlFor: formItemId,
3112
+ ...props
3113
+ });
3114
+ });
3115
+ FormLabel.displayName = "FormLabel";
3116
+ const FormControl = React$1.forwardRef(({ ...props }, ref) => {
3117
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
3118
+ return /* @__PURE__ */ jsx(Slot, {
3119
+ ref,
3120
+ id: formItemId,
3121
+ "aria-describedby": !error ? formDescriptionId : `${formDescriptionId} ${formMessageId}`,
3122
+ "aria-invalid": !!error,
3123
+ ...props
3124
+ });
3125
+ });
3126
+ FormControl.displayName = "FormControl";
3127
+ const FormDescription = React$1.forwardRef(({ className, ...props }, ref) => {
3128
+ const { formDescriptionId } = useFormField();
3129
+ return /* @__PURE__ */ jsx("p", {
3130
+ ref,
3131
+ id: formDescriptionId,
3132
+ className: twMerge("text-sm text-foreground", className),
3133
+ ...props
3134
+ });
3135
+ });
3136
+ FormDescription.displayName = "FormDescription";
3137
+ const FormMessage = React$1.forwardRef(({ className, children, ...props }, ref) => {
3138
+ const { error, formMessageId } = useFormField();
3139
+ const body = error ? String(error.message) : children;
3140
+ if (!body) return null;
3141
+ return /* @__PURE__ */ jsx("p", {
3142
+ ref,
3143
+ id: formMessageId,
3144
+ className: twMerge("text-sm font-medium text-destructive", className),
3145
+ ...props,
3146
+ children: body
3147
+ });
3148
+ });
3149
+ FormMessage.displayName = "FormMessage";
3150
+ //#endregion
3151
+ //#region editors/document-model-editor/components/text-area.tsx
3152
+ const Textarea = forwardRef(({ className, ...props }, ref) => {
3153
+ const textareaRef = useRef(null);
3154
+ const adjustHeight = useCallback((textarea) => {
3155
+ textarea.style.height = "auto";
3156
+ const newHeight = Math.max(textarea.scrollHeight, textarea.offsetHeight);
3157
+ textarea.style.height = `${newHeight}px`;
3158
+ }, []);
3159
+ const handleInput = useCallback((e) => {
3160
+ adjustHeight(e.currentTarget);
3161
+ }, [adjustHeight]);
3162
+ React$1.useEffect(() => {
3163
+ if (textareaRef.current) adjustHeight(textareaRef.current);
3164
+ }, [adjustHeight]);
3165
+ useImperativeHandle(ref, () => ({
3166
+ focus: () => textareaRef.current?.focus(),
3167
+ element: textareaRef.current
3168
+ }));
3169
+ return /* @__PURE__ */ jsx("textarea", {
3170
+ ...props,
3171
+ 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),
3172
+ ref: textareaRef,
3173
+ onInput: handleInput
3174
+ });
3175
+ });
3176
+ Textarea.displayName = "Textarea";
3177
+ //#endregion
3178
+ //#region editors/document-model-editor/components/text-field.tsx
3179
+ const TextField = forwardRef(({ name, value, onSubmit, label, placeholder, unique, className = "", rows = 1, focusOnMount = false, required = false, allowEmpty = false, shouldReset = false, onChange }, ref) => {
3180
+ const textareaRef = useRef(null);
3181
+ const id = useId();
3182
+ useEffect(() => {
3183
+ if (focusOnMount && textareaRef.current) textareaRef.current.focus();
3184
+ }, [focusOnMount]);
3185
+ const form = useForm({
3186
+ resolver: a(z.object({ [name]: createNameSchema({
3187
+ required,
3188
+ allowEmpty,
3189
+ unique
3190
+ }) })),
3191
+ defaultValues: { [name]: value ?? "" }
3192
+ });
3193
+ const handleSubmit = useCallback((values) => {
3194
+ const newValue = values[name];
3195
+ if (newValue === void 0 || value === newValue) return;
3196
+ onSubmit(newValue);
3197
+ if (shouldReset) form.reset({ [name]: "" });
3198
+ }, [
3199
+ name,
3200
+ value,
3201
+ onSubmit,
3202
+ form,
3203
+ shouldReset
3204
+ ]);
3205
+ const handleBlur = useCallback(async () => {
3206
+ const currentValue = form.getValues()[name] ?? "";
3207
+ if (value === null || value === void 0) {
3208
+ if (!currentValue || currentValue.trim() === "") return;
3209
+ }
3210
+ if (compareStringsWithoutWhitespace(currentValue, value ?? "")) return;
3211
+ try {
3212
+ await form.trigger();
3213
+ if (form.formState.isValid) await form.handleSubmit(handleSubmit)();
3214
+ } catch (_e) {}
3215
+ }, [
3216
+ form,
3217
+ handleSubmit,
3218
+ name,
3219
+ value
3220
+ ]);
3221
+ const onEnterKeyDown = useCallback((e) => {
3222
+ if (e.key === "Enter") {
3223
+ e.preventDefault();
3224
+ e.target.blur();
3225
+ }
3226
+ }, []);
3227
+ const handleChange = useCallback((e) => {
3228
+ const newValue = e.target.value;
3229
+ onChange?.(newValue);
3230
+ }, [onChange]);
3231
+ useImperativeHandle(ref, () => ({ focus: () => textareaRef.current?.focus() }));
3232
+ useEffect(() => {
3233
+ form.reset({ [name]: value ?? "" });
3234
+ }, [
3235
+ form,
3236
+ name,
3237
+ value
3238
+ ]);
3239
+ return /* @__PURE__ */ jsx(Form, {
3240
+ ...form,
3241
+ children: /* @__PURE__ */ jsx(FormField, {
3242
+ control: form.control,
3243
+ name,
3244
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, {
3245
+ className: "grid h-full grid-rows-[auto,1fr] gap-2 overflow-visible",
3246
+ children: [
3247
+ !!label && /* @__PURE__ */ jsx(FormLabel, {
3248
+ htmlFor: name,
3249
+ className: "text-sm font-medium text-foreground",
3250
+ children: label
3251
+ }),
3252
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(Textarea, {
3253
+ ...field,
3254
+ id,
3255
+ name,
3256
+ ref: (node) => {
3257
+ if (node) {
3258
+ field.ref(node.element);
3259
+ textareaRef.current = node;
3260
+ }
3261
+ },
3262
+ placeholder,
3263
+ onBlur: () => void handleBlur(),
3264
+ onChange: (e) => {
3265
+ field.onChange(e);
3266
+ handleChange(e);
3267
+ },
3268
+ onKeyDown: onEnterKeyDown,
3269
+ rows,
3270
+ className
3271
+ }) }),
3272
+ /* @__PURE__ */ jsx(FormMessage, {})
3273
+ ]
3274
+ })
3275
+ })
3276
+ });
3277
+ });
3278
+ TextField.displayName = "TextField";
3279
+ z.object({
3280
+ name: z.string(),
3281
+ documentType: z.string(),
3282
+ extension: z.string().optional().default(""),
3283
+ description: z.string(),
3284
+ authorName: z.string(),
3285
+ authorWebsite: z.string()
3286
+ });
3287
+ function ModelMetadata(props) {
3288
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(ModelNameForm, { ...props }), /* @__PURE__ */ jsx("div", {
3289
+ className: "flex h-full flex-col gap-4",
3290
+ children: /* @__PURE__ */ jsxs("div", {
3291
+ className: "grid flex-1 grid-cols-3 items-start gap-4",
3292
+ children: [/* @__PURE__ */ jsxs("div", {
3293
+ className: "col-span-2 flex h-full flex-col gap-4",
3294
+ children: [/* @__PURE__ */ jsx("div", {
3295
+ className: "shrink-0",
3296
+ children: /* @__PURE__ */ jsx(DocumentTypeForm, { ...props })
3297
+ }), /* @__PURE__ */ jsx("div", {
3298
+ className: "min-h-0 flex-1",
3299
+ children: /* @__PURE__ */ jsx(DescriptionForm, { ...props })
3300
+ })]
3301
+ }), /* @__PURE__ */ jsxs("div", {
3302
+ className: "col-span-1 flex flex-col gap-4",
3303
+ children: [
3304
+ /* @__PURE__ */ jsx(AuthorNameForm, { ...props }),
3305
+ /* @__PURE__ */ jsx(AuthorWebsiteForm, { ...props }),
3306
+ /* @__PURE__ */ jsx(ModelExtensionForm, { ...props })
3307
+ ]
3308
+ })]
3309
+ })
3310
+ })] });
3311
+ }
3312
+ function ModelNameForm(props) {
3313
+ const { name, globalStateSchema, localStateSchema, setModelName, setStateSchema } = props;
3314
+ const onSubmit = useCallback((newName) => {
3315
+ if (name === newName) return;
3316
+ setModelName(newName);
3317
+ if (!!!globalStateSchema) {
3318
+ const initialSchemaDoc = makeInitialSchemaDoc(newName, "global");
3319
+ setStateSchema(initialSchemaDoc, "global");
3320
+ return;
3321
+ }
3322
+ const newSchema = renameSchemaType(globalStateSchema, name, newName, "global");
3323
+ setStateSchema(newSchema, "global");
3324
+ if (localStateSchema) {
3325
+ const newLocalStateSchema = renameSchemaType(localStateSchema, name, newName, "local");
3326
+ setStateSchema(newLocalStateSchema, "local");
3327
+ }
3328
+ handleModelNameChange({
3329
+ oldName: name,
3330
+ newName,
3331
+ globalStateSchema,
3332
+ localStateSchema,
3333
+ setStateSchema
3334
+ });
3335
+ }, [
3336
+ name,
3337
+ globalStateSchema,
3338
+ localStateSchema,
3339
+ setStateSchema,
3340
+ setModelName
3341
+ ]);
3342
+ return /* @__PURE__ */ jsx(TextField, {
3343
+ name: "name",
3344
+ value: name,
3345
+ onSubmit,
3346
+ placeholder: "Model name",
3347
+ className: "border-none pl-0 text-xl font-bold text-foreground",
3348
+ required: true,
3349
+ focusOnMount: true
3350
+ });
3351
+ }
3352
+ function DocumentTypeForm(props) {
3353
+ const { documentType, setModelId } = props;
3354
+ return /* @__PURE__ */ jsx(TextField, {
3355
+ label: "Document Type *",
3356
+ name: "powerhouse/document-model",
3357
+ value: documentType,
3358
+ onSubmit: setModelId,
3359
+ placeholder: "Document Type",
3360
+ required: true
3361
+ });
3362
+ }
3363
+ function ModelExtensionForm(props) {
3364
+ const { extension, setModelExtension } = props;
3365
+ return /* @__PURE__ */ jsx(TextField, {
3366
+ name: "extension",
3367
+ value: extension,
3368
+ onSubmit: setModelExtension,
3369
+ label: "Model Extension",
3370
+ placeholder: "Example .phdm",
3371
+ allowEmpty: true
3372
+ });
3373
+ }
3374
+ function DescriptionForm(props) {
3375
+ const { description, setModelDescription } = props;
3376
+ return /* @__PURE__ */ jsx(TextField, {
3377
+ name: "description",
3378
+ label: "Model Description",
3379
+ value: description,
3380
+ onSubmit: setModelDescription,
3381
+ placeholder: "Describe your document to others",
3382
+ allowEmpty: true,
3383
+ className: "h-full"
3384
+ });
3385
+ }
3386
+ function AuthorNameForm(props) {
3387
+ const { authorName, setAuthorName } = props;
3388
+ return /* @__PURE__ */ jsx(TextField, {
3389
+ name: "authorName",
3390
+ value: authorName,
3391
+ onSubmit: setAuthorName,
3392
+ label: "Author Name",
3393
+ placeholder: "Username or organisation",
3394
+ allowEmpty: true
3395
+ });
3396
+ }
3397
+ function AuthorWebsiteForm(props) {
3398
+ const { authorWebsite, setAuthorWebsite } = props;
3399
+ return /* @__PURE__ */ jsx(TextField, {
3400
+ name: "authorWebsite",
3401
+ value: authorWebsite,
3402
+ label: "Website URL",
3403
+ onSubmit: (newAuthorWebsite) => {
3404
+ if (!!authorWebsite && !newAuthorWebsite) return;
3405
+ setAuthorWebsite(newAuthorWebsite);
3406
+ },
3407
+ placeholder: "https://www.powerhouse.inc/",
3408
+ allowEmpty: true
3409
+ });
3410
+ }
3411
+ //#endregion
3412
+ //#region editors/document-model-editor/components/module-form.tsx
3413
+ function ModuleForm({ module, onAddModule, updateModuleName, modules = [] }) {
3414
+ const isEdit = !!module;
3415
+ const moduleNames = modules.map((m) => m.name);
3416
+ const handleSubmit = async (name) => {
3417
+ const formattedName = toLowercaseSnakeCase(name);
3418
+ if (!formattedName.length) return;
3419
+ if (isEdit) {
3420
+ if (formattedName !== module.name) updateModuleName(module.id, formattedName);
3421
+ } else await onAddModule(formattedName);
3422
+ };
3423
+ return /* @__PURE__ */ jsx(TextField, {
3424
+ name: "name",
3425
+ label: isEdit ? "Module name *" : "Add module *",
3426
+ value: module?.name,
3427
+ onSubmit: (name) => void handleSubmit(name),
3428
+ placeholder: "Add module",
3429
+ unique: moduleNames,
3430
+ shouldReset: !isEdit,
3431
+ required: true
3432
+ }, module?.id ?? "new");
3433
+ }
3434
+ //#endregion
3435
+ //#region editors/document-model-editor/components/operation-form.tsx
3436
+ function OperationForm({ operation, module, focusOnMount, allOperationNames, onAddOperationAndInitialSchema, updateOperationName, deleteOperation }) {
3437
+ const isEdit = !!operation;
3438
+ const handleSubmit = async (name) => {
3439
+ if (isEdit && name === "") {
3440
+ deleteOperation(operation.id);
3441
+ return;
3442
+ }
3443
+ const formattedName = toConstantCase(name);
3444
+ if (isEdit) {
3445
+ if (formattedName !== operation.name) updateOperationName(operation.id, formattedName);
3446
+ } else await onAddOperationAndInitialSchema(module.id, formattedName);
3447
+ };
3448
+ const handleChange = (value) => {
3449
+ if (isEdit && value === "") deleteOperation(operation.id);
3450
+ };
3451
+ return /* @__PURE__ */ jsx(TextField, {
3452
+ name: "name",
3453
+ value: operation?.name,
3454
+ label: isEdit ? "Operation name *" : "Add operation *",
3455
+ onSubmit: (name) => void handleSubmit(name),
3456
+ onChange: handleChange,
3457
+ placeholder: "Add operation",
3458
+ required: !isEdit,
3459
+ allowEmpty: !isEdit,
3460
+ shouldReset: !isEdit,
3461
+ focusOnMount,
3462
+ unique: allOperationNames
3463
+ });
3464
+ }
3465
+ //#endregion
3466
+ //#region editors/document-model-editor/components/operation-description-form.tsx
3467
+ function OperationDescriptionForm({ operation, focusOnMount, setOperationDescription }) {
3468
+ const textFieldRef = useRef(null);
3469
+ useEffect(() => {
3470
+ if (focusOnMount && textFieldRef.current) textFieldRef.current.focus();
3471
+ }, [focusOnMount]);
3472
+ return /* @__PURE__ */ jsx(TextField, {
3473
+ ref: textFieldRef,
3474
+ name: "description",
3475
+ value: operation.description,
3476
+ onSubmit: (newDescription) => setOperationDescription(operation.id, newDescription),
3477
+ label: "Operation description",
3478
+ allowEmpty: true,
3479
+ placeholder: "Operation Description"
3480
+ });
3481
+ }
3482
+ //#endregion
3483
+ //#region editors/document-model-editor/components/operation-error-form.tsx
3484
+ function OperationErrorForm({ operation, error, focusOnMount, onSubmit, onAddOperationError, deleteOperationError, setOperationErrorName }) {
3485
+ const textFieldRef = useRef(null);
3486
+ const isEdit = !!error;
3487
+ const allOperationErrorNames = operation.errors.map((o) => o.name).filter((n) => n !== null);
3488
+ const handleSubmit = (name) => {
3489
+ if (isEdit && name === "") {
3490
+ deleteOperationError(error.id);
3491
+ return;
3492
+ }
3493
+ const formattedName = pascalCase(name);
3494
+ if (isEdit) setOperationErrorName(operation.id, error.id, formattedName);
3495
+ else onAddOperationError(operation.id, formattedName);
3496
+ onSubmit?.();
3497
+ };
3498
+ const handleChange = (value) => {
3499
+ if (isEdit && value === "") deleteOperationError(error.id);
3500
+ };
3501
+ return /* @__PURE__ */ jsx(TextField, {
3502
+ ref: textFieldRef,
3503
+ name: "name",
3504
+ value: error?.name,
3505
+ onSubmit: handleSubmit,
3506
+ onChange: handleChange,
3507
+ placeholder: "Add exception",
3508
+ required: !isEdit,
3509
+ allowEmpty: !isEdit,
3510
+ shouldReset: !isEdit,
3511
+ unique: allOperationErrorNames,
3512
+ focusOnMount
3513
+ });
3514
+ }
3515
+ //#endregion
3516
+ //#region editors/document-model-editor/components/operation-errors.tsx
3517
+ function OperationErrors({ operation, addOperationError, deleteOperationError, setOperationErrorName }) {
3518
+ const addErrorFormId = useId();
3519
+ const [shouldFocusAddForm, setShouldFocusAddForm] = useState(false);
3520
+ const onAddOperationError = useCallback(async (operationId, error) => {
3521
+ const errorId = await addOperationError(operationId, error);
3522
+ if (errorId) setShouldFocusAddForm(true);
3523
+ return errorId;
3524
+ }, [addOperationError, setShouldFocusAddForm]);
3525
+ const onAddOperationErrorSubmit = useCallback(() => setShouldFocusAddForm(false), [setShouldFocusAddForm]);
3526
+ return /* @__PURE__ */ jsxs("ul", {
3527
+ className: "ml-4 list-disc",
3528
+ children: [operation.errors.map((error) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(OperationErrorForm, {
3529
+ error,
3530
+ operation,
3531
+ onAddOperationError,
3532
+ deleteOperationError,
3533
+ setOperationErrorName
3534
+ }) }, error.id)), /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(OperationErrorForm, {
3535
+ operation,
3536
+ onAddOperationError,
3537
+ deleteOperationError,
3538
+ setOperationErrorName,
3539
+ focusOnMount: shouldFocusAddForm,
3540
+ onSubmit: onAddOperationErrorSubmit
3541
+ }, `${addErrorFormId}-${shouldFocusAddForm}`) })]
3542
+ });
3543
+ }
3544
+ //#endregion
3545
+ //#region editors/document-model-editor/components/operation.tsx
3546
+ const GraphqlEditor = lazy(() => import("./graphql-editor-CBJXEY_C.mjs"));
3547
+ function Operation(props) {
3548
+ const { operation, module, allOperationNames, lastCreatedOperationId, onAddOperationAndInitialSchema, updateOperationName, deleteOperation, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired } = props;
3549
+ const noInputRequired = isEmptyOperationSchema(operation.schema);
3550
+ const handleToggleNoInput = useCallback((checked) => toggleNoInputRequired(operation.id, checked), [operation.id, toggleNoInputRequired]);
3551
+ const handleUpdateDocument = useCallback((newDoc) => updateOperationSchema(operation.id, newDoc), [operation.id, updateOperationSchema]);
3552
+ const customLinter = useCallback((doc) => operation.name ? ensureValidOperationSchemaInputName(doc, operation.name) : [], [operation.name]);
3553
+ return /* @__PURE__ */ jsxs("div", {
3554
+ className: "mt-4 grid grid-cols-2 gap-x-12",
3555
+ style: {
3556
+ gridTemplateAreas: `
3557
+ "left editor"
3558
+ "errors editor"
3559
+ `,
3560
+ gridTemplateRows: "auto 1fr"
3561
+ },
3562
+ children: [
3563
+ /* @__PURE__ */ jsxs("div", {
3564
+ className: "flex flex-col gap-2",
3565
+ style: { gridArea: "left" },
3566
+ children: [/* @__PURE__ */ jsx(OperationForm, {
3567
+ operation,
3568
+ onAddOperationAndInitialSchema,
3569
+ updateOperationName,
3570
+ deleteOperation,
3571
+ module,
3572
+ allOperationNames
3573
+ }), /* @__PURE__ */ jsx(OperationDescriptionForm, {
3574
+ operation,
3575
+ focusOnMount: operation.id === lastCreatedOperationId,
3576
+ setOperationDescription
3577
+ })]
3578
+ }),
3579
+ /* @__PURE__ */ jsxs("div", {
3580
+ className: "relative top-8",
3581
+ style: { gridArea: "editor" },
3582
+ children: [/* @__PURE__ */ jsxs("label", {
3583
+ className: "mb-2 flex cursor-pointer items-center gap-2",
3584
+ children: [/* @__PURE__ */ jsx("input", {
3585
+ type: "checkbox",
3586
+ checked: noInputRequired,
3587
+ onChange: (e) => handleToggleNoInput(e.target.checked),
3588
+ className: "size-4 rounded-sm border-border"
3589
+ }), /* @__PURE__ */ jsx("span", {
3590
+ className: "text-sm text-foreground",
3591
+ children: "Operation with no inputs"
3592
+ })]
3593
+ }), !noInputRequired && /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(GraphqlEditor, {
3594
+ doc: operation.schema ?? "",
3595
+ updateDocumentInModel: handleUpdateDocument,
3596
+ customLinter
3597
+ }) })]
3598
+ }),
3599
+ /* @__PURE__ */ jsxs("div", {
3600
+ style: { gridArea: "errors" },
3601
+ children: [/* @__PURE__ */ jsx("h3", {
3602
+ className: "my-2 text-sm font-medium text-foreground",
3603
+ children: "Reducer Exceptions"
3604
+ }), /* @__PURE__ */ jsx(OperationErrors, {
3605
+ operation,
3606
+ addOperationError,
3607
+ deleteOperationError,
3608
+ setOperationErrorName
3609
+ })]
3610
+ })
3611
+ ]
3612
+ });
3613
+ }
3614
+ //#endregion
3615
+ //#region editors/document-model-editor/components/operations.tsx
3616
+ function Operations({ module, allOperations, shouldFocusNewOperation, updateOperationName, deleteOperation, addOperationAndInitialSchema, addOperationError, deleteOperationError, setOperationErrorName, updateOperationSchema, setOperationDescription, toggleNoInputRequired }) {
3617
+ const [lastCreatedOperationId, setLastCreatedOperationId] = useState(null);
3618
+ const addOperationFormId = useId();
3619
+ const allOperationNames = allOperations.map((o) => o.name).filter((n) => n !== null);
3620
+ const onAddOperationAndInitialSchema = useCallback(async (moduleId, name) => {
3621
+ const operationId = await addOperationAndInitialSchema(moduleId, name);
3622
+ if (operationId) setLastCreatedOperationId(operationId);
3623
+ return operationId;
3624
+ }, [addOperationAndInitialSchema, setLastCreatedOperationId]);
3625
+ return /* @__PURE__ */ jsxs("div", { children: [module.operations.map((operation) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Operation, {
3626
+ operation,
3627
+ module,
3628
+ lastCreatedOperationId,
3629
+ allOperationNames,
3630
+ addOperationError,
3631
+ deleteOperationError,
3632
+ setOperationErrorName,
3633
+ onAddOperationAndInitialSchema,
3634
+ updateOperationName,
3635
+ deleteOperation,
3636
+ updateOperationSchema,
3637
+ setOperationDescription,
3638
+ toggleNoInputRequired
3639
+ }) }, operation.id)), /* @__PURE__ */ jsx("div", {
3640
+ className: "mt-6 w-1/2 pr-6",
3641
+ children: /* @__PURE__ */ jsx(OperationForm, {
3642
+ onAddOperationAndInitialSchema,
3643
+ updateOperationName,
3644
+ deleteOperation,
3645
+ module,
3646
+ allOperationNames,
3647
+ focusOnMount: shouldFocusNewOperation
3648
+ }, addOperationFormId)
3649
+ })] });
3650
+ }
3651
+ //#endregion
3652
+ //#region editors/document-model-editor/components/module.tsx
3653
+ function Module(props) {
3654
+ const { module, modules, allOperations, lastCreatedModuleId, onAddModule, updateModuleName, deleteModule, updateOperationName, deleteOperation, addOperationAndInitialSchema, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired } = props;
3655
+ return /* @__PURE__ */ jsxs("div", {
3656
+ className: "relative rounded-3xl bg-muted p-6",
3657
+ children: [/* @__PURE__ */ jsxs("div", {
3658
+ className: "mb-2 w-1/2 pr-6",
3659
+ children: [/* @__PURE__ */ jsx(ModuleForm, {
3660
+ modules,
3661
+ module,
3662
+ onAddModule,
3663
+ updateModuleName
3664
+ }), !!module && /* @__PURE__ */ jsx("button", {
3665
+ "aria-label": "Delete module",
3666
+ tabIndex: -1,
3667
+ className: "absolute top-1 right-1 p-2 text-foreground transition-colors hover:hover-effect",
3668
+ onClick: () => {
3669
+ deleteModule(module.id);
3670
+ },
3671
+ children: /* @__PURE__ */ jsx("svg", {
3672
+ className: "size-6",
3673
+ viewBox: "0 0 24 24",
3674
+ fill: "currentcolor",
3675
+ children: /* @__PURE__ */ jsx("path", {
3676
+ fillRule: "evenodd",
3677
+ clipRule: "evenodd",
3678
+ 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"
3679
+ })
3680
+ })
3681
+ })]
3682
+ }), !!module && /* @__PURE__ */ jsx(Operations, {
3683
+ module,
3684
+ allOperations,
3685
+ shouldFocusNewOperation: module.id === lastCreatedModuleId,
3686
+ updateOperationName,
3687
+ deleteOperation,
3688
+ addOperationAndInitialSchema,
3689
+ updateOperationSchema,
3690
+ setOperationDescription,
3691
+ addOperationError,
3692
+ deleteOperationError,
3693
+ setOperationErrorName,
3694
+ toggleNoInputRequired
3695
+ })]
3696
+ });
3697
+ }
3698
+ //#endregion
3699
+ //#region editors/document-model-editor/components/modules.tsx
3700
+ function Modules({ modules, allOperations, addModule, updateModuleName, deleteModule, updateOperationName, deleteOperation, addOperationAndInitialSchema, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired }) {
3701
+ const [lastCreatedModuleId, setLastCreatedModuleId] = useState(null);
3702
+ const focusTrapRef = useRef(null);
3703
+ const onAddModule = useCallback(async (name) => {
3704
+ const moduleId = await addModule(name);
3705
+ if (moduleId) {
3706
+ setLastCreatedModuleId(moduleId);
3707
+ focusTrapRef.current?.focus();
3708
+ }
3709
+ return moduleId;
3710
+ }, [addModule, setLastCreatedModuleId]);
3711
+ return /* @__PURE__ */ jsxs("div", {
3712
+ className: "flex flex-col gap-2",
3713
+ children: [
3714
+ modules.map((module) => /* @__PURE__ */ jsx(Module, {
3715
+ module,
3716
+ modules,
3717
+ allOperations,
3718
+ lastCreatedModuleId,
3719
+ onAddModule,
3720
+ updateModuleName,
3721
+ deleteModule,
3722
+ updateOperationName,
3723
+ deleteOperation,
3724
+ addOperationAndInitialSchema,
3725
+ updateOperationSchema,
3726
+ setOperationDescription,
3727
+ addOperationError,
3728
+ deleteOperationError,
3729
+ setOperationErrorName,
3730
+ toggleNoInputRequired
3731
+ }, module.id)),
3732
+ /* @__PURE__ */ jsx(Module, {
3733
+ modules,
3734
+ allOperations,
3735
+ lastCreatedModuleId,
3736
+ onAddModule,
3737
+ updateModuleName,
3738
+ deleteModule,
3739
+ updateOperationName,
3740
+ deleteOperation,
3741
+ addOperationAndInitialSchema,
3742
+ updateOperationSchema,
3743
+ setOperationDescription,
3744
+ addOperationError,
3745
+ deleteOperationError,
3746
+ setOperationErrorName,
3747
+ toggleNoInputRequired
3748
+ }, "add-module"),
3749
+ /* @__PURE__ */ jsx("div", {
3750
+ ref: focusTrapRef,
3751
+ tabIndex: 0,
3752
+ className: "size-0 overflow-hidden",
3753
+ "aria-hidden": "true"
3754
+ })
3755
+ ]
3756
+ });
3757
+ }
3758
+ //#endregion
3759
+ //#region editors/document-model-editor/components/version-controls.tsx
3760
+ const compactButtonStyle$1 = "min-h-0 min-w-0 flex-none rounded-lg px-6 py-1.5 text-sm whitespace-nowrap";
3761
+ function VersionControls(props) {
3762
+ const { specifications, viewedVersion, onViewVersion, onReleaseNewVersion } = props;
3763
+ const [showReleaseModal, setShowReleaseModal] = useState(false);
3764
+ const latestVersion = specifications[specifications.length - 1].version;
3765
+ const nextVersion = latestVersion + 1;
3766
+ return /* @__PURE__ */ jsxs("div", {
3767
+ className: "mb-4 flex items-center justify-between gap-4",
3768
+ children: [
3769
+ /* @__PURE__ */ jsxs("div", {
3770
+ className: "flex items-center gap-2",
3771
+ children: [/* @__PURE__ */ jsxs("span", {
3772
+ className: "rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground",
3773
+ "data-testid": "model-version-badge",
3774
+ children: ["Version ", viewedVersion]
3775
+ }), specifications.length >= 2 && /* @__PURE__ */ jsx("div", {
3776
+ "aria-label": "Document model version",
3777
+ "data-testid": "model-version-switcher",
3778
+ children: /* @__PURE__ */ jsx(ConnectSelect, {
3779
+ absolutePositionMenu: true,
3780
+ containerClassName: "z-10 [&_svg]:size-4",
3781
+ id: "model-version-switcher",
3782
+ itemClassName: "gap-1 px-2 py-1 font-mono text-xs leading-none [&_p:empty]:hidden",
3783
+ items: specifications.map((spec) => ({
3784
+ value: String(spec.version),
3785
+ displayValue: /* @__PURE__ */ jsx("span", {
3786
+ className: "normal-case",
3787
+ children: spec.version === latestVersion ? `v${spec.version} (latest)` : `v${spec.version} (frozen)`
3788
+ })
3789
+ })),
3790
+ listClassName: "border border-t-0 border-border shadow-md",
3791
+ menuClassName: "min-w-0 pr-1.5",
3792
+ onChange: (value) => {
3793
+ const version = Number(value);
3794
+ onViewVersion(version === latestVersion ? "latest" : version);
3795
+ },
3796
+ value: String(viewedVersion)
3797
+ })
3798
+ })]
3799
+ }),
3800
+ /* @__PURE__ */ jsx(Button, {
3801
+ className: "inline-flex h-8 items-center justify-center py-0",
3802
+ "data-testid": "release-new-version-button",
3803
+ onClick: () => setShowReleaseModal(true),
3804
+ type: "button",
3805
+ children: "Release new version"
3806
+ }),
3807
+ /* @__PURE__ */ jsx(Modal, {
3808
+ open: showReleaseModal,
3809
+ onOpenChange: (status) => {
3810
+ if (!status) setShowReleaseModal(false);
3811
+ },
3812
+ children: /* @__PURE__ */ jsxs("div", {
3813
+ className: "w-[440px] p-6",
3814
+ children: [
3815
+ /* @__PURE__ */ jsxs("div", {
3816
+ className: "pb-2 text-2xl font-bold text-foreground",
3817
+ children: ["Release version ", nextVersion]
3818
+ }),
3819
+ /* @__PURE__ */ jsxs("div", {
3820
+ className: "my-4 rounded-md bg-background p-4 text-left text-sm text-foreground",
3821
+ children: [/* @__PURE__ */ jsxs("p", { children: [
3822
+ "Version ",
3823
+ latestVersion,
3824
+ " will be frozen as-is. Version",
3825
+ " ",
3826
+ nextVersion,
3827
+ " starts as an identical copy, and all further edits apply to version ",
3828
+ nextVersion,
3829
+ "."
3830
+ ] }), /* @__PURE__ */ jsxs("p", {
3831
+ className: "mt-3",
3832
+ children: [
3833
+ "Existing version ",
3834
+ latestVersion,
3835
+ " documents will be upgradeable once you define the migration."
3836
+ ]
3837
+ })]
3838
+ }),
3839
+ /* @__PURE__ */ jsxs("div", {
3840
+ className: "mt-4 flex justify-between gap-3",
3841
+ children: [/* @__PURE__ */ jsx(ModalButton, {
3842
+ className: compactButtonStyle$1,
3843
+ onClick: () => setShowReleaseModal(false),
3844
+ variant: "cancel",
3845
+ children: "Cancel"
3846
+ }), /* @__PURE__ */ jsxs(ModalButton, {
3847
+ className: compactButtonStyle$1,
3848
+ "data-testid": "confirm-release-button",
3849
+ onClick: () => {
3850
+ setShowReleaseModal(false);
3851
+ onReleaseNewVersion();
3852
+ },
3853
+ variant: "confirm",
3854
+ children: ["Release version ", nextVersion]
3855
+ })]
3856
+ })
3857
+ ]
3858
+ })
3859
+ })
3860
+ ]
3861
+ });
3862
+ }
3863
+ function FrozenVersionBanner(props) {
3864
+ const { viewedVersion, latestVersion } = props;
3865
+ return /* @__PURE__ */ jsxs("div", {
3866
+ className: "mb-4 rounded-md border border-border bg-muted p-3 text-sm text-foreground",
3867
+ "data-testid": "frozen-version-banner",
3868
+ children: [
3869
+ "Version ",
3870
+ viewedVersion,
3871
+ " is frozen. You're viewing it read-only. Edits go to version ",
3872
+ latestVersion,
3873
+ "."
3874
+ ]
3875
+ });
3876
+ }
3877
+ //#endregion
3878
+ //#region editors/document-model-editor/components/version-advisory-modal.tsx
3879
+ const compactButtonStyle = "min-h-0 min-w-0 flex-none rounded-lg px-4 py-1.5 text-sm whitespace-nowrap";
3880
+ function FieldDiffList(props) {
3881
+ const { label, fields } = props;
3882
+ if (fields.length === 0) return null;
3883
+ return /* @__PURE__ */ jsxs("div", {
3884
+ className: "mt-3",
3885
+ children: [/* @__PURE__ */ jsx("p", {
3886
+ className: "mb-1.5",
3887
+ children: label
3888
+ }), /* @__PURE__ */ jsx("div", {
3889
+ className: "flex flex-col items-start gap-1",
3890
+ children: fields.map((field) => /* @__PURE__ */ jsx("span", {
3891
+ className: "rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground",
3892
+ children: field
3893
+ }, field))
3894
+ })]
3895
+ });
3896
+ }
3897
+ function VersionAdvisoryModal(props) {
3898
+ const { prompt, onReleaseFirst, onKeepEditing, onCancel } = props;
3899
+ if (!prompt) return null;
3900
+ const { version, reason, diff } = prompt;
3901
+ const nextVersion = version + 1;
3902
+ return /* @__PURE__ */ jsx(Modal, {
3903
+ open: true,
3904
+ onOpenChange: (status) => {
3905
+ if (!status) onCancel();
3906
+ },
3907
+ children: /* @__PURE__ */ jsxs("div", {
3908
+ className: "w-[440px] p-6",
3909
+ "data-testid": "version-advisory-modal",
3910
+ children: [
3911
+ /* @__PURE__ */ jsxs("div", {
3912
+ className: "pb-2 text-2xl font-bold text-foreground",
3913
+ children: [
3914
+ "Is version ",
3915
+ version,
3916
+ " of this model already in use?"
3917
+ ]
3918
+ }),
3919
+ /* @__PURE__ */ jsxs("div", {
3920
+ className: "my-4 rounded-md bg-background p-4 text-left text-sm text-foreground",
3921
+ children: [
3922
+ /* @__PURE__ */ jsxs("p", { children: [
3923
+ reason,
3924
+ " Documents that were already created with version ",
3925
+ version,
3926
+ " ",
3927
+ "may stop working correctly."
3928
+ ] }),
3929
+ diff && /* @__PURE__ */ jsxs(Fragment, { children: [
3930
+ /* @__PURE__ */ jsx(FieldDiffList, {
3931
+ fields: diff.addedFields,
3932
+ label: "New fields:"
3933
+ }),
3934
+ /* @__PURE__ */ jsx(FieldDiffList, {
3935
+ fields: diff.removedFields,
3936
+ label: "Removed fields:"
3937
+ }),
3938
+ /* @__PURE__ */ jsx(FieldDiffList, {
3939
+ fields: diff.changedFields,
3940
+ label: "Changed fields:"
3941
+ })
3942
+ ] }),
3943
+ /* @__PURE__ */ jsxs("p", {
3944
+ className: "mt-3",
3945
+ children: [
3946
+ "If others are already using version ",
3947
+ version,
3948
+ ", release version",
3949
+ " ",
3950
+ nextVersion,
3951
+ " first. Your change will go into version ",
3952
+ nextVersion,
3953
+ ", and existing documents can be updated safely."
3954
+ ]
3955
+ })
3956
+ ]
3957
+ }),
3958
+ /* @__PURE__ */ jsxs("div", {
3959
+ className: "mt-4 flex flex-col gap-2",
3960
+ children: [/* @__PURE__ */ jsx(ModalButton, {
3961
+ className: compactButtonStyle,
3962
+ "data-testid": "advisory-release-first",
3963
+ onClick: onReleaseFirst,
3964
+ variant: "confirm",
3965
+ children: `It's in use — release v${nextVersion} first`
3966
+ }), /* @__PURE__ */ jsxs(ModalButton, {
3967
+ className: compactButtonStyle,
3968
+ "data-testid": "advisory-keep-editing",
3969
+ onClick: onKeepEditing,
3970
+ variant: "cancel",
3971
+ children: ["Still in development — keep editing v", version]
3972
+ })]
3973
+ })
3974
+ ]
3975
+ })
3976
+ });
3977
+ }
3978
+ //#endregion
3979
+ //#region editors/document-model-editor/config.ts
3980
+ const editorConfig = { isExternalControlsEnabled: false };
3981
+ //#endregion
3982
+ //#region editors/document-model-editor/hooks/useDocumentModelDocument.ts
3983
+ function useSelectedDocumentModelDocument() {
3984
+ return useSelectedDocumentOfType("powerhouse/document-model");
3985
+ }
3986
+ //#endregion
3987
+ //#region editors/document-model-editor/utils/change-classification.ts
3988
+ function isShapeTypeNode(node) {
3989
+ return node.kind === import_graphql.Kind.OBJECT_TYPE_DEFINITION || node.kind === import_graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION || node.kind === import_graphql.Kind.ENUM_TYPE_DEFINITION;
3990
+ }
3991
+ function collectTypeFields(doc) {
3992
+ const types = /* @__PURE__ */ new Map();
3993
+ for (const definition of doc.definitions) {
3994
+ if (!isShapeTypeNode(definition)) continue;
3995
+ const fields = /* @__PURE__ */ new Map();
3996
+ if (definition.kind === import_graphql.Kind.ENUM_TYPE_DEFINITION) for (const value of definition.values ?? []) fields.set(value.name.value, "value");
3997
+ else for (const field of definition.fields ?? []) fields.set(field.name.value, (0, import_graphql.print)(field.type));
3998
+ types.set(definition.name.value, fields);
3999
+ }
4000
+ return types;
4001
+ }
4002
+ function escapeRegExp(value) {
4003
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4004
+ }
4005
+ function replaceTypeName(printedType, oldName, newName) {
4006
+ return printedType.replace(new RegExp(`\\b${escapeRegExp(oldName)}\\b`, "g"), newName);
4007
+ }
4008
+ function typeSignature(name, fields) {
4009
+ return [...fields.entries()].map(([field, type]) => `${field}:${replaceTypeName(type, name, "__SELF__")}`).sort().join("|");
4010
+ }
4011
+ function detectTypeRenames(oldTypes, newTypes) {
4012
+ const renames = /* @__PURE__ */ new Map();
4013
+ const removed = [...oldTypes.keys()].filter((name) => !newTypes.has(name));
4014
+ const added = new Set([...newTypes.keys()].filter((name) => !oldTypes.has(name)));
4015
+ for (const oldName of removed) {
4016
+ const oldSignature = typeSignature(oldName, oldTypes.get(oldName));
4017
+ for (const newName of added) if (typeSignature(newName, newTypes.get(newName)) === oldSignature) {
4018
+ renames.set(oldName, newName);
4019
+ added.delete(newName);
4020
+ break;
4021
+ }
4022
+ }
4023
+ return renames;
4024
+ }
4025
+ function flattenFields(types, renames) {
4026
+ const fields = /* @__PURE__ */ new Map();
4027
+ for (const [typeName, typeFields] of types) {
4028
+ const resolvedTypeName = renames.get(typeName) ?? typeName;
4029
+ for (const [fieldName, printedType] of typeFields) {
4030
+ let resolvedType = printedType;
4031
+ for (const [oldName, newName] of renames) resolvedType = replaceTypeName(resolvedType, oldName, newName);
4032
+ fields.set(`${resolvedTypeName}.${fieldName}`, resolvedType);
4033
+ }
4034
+ }
4035
+ return fields;
4036
+ }
4037
+ function hasShapeChange(diff) {
4038
+ return diff.addedFields.length > 0 || diff.removedFields.length > 0 || diff.changedFields.length > 0;
4039
+ }
4040
+ function diffSdlShapes(oldSdl, newSdl) {
4041
+ const empty = {
4042
+ addedFields: [],
4043
+ removedFields: [],
4044
+ changedFields: []
4045
+ };
4046
+ let oldDoc;
4047
+ let newDoc;
4048
+ try {
4049
+ oldDoc = (0, import_graphql.parse)(oldSdl);
4050
+ newDoc = (0, import_graphql.parse)(newSdl);
4051
+ } catch {
4052
+ return empty;
4053
+ }
4054
+ const oldTypes = collectTypeFields(oldDoc);
4055
+ const newTypes = collectTypeFields(newDoc);
4056
+ const oldFields = flattenFields(oldTypes, detectTypeRenames(oldTypes, newTypes));
4057
+ const newFields = flattenFields(newTypes, /* @__PURE__ */ new Map());
4058
+ const diff = {
4059
+ addedFields: [],
4060
+ removedFields: [],
4061
+ changedFields: []
4062
+ };
4063
+ for (const [key, newType] of newFields) {
4064
+ const oldType = oldFields.get(key);
4065
+ if (oldType === void 0) diff.addedFields.push(key);
4066
+ else if (oldType !== newType) diff.changedFields.push(`${key}: ${oldType} → ${newType}`);
4067
+ }
4068
+ for (const key of oldFields.keys()) if (!newFields.has(key)) diff.removedFields.push(key);
4069
+ return diff;
4070
+ }
4071
+ const SAFE = { kind: "safe" };
4072
+ function isBlank(value) {
4073
+ return !value || !value.trim() || value.trim() === "{}";
4074
+ }
4075
+ /**
4076
+ * True for a blank SDL, or an SDL whose types contain nothing but the
4077
+ * `_placeholder` field the editor seeds new state/operation schemas with
4078
+ * (see `makeInitialSchemaDoc` / `makeOperationInitialDoc` in ./helpers.ts).
4079
+ * Replacing a placeholder-only schema with real fields is a user's first
4080
+ * edit on a brand-new model, not a version-relevant change.
4081
+ */
4082
+ function isPlaceholderOnlySchema(sdl) {
4083
+ if (isBlank(sdl)) return true;
4084
+ let doc;
4085
+ try {
4086
+ doc = (0, import_graphql.parse)(sdl);
4087
+ } catch {
4088
+ return false;
4089
+ }
4090
+ return [...collectTypeFields(doc).values()].every((fields) => fields.size === 0 || fields.size === 1 && fields.has("_placeholder"));
4091
+ }
4092
+ function findOperation(spec, operationId) {
4093
+ for (const module of spec.modules) {
4094
+ const operation = module.operations.find((op) => op.id === operationId);
4095
+ if (operation) return operation;
4096
+ }
4097
+ }
4098
+ function addedSinceLastRelease(operationId, previousSpec) {
4099
+ return previousSpec !== void 0 && !findOperation(previousSpec, operationId);
4100
+ }
4101
+ function classifySetStateSchema(input, latestSpec) {
4102
+ const currentSchema = input.scope === "local" ? latestSpec.state.local.schema : latestSpec.state.global.schema;
4103
+ if (isPlaceholderOnlySchema(currentSchema)) return SAFE;
4104
+ const diff = diffSdlShapes(currentSchema, input.schema);
4105
+ if (!hasShapeChange(diff)) return SAFE;
4106
+ return {
4107
+ kind: "version-relevant",
4108
+ 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.`,
4109
+ diff
4110
+ };
4111
+ }
4112
+ /**
4113
+ * The editor pre-fills a fresh model's initial value from the placeholder
4114
+ * schema, so a value that is blank or carries only the `_placeholder` key is
4115
+ * still being initialized rather than changed.
4116
+ */
4117
+ function isPlaceholderOnlyInitialValue(value) {
4118
+ if (isBlank(value)) return true;
4119
+ let parsed;
4120
+ try {
4121
+ parsed = JSON.parse(value);
4122
+ } catch {
4123
+ return false;
4124
+ }
4125
+ if (typeof parsed !== "object" || parsed === null) return false;
4126
+ return Object.keys(parsed).every((key) => key === "_placeholder");
4127
+ }
4128
+ function classifySetInitialState(input, latestSpec) {
4129
+ const currentValue = input.scope === "local" ? latestSpec.state.local.initialValue : latestSpec.state.global.initialValue;
4130
+ if (isPlaceholderOnlyInitialValue(currentValue)) return SAFE;
4131
+ if (compareStringsWithoutWhitespace(currentValue, input.initialValue)) return SAFE;
4132
+ return {
4133
+ kind: "version-relevant",
4134
+ reason: `You're changing the starting content that version ${latestSpec.version} documents are built on.`
4135
+ };
4136
+ }
4137
+ function classifyOperationChange(action, operationId, latestSpec, previousSpec) {
4138
+ if (addedSinceLastRelease(operationId, previousSpec)) return SAFE;
4139
+ const operation = findOperation(latestSpec, operationId);
4140
+ if (!operation) return SAFE;
4141
+ const operationLabel = operation.name || "an operation";
4142
+ switch (action.type) {
4143
+ case "DELETE_OPERATION": return {
4144
+ kind: "version-relevant",
4145
+ reason: `You're removing the "${operationLabel}" operation from version ${latestSpec.version}.`
4146
+ };
4147
+ case "SET_OPERATION_NAME":
4148
+ if (isBlank(operation.name)) return SAFE;
4149
+ return {
4150
+ kind: "version-relevant",
4151
+ reason: `You're renaming the "${operationLabel}" operation in version ${latestSpec.version}.`
4152
+ };
4153
+ case "SET_OPERATION_SCHEMA": {
4154
+ if (isPlaceholderOnlySchema(operation.schema ?? "")) return SAFE;
4155
+ if (isBlank(action.input.schema)) return {
4156
+ kind: "version-relevant",
4157
+ reason: `You're changing the information that the "${operationLabel}" operation accepts in version ${latestSpec.version}.`
4158
+ };
4159
+ const diff = diffSdlShapes(operation.schema ?? "", action.input.schema ?? "");
4160
+ if (!hasShapeChange(diff)) return SAFE;
4161
+ return {
4162
+ kind: "version-relevant",
4163
+ reason: `You're changing the information that the "${operationLabel}" operation accepts in version ${latestSpec.version}.`,
4164
+ diff
4165
+ };
4166
+ }
4167
+ default: return SAFE;
4168
+ }
4169
+ }
4170
+ function classifyDeleteModule(moduleId, latestSpec, previousSpec) {
4171
+ const module = latestSpec.modules.find((candidate) => candidate.id === moduleId);
4172
+ if (!module || module.operations.length === 0) return SAFE;
4173
+ if (module.operations.every((operation) => addedSinceLastRelease(operation.id, previousSpec))) return SAFE;
4174
+ return {
4175
+ kind: "version-relevant",
4176
+ reason: `You're removing the "${module.name}" module and all of its operations from version ${latestSpec.version}.`
4177
+ };
4178
+ }
4179
+ /**
4180
+ * Classifies a document-model action as version-relevant (would break
4181
+ * documents created with the current version) or safe. `previousSpec` is the
4182
+ * last released specification, used to exempt operations added since the
4183
+ * release.
4184
+ */
4185
+ function classifyDocumentModelAction(action, latestSpec, previousSpec) {
4186
+ switch (action.type) {
4187
+ case "SET_STATE_SCHEMA": return classifySetStateSchema(action.input, latestSpec);
4188
+ case "SET_INITIAL_STATE": return classifySetInitialState(action.input, latestSpec);
4189
+ case "DELETE_OPERATION":
4190
+ case "SET_OPERATION_NAME":
4191
+ case "SET_OPERATION_SCHEMA": return classifyOperationChange(action, action.input.id, latestSpec, previousSpec);
4192
+ case "DELETE_MODULE": return classifyDeleteModule(action.input.id, latestSpec, previousSpec);
4193
+ default: return SAFE;
4194
+ }
4195
+ }
4196
+ /**
4197
+ * Pure decision core of the version advisory: given the actions about to be
4198
+ * dispatched, decide whether to dispatch immediately or prompt the user.
4199
+ */
4200
+ function decideDispatch(actions, latestSpec, previousSpec, hasSessionChoice) {
4201
+ if (hasSessionChoice) return { kind: "dispatch" };
4202
+ for (const action of actions) {
4203
+ const classification = classifyDocumentModelAction(action, latestSpec, previousSpec);
4204
+ if (classification.kind === "version-relevant") return {
4205
+ kind: "prompt",
4206
+ reason: classification.reason,
4207
+ diff: classification.diff
4208
+ };
4209
+ }
4210
+ return { kind: "dispatch" };
4211
+ }
4212
+ //#endregion
4213
+ //#region editors/document-model-editor/hooks/useVersionAdvisory.ts
4214
+ /**
4215
+ * Versions the user has confirmed as "still in development" (or that were
4216
+ * just created via an explicit release) for this browser session. Keyed by
4217
+ * `${documentId}:${version}`. Deliberately in-memory: a publisher returning
4218
+ * in a later session is asked again, which is when the reminder matters.
4219
+ */
4220
+ const sessionVersionChoices = /* @__PURE__ */ new Set();
4221
+ function useVersionAdvisory(args) {
4222
+ const { documentId, latestSpec, previousSpec, dispatch, onReleaseError } = args;
4223
+ const [prompt, setPrompt] = useState(void 0);
4224
+ const pendingRef = useRef(void 0);
4225
+ const choiceKey = `${documentId}:${latestSpec.version}`;
4226
+ const guardedDispatch = (...dispatchArgs) => {
4227
+ const [action] = dispatchArgs;
4228
+ const decision = decideDispatch((Array.isArray(action) ? action : [action]).filter((candidate) => candidate !== void 0), latestSpec, previousSpec, sessionVersionChoices.has(choiceKey));
4229
+ if (decision.kind === "dispatch") {
4230
+ dispatch(...dispatchArgs);
4231
+ return;
4232
+ }
4233
+ pendingRef.current = dispatchArgs;
4234
+ setPrompt({
4235
+ version: latestSpec.version,
4236
+ reason: decision.reason,
4237
+ diff: decision.diff
4238
+ });
4239
+ };
4240
+ const flushPending = () => {
4241
+ const pending = pendingRef.current;
4242
+ pendingRef.current = void 0;
4243
+ if (pending) dispatch(...pending);
4244
+ };
4245
+ const releaseFirst = () => {
4246
+ setPrompt(void 0);
4247
+ if (!pendingRef.current) return;
4248
+ dispatch(releaseNewVersion(), (errors) => {
4249
+ if (errors.length > 0) {
4250
+ pendingRef.current = void 0;
4251
+ onReleaseError?.(errors[0].message);
4252
+ }
4253
+ }, () => {
4254
+ if (!pendingRef.current) return;
4255
+ sessionVersionChoices.add(`${documentId}:${latestSpec.version + 1}`);
4256
+ flushPending();
4257
+ });
4258
+ };
4259
+ const keepEditing = () => {
4260
+ sessionVersionChoices.add(choiceKey);
4261
+ setPrompt(void 0);
4262
+ flushPending();
4263
+ };
4264
+ const cancelAdvisory = () => {
4265
+ pendingRef.current = void 0;
4266
+ setPrompt(void 0);
4267
+ };
4268
+ const markVersionInDevelopment = (version) => {
4269
+ sessionVersionChoices.add(`${documentId}:${version}`);
4270
+ };
4271
+ return {
4272
+ guardedDispatch,
4273
+ prompt,
4274
+ releaseFirst,
4275
+ keepEditing,
4276
+ cancelAdvisory,
4277
+ markVersionInDevelopment
4278
+ };
4279
+ }
4280
+ //#endregion
4281
+ //#region editors/document-model-editor/editor.tsx
4282
+ var editor_exports = /* @__PURE__ */ __exportAll({ default: () => Editor });
4283
+ const StateSchemas = lazy(() => import("./state-schemas-BHuo0GPl.mjs"));
4284
+ const noopSetStateSchema = () => void 0;
4285
+ const noopSetInitialState = () => void 0;
4286
+ function Editor() {
4287
+ useSetPHDocumentEditorConfig(editorConfig);
4288
+ const toast = usePHToast();
4289
+ const [document, dispatch] = useSelectedDocumentModelDocument();
4290
+ const [scope, setScope] = useState("global");
4291
+ const documentNodeName = document.header.name;
4292
+ const { name: modelName, id: documentType, extension, description, author: { name: authorName, website: authorWebsite } } = document.state.global;
4293
+ const specifications = document.state.global.specifications;
4294
+ const latestSpec = specifications[specifications.length - 1];
4295
+ const previousSpec = specifications.length >= 2 ? specifications[specifications.length - 2] : void 0;
4296
+ const [viewedVersion, setViewedVersion] = useState("latest");
4297
+ const viewedSpec = viewedVersion === "latest" ? latestSpec : specifications.find((spec) => spec.version === viewedVersion) ?? latestSpec;
4298
+ const isViewingFrozenVersion = viewedSpec.version !== latestSpec.version;
4299
+ const { state: { global: { schema: globalStateSchema, initialValue: globalStateInitialValue }, local: { schema: localStateSchema, initialValue: localStateInitialValue } }, modules } = viewedSpec;
4300
+ const operations = modules.flatMap((module) => module.operations);
4301
+ const { state: { global: { schema: latestGlobalStateSchema, initialValue: latestGlobalStateInitialValue }, local: { schema: latestLocalStateSchema, initialValue: latestLocalStateInitialValue } }, modules: latestModules } = latestSpec;
4302
+ const latestOperations = latestModules.flatMap((module) => module.operations);
4303
+ const shouldSetInitialName = useRef(!modelName && !!documentNodeName && latestOperations.length === 0);
4304
+ useEffect(() => {
4305
+ if (!shouldSetInitialName.current || !documentNodeName) return;
4306
+ const initialSchemaDoc = initializeModelSchema(documentNodeName);
4307
+ const actions = [setModelName({ name: documentNodeName }), setStateSchema({
4308
+ schema: initialSchemaDoc,
4309
+ scope: "global"
4310
+ })];
4311
+ dispatch(actions);
4312
+ shouldSetInitialName.current = false;
4313
+ }, [documentNodeName, dispatch]);
4314
+ const { guardedDispatch, prompt, releaseFirst, keepEditing, cancelAdvisory, markVersionInDevelopment } = useVersionAdvisory({
4315
+ documentId: document.header.id,
4316
+ latestSpec,
4317
+ previousSpec,
4318
+ dispatch,
4319
+ onReleaseError: (message) => {
4320
+ if (toast) toast(message, { type: "connect-warning" });
4321
+ }
4322
+ });
4323
+ const handleReleaseNewVersion = () => {
4324
+ const nextVersion = latestSpec.version + 1;
4325
+ dispatch(releaseNewVersion(), (errors) => {
4326
+ if (errors.length > 0 && toast) toast(errors[0].message, { type: "connect-warning" });
4327
+ }, () => {
4328
+ markVersionInDevelopment(nextVersion);
4329
+ setViewedVersion("latest");
4330
+ });
4331
+ };
4332
+ const operationSchemasSdl = operations.flatMap((operation) => operation.schema ?? []).join("\n");
4333
+ const handleSetModelId = (id) => {
4334
+ if (compareStringsWithoutWhitespace(id, documentType)) return;
4335
+ guardedDispatch([setModelId({ id })]);
4336
+ };
4337
+ const handleSetModelDescription = (newDescription) => {
4338
+ if (compareStringsWithoutWhitespace(newDescription, description)) return;
4339
+ guardedDispatch(setModelDescription({ description: newDescription }));
4340
+ };
4341
+ const handleSetModelExtension = (newExtension) => {
4342
+ if (compareStringsWithoutWhitespace(newExtension, extension)) return;
4343
+ guardedDispatch(setModelExtension({ extension: newExtension }));
4344
+ };
4345
+ const handleSetModelName = (newName) => {
4346
+ if (compareStringsWithoutWhitespace(newName, modelName)) return;
4347
+ guardedDispatch(setModelName({ name: newName }));
4348
+ };
4349
+ const handleSetAuthorName = (newAuthorName) => {
4350
+ if (compareStringsWithoutWhitespace(newAuthorName, authorName)) return;
4351
+ guardedDispatch(setAuthorName({ authorName: newAuthorName }));
4352
+ };
4353
+ const handleSetAuthorWebsite = (newAuthorWebsite) => {
4354
+ if (compareStringsWithoutWhitespace(newAuthorWebsite, authorWebsite ?? "")) return;
4355
+ guardedDispatch(setAuthorWebsite({ authorWebsite: newAuthorWebsite }));
4356
+ };
4357
+ const handleSetStateSchema = (newSchema, scope) => {
4358
+ if (compareStringsWithoutWhitespace(newSchema, scope === "global" ? latestGlobalStateSchema : latestLocalStateSchema)) return;
4359
+ guardedDispatch(setStateSchema({
4360
+ schema: newSchema,
4361
+ scope
4362
+ }));
4363
+ };
4364
+ const handleSetInitialState = (newInitialValue, scope) => {
4365
+ if (compareStringsWithoutWhitespace(newInitialValue, scope === "global" ? latestGlobalStateInitialValue : latestLocalStateInitialValue)) return;
4366
+ guardedDispatch(setInitialState({
4367
+ initialValue: newInitialValue,
4368
+ scope
4369
+ }));
4370
+ };
4371
+ const handleAddModule = (name) => {
4372
+ return new Promise((resolve) => {
4373
+ try {
4374
+ if (latestModules.some((module) => compareStringsWithoutWhitespace(module.name, name))) {
4375
+ resolve(void 0);
4376
+ return;
4377
+ }
4378
+ const id = generateId();
4379
+ guardedDispatch(addModule({
4380
+ id,
4381
+ name
4382
+ }));
4383
+ resolve(id);
4384
+ } catch (error) {
4385
+ console.error("Failed to add module:", error);
4386
+ resolve(void 0);
4387
+ }
4388
+ });
4389
+ };
4390
+ const handleSetModuleName = (id, name) => {
4391
+ if (latestModules.some((module) => compareStringsWithoutWhitespace(module.name, name))) return;
4392
+ guardedDispatch(setModuleName({
4393
+ id,
4394
+ name
4395
+ }));
4396
+ };
4397
+ const handleDeleteModule = (id) => {
4398
+ guardedDispatch(deleteModule({ id }));
4399
+ };
4400
+ const handleAddOperation = (moduleId, name) => {
4401
+ return new Promise((resolve) => {
4402
+ const id = generateId();
4403
+ guardedDispatch(addOperation({
4404
+ id,
4405
+ moduleId,
4406
+ name,
4407
+ scope
4408
+ }), (errors) => {
4409
+ if (errors.length > 0) {
4410
+ if (toast) toast(errors[0].message, { type: "connect-warning" });
4411
+ resolve(void 0);
4412
+ } else resolve(id);
4413
+ }, () => resolve(id));
4414
+ });
4415
+ };
4416
+ const handleSetOperationName = (id, name) => {
4417
+ guardedDispatch(setOperationName({
4418
+ id,
4419
+ name
4420
+ }), (errors) => {
4421
+ if (errors.length > 0 && toast) toast(errors[0].message, { type: "connect-warning" });
4422
+ });
4423
+ };
4424
+ const handleSetOperationSchema = (id, newSchema) => {
4425
+ const operation = latestOperations.find((operation) => operation.id === id);
4426
+ if (operation?.schema && compareStringsWithoutWhitespace(newSchema, operation.schema)) return;
4427
+ guardedDispatch(setOperationSchema({
4428
+ id,
4429
+ schema: newSchema
4430
+ }));
4431
+ };
4432
+ const handleToggleNoInputRequired = (id, noInputRequired) => {
4433
+ const operation = latestOperations.find((op) => op.id === id);
4434
+ if (!operation?.name) return;
4435
+ if (noInputRequired) guardedDispatch(setOperationSchema({
4436
+ id,
4437
+ schema: makeEmptyOperationSchema(operation.name)
4438
+ }));
4439
+ else guardedDispatch(setOperationSchema({
4440
+ id,
4441
+ schema: makeOperationInitialDoc(operation.name)
4442
+ }));
4443
+ };
4444
+ const handleSetOperationDescription = (id, newDescription) => {
4445
+ if (compareStringsWithoutWhitespace(latestOperations.find((operation) => operation.id === id)?.description ?? "", newDescription)) return;
4446
+ guardedDispatch(setOperationDescription({
4447
+ id,
4448
+ description: newDescription
4449
+ }));
4450
+ };
4451
+ const handleDeleteOperation = (id) => {
4452
+ guardedDispatch(deleteOperation({ id }));
4453
+ };
4454
+ const handleAddOperationError = (operationId, errorName) => {
4455
+ return new Promise((resolve) => {
4456
+ try {
4457
+ if ((latestOperations.find((operation) => operation.id === operationId)?.errors.map((error) => error.name).filter(Boolean) ?? []).some((name) => compareStringsWithoutWhitespace(name, errorName))) {
4458
+ resolve(void 0);
4459
+ return;
4460
+ }
4461
+ const id = generateId();
4462
+ const errorCode = pascalCase(errorName);
4463
+ guardedDispatch(addOperationError({
4464
+ id,
4465
+ operationId,
4466
+ errorName,
4467
+ errorCode
4468
+ }));
4469
+ resolve(id);
4470
+ } catch (error) {
4471
+ console.error("Failed to add operation error:", error);
4472
+ resolve(void 0);
4473
+ }
4474
+ });
4475
+ };
4476
+ const handleDeleteOperationError = (id) => {
4477
+ guardedDispatch(deleteOperationError({ id }));
4478
+ };
4479
+ const handleSetOperationErrorName = (operationId, errorId, errorName) => {
4480
+ if ((latestOperations.find((operation) => operation.id === operationId)?.errors.map((error) => error.name).filter(Boolean) ?? []).some((name) => compareStringsWithoutWhitespace(name, errorName))) return;
4481
+ guardedDispatch(setOperationErrorName({
4482
+ id: errorId,
4483
+ errorName
4484
+ }));
4485
+ };
4486
+ const addOperationAndInitialSchema = async (moduleId, name) => {
4487
+ try {
4488
+ const id = await handleAddOperation(moduleId, name);
4489
+ if (!id) return void 0;
4490
+ try {
4491
+ handleSetOperationSchema(id, makeOperationInitialDoc(name));
4492
+ return id;
4493
+ } catch (error) {
4494
+ console.error("Failed to update operation schema:", error);
4495
+ return;
4496
+ }
4497
+ } catch (error) {
4498
+ console.error("Failed to add operation and schema:", error);
4499
+ return;
4500
+ }
4501
+ };
4502
+ return /* @__PURE__ */ jsxs("main", {
4503
+ className: "min-h-dvh bg-background p-6",
4504
+ children: [
4505
+ /* @__PURE__ */ jsx(DocumentToolbar, {}),
4506
+ /* @__PURE__ */ jsx(SchemaContextProvider, {
4507
+ globalStateSchemaSdl: globalStateSchema,
4508
+ localStateSchemaSdl: localStateSchema,
4509
+ operationSchemasSdl,
4510
+ children: /* @__PURE__ */ jsxs("div", {
4511
+ className: "mx-auto max-w-6xl px-4 pt-8",
4512
+ children: [
4513
+ /* @__PURE__ */ jsx(VersionControls, {
4514
+ specifications,
4515
+ viewedVersion: viewedSpec.version,
4516
+ onViewVersion: setViewedVersion,
4517
+ onReleaseNewVersion: handleReleaseNewVersion
4518
+ }),
4519
+ /* @__PURE__ */ jsx(ModelMetadata, {
4520
+ name: modelName,
4521
+ documentType,
4522
+ extension,
4523
+ description,
4524
+ authorName,
4525
+ authorWebsite: authorWebsite ?? "",
4526
+ globalStateSchema: latestGlobalStateSchema,
4527
+ localStateSchema: latestLocalStateSchema,
4528
+ setModelId: handleSetModelId,
4529
+ setModelDescription: handleSetModelDescription,
4530
+ setModelExtension: handleSetModelExtension,
4531
+ setModelName: handleSetModelName,
4532
+ setAuthorName: handleSetAuthorName,
4533
+ setAuthorWebsite: handleSetAuthorWebsite,
4534
+ setStateSchema: handleSetStateSchema
4535
+ }),
4536
+ /* @__PURE__ */ jsx(Divider, {}),
4537
+ isViewingFrozenVersion && /* @__PURE__ */ jsx(FrozenVersionBanner, {
4538
+ latestVersion: latestSpec.version,
4539
+ viewedVersion: viewedSpec.version
4540
+ }),
4541
+ /* @__PURE__ */ jsxs("div", {
4542
+ className: isViewingFrozenVersion ? "pointer-events-none opacity-80 select-none" : void 0,
4543
+ inert: isViewingFrozenVersion || void 0,
4544
+ children: [
4545
+ /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(StateSchemas, {
4546
+ modelName,
4547
+ globalStateSchema,
4548
+ globalStateInitialValue,
4549
+ localStateSchema,
4550
+ localStateInitialValue,
4551
+ setStateSchema: isViewingFrozenVersion ? noopSetStateSchema : handleSetStateSchema,
4552
+ setInitialState: isViewingFrozenVersion ? noopSetInitialState : handleSetInitialState,
4553
+ currentScope: scope,
4554
+ onScopeChange: setScope
4555
+ }) }),
4556
+ /* @__PURE__ */ jsx(Divider, {}),
4557
+ /* @__PURE__ */ jsxs("h3", {
4558
+ className: "mb-6 text-lg text-foreground capitalize",
4559
+ children: [scope, " Operations"]
4560
+ }),
4561
+ /* @__PURE__ */ jsx(Modules, {
4562
+ modules: modules.map((module) => ({
4563
+ ...module,
4564
+ operations: module.operations.filter((op) => op.scope === scope)
4565
+ })),
4566
+ allOperations: operations,
4567
+ addModule: handleAddModule,
4568
+ updateModuleName: handleSetModuleName,
4569
+ deleteModule: handleDeleteModule,
4570
+ updateOperationName: handleSetOperationName,
4571
+ updateOperationSchema: handleSetOperationSchema,
4572
+ setOperationDescription: handleSetOperationDescription,
4573
+ deleteOperation: handleDeleteOperation,
4574
+ addOperationError: handleAddOperationError,
4575
+ deleteOperationError: handleDeleteOperationError,
4576
+ setOperationErrorName: handleSetOperationErrorName,
4577
+ addOperationAndInitialSchema,
4578
+ toggleNoInputRequired: handleToggleNoInputRequired
4579
+ })
4580
+ ]
4581
+ })
4582
+ ]
4583
+ })
4584
+ }),
4585
+ /* @__PURE__ */ jsx(VersionAdvisoryModal, {
4586
+ prompt,
4587
+ onReleaseFirst: releaseFirst,
4588
+ onKeepEditing: keepEditing,
4589
+ onCancel: cancelAdvisory
4590
+ })
4591
+ ]
4592
+ });
4593
+ }
4594
+ //#endregion
4595
+ export { makeInitialSchemaDoc as a, validateStateObject as c, Editor as default, StateValidationError as i, Button as n, makeMinimalObjectForStateType as o, ensureValidStateSchemaName as r, makeStateSchemaNameForScope as s, editor_exports as t };
4596
+
4597
+ //# sourceMappingURL=editor-96sMeumV.mjs.map