@powerhousedao/powerhouse-vetra-packages 6.2.3-dev.10 → 6.2.3-dev.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/dist/browser/assets/{entry-DvpdFGdw.js → entry-4ObkElbc.js} +2 -2
  2. package/dist/browser/assets/{projection-entry-QU4xTPM_.js → projection-entry-DRGRQCSu.js} +8 -8
  3. package/dist/browser/{button-CuO8Gh3v.js → button-sZQCXeCo.js} +131 -24
  4. package/dist/browser/button-sZQCXeCo.js.map +1 -0
  5. package/dist/browser/chunk-BVTlhY3a.js +24 -0
  6. package/dist/browser/{dist-BAJ5nRDl.js → dist-D3_ER0Dn.js} +2 -399
  7. package/dist/browser/dist-D3_ER0Dn.js.map +1 -0
  8. package/dist/browser/document-models/index.js +2 -1
  9. package/dist/browser/{documents-J_l59mSV.js → documents-C-lAnv6o.js} +604 -735
  10. package/dist/browser/documents-C-lAnv6o.js.map +1 -0
  11. package/dist/browser/editor-CQ4wUFK5.js +3679 -0
  12. package/dist/browser/editor-CQ4wUFK5.js.map +1 -0
  13. package/dist/browser/{editor-D_gIraSB.js → editor-DNV-46lY.js} +5 -5
  14. package/dist/browser/{editor-D_gIraSB.js.map → editor-DNV-46lY.js.map} +1 -1
  15. package/dist/browser/editors/document-model-editor/module.js +1 -1
  16. package/dist/browser/editors/generic-drive-explorer/index.js +13 -8
  17. package/dist/browser/editors/generic-drive-explorer/index.js.map +1 -1
  18. package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
  19. package/dist/browser/folder-view-CzItU0hn.js +957 -0
  20. package/dist/browser/folder-view-CzItU0hn.js.map +1 -0
  21. package/dist/browser/{graphql-editor-C9wxFf0b.js → graphql-editor-DoXZvdNr.js} +7 -9
  22. package/dist/browser/{graphql-editor-C9wxFf0b.js.map → graphql-editor-DoXZvdNr.js.map} +1 -1
  23. package/dist/{node/hooks-D0DcS3MV.mjs → browser/hooks-Bh1JCohS.js} +2 -2
  24. package/dist/browser/{hooks-KKcNp2X0.js.map → hooks-Bh1JCohS.js.map} +1 -1
  25. package/dist/browser/index.js +120 -20
  26. package/dist/browser/index.js.map +1 -1
  27. package/dist/browser/{json-editor-BIGVi54h.js → json-editor-DBhkG5TF.js} +3 -4
  28. package/dist/browser/{json-editor-BIGVi54h.js.map → json-editor-DBhkG5TF.js.map} +1 -1
  29. package/dist/browser/{parser-CkF6Qt8V.js → parser-BBzK7bLd.js} +1 -1
  30. package/dist/browser/{parser-CkF6Qt8V.js.map → parser-BBzK7bLd.js.map} +1 -1
  31. package/dist/browser/{schema-context-ZyeclQwy.js → schema-context-p2bhyog_.js} +3 -3
  32. package/dist/browser/{schema-context-ZyeclQwy.js.map → schema-context-p2bhyog_.js.map} +1 -1
  33. package/dist/browser/src-CVV6HzQZ-D-OQvEkh.js +5151 -0
  34. package/dist/browser/src-CVV6HzQZ-D-OQvEkh.js.map +1 -0
  35. package/dist/browser/state-schemas-B47wHvDV.js +694 -0
  36. package/dist/browser/state-schemas-B47wHvDV.js.map +1 -0
  37. package/dist/browser/tslib.es6-CeIASJ2O.js +32 -0
  38. package/dist/browser/tslib.es6-CeIASJ2O.js.map +1 -0
  39. package/dist/node/{button-Da7CxMn7.mjs → button-5bnYEAVq.mjs} +130 -23
  40. package/dist/node/button-5bnYEAVq.mjs.map +1 -0
  41. package/dist/node/chunk-17FXJ3dL.mjs +31 -0
  42. package/dist/node/{dist-CzYOpeXN.mjs → dist-Bf_PIbO7.mjs} +2 -399
  43. package/dist/node/dist-Bf_PIbO7.mjs.map +1 -0
  44. package/dist/node/document-models/index.mjs +2 -1
  45. package/dist/node/documents-XAQfHX5Q.mjs +17 -0
  46. package/dist/node/documents-XAQfHX5Q.mjs.map +1 -0
  47. package/dist/node/editor-BiiLqEe9.mjs +3679 -0
  48. package/dist/node/editor-BiiLqEe9.mjs.map +1 -0
  49. package/dist/node/{editor-CJSAZpIG.mjs → editor-Cp2TC5MJ.mjs} +5 -5
  50. package/dist/node/{editor-CJSAZpIG.mjs.map → editor-Cp2TC5MJ.mjs.map} +1 -1
  51. package/dist/node/editors/document-model-editor/module.mjs +1 -1
  52. package/dist/node/editors/generic-drive-explorer/index.mjs +4 -5
  53. package/dist/node/editors/generic-drive-explorer/index.mjs.map +1 -1
  54. package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
  55. package/dist/node/folder-view-m_rH84Nz.mjs +962 -0
  56. package/dist/node/folder-view-m_rH84Nz.mjs.map +1 -0
  57. package/dist/node/{graphql-BfAoPeWM.mjs → graphql-BvV3tC1U.mjs} +2 -2
  58. package/dist/node/{graphql-BfAoPeWM.mjs.map → graphql-BvV3tC1U.mjs.map} +1 -1
  59. package/dist/node/{graphql-editor-CnK5kIk9.mjs → graphql-editor-BhF6KN6y.mjs} +6 -7
  60. package/dist/node/{graphql-editor-CnK5kIk9.mjs.map → graphql-editor-BhF6KN6y.mjs.map} +1 -1
  61. package/dist/{browser/hooks-KKcNp2X0.js → node/hooks-Di3FASx-.mjs} +2 -2
  62. package/dist/node/{hooks-D0DcS3MV.mjs.map → hooks-Di3FASx-.mjs.map} +1 -1
  63. package/dist/node/index.mjs +142 -21
  64. package/dist/node/index.mjs.map +1 -1
  65. package/dist/node/{json-editor-j8_JGfcP.mjs → json-editor-Cqc0zuz0.mjs} +3 -4
  66. package/dist/node/{json-editor-j8_JGfcP.mjs.map → json-editor-Cqc0zuz0.mjs.map} +1 -1
  67. package/dist/node/{schema-context-DL8jhi_d.mjs → schema-context-mHmP3Cl6.mjs} +3 -3
  68. package/dist/node/{schema-context-DL8jhi_d.mjs.map → schema-context-mHmP3Cl6.mjs.map} +1 -1
  69. package/dist/node/{connect-D3-HufsW.mjs → src-CVV6HzQZ-CvqjXbXk.mjs} +1829 -11022
  70. package/dist/node/src-CVV6HzQZ-CvqjXbXk.mjs.map +1 -0
  71. package/dist/node/state-schemas-DXG02fMh.mjs +695 -0
  72. package/dist/node/state-schemas-DXG02fMh.mjs.map +1 -0
  73. package/dist/node/{main-7sul-YJl.mjs → tslib.es6-DdiHgz9e.mjs} +3 -203
  74. package/dist/node/tslib.es6-DdiHgz9e.mjs.map +1 -0
  75. package/package.json +7 -7
  76. package/dist/browser/button-CuO8Gh3v.js.map +0 -1
  77. package/dist/browser/connect-kwnl2v6o.js +0 -14328
  78. package/dist/browser/connect-kwnl2v6o.js.map +0 -1
  79. package/dist/browser/dist-B4FWbuEM.js +0 -4148
  80. package/dist/browser/dist-B4FWbuEM.js.map +0 -1
  81. package/dist/browser/dist-BAJ5nRDl.js.map +0 -1
  82. package/dist/browser/dist-D0tSbK8B.js +0 -4721
  83. package/dist/browser/dist-D0tSbK8B.js.map +0 -1
  84. package/dist/browser/document-drive-fcQ4o8i3.js +0 -8320
  85. package/dist/browser/document-drive-fcQ4o8i3.js.map +0 -1
  86. package/dist/browser/documents-J_l59mSV.js.map +0 -1
  87. package/dist/browser/editor-CbJkIqg_.js +0 -1809
  88. package/dist/browser/editor-CbJkIqg_.js.map +0 -1
  89. package/dist/browser/folder-view-CGcqEbak.js +0 -232
  90. package/dist/browser/folder-view-CGcqEbak.js.map +0 -1
  91. package/dist/browser/lib-BWPfFpyy.js +0 -209
  92. package/dist/browser/lib-BWPfFpyy.js.map +0 -1
  93. package/dist/browser/printer-CEYr4JOg.js +0 -604
  94. package/dist/browser/printer-CEYr4JOg.js.map +0 -1
  95. package/dist/browser/state-schemas-C9Nb7S5z.js +0 -298
  96. package/dist/browser/state-schemas-C9Nb7S5z.js.map +0 -1
  97. package/dist/node/button-Da7CxMn7.mjs.map +0 -1
  98. package/dist/node/connect-D3-HufsW.mjs.map +0 -1
  99. package/dist/node/dist-CzYOpeXN.mjs.map +0 -1
  100. package/dist/node/dist-D5Xp9PwJ.mjs +0 -4729
  101. package/dist/node/dist-D5Xp9PwJ.mjs.map +0 -1
  102. package/dist/node/dist-DT7jI9ol.mjs +0 -4148
  103. package/dist/node/dist-DT7jI9ol.mjs.map +0 -1
  104. package/dist/node/document-drive-DuGBBYw5.mjs +0 -8337
  105. package/dist/node/document-drive-DuGBBYw5.mjs.map +0 -1
  106. package/dist/node/documents-DCf53bzO.mjs +0 -747
  107. package/dist/node/documents-DCf53bzO.mjs.map +0 -1
  108. package/dist/node/editor-D8SL0ydm.mjs +0 -1809
  109. package/dist/node/editor-D8SL0ydm.mjs.map +0 -1
  110. package/dist/node/folder-view-ChtWc33j.mjs +0 -232
  111. package/dist/node/folder-view-ChtWc33j.mjs.map +0 -1
  112. package/dist/node/main-7sul-YJl.mjs.map +0 -1
  113. package/dist/node/state-schemas-DURvYjxG.mjs +0 -299
  114. package/dist/node/state-schemas-DURvYjxG.mjs.map +0 -1
@@ -1,1809 +0,0 @@
1
- import { E as $ZodError, T as parseAsync, a as snakeCase, h as object, n as constantCase, p as literal, r as pascalCase, v as string, w as parse$1, x as url, y as union } from "./dist-DT7jI9ol.mjs";
2
- import { $ as setModuleName, F as deleteModule, I as deleteOperation, J as setInitialState, K as setAuthorName, L as deleteOperationError, Q as setModelName, W as releaseNewVersion, X as setModelExtension, Y as setModelDescription, Z as setModelId, at as setStateSchema, b as addOperationError, ft as generateId, it as setOperationSchema, nt as setOperationErrorName, q as setAuthorWebsite, rt as setOperationName, tt as setOperationDescription, v as addModule, y as addOperation } from "./document-drive-DuGBBYw5.mjs";
3
- import { t as require_graphql } from "./graphql-BfAoPeWM.mjs";
4
- import { _ as Modal, a as DocumentToolbar, b as Primitive, c as ModalButton, d as FormProvider, f as appendErrors, g as useFormContext, h as useForm, m as set, p as get, r as ConnectSelect, u as Controller, x as Slot } from "./connect-D3-HufsW.mjs";
5
- import { w as twMerge } from "./dist-CzYOpeXN.mjs";
6
- import { j as usePHToast, v as useSetPHDocumentEditorConfig, x as useSelectedDocumentOfType } from "./dist-D5Xp9PwJ.mjs";
7
- import { a as compareStringsWithoutWhitespace, c as isEmptyOperationSchema, f as makeOperationInitialDoc, l as makeEmptyOperationSchema, m as renameSchemaType, n as ensureValidOperationSchemaInputName, o as handleModelNameChange, s as initializeModelSchema, t as Button, u as makeInitialSchemaDoc } from "./button-Da7CxMn7.mjs";
8
- import { t as SchemaContextProvider } from "./schema-context-DL8jhi_d.mjs";
9
- import * as React$1 from "react";
10
- import React, { Suspense, forwardRef, lazy, useCallback, useEffect, useId, useImperativeHandle, useRef, useState } from "react";
11
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
12
- //#region ../../node_modules/.pnpm/clsx@2.0.0/node_modules/clsx/dist/clsx.mjs
13
- function r$1(e) {
14
- var t, f, n = "";
15
- if ("string" == typeof e || "number" == typeof e) n += e;
16
- 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);
17
- else for (t in e) e[t] && (n && (n += " "), n += t);
18
- return n;
19
- }
20
- function clsx() {
21
- for (var e, t, f = 0, n = ""; f < arguments.length;) (e = arguments[f++]) && (t = r$1(e)) && (n && (n += " "), n += t);
22
- return n;
23
- }
24
- //#endregion
25
- //#region ../../node_modules/.pnpm/class-variance-authority@0.7.0/node_modules/class-variance-authority/dist/index.mjs
26
- const falsyToString = (value) => typeof value === "boolean" ? "".concat(value) : value === 0 ? "0" : value;
27
- const cx = clsx;
28
- const cva = (base, config) => {
29
- return (props) => {
30
- var ref;
31
- 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);
32
- const { variants, defaultVariants } = config;
33
- const getVariantClassNames = Object.keys(variants).map((variant) => {
34
- const variantProp = props === null || props === void 0 ? void 0 : props[variant];
35
- const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
36
- if (variantProp === null) return null;
37
- const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
38
- return variants[variant][variantKey];
39
- });
40
- const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
41
- let [key, value] = param;
42
- if (value === void 0) return acc;
43
- acc[key] = value;
44
- return acc;
45
- }, {});
46
- return cx(base, getVariantClassNames, config === null || config === void 0 ? void 0 : (ref = config.compoundVariants) === null || ref === void 0 ? void 0 : ref.reduce((acc, param1) => {
47
- let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param1;
48
- return Object.entries(compoundVariantOptions).every((param) => {
49
- let [key, value] = param;
50
- return Array.isArray(value) ? value.includes({
51
- ...defaultVariants,
52
- ...propsWithoutUndefined
53
- }[key]) : {
54
- ...defaultVariants,
55
- ...propsWithoutUndefined
56
- }[key] === value;
57
- }) ? [
58
- ...acc,
59
- cvClass,
60
- cvClassName
61
- ] : acc;
62
- }, []), props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
63
- };
64
- };
65
- //#endregion
66
- //#region editors/document-model-editor/components/divider.tsx
67
- function Divider({ className, size = "sm", margin = "md" }) {
68
- function getSize() {
69
- if (size === "sm") return "h-px";
70
- if (size === "md") return "h-1";
71
- return "h-1.5";
72
- }
73
- function getMargin() {
74
- if (margin === "sm") return "my-4";
75
- if (margin === "md") return "my-6";
76
- return "my-8";
77
- }
78
- return /* @__PURE__ */ jsx("div", { className: twMerge("bg-secondary", getSize(), getMargin(), className) });
79
- }
80
- //#endregion
81
- //#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
82
- const r = (t, r, o) => {
83
- if (t && "reportValidity" in t) {
84
- const s = get(o, r);
85
- t.setCustomValidity(s && s.message || ""), t.reportValidity();
86
- }
87
- }, o = (e, t) => {
88
- for (const o in t.fields) {
89
- const s = t.fields[o];
90
- s && s.ref && "reportValidity" in s.ref ? r(s.ref, o, e) : s && s.refs && s.refs.forEach((t) => r(t, o, e));
91
- }
92
- }, s$1 = (r, s) => {
93
- s.shouldUseNativeValidation && o(r, s);
94
- const n = {};
95
- for (const o in r) {
96
- const f = get(s.fields, o), c = Object.assign(r[o] || {}, { ref: f && f.ref });
97
- if (i$1(s.names || Object.keys(r), o)) {
98
- const r = Object.assign({}, get(n, o));
99
- set(r, "root", c), set(n, o, r);
100
- } else set(n, o, c);
101
- }
102
- return n;
103
- }, i$1 = (e, t) => {
104
- const r = n(t);
105
- return e.some((e) => n(e).match(`^${r}\\.\\d+`));
106
- };
107
- function n(e) {
108
- return e.replace(/\]|\[/g, "");
109
- }
110
- //#endregion
111
- //#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
112
- function t(r, e) {
113
- try {
114
- var o = r();
115
- } catch (r) {
116
- return e(r);
117
- }
118
- return o && o.then ? o.then(void 0, e) : o;
119
- }
120
- function s(r, e) {
121
- for (var n = {}; r.length;) {
122
- var t = r[0], s = t.code, i = t.message, a = t.path.join(".");
123
- if (!n[a]) if ("unionErrors" in t) {
124
- var u = t.unionErrors[0].errors[0];
125
- n[a] = {
126
- message: u.message,
127
- type: u.code
128
- };
129
- } else n[a] = {
130
- message: i,
131
- type: s
132
- };
133
- if ("unionErrors" in t && t.unionErrors.forEach(function(e) {
134
- return e.errors.forEach(function(e) {
135
- return r.push(e);
136
- });
137
- }), e) {
138
- var c = n[a].types, f = c && c[t.code];
139
- n[a] = appendErrors(a, e, n, s, f ? [].concat(f, t.message) : t.message);
140
- }
141
- r.shift();
142
- }
143
- return n;
144
- }
145
- function i(r, e) {
146
- for (var n = {}; r.length;) {
147
- var t = r[0], s = t.code, i = t.message, a = t.path.join(".");
148
- if (!n[a]) if ("invalid_union" === t.code && t.errors.length > 0) {
149
- var u = t.errors[0][0];
150
- n[a] = {
151
- message: u.message,
152
- type: u.code
153
- };
154
- } else n[a] = {
155
- message: i,
156
- type: s
157
- };
158
- if ("invalid_union" === t.code && t.errors.forEach(function(e) {
159
- return e.forEach(function(e) {
160
- return r.push(e);
161
- });
162
- }), e) {
163
- var c = n[a].types, f = c && c[t.code];
164
- n[a] = appendErrors(a, e, n, s, f ? [].concat(f, t.message) : t.message);
165
- }
166
- r.shift();
167
- }
168
- return n;
169
- }
170
- function a(o$1, a, u) {
171
- if (void 0 === u && (u = {}), function(r) {
172
- return "_def" in r && "object" == typeof r._def && "typeName" in r._def;
173
- }(o$1)) return function(n, i, c) {
174
- try {
175
- return Promise.resolve(t(function() {
176
- return Promise.resolve(o$1["sync" === u.mode ? "parse" : "parseAsync"](n, a)).then(function(e) {
177
- return c.shouldUseNativeValidation && o({}, c), {
178
- errors: {},
179
- values: u.raw ? Object.assign({}, n) : e
180
- };
181
- });
182
- }, function(r) {
183
- if (function(r) {
184
- return Array.isArray(null == r ? void 0 : r.issues);
185
- }(r)) return {
186
- values: {},
187
- errors: s$1(s(r.errors, !c.shouldUseNativeValidation && "all" === c.criteriaMode), c)
188
- };
189
- throw r;
190
- }));
191
- } catch (r) {
192
- return Promise.reject(r);
193
- }
194
- };
195
- if (function(r) {
196
- return "_zod" in r && "object" == typeof r._zod;
197
- }(o$1)) return function(s, c, f) {
198
- try {
199
- return Promise.resolve(t(function() {
200
- return Promise.resolve(("sync" === u.mode ? parse$1 : parseAsync)(o$1, s, a)).then(function(e) {
201
- return f.shouldUseNativeValidation && o({}, f), {
202
- errors: {},
203
- values: u.raw ? Object.assign({}, s) : e
204
- };
205
- });
206
- }, function(r) {
207
- if (function(r) {
208
- return r instanceof $ZodError;
209
- }(r)) return {
210
- values: {},
211
- errors: s$1(i(r.issues, !f.shouldUseNativeValidation && "all" === f.criteriaMode), f)
212
- };
213
- throw r;
214
- }));
215
- } catch (r) {
216
- return Promise.reject(r);
217
- }
218
- };
219
- throw new Error("Invalid input: not a Zod schema");
220
- }
221
- //#endregion
222
- //#region editors/document-model-editor/schemas/inputs.ts
223
- const isUppercase = (value) => !/\p{Ll}/u.test(value);
224
- const isLowercase = (value) => !/\p{Lu}/u.test(value);
225
- function createNameSchema(options = {}) {
226
- const { required = false, allowEmpty = false, unique = [] } = options;
227
- const baseSchema = allowEmpty ? string() : string().min(1);
228
- const uniqueRefinement = baseSchema.refine((value) => {
229
- if (!value && allowEmpty) return true;
230
- return !unique.map((n) => n.toLowerCase()).includes(value.replace(/^\s+|\s+$/g, "_").toLowerCase());
231
- }, { message: "Item with this name already exists" });
232
- if (!required) return unique.length > 0 ? string().optional().refine((value) => {
233
- if (value === void 0) return true;
234
- if (!value && allowEmpty) return true;
235
- return !unique.map((n) => n.toLowerCase()).includes(value.replace(/^\s+|\s+$/g, "_").toLowerCase());
236
- }, { message: "Item with this name already exists" }) : string().optional();
237
- return unique.length > 0 ? uniqueRefinement : baseSchema;
238
- }
239
- function createConstantCaseSchema(options = {}) {
240
- return createNameSchema(options).transform((value) => value ? value.toUpperCase() : value).refine((value) => !value || isUppercase(value), { message: "Must be uppercase" });
241
- }
242
- function createLowercaseSnakeCaseSchema(options = {}) {
243
- return createNameSchema(options).transform((value) => value ? value.toLowerCase() : value).refine((value) => !value || isLowercase(value), { message: "Must be lowercase" });
244
- }
245
- function toLowercaseSnakeCase(value, options = {}) {
246
- return createLowercaseSnakeCaseSchema(options).parse(snakeCase(value));
247
- }
248
- function toConstantCase(value, options = {}) {
249
- return createConstantCaseSchema(options).parse(constantCase(value));
250
- }
251
- object({
252
- name: createNameSchema({ allowEmpty: true }),
253
- website: union([url(), literal("")]).optional().default("")
254
- }).default({
255
- name: "",
256
- website: ""
257
- });
258
- //#endregion
259
- //#region editors/document-model-editor/context/form-context.ts
260
- const FormFieldContext = React.createContext({});
261
- const FormItemContext = React.createContext({});
262
- //#endregion
263
- //#region editors/document-model-editor/hooks/useFormField.ts
264
- const useFormField = () => {
265
- const fieldContext = React.useContext(FormFieldContext);
266
- const itemContext = React.useContext(FormItemContext);
267
- const { getFieldState, formState } = useFormContext();
268
- const fieldState = getFieldState(fieldContext.name, formState);
269
- if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
270
- const { id } = itemContext;
271
- return {
272
- id,
273
- name: fieldContext.name,
274
- formItemId: `${id}-form-item`,
275
- formDescriptionId: `${id}-form-item-description`,
276
- formMessageId: `${id}-form-item-message`,
277
- ...fieldState
278
- };
279
- };
280
- //#endregion
281
- //#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
282
- var NAME = "Label";
283
- var Label$1 = React$1.forwardRef((props, forwardedRef) => {
284
- return /* @__PURE__ */ jsx(Primitive.label, {
285
- ...props,
286
- ref: forwardedRef,
287
- onMouseDown: (event) => {
288
- if (event.target.closest("button, input, select, textarea")) return;
289
- props.onMouseDown?.(event);
290
- if (!event.defaultPrevented && event.detail > 1) event.preventDefault();
291
- }
292
- });
293
- });
294
- Label$1.displayName = NAME;
295
- var Root = Label$1;
296
- //#endregion
297
- //#region editors/document-model-editor/components/label.tsx
298
- const labelVariants = cva("text-sm leading-none font-medium peer-disabled:disabled-effect");
299
- const Label = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(Root, {
300
- ref,
301
- className: twMerge(labelVariants(), className),
302
- ...props
303
- }));
304
- Label.displayName = Root.displayName;
305
- //#endregion
306
- //#region editors/document-model-editor/components/form.tsx
307
- const Form = FormProvider;
308
- const FormField = ({ ...props }) => {
309
- return /* @__PURE__ */ jsx(FormFieldContext.Provider, {
310
- value: { name: props.name },
311
- children: /* @__PURE__ */ jsx(Controller, { ...props })
312
- });
313
- };
314
- const FormItem = React$1.forwardRef(({ className, ...props }, ref) => {
315
- const id = React$1.useId();
316
- return /* @__PURE__ */ jsx(FormItemContext.Provider, {
317
- value: { id },
318
- children: /* @__PURE__ */ jsx("div", {
319
- ref,
320
- className,
321
- ...props
322
- })
323
- });
324
- });
325
- FormItem.displayName = "FormItem";
326
- const FormLabel = React$1.forwardRef(({ className, ...props }, ref) => {
327
- const { error, formItemId } = useFormField();
328
- return /* @__PURE__ */ jsx(Label, {
329
- ref,
330
- className: twMerge(error && "text-destructive", className),
331
- htmlFor: formItemId,
332
- ...props
333
- });
334
- });
335
- FormLabel.displayName = "FormLabel";
336
- const FormControl = React$1.forwardRef(({ ...props }, ref) => {
337
- const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
338
- return /* @__PURE__ */ jsx(Slot, {
339
- ref,
340
- id: formItemId,
341
- "aria-describedby": !error ? formDescriptionId : `${formDescriptionId} ${formMessageId}`,
342
- "aria-invalid": !!error,
343
- ...props
344
- });
345
- });
346
- FormControl.displayName = "FormControl";
347
- const FormDescription = React$1.forwardRef(({ className, ...props }, ref) => {
348
- const { formDescriptionId } = useFormField();
349
- return /* @__PURE__ */ jsx("p", {
350
- ref,
351
- id: formDescriptionId,
352
- className: twMerge("text-sm text-foreground", className),
353
- ...props
354
- });
355
- });
356
- FormDescription.displayName = "FormDescription";
357
- const FormMessage = React$1.forwardRef(({ className, children, ...props }, ref) => {
358
- const { error, formMessageId } = useFormField();
359
- const body = error ? String(error.message) : children;
360
- if (!body) return null;
361
- return /* @__PURE__ */ jsx("p", {
362
- ref,
363
- id: formMessageId,
364
- className: twMerge("text-sm font-medium text-destructive", className),
365
- ...props,
366
- children: body
367
- });
368
- });
369
- FormMessage.displayName = "FormMessage";
370
- //#endregion
371
- //#region editors/document-model-editor/components/text-area.tsx
372
- const Textarea = forwardRef(({ className, ...props }, ref) => {
373
- const textareaRef = useRef(null);
374
- const adjustHeight = useCallback((textarea) => {
375
- textarea.style.height = "auto";
376
- const newHeight = Math.max(textarea.scrollHeight, textarea.offsetHeight);
377
- textarea.style.height = `${newHeight}px`;
378
- }, []);
379
- const handleInput = useCallback((e) => {
380
- adjustHeight(e.currentTarget);
381
- }, [adjustHeight]);
382
- React$1.useEffect(() => {
383
- if (textareaRef.current) adjustHeight(textareaRef.current);
384
- }, [adjustHeight]);
385
- useImperativeHandle(ref, () => ({
386
- focus: () => textareaRef.current?.focus(),
387
- element: textareaRef.current
388
- }));
389
- return /* @__PURE__ */ jsx("textarea", {
390
- ...props,
391
- 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),
392
- ref: textareaRef,
393
- onInput: handleInput
394
- });
395
- });
396
- Textarea.displayName = "Textarea";
397
- //#endregion
398
- //#region editors/document-model-editor/components/text-field.tsx
399
- const TextField = forwardRef(({ name, value, onSubmit, label, placeholder, unique, className = "", rows = 1, focusOnMount = false, required = false, allowEmpty = false, shouldReset = false, onChange }, ref) => {
400
- const textareaRef = useRef(null);
401
- const id = useId();
402
- useEffect(() => {
403
- if (focusOnMount && textareaRef.current) textareaRef.current.focus();
404
- }, [focusOnMount]);
405
- const form = useForm({
406
- resolver: a(object({ [name]: createNameSchema({
407
- required,
408
- allowEmpty,
409
- unique
410
- }) })),
411
- defaultValues: { [name]: value ?? "" }
412
- });
413
- const handleSubmit = useCallback((values) => {
414
- const newValue = values[name];
415
- if (newValue === void 0 || value === newValue) return;
416
- onSubmit(newValue);
417
- if (shouldReset) form.reset({ [name]: "" });
418
- }, [
419
- name,
420
- value,
421
- onSubmit,
422
- form,
423
- shouldReset
424
- ]);
425
- const handleBlur = useCallback(async () => {
426
- const currentValue = form.getValues()[name] ?? "";
427
- if (value === null || value === void 0) {
428
- if (!currentValue || currentValue.trim() === "") return;
429
- }
430
- if (compareStringsWithoutWhitespace(currentValue, value ?? "")) return;
431
- try {
432
- await form.trigger();
433
- if (form.formState.isValid) await form.handleSubmit(handleSubmit)();
434
- } catch (_e) {}
435
- }, [
436
- form,
437
- handleSubmit,
438
- name,
439
- value
440
- ]);
441
- const onEnterKeyDown = useCallback((e) => {
442
- if (e.key === "Enter") {
443
- e.preventDefault();
444
- e.target.blur();
445
- }
446
- }, []);
447
- const handleChange = useCallback((e) => {
448
- const newValue = e.target.value;
449
- onChange?.(newValue);
450
- }, [onChange]);
451
- useImperativeHandle(ref, () => ({ focus: () => textareaRef.current?.focus() }));
452
- useEffect(() => {
453
- form.reset({ [name]: value ?? "" });
454
- }, [
455
- form,
456
- name,
457
- value
458
- ]);
459
- return /* @__PURE__ */ jsx(Form, {
460
- ...form,
461
- children: /* @__PURE__ */ jsx(FormField, {
462
- control: form.control,
463
- name,
464
- render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, {
465
- className: "grid h-full grid-rows-[auto,1fr] gap-2 overflow-visible",
466
- children: [
467
- !!label && /* @__PURE__ */ jsx(FormLabel, {
468
- htmlFor: name,
469
- className: "text-sm font-medium text-foreground",
470
- children: label
471
- }),
472
- /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(Textarea, {
473
- ...field,
474
- id,
475
- name,
476
- ref: (node) => {
477
- if (node) {
478
- field.ref(node.element);
479
- textareaRef.current = node;
480
- }
481
- },
482
- placeholder,
483
- onBlur: () => void handleBlur(),
484
- onChange: (e) => {
485
- field.onChange(e);
486
- handleChange(e);
487
- },
488
- onKeyDown: onEnterKeyDown,
489
- rows,
490
- className
491
- }) }),
492
- /* @__PURE__ */ jsx(FormMessage, {})
493
- ]
494
- })
495
- })
496
- });
497
- });
498
- TextField.displayName = "TextField";
499
- object({
500
- name: string(),
501
- documentType: string(),
502
- extension: string().optional().default(""),
503
- description: string(),
504
- authorName: string(),
505
- authorWebsite: string()
506
- });
507
- function ModelMetadata(props) {
508
- return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(ModelNameForm, { ...props }), /* @__PURE__ */ jsx("div", {
509
- className: "flex h-full flex-col gap-4",
510
- children: /* @__PURE__ */ jsxs("div", {
511
- className: "grid flex-1 grid-cols-3 items-start gap-4",
512
- children: [/* @__PURE__ */ jsxs("div", {
513
- className: "col-span-2 flex h-full flex-col gap-4",
514
- children: [/* @__PURE__ */ jsx("div", {
515
- className: "shrink-0",
516
- children: /* @__PURE__ */ jsx(DocumentTypeForm, { ...props })
517
- }), /* @__PURE__ */ jsx("div", {
518
- className: "min-h-0 flex-1",
519
- children: /* @__PURE__ */ jsx(DescriptionForm, { ...props })
520
- })]
521
- }), /* @__PURE__ */ jsxs("div", {
522
- className: "col-span-1 flex flex-col gap-4",
523
- children: [
524
- /* @__PURE__ */ jsx(AuthorNameForm, { ...props }),
525
- /* @__PURE__ */ jsx(AuthorWebsiteForm, { ...props }),
526
- /* @__PURE__ */ jsx(ModelExtensionForm, { ...props })
527
- ]
528
- })]
529
- })
530
- })] });
531
- }
532
- function ModelNameForm(props) {
533
- const { name, globalStateSchema, localStateSchema, setModelName, setStateSchema } = props;
534
- return /* @__PURE__ */ jsx(TextField, {
535
- name: "name",
536
- value: name,
537
- onSubmit: useCallback((newName) => {
538
- if (name === newName) return;
539
- setModelName(newName);
540
- if (!!!globalStateSchema) {
541
- setStateSchema(makeInitialSchemaDoc(newName, "global"), "global");
542
- return;
543
- }
544
- setStateSchema(renameSchemaType(globalStateSchema, name, newName, "global"), "global");
545
- if (localStateSchema) setStateSchema(renameSchemaType(localStateSchema, name, newName, "local"), "local");
546
- handleModelNameChange({
547
- oldName: name,
548
- newName,
549
- globalStateSchema,
550
- localStateSchema,
551
- setStateSchema
552
- });
553
- }, [
554
- name,
555
- globalStateSchema,
556
- localStateSchema,
557
- setStateSchema,
558
- setModelName
559
- ]),
560
- placeholder: "Model name",
561
- className: "border-none pl-0 text-xl font-bold text-foreground",
562
- required: true,
563
- focusOnMount: true
564
- });
565
- }
566
- function DocumentTypeForm(props) {
567
- const { documentType, setModelId } = props;
568
- return /* @__PURE__ */ jsx(TextField, {
569
- label: "Document Type *",
570
- name: "powerhouse/document-model",
571
- value: documentType,
572
- onSubmit: setModelId,
573
- placeholder: "Document Type",
574
- required: true
575
- });
576
- }
577
- function ModelExtensionForm(props) {
578
- const { extension, setModelExtension } = props;
579
- return /* @__PURE__ */ jsx(TextField, {
580
- name: "extension",
581
- value: extension,
582
- onSubmit: setModelExtension,
583
- label: "Model Extension",
584
- placeholder: "Example .phdm",
585
- allowEmpty: true
586
- });
587
- }
588
- function DescriptionForm(props) {
589
- const { description, setModelDescription } = props;
590
- return /* @__PURE__ */ jsx(TextField, {
591
- name: "description",
592
- label: "Model Description",
593
- value: description,
594
- onSubmit: setModelDescription,
595
- placeholder: "Describe your document to others",
596
- allowEmpty: true,
597
- className: "h-full"
598
- });
599
- }
600
- function AuthorNameForm(props) {
601
- const { authorName, setAuthorName } = props;
602
- return /* @__PURE__ */ jsx(TextField, {
603
- name: "authorName",
604
- value: authorName,
605
- onSubmit: setAuthorName,
606
- label: "Author Name",
607
- placeholder: "Username or organisation",
608
- allowEmpty: true
609
- });
610
- }
611
- function AuthorWebsiteForm(props) {
612
- const { authorWebsite, setAuthorWebsite } = props;
613
- return /* @__PURE__ */ jsx(TextField, {
614
- name: "authorWebsite",
615
- value: authorWebsite,
616
- label: "Website URL",
617
- onSubmit: (newAuthorWebsite) => {
618
- if (!!authorWebsite && !newAuthorWebsite) return;
619
- setAuthorWebsite(newAuthorWebsite);
620
- },
621
- placeholder: "https://www.powerhouse.inc/",
622
- allowEmpty: true
623
- });
624
- }
625
- //#endregion
626
- //#region editors/document-model-editor/components/module-form.tsx
627
- function ModuleForm({ module, onAddModule, updateModuleName, modules = [] }) {
628
- const isEdit = !!module;
629
- const moduleNames = modules.map((m) => m.name);
630
- const handleSubmit = async (name) => {
631
- const formattedName = toLowercaseSnakeCase(name);
632
- if (!formattedName.length) return;
633
- if (isEdit) {
634
- if (formattedName !== module.name) updateModuleName(module.id, formattedName);
635
- } else await onAddModule(formattedName);
636
- };
637
- return /* @__PURE__ */ jsx(TextField, {
638
- name: "name",
639
- label: isEdit ? "Module name *" : "Add module *",
640
- value: module?.name,
641
- onSubmit: (name) => void handleSubmit(name),
642
- placeholder: "Add module",
643
- unique: moduleNames,
644
- shouldReset: !isEdit,
645
- required: true
646
- }, module?.id ?? "new");
647
- }
648
- //#endregion
649
- //#region editors/document-model-editor/components/operation-form.tsx
650
- function OperationForm({ operation, module, focusOnMount, allOperationNames, onAddOperationAndInitialSchema, updateOperationName, deleteOperation }) {
651
- const isEdit = !!operation;
652
- const handleSubmit = async (name) => {
653
- if (isEdit && name === "") {
654
- deleteOperation(operation.id);
655
- return;
656
- }
657
- const formattedName = toConstantCase(name);
658
- if (isEdit) {
659
- if (formattedName !== operation.name) updateOperationName(operation.id, formattedName);
660
- } else await onAddOperationAndInitialSchema(module.id, formattedName);
661
- };
662
- const handleChange = (value) => {
663
- if (isEdit && value === "") deleteOperation(operation.id);
664
- };
665
- return /* @__PURE__ */ jsx(TextField, {
666
- name: "name",
667
- value: operation?.name,
668
- label: isEdit ? "Operation name *" : "Add operation *",
669
- onSubmit: (name) => void handleSubmit(name),
670
- onChange: handleChange,
671
- placeholder: "Add operation",
672
- required: !isEdit,
673
- allowEmpty: !isEdit,
674
- shouldReset: !isEdit,
675
- focusOnMount,
676
- unique: allOperationNames
677
- });
678
- }
679
- //#endregion
680
- //#region editors/document-model-editor/components/operation-description-form.tsx
681
- function OperationDescriptionForm({ operation, focusOnMount, setOperationDescription }) {
682
- const textFieldRef = useRef(null);
683
- useEffect(() => {
684
- if (focusOnMount && textFieldRef.current) textFieldRef.current.focus();
685
- }, [focusOnMount]);
686
- return /* @__PURE__ */ jsx(TextField, {
687
- ref: textFieldRef,
688
- name: "description",
689
- value: operation.description,
690
- onSubmit: (newDescription) => setOperationDescription(operation.id, newDescription),
691
- label: "Operation description",
692
- allowEmpty: true,
693
- placeholder: "Operation Description"
694
- });
695
- }
696
- //#endregion
697
- //#region editors/document-model-editor/components/operation-error-form.tsx
698
- function OperationErrorForm({ operation, error, focusOnMount, onSubmit, onAddOperationError, deleteOperationError, setOperationErrorName }) {
699
- const textFieldRef = useRef(null);
700
- const isEdit = !!error;
701
- const allOperationErrorNames = operation.errors.map((o) => o.name).filter((n) => n !== null);
702
- const handleSubmit = (name) => {
703
- if (isEdit && name === "") {
704
- deleteOperationError(error.id);
705
- return;
706
- }
707
- const formattedName = pascalCase(name);
708
- if (isEdit) setOperationErrorName(operation.id, error.id, formattedName);
709
- else onAddOperationError(operation.id, formattedName);
710
- onSubmit?.();
711
- };
712
- const handleChange = (value) => {
713
- if (isEdit && value === "") deleteOperationError(error.id);
714
- };
715
- return /* @__PURE__ */ jsx(TextField, {
716
- ref: textFieldRef,
717
- name: "name",
718
- value: error?.name,
719
- onSubmit: handleSubmit,
720
- onChange: handleChange,
721
- placeholder: "Add exception",
722
- required: !isEdit,
723
- allowEmpty: !isEdit,
724
- shouldReset: !isEdit,
725
- unique: allOperationErrorNames,
726
- focusOnMount
727
- });
728
- }
729
- //#endregion
730
- //#region editors/document-model-editor/components/operation-errors.tsx
731
- function OperationErrors({ operation, addOperationError, deleteOperationError, setOperationErrorName }) {
732
- const addErrorFormId = useId();
733
- const [shouldFocusAddForm, setShouldFocusAddForm] = useState(false);
734
- const onAddOperationError = useCallback(async (operationId, error) => {
735
- const errorId = await addOperationError(operationId, error);
736
- if (errorId) setShouldFocusAddForm(true);
737
- return errorId;
738
- }, [addOperationError, setShouldFocusAddForm]);
739
- const onAddOperationErrorSubmit = useCallback(() => setShouldFocusAddForm(false), [setShouldFocusAddForm]);
740
- return /* @__PURE__ */ jsxs("ul", {
741
- className: "ml-4 list-disc",
742
- children: [operation.errors.map((error) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(OperationErrorForm, {
743
- error,
744
- operation,
745
- onAddOperationError,
746
- deleteOperationError,
747
- setOperationErrorName
748
- }) }, error.id)), /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(OperationErrorForm, {
749
- operation,
750
- onAddOperationError,
751
- deleteOperationError,
752
- setOperationErrorName,
753
- focusOnMount: shouldFocusAddForm,
754
- onSubmit: onAddOperationErrorSubmit
755
- }, `${addErrorFormId}-${shouldFocusAddForm}`) })]
756
- });
757
- }
758
- //#endregion
759
- //#region editors/document-model-editor/components/operation.tsx
760
- const GraphqlEditor = lazy(() => import("./graphql-editor-CnK5kIk9.mjs"));
761
- function Operation(props) {
762
- const { operation, module, allOperationNames, lastCreatedOperationId, onAddOperationAndInitialSchema, updateOperationName, deleteOperation, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired } = props;
763
- const noInputRequired = isEmptyOperationSchema(operation.schema);
764
- const handleToggleNoInput = useCallback((checked) => toggleNoInputRequired(operation.id, checked), [operation.id, toggleNoInputRequired]);
765
- const handleUpdateDocument = useCallback((newDoc) => updateOperationSchema(operation.id, newDoc), [operation.id, updateOperationSchema]);
766
- const customLinter = useCallback((doc) => operation.name ? ensureValidOperationSchemaInputName(doc, operation.name) : [], [operation.name]);
767
- return /* @__PURE__ */ jsxs("div", {
768
- className: "mt-4 grid grid-cols-2 gap-x-12",
769
- style: {
770
- gridTemplateAreas: `
771
- "left editor"
772
- "errors editor"
773
- `,
774
- gridTemplateRows: "auto 1fr"
775
- },
776
- children: [
777
- /* @__PURE__ */ jsxs("div", {
778
- className: "flex flex-col gap-2",
779
- style: { gridArea: "left" },
780
- children: [/* @__PURE__ */ jsx(OperationForm, {
781
- operation,
782
- onAddOperationAndInitialSchema,
783
- updateOperationName,
784
- deleteOperation,
785
- module,
786
- allOperationNames
787
- }), /* @__PURE__ */ jsx(OperationDescriptionForm, {
788
- operation,
789
- focusOnMount: operation.id === lastCreatedOperationId,
790
- setOperationDescription
791
- })]
792
- }),
793
- /* @__PURE__ */ jsxs("div", {
794
- className: "relative top-8",
795
- style: { gridArea: "editor" },
796
- children: [/* @__PURE__ */ jsxs("label", {
797
- className: "mb-2 flex cursor-pointer items-center gap-2",
798
- children: [/* @__PURE__ */ jsx("input", {
799
- type: "checkbox",
800
- checked: noInputRequired,
801
- onChange: (e) => handleToggleNoInput(e.target.checked),
802
- className: "size-4 rounded-sm border-border"
803
- }), /* @__PURE__ */ jsx("span", {
804
- className: "text-sm text-foreground",
805
- children: "Operation with no inputs"
806
- })]
807
- }), !noInputRequired && /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(GraphqlEditor, {
808
- doc: operation.schema ?? "",
809
- updateDocumentInModel: handleUpdateDocument,
810
- customLinter
811
- }) })]
812
- }),
813
- /* @__PURE__ */ jsxs("div", {
814
- style: { gridArea: "errors" },
815
- children: [/* @__PURE__ */ jsx("h3", {
816
- className: "my-2 text-sm font-medium text-foreground",
817
- children: "Reducer Exceptions"
818
- }), /* @__PURE__ */ jsx(OperationErrors, {
819
- operation,
820
- addOperationError,
821
- deleteOperationError,
822
- setOperationErrorName
823
- })]
824
- })
825
- ]
826
- });
827
- }
828
- //#endregion
829
- //#region editors/document-model-editor/components/operations.tsx
830
- function Operations({ module, allOperations, shouldFocusNewOperation, updateOperationName, deleteOperation, addOperationAndInitialSchema, addOperationError, deleteOperationError, setOperationErrorName, updateOperationSchema, setOperationDescription, toggleNoInputRequired }) {
831
- const [lastCreatedOperationId, setLastCreatedOperationId] = useState(null);
832
- const addOperationFormId = useId();
833
- const allOperationNames = allOperations.map((o) => o.name).filter((n) => n !== null);
834
- const onAddOperationAndInitialSchema = useCallback(async (moduleId, name) => {
835
- const operationId = await addOperationAndInitialSchema(moduleId, name);
836
- if (operationId) setLastCreatedOperationId(operationId);
837
- return operationId;
838
- }, [addOperationAndInitialSchema, setLastCreatedOperationId]);
839
- return /* @__PURE__ */ jsxs("div", { children: [module.operations.map((operation) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Operation, {
840
- operation,
841
- module,
842
- lastCreatedOperationId,
843
- allOperationNames,
844
- addOperationError,
845
- deleteOperationError,
846
- setOperationErrorName,
847
- onAddOperationAndInitialSchema,
848
- updateOperationName,
849
- deleteOperation,
850
- updateOperationSchema,
851
- setOperationDescription,
852
- toggleNoInputRequired
853
- }) }, operation.id)), /* @__PURE__ */ jsx("div", {
854
- className: "mt-6 w-1/2 pr-6",
855
- children: /* @__PURE__ */ jsx(OperationForm, {
856
- onAddOperationAndInitialSchema,
857
- updateOperationName,
858
- deleteOperation,
859
- module,
860
- allOperationNames,
861
- focusOnMount: shouldFocusNewOperation
862
- }, addOperationFormId)
863
- })] });
864
- }
865
- //#endregion
866
- //#region editors/document-model-editor/components/module.tsx
867
- function Module(props) {
868
- const { module, modules, allOperations, lastCreatedModuleId, onAddModule, updateModuleName, deleteModule, updateOperationName, deleteOperation, addOperationAndInitialSchema, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired } = props;
869
- return /* @__PURE__ */ jsxs("div", {
870
- className: "relative rounded-3xl bg-muted p-6",
871
- children: [/* @__PURE__ */ jsxs("div", {
872
- className: "mb-2 w-1/2 pr-6",
873
- children: [/* @__PURE__ */ jsx(ModuleForm, {
874
- modules,
875
- module,
876
- onAddModule,
877
- updateModuleName
878
- }), !!module && /* @__PURE__ */ jsx("button", {
879
- "aria-label": "Delete module",
880
- tabIndex: -1,
881
- className: "absolute top-1 right-1 p-2 text-foreground transition-colors hover:hover-effect",
882
- onClick: () => {
883
- deleteModule(module.id);
884
- },
885
- children: /* @__PURE__ */ jsx("svg", {
886
- className: "size-6",
887
- viewBox: "0 0 24 24",
888
- fill: "currentcolor",
889
- children: /* @__PURE__ */ jsx("path", {
890
- fillRule: "evenodd",
891
- clipRule: "evenodd",
892
- 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"
893
- })
894
- })
895
- })]
896
- }), !!module && /* @__PURE__ */ jsx(Operations, {
897
- module,
898
- allOperations,
899
- shouldFocusNewOperation: module.id === lastCreatedModuleId,
900
- updateOperationName,
901
- deleteOperation,
902
- addOperationAndInitialSchema,
903
- updateOperationSchema,
904
- setOperationDescription,
905
- addOperationError,
906
- deleteOperationError,
907
- setOperationErrorName,
908
- toggleNoInputRequired
909
- })]
910
- });
911
- }
912
- //#endregion
913
- //#region editors/document-model-editor/components/modules.tsx
914
- function Modules({ modules, allOperations, addModule, updateModuleName, deleteModule, updateOperationName, deleteOperation, addOperationAndInitialSchema, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired }) {
915
- const [lastCreatedModuleId, setLastCreatedModuleId] = useState(null);
916
- const focusTrapRef = useRef(null);
917
- const onAddModule = useCallback(async (name) => {
918
- const moduleId = await addModule(name);
919
- if (moduleId) {
920
- setLastCreatedModuleId(moduleId);
921
- focusTrapRef.current?.focus();
922
- }
923
- return moduleId;
924
- }, [addModule, setLastCreatedModuleId]);
925
- return /* @__PURE__ */ jsxs("div", {
926
- className: "flex flex-col gap-2",
927
- children: [
928
- modules.map((module) => /* @__PURE__ */ jsx(Module, {
929
- module,
930
- modules,
931
- allOperations,
932
- lastCreatedModuleId,
933
- onAddModule,
934
- updateModuleName,
935
- deleteModule,
936
- updateOperationName,
937
- deleteOperation,
938
- addOperationAndInitialSchema,
939
- updateOperationSchema,
940
- setOperationDescription,
941
- addOperationError,
942
- deleteOperationError,
943
- setOperationErrorName,
944
- toggleNoInputRequired
945
- }, module.id)),
946
- /* @__PURE__ */ jsx(Module, {
947
- modules,
948
- allOperations,
949
- lastCreatedModuleId,
950
- onAddModule,
951
- updateModuleName,
952
- deleteModule,
953
- updateOperationName,
954
- deleteOperation,
955
- addOperationAndInitialSchema,
956
- updateOperationSchema,
957
- setOperationDescription,
958
- addOperationError,
959
- deleteOperationError,
960
- setOperationErrorName,
961
- toggleNoInputRequired
962
- }, "add-module"),
963
- /* @__PURE__ */ jsx("div", {
964
- ref: focusTrapRef,
965
- tabIndex: 0,
966
- className: "size-0 overflow-hidden",
967
- "aria-hidden": "true"
968
- })
969
- ]
970
- });
971
- }
972
- //#endregion
973
- //#region editors/document-model-editor/components/version-controls.tsx
974
- const compactButtonStyle$1 = "min-h-0 min-w-0 flex-none rounded-lg px-6 py-1.5 text-sm whitespace-nowrap";
975
- function VersionControls(props) {
976
- const { specifications, viewedVersion, onViewVersion, onReleaseNewVersion } = props;
977
- const [showReleaseModal, setShowReleaseModal] = useState(false);
978
- const latestVersion = specifications[specifications.length - 1].version;
979
- const nextVersion = latestVersion + 1;
980
- return /* @__PURE__ */ jsxs("div", {
981
- className: "mb-4 flex items-center justify-between gap-4",
982
- children: [
983
- /* @__PURE__ */ jsxs("div", {
984
- className: "flex items-center gap-2",
985
- children: [/* @__PURE__ */ jsxs("span", {
986
- className: "rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground",
987
- "data-testid": "model-version-badge",
988
- children: ["Version ", viewedVersion]
989
- }), specifications.length >= 2 && /* @__PURE__ */ jsx("div", {
990
- "aria-label": "Document model version",
991
- "data-testid": "model-version-switcher",
992
- children: /* @__PURE__ */ jsx(ConnectSelect, {
993
- absolutePositionMenu: true,
994
- containerClassName: "z-10 [&_svg]:size-4",
995
- id: "model-version-switcher",
996
- itemClassName: "gap-1 px-2 py-1 font-mono text-xs leading-none [&_p:empty]:hidden",
997
- items: specifications.map((spec) => ({
998
- value: String(spec.version),
999
- displayValue: /* @__PURE__ */ jsx("span", {
1000
- className: "normal-case",
1001
- children: spec.version === latestVersion ? `v${spec.version} (latest)` : `v${spec.version} (frozen)`
1002
- })
1003
- })),
1004
- listClassName: "border border-t-0 border-border shadow-md",
1005
- menuClassName: "min-w-0 pr-1.5",
1006
- onChange: (value) => {
1007
- const version = Number(value);
1008
- onViewVersion(version === latestVersion ? "latest" : version);
1009
- },
1010
- value: String(viewedVersion)
1011
- })
1012
- })]
1013
- }),
1014
- /* @__PURE__ */ jsx(Button, {
1015
- className: "inline-flex h-8 items-center justify-center py-0",
1016
- "data-testid": "release-new-version-button",
1017
- onClick: () => setShowReleaseModal(true),
1018
- type: "button",
1019
- children: "Release new version"
1020
- }),
1021
- /* @__PURE__ */ jsx(Modal, {
1022
- open: showReleaseModal,
1023
- onOpenChange: (status) => {
1024
- if (!status) setShowReleaseModal(false);
1025
- },
1026
- children: /* @__PURE__ */ jsxs("div", {
1027
- className: "w-[440px] p-6",
1028
- children: [
1029
- /* @__PURE__ */ jsxs("div", {
1030
- className: "pb-2 text-2xl font-bold text-foreground",
1031
- children: ["Release version ", nextVersion]
1032
- }),
1033
- /* @__PURE__ */ jsxs("div", {
1034
- className: "my-4 rounded-md bg-background p-4 text-left text-sm text-foreground",
1035
- children: [/* @__PURE__ */ jsxs("p", { children: [
1036
- "Version ",
1037
- latestVersion,
1038
- " will be frozen as-is. Version",
1039
- " ",
1040
- nextVersion,
1041
- " starts as an identical copy, and all further edits apply to version ",
1042
- nextVersion,
1043
- "."
1044
- ] }), /* @__PURE__ */ jsxs("p", {
1045
- className: "mt-3",
1046
- children: [
1047
- "Existing version ",
1048
- latestVersion,
1049
- " documents will be upgradeable once you define the migration."
1050
- ]
1051
- })]
1052
- }),
1053
- /* @__PURE__ */ jsxs("div", {
1054
- className: "mt-4 flex justify-between gap-3",
1055
- children: [/* @__PURE__ */ jsx(ModalButton, {
1056
- className: compactButtonStyle$1,
1057
- onClick: () => setShowReleaseModal(false),
1058
- variant: "cancel",
1059
- children: "Cancel"
1060
- }), /* @__PURE__ */ jsxs(ModalButton, {
1061
- className: compactButtonStyle$1,
1062
- "data-testid": "confirm-release-button",
1063
- onClick: () => {
1064
- setShowReleaseModal(false);
1065
- onReleaseNewVersion();
1066
- },
1067
- variant: "confirm",
1068
- children: ["Release version ", nextVersion]
1069
- })]
1070
- })
1071
- ]
1072
- })
1073
- })
1074
- ]
1075
- });
1076
- }
1077
- function FrozenVersionBanner(props) {
1078
- const { viewedVersion, latestVersion } = props;
1079
- return /* @__PURE__ */ jsxs("div", {
1080
- className: "mb-4 rounded-md border border-border bg-muted p-3 text-sm text-foreground",
1081
- "data-testid": "frozen-version-banner",
1082
- children: [
1083
- "Version ",
1084
- viewedVersion,
1085
- " is frozen. You're viewing it read-only. Edits go to version ",
1086
- latestVersion,
1087
- "."
1088
- ]
1089
- });
1090
- }
1091
- //#endregion
1092
- //#region editors/document-model-editor/components/version-advisory-modal.tsx
1093
- const compactButtonStyle = "min-h-0 min-w-0 flex-none rounded-lg px-4 py-1.5 text-sm whitespace-nowrap";
1094
- function FieldDiffList(props) {
1095
- const { label, fields } = props;
1096
- if (fields.length === 0) return null;
1097
- return /* @__PURE__ */ jsxs("div", {
1098
- className: "mt-3",
1099
- children: [/* @__PURE__ */ jsx("p", {
1100
- className: "mb-1.5",
1101
- children: label
1102
- }), /* @__PURE__ */ jsx("div", {
1103
- className: "flex flex-col items-start gap-1",
1104
- children: fields.map((field) => /* @__PURE__ */ jsx("span", {
1105
- className: "rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground",
1106
- children: field
1107
- }, field))
1108
- })]
1109
- });
1110
- }
1111
- function VersionAdvisoryModal(props) {
1112
- const { prompt, onReleaseFirst, onKeepEditing, onCancel } = props;
1113
- if (!prompt) return null;
1114
- const { version, reason, diff } = prompt;
1115
- const nextVersion = version + 1;
1116
- return /* @__PURE__ */ jsx(Modal, {
1117
- open: true,
1118
- onOpenChange: (status) => {
1119
- if (!status) onCancel();
1120
- },
1121
- children: /* @__PURE__ */ jsxs("div", {
1122
- className: "w-[440px] p-6",
1123
- "data-testid": "version-advisory-modal",
1124
- children: [
1125
- /* @__PURE__ */ jsxs("div", {
1126
- className: "pb-2 text-2xl font-bold text-foreground",
1127
- children: [
1128
- "Is version ",
1129
- version,
1130
- " of this model already in use?"
1131
- ]
1132
- }),
1133
- /* @__PURE__ */ jsxs("div", {
1134
- className: "my-4 rounded-md bg-background p-4 text-left text-sm text-foreground",
1135
- children: [
1136
- /* @__PURE__ */ jsxs("p", { children: [
1137
- reason,
1138
- " Documents that were already created with version ",
1139
- version,
1140
- " ",
1141
- "may stop working correctly."
1142
- ] }),
1143
- diff && /* @__PURE__ */ jsxs(Fragment$1, { children: [
1144
- /* @__PURE__ */ jsx(FieldDiffList, {
1145
- fields: diff.addedFields,
1146
- label: "New fields:"
1147
- }),
1148
- /* @__PURE__ */ jsx(FieldDiffList, {
1149
- fields: diff.removedFields,
1150
- label: "Removed fields:"
1151
- }),
1152
- /* @__PURE__ */ jsx(FieldDiffList, {
1153
- fields: diff.changedFields,
1154
- label: "Changed fields:"
1155
- })
1156
- ] }),
1157
- /* @__PURE__ */ jsxs("p", {
1158
- className: "mt-3",
1159
- children: [
1160
- "If others are already using version ",
1161
- version,
1162
- ", release version",
1163
- " ",
1164
- nextVersion,
1165
- " first. Your change will go into version ",
1166
- nextVersion,
1167
- ", and existing documents can be updated safely."
1168
- ]
1169
- })
1170
- ]
1171
- }),
1172
- /* @__PURE__ */ jsxs("div", {
1173
- className: "mt-4 flex flex-col gap-2",
1174
- children: [/* @__PURE__ */ jsx(ModalButton, {
1175
- className: compactButtonStyle,
1176
- "data-testid": "advisory-release-first",
1177
- onClick: onReleaseFirst,
1178
- variant: "confirm",
1179
- children: `It's in use — release v${nextVersion} first`
1180
- }), /* @__PURE__ */ jsxs(ModalButton, {
1181
- className: compactButtonStyle,
1182
- "data-testid": "advisory-keep-editing",
1183
- onClick: onKeepEditing,
1184
- variant: "cancel",
1185
- children: ["Still in development — keep editing v", version]
1186
- })]
1187
- })
1188
- ]
1189
- })
1190
- });
1191
- }
1192
- //#endregion
1193
- //#region editors/document-model-editor/config.ts
1194
- const editorConfig = { isExternalControlsEnabled: false };
1195
- //#endregion
1196
- //#region editors/document-model-editor/hooks/useDocumentModelDocument.ts
1197
- function useSelectedDocumentModelDocument() {
1198
- return useSelectedDocumentOfType("powerhouse/document-model");
1199
- }
1200
- //#endregion
1201
- //#region editors/document-model-editor/utils/change-classification.ts
1202
- var import_graphql = require_graphql();
1203
- function isShapeTypeNode(node) {
1204
- 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;
1205
- }
1206
- function collectTypeFields(doc) {
1207
- const types = /* @__PURE__ */ new Map();
1208
- for (const definition of doc.definitions) {
1209
- if (!isShapeTypeNode(definition)) continue;
1210
- const fields = /* @__PURE__ */ new Map();
1211
- if (definition.kind === import_graphql.Kind.ENUM_TYPE_DEFINITION) for (const value of definition.values ?? []) fields.set(value.name.value, "value");
1212
- else for (const field of definition.fields ?? []) fields.set(field.name.value, (0, import_graphql.print)(field.type));
1213
- types.set(definition.name.value, fields);
1214
- }
1215
- return types;
1216
- }
1217
- function escapeRegExp(value) {
1218
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1219
- }
1220
- function replaceTypeName(printedType, oldName, newName) {
1221
- return printedType.replace(new RegExp(`\\b${escapeRegExp(oldName)}\\b`, "g"), newName);
1222
- }
1223
- function typeSignature(name, fields) {
1224
- return [...fields.entries()].map(([field, type]) => `${field}:${replaceTypeName(type, name, "__SELF__")}`).sort().join("|");
1225
- }
1226
- function detectTypeRenames(oldTypes, newTypes) {
1227
- const renames = /* @__PURE__ */ new Map();
1228
- const removed = [...oldTypes.keys()].filter((name) => !newTypes.has(name));
1229
- const added = new Set([...newTypes.keys()].filter((name) => !oldTypes.has(name)));
1230
- for (const oldName of removed) {
1231
- const oldSignature = typeSignature(oldName, oldTypes.get(oldName));
1232
- for (const newName of added) if (typeSignature(newName, newTypes.get(newName)) === oldSignature) {
1233
- renames.set(oldName, newName);
1234
- added.delete(newName);
1235
- break;
1236
- }
1237
- }
1238
- return renames;
1239
- }
1240
- function flattenFields(types, renames) {
1241
- const fields = /* @__PURE__ */ new Map();
1242
- for (const [typeName, typeFields] of types) {
1243
- const resolvedTypeName = renames.get(typeName) ?? typeName;
1244
- for (const [fieldName, printedType] of typeFields) {
1245
- let resolvedType = printedType;
1246
- for (const [oldName, newName] of renames) resolvedType = replaceTypeName(resolvedType, oldName, newName);
1247
- fields.set(`${resolvedTypeName}.${fieldName}`, resolvedType);
1248
- }
1249
- }
1250
- return fields;
1251
- }
1252
- function hasShapeChange(diff) {
1253
- return diff.addedFields.length > 0 || diff.removedFields.length > 0 || diff.changedFields.length > 0;
1254
- }
1255
- function diffSdlShapes(oldSdl, newSdl) {
1256
- const empty = {
1257
- addedFields: [],
1258
- removedFields: [],
1259
- changedFields: []
1260
- };
1261
- let oldDoc;
1262
- let newDoc;
1263
- try {
1264
- oldDoc = (0, import_graphql.parse)(oldSdl);
1265
- newDoc = (0, import_graphql.parse)(newSdl);
1266
- } catch {
1267
- return empty;
1268
- }
1269
- const oldTypes = collectTypeFields(oldDoc);
1270
- const newTypes = collectTypeFields(newDoc);
1271
- const oldFields = flattenFields(oldTypes, detectTypeRenames(oldTypes, newTypes));
1272
- const newFields = flattenFields(newTypes, /* @__PURE__ */ new Map());
1273
- const diff = {
1274
- addedFields: [],
1275
- removedFields: [],
1276
- changedFields: []
1277
- };
1278
- for (const [key, newType] of newFields) {
1279
- const oldType = oldFields.get(key);
1280
- if (oldType === void 0) diff.addedFields.push(key);
1281
- else if (oldType !== newType) diff.changedFields.push(`${key}: ${oldType} → ${newType}`);
1282
- }
1283
- for (const key of oldFields.keys()) if (!newFields.has(key)) diff.removedFields.push(key);
1284
- return diff;
1285
- }
1286
- const SAFE = { kind: "safe" };
1287
- function isBlank(value) {
1288
- return !value || !value.trim() || value.trim() === "{}";
1289
- }
1290
- /**
1291
- * True for a blank SDL, or an SDL whose types contain nothing but the
1292
- * `_placeholder` field the editor seeds new state/operation schemas with
1293
- * (see `makeInitialSchemaDoc` / `makeOperationInitialDoc` in ./helpers.ts).
1294
- * Replacing a placeholder-only schema with real fields is a user's first
1295
- * edit on a brand-new model, not a version-relevant change.
1296
- */
1297
- function isPlaceholderOnlySchema(sdl) {
1298
- if (isBlank(sdl)) return true;
1299
- let doc;
1300
- try {
1301
- doc = (0, import_graphql.parse)(sdl);
1302
- } catch {
1303
- return false;
1304
- }
1305
- return [...collectTypeFields(doc).values()].every((fields) => fields.size === 0 || fields.size === 1 && fields.has("_placeholder"));
1306
- }
1307
- function findOperation(spec, operationId) {
1308
- for (const module of spec.modules) {
1309
- const operation = module.operations.find((op) => op.id === operationId);
1310
- if (operation) return operation;
1311
- }
1312
- }
1313
- function addedSinceLastRelease(operationId, previousSpec) {
1314
- return previousSpec !== void 0 && !findOperation(previousSpec, operationId);
1315
- }
1316
- function classifySetStateSchema(input, latestSpec) {
1317
- const currentSchema = input.scope === "local" ? latestSpec.state.local.schema : latestSpec.state.global.schema;
1318
- if (isPlaceholderOnlySchema(currentSchema)) return SAFE;
1319
- const diff = diffSdlShapes(currentSchema, input.schema);
1320
- if (!hasShapeChange(diff)) return SAFE;
1321
- return {
1322
- kind: "version-relevant",
1323
- 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.`,
1324
- diff
1325
- };
1326
- }
1327
- /**
1328
- * The editor pre-fills a fresh model's initial value from the placeholder
1329
- * schema, so a value that is blank or carries only the `_placeholder` key is
1330
- * still being initialized rather than changed.
1331
- */
1332
- function isPlaceholderOnlyInitialValue(value) {
1333
- if (isBlank(value)) return true;
1334
- let parsed;
1335
- try {
1336
- parsed = JSON.parse(value);
1337
- } catch {
1338
- return false;
1339
- }
1340
- if (typeof parsed !== "object" || parsed === null) return false;
1341
- return Object.keys(parsed).every((key) => key === "_placeholder");
1342
- }
1343
- function classifySetInitialState(input, latestSpec) {
1344
- const currentValue = input.scope === "local" ? latestSpec.state.local.initialValue : latestSpec.state.global.initialValue;
1345
- if (isPlaceholderOnlyInitialValue(currentValue)) return SAFE;
1346
- if (compareStringsWithoutWhitespace(currentValue, input.initialValue)) return SAFE;
1347
- return {
1348
- kind: "version-relevant",
1349
- reason: `You're changing the starting content that version ${latestSpec.version} documents are built on.`
1350
- };
1351
- }
1352
- function classifyOperationChange(action, operationId, latestSpec, previousSpec) {
1353
- if (addedSinceLastRelease(operationId, previousSpec)) return SAFE;
1354
- const operation = findOperation(latestSpec, operationId);
1355
- if (!operation) return SAFE;
1356
- const operationLabel = operation.name || "an operation";
1357
- switch (action.type) {
1358
- case "DELETE_OPERATION": return {
1359
- kind: "version-relevant",
1360
- reason: `You're removing the "${operationLabel}" operation from version ${latestSpec.version}.`
1361
- };
1362
- case "SET_OPERATION_NAME":
1363
- if (isBlank(operation.name)) return SAFE;
1364
- return {
1365
- kind: "version-relevant",
1366
- reason: `You're renaming the "${operationLabel}" operation in version ${latestSpec.version}.`
1367
- };
1368
- case "SET_OPERATION_SCHEMA": {
1369
- if (isPlaceholderOnlySchema(operation.schema ?? "")) return SAFE;
1370
- if (isBlank(action.input.schema)) return {
1371
- kind: "version-relevant",
1372
- reason: `You're changing the information that the "${operationLabel}" operation accepts in version ${latestSpec.version}.`
1373
- };
1374
- const diff = diffSdlShapes(operation.schema ?? "", action.input.schema ?? "");
1375
- if (!hasShapeChange(diff)) return SAFE;
1376
- return {
1377
- kind: "version-relevant",
1378
- reason: `You're changing the information that the "${operationLabel}" operation accepts in version ${latestSpec.version}.`,
1379
- diff
1380
- };
1381
- }
1382
- default: return SAFE;
1383
- }
1384
- }
1385
- function classifyDeleteModule(moduleId, latestSpec, previousSpec) {
1386
- const module = latestSpec.modules.find((candidate) => candidate.id === moduleId);
1387
- if (!module || module.operations.length === 0) return SAFE;
1388
- if (module.operations.every((operation) => addedSinceLastRelease(operation.id, previousSpec))) return SAFE;
1389
- return {
1390
- kind: "version-relevant",
1391
- reason: `You're removing the "${module.name}" module and all of its operations from version ${latestSpec.version}.`
1392
- };
1393
- }
1394
- /**
1395
- * Classifies a document-model action as version-relevant (would break
1396
- * documents created with the current version) or safe. `previousSpec` is the
1397
- * last released specification, used to exempt operations added since the
1398
- * release.
1399
- */
1400
- function classifyDocumentModelAction(action, latestSpec, previousSpec) {
1401
- switch (action.type) {
1402
- case "SET_STATE_SCHEMA": return classifySetStateSchema(action.input, latestSpec);
1403
- case "SET_INITIAL_STATE": return classifySetInitialState(action.input, latestSpec);
1404
- case "DELETE_OPERATION":
1405
- case "SET_OPERATION_NAME":
1406
- case "SET_OPERATION_SCHEMA": return classifyOperationChange(action, action.input.id, latestSpec, previousSpec);
1407
- case "DELETE_MODULE": return classifyDeleteModule(action.input.id, latestSpec, previousSpec);
1408
- default: return SAFE;
1409
- }
1410
- }
1411
- /**
1412
- * Pure decision core of the version advisory: given the actions about to be
1413
- * dispatched, decide whether to dispatch immediately or prompt the user.
1414
- */
1415
- function decideDispatch(actions, latestSpec, previousSpec, hasSessionChoice) {
1416
- if (hasSessionChoice) return { kind: "dispatch" };
1417
- for (const action of actions) {
1418
- const classification = classifyDocumentModelAction(action, latestSpec, previousSpec);
1419
- if (classification.kind === "version-relevant") return {
1420
- kind: "prompt",
1421
- reason: classification.reason,
1422
- diff: classification.diff
1423
- };
1424
- }
1425
- return { kind: "dispatch" };
1426
- }
1427
- //#endregion
1428
- //#region editors/document-model-editor/hooks/useVersionAdvisory.ts
1429
- /**
1430
- * Versions the user has confirmed as "still in development" (or that were
1431
- * just created via an explicit release) for this browser session. Keyed by
1432
- * `${documentId}:${version}`. Deliberately in-memory: a publisher returning
1433
- * in a later session is asked again, which is when the reminder matters.
1434
- */
1435
- const sessionVersionChoices = /* @__PURE__ */ new Set();
1436
- function useVersionAdvisory(args) {
1437
- const { documentId, latestSpec, previousSpec, dispatch, onReleaseError } = args;
1438
- const [prompt, setPrompt] = useState(void 0);
1439
- const pendingRef = useRef(void 0);
1440
- const choiceKey = `${documentId}:${latestSpec.version}`;
1441
- const guardedDispatch = (...dispatchArgs) => {
1442
- const [action] = dispatchArgs;
1443
- const decision = decideDispatch((Array.isArray(action) ? action : [action]).filter((candidate) => candidate !== void 0), latestSpec, previousSpec, sessionVersionChoices.has(choiceKey));
1444
- if (decision.kind === "dispatch") {
1445
- dispatch(...dispatchArgs);
1446
- return;
1447
- }
1448
- pendingRef.current = dispatchArgs;
1449
- setPrompt({
1450
- version: latestSpec.version,
1451
- reason: decision.reason,
1452
- diff: decision.diff
1453
- });
1454
- };
1455
- const flushPending = () => {
1456
- const pending = pendingRef.current;
1457
- pendingRef.current = void 0;
1458
- if (pending) dispatch(...pending);
1459
- };
1460
- const releaseFirst = () => {
1461
- setPrompt(void 0);
1462
- if (!pendingRef.current) return;
1463
- dispatch(releaseNewVersion(), (errors) => {
1464
- if (errors.length > 0) {
1465
- pendingRef.current = void 0;
1466
- onReleaseError?.(errors[0].message);
1467
- }
1468
- }, () => {
1469
- if (!pendingRef.current) return;
1470
- sessionVersionChoices.add(`${documentId}:${latestSpec.version + 1}`);
1471
- flushPending();
1472
- });
1473
- };
1474
- const keepEditing = () => {
1475
- sessionVersionChoices.add(choiceKey);
1476
- setPrompt(void 0);
1477
- flushPending();
1478
- };
1479
- const cancelAdvisory = () => {
1480
- pendingRef.current = void 0;
1481
- setPrompt(void 0);
1482
- };
1483
- const markVersionInDevelopment = (version) => {
1484
- sessionVersionChoices.add(`${documentId}:${version}`);
1485
- };
1486
- return {
1487
- guardedDispatch,
1488
- prompt,
1489
- releaseFirst,
1490
- keepEditing,
1491
- cancelAdvisory,
1492
- markVersionInDevelopment
1493
- };
1494
- }
1495
- //#endregion
1496
- //#region editors/document-model-editor/editor.tsx
1497
- const StateSchemas = lazy(() => import("./state-schemas-DURvYjxG.mjs"));
1498
- const noopSetStateSchema = () => void 0;
1499
- const noopSetInitialState = () => void 0;
1500
- function Editor() {
1501
- useSetPHDocumentEditorConfig(editorConfig);
1502
- const toast = usePHToast();
1503
- const [document, dispatch] = useSelectedDocumentModelDocument();
1504
- const [scope, setScope] = useState("global");
1505
- const documentNodeName = document.header.name;
1506
- const { name: modelName, id: documentType, extension, description, author: { name: authorName, website: authorWebsite } } = document.state.global;
1507
- const specifications = document.state.global.specifications;
1508
- const latestSpec = specifications[specifications.length - 1];
1509
- const previousSpec = specifications.length >= 2 ? specifications[specifications.length - 2] : void 0;
1510
- const [viewedVersion, setViewedVersion] = useState("latest");
1511
- const viewedSpec = viewedVersion === "latest" ? latestSpec : specifications.find((spec) => spec.version === viewedVersion) ?? latestSpec;
1512
- const isViewingFrozenVersion = viewedSpec.version !== latestSpec.version;
1513
- const { state: { global: { schema: globalStateSchema, initialValue: globalStateInitialValue }, local: { schema: localStateSchema, initialValue: localStateInitialValue } }, modules } = viewedSpec;
1514
- const operations = modules.flatMap((module) => module.operations);
1515
- const { state: { global: { schema: latestGlobalStateSchema, initialValue: latestGlobalStateInitialValue }, local: { schema: latestLocalStateSchema, initialValue: latestLocalStateInitialValue } }, modules: latestModules } = latestSpec;
1516
- const latestOperations = latestModules.flatMap((module) => module.operations);
1517
- const shouldSetInitialName = useRef(!modelName && !!documentNodeName && latestOperations.length === 0);
1518
- useEffect(() => {
1519
- if (!shouldSetInitialName.current || !documentNodeName) return;
1520
- const initialSchemaDoc = initializeModelSchema(documentNodeName);
1521
- dispatch([setModelName({ name: documentNodeName }), setStateSchema({
1522
- schema: initialSchemaDoc,
1523
- scope: "global"
1524
- })]);
1525
- shouldSetInitialName.current = false;
1526
- }, [documentNodeName, dispatch]);
1527
- const { guardedDispatch, prompt, releaseFirst, keepEditing, cancelAdvisory, markVersionInDevelopment } = useVersionAdvisory({
1528
- documentId: document.header.id,
1529
- latestSpec,
1530
- previousSpec,
1531
- dispatch,
1532
- onReleaseError: (message) => {
1533
- if (toast) toast(message, { type: "connect-warning" });
1534
- }
1535
- });
1536
- const handleReleaseNewVersion = () => {
1537
- const nextVersion = latestSpec.version + 1;
1538
- dispatch(releaseNewVersion(), (errors) => {
1539
- if (errors.length > 0 && toast) toast(errors[0].message, { type: "connect-warning" });
1540
- }, () => {
1541
- markVersionInDevelopment(nextVersion);
1542
- setViewedVersion("latest");
1543
- });
1544
- };
1545
- const operationSchemasSdl = operations.flatMap((operation) => operation.schema ?? []).join("\n");
1546
- const handleSetModelId = (id) => {
1547
- if (compareStringsWithoutWhitespace(id, documentType)) return;
1548
- guardedDispatch([setModelId({ id })]);
1549
- };
1550
- const handleSetModelDescription = (newDescription) => {
1551
- if (compareStringsWithoutWhitespace(newDescription, description)) return;
1552
- guardedDispatch(setModelDescription({ description: newDescription }));
1553
- };
1554
- const handleSetModelExtension = (newExtension) => {
1555
- if (compareStringsWithoutWhitespace(newExtension, extension)) return;
1556
- guardedDispatch(setModelExtension({ extension: newExtension }));
1557
- };
1558
- const handleSetModelName = (newName) => {
1559
- if (compareStringsWithoutWhitespace(newName, modelName)) return;
1560
- guardedDispatch(setModelName({ name: newName }));
1561
- };
1562
- const handleSetAuthorName = (newAuthorName) => {
1563
- if (compareStringsWithoutWhitespace(newAuthorName, authorName)) return;
1564
- guardedDispatch(setAuthorName({ authorName: newAuthorName }));
1565
- };
1566
- const handleSetAuthorWebsite = (newAuthorWebsite) => {
1567
- if (compareStringsWithoutWhitespace(newAuthorWebsite, authorWebsite ?? "")) return;
1568
- guardedDispatch(setAuthorWebsite({ authorWebsite: newAuthorWebsite }));
1569
- };
1570
- const handleSetStateSchema = (newSchema, scope) => {
1571
- if (compareStringsWithoutWhitespace(newSchema, scope === "global" ? latestGlobalStateSchema : latestLocalStateSchema)) return;
1572
- guardedDispatch(setStateSchema({
1573
- schema: newSchema,
1574
- scope
1575
- }));
1576
- };
1577
- const handleSetInitialState = (newInitialValue, scope) => {
1578
- if (compareStringsWithoutWhitespace(newInitialValue, scope === "global" ? latestGlobalStateInitialValue : latestLocalStateInitialValue)) return;
1579
- guardedDispatch(setInitialState({
1580
- initialValue: newInitialValue,
1581
- scope
1582
- }));
1583
- };
1584
- const handleAddModule = (name) => {
1585
- return new Promise((resolve) => {
1586
- try {
1587
- if (latestModules.some((module) => compareStringsWithoutWhitespace(module.name, name))) {
1588
- resolve(void 0);
1589
- return;
1590
- }
1591
- const id = generateId();
1592
- guardedDispatch(addModule({
1593
- id,
1594
- name
1595
- }));
1596
- resolve(id);
1597
- } catch (error) {
1598
- console.error("Failed to add module:", error);
1599
- resolve(void 0);
1600
- }
1601
- });
1602
- };
1603
- const handleSetModuleName = (id, name) => {
1604
- if (latestModules.some((module) => compareStringsWithoutWhitespace(module.name, name))) return;
1605
- guardedDispatch(setModuleName({
1606
- id,
1607
- name
1608
- }));
1609
- };
1610
- const handleDeleteModule = (id) => {
1611
- guardedDispatch(deleteModule({ id }));
1612
- };
1613
- const handleAddOperation = (moduleId, name) => {
1614
- return new Promise((resolve) => {
1615
- const id = generateId();
1616
- guardedDispatch(addOperation({
1617
- id,
1618
- moduleId,
1619
- name,
1620
- scope
1621
- }), (errors) => {
1622
- if (errors.length > 0) {
1623
- if (toast) toast(errors[0].message, { type: "connect-warning" });
1624
- resolve(void 0);
1625
- } else resolve(id);
1626
- }, () => resolve(id));
1627
- });
1628
- };
1629
- const handleSetOperationName = (id, name) => {
1630
- guardedDispatch(setOperationName({
1631
- id,
1632
- name
1633
- }), (errors) => {
1634
- if (errors.length > 0 && toast) toast(errors[0].message, { type: "connect-warning" });
1635
- });
1636
- };
1637
- const handleSetOperationSchema = (id, newSchema) => {
1638
- const operation = latestOperations.find((operation) => operation.id === id);
1639
- if (operation?.schema && compareStringsWithoutWhitespace(newSchema, operation.schema)) return;
1640
- guardedDispatch(setOperationSchema({
1641
- id,
1642
- schema: newSchema
1643
- }));
1644
- };
1645
- const handleToggleNoInputRequired = (id, noInputRequired) => {
1646
- const operation = latestOperations.find((op) => op.id === id);
1647
- if (!operation?.name) return;
1648
- if (noInputRequired) guardedDispatch(setOperationSchema({
1649
- id,
1650
- schema: makeEmptyOperationSchema(operation.name)
1651
- }));
1652
- else guardedDispatch(setOperationSchema({
1653
- id,
1654
- schema: makeOperationInitialDoc(operation.name)
1655
- }));
1656
- };
1657
- const handleSetOperationDescription = (id, newDescription) => {
1658
- if (compareStringsWithoutWhitespace(latestOperations.find((operation) => operation.id === id)?.description ?? "", newDescription)) return;
1659
- guardedDispatch(setOperationDescription({
1660
- id,
1661
- description: newDescription
1662
- }));
1663
- };
1664
- const handleDeleteOperation = (id) => {
1665
- guardedDispatch(deleteOperation({ id }));
1666
- };
1667
- const handleAddOperationError = (operationId, errorName) => {
1668
- return new Promise((resolve) => {
1669
- try {
1670
- if ((latestOperations.find((operation) => operation.id === operationId)?.errors.map((error) => error.name).filter(Boolean) ?? []).some((name) => compareStringsWithoutWhitespace(name, errorName))) {
1671
- resolve(void 0);
1672
- return;
1673
- }
1674
- const id = generateId();
1675
- guardedDispatch(addOperationError({
1676
- id,
1677
- operationId,
1678
- errorName,
1679
- errorCode: pascalCase(errorName)
1680
- }));
1681
- resolve(id);
1682
- } catch (error) {
1683
- console.error("Failed to add operation error:", error);
1684
- resolve(void 0);
1685
- }
1686
- });
1687
- };
1688
- const handleDeleteOperationError = (id) => {
1689
- guardedDispatch(deleteOperationError({ id }));
1690
- };
1691
- const handleSetOperationErrorName = (operationId, errorId, errorName) => {
1692
- if ((latestOperations.find((operation) => operation.id === operationId)?.errors.map((error) => error.name).filter(Boolean) ?? []).some((name) => compareStringsWithoutWhitespace(name, errorName))) return;
1693
- guardedDispatch(setOperationErrorName({
1694
- id: errorId,
1695
- errorName
1696
- }));
1697
- };
1698
- const addOperationAndInitialSchema = async (moduleId, name) => {
1699
- try {
1700
- const id = await handleAddOperation(moduleId, name);
1701
- if (!id) return void 0;
1702
- try {
1703
- handleSetOperationSchema(id, makeOperationInitialDoc(name));
1704
- return id;
1705
- } catch (error) {
1706
- console.error("Failed to update operation schema:", error);
1707
- return;
1708
- }
1709
- } catch (error) {
1710
- console.error("Failed to add operation and schema:", error);
1711
- return;
1712
- }
1713
- };
1714
- return /* @__PURE__ */ jsxs("main", {
1715
- className: "min-h-dvh bg-background p-6",
1716
- children: [
1717
- /* @__PURE__ */ jsx(DocumentToolbar, {}),
1718
- /* @__PURE__ */ jsx(SchemaContextProvider, {
1719
- globalStateSchemaSdl: globalStateSchema,
1720
- localStateSchemaSdl: localStateSchema,
1721
- operationSchemasSdl,
1722
- children: /* @__PURE__ */ jsxs("div", {
1723
- className: "mx-auto max-w-6xl px-4 pt-8",
1724
- children: [
1725
- /* @__PURE__ */ jsx(VersionControls, {
1726
- specifications,
1727
- viewedVersion: viewedSpec.version,
1728
- onViewVersion: setViewedVersion,
1729
- onReleaseNewVersion: handleReleaseNewVersion
1730
- }),
1731
- /* @__PURE__ */ jsx(ModelMetadata, {
1732
- name: modelName,
1733
- documentType,
1734
- extension,
1735
- description,
1736
- authorName,
1737
- authorWebsite: authorWebsite ?? "",
1738
- globalStateSchema: latestGlobalStateSchema,
1739
- localStateSchema: latestLocalStateSchema,
1740
- setModelId: handleSetModelId,
1741
- setModelDescription: handleSetModelDescription,
1742
- setModelExtension: handleSetModelExtension,
1743
- setModelName: handleSetModelName,
1744
- setAuthorName: handleSetAuthorName,
1745
- setAuthorWebsite: handleSetAuthorWebsite,
1746
- setStateSchema: handleSetStateSchema
1747
- }),
1748
- /* @__PURE__ */ jsx(Divider, {}),
1749
- isViewingFrozenVersion && /* @__PURE__ */ jsx(FrozenVersionBanner, {
1750
- latestVersion: latestSpec.version,
1751
- viewedVersion: viewedSpec.version
1752
- }),
1753
- /* @__PURE__ */ jsxs("div", {
1754
- className: isViewingFrozenVersion ? "pointer-events-none opacity-80 select-none" : void 0,
1755
- inert: isViewingFrozenVersion || void 0,
1756
- children: [
1757
- /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(StateSchemas, {
1758
- modelName,
1759
- globalStateSchema,
1760
- globalStateInitialValue,
1761
- localStateSchema,
1762
- localStateInitialValue,
1763
- setStateSchema: isViewingFrozenVersion ? noopSetStateSchema : handleSetStateSchema,
1764
- setInitialState: isViewingFrozenVersion ? noopSetInitialState : handleSetInitialState,
1765
- currentScope: scope,
1766
- onScopeChange: setScope
1767
- }) }),
1768
- /* @__PURE__ */ jsx(Divider, {}),
1769
- /* @__PURE__ */ jsxs("h3", {
1770
- className: "mb-6 text-lg text-foreground capitalize",
1771
- children: [scope, " Operations"]
1772
- }),
1773
- /* @__PURE__ */ jsx(Modules, {
1774
- modules: modules.map((module) => ({
1775
- ...module,
1776
- operations: module.operations.filter((op) => op.scope === scope)
1777
- })),
1778
- allOperations: operations,
1779
- addModule: handleAddModule,
1780
- updateModuleName: handleSetModuleName,
1781
- deleteModule: handleDeleteModule,
1782
- updateOperationName: handleSetOperationName,
1783
- updateOperationSchema: handleSetOperationSchema,
1784
- setOperationDescription: handleSetOperationDescription,
1785
- deleteOperation: handleDeleteOperation,
1786
- addOperationError: handleAddOperationError,
1787
- deleteOperationError: handleDeleteOperationError,
1788
- setOperationErrorName: handleSetOperationErrorName,
1789
- addOperationAndInitialSchema,
1790
- toggleNoInputRequired: handleToggleNoInputRequired
1791
- })
1792
- ]
1793
- })
1794
- ]
1795
- })
1796
- }),
1797
- /* @__PURE__ */ jsx(VersionAdvisoryModal, {
1798
- prompt,
1799
- onReleaseFirst: releaseFirst,
1800
- onKeepEditing: keepEditing,
1801
- onCancel: cancelAdvisory
1802
- })
1803
- ]
1804
- });
1805
- }
1806
- //#endregion
1807
- export { Editor as default };
1808
-
1809
- //# sourceMappingURL=editor-D8SL0ydm.mjs.map