@powerhousedao/powerhouse-vetra-packages 6.2.2-dev.41 → 6.2.2-dev.43
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.
- package/dist/browser/assets/{entry-Db_lIhQq.js → entry-CcSqsfaf.js} +2 -2
- package/dist/browser/assets/{projection-entry-DqgHaUSy.js → projection-entry-qnPqxpN3.js} +3 -3
- package/dist/browser/{linting-_AQWr8aE.js → button-CuO8Gh3v.js} +17 -4
- package/dist/browser/button-CuO8Gh3v.js.map +1 -0
- package/dist/browser/{connect-BUnNjGUW.js → connect-Cs9_OfUW.js} +49 -7
- package/dist/browser/{connect-BUnNjGUW.js.map → connect-Cs9_OfUW.js.map} +1 -1
- package/dist/browser/{dist-BatmWBzA.js → dist-Cw08sCbR.js} +150 -25
- package/dist/browser/dist-Cw08sCbR.js.map +1 -0
- package/dist/browser/{document-drive-D3Z9vXTQ.js → document-drive-CLF3V3yq.js} +22 -6
- package/dist/browser/document-drive-CLF3V3yq.js.map +1 -0
- package/dist/browser/document-models/index.js +1 -1
- package/dist/browser/{editor-Bn6uXvxG.js → editor-CRj28xcj.js} +668 -101
- package/dist/browser/editor-CRj28xcj.js.map +1 -0
- package/dist/browser/{editor-BLeFoOh6.js → editor-Clf15hps.js} +5 -5
- package/dist/browser/{editor-BLeFoOh6.js.map → editor-Clf15hps.js.map} +1 -1
- package/dist/browser/editors/document-model-editor/module.js +1 -1
- package/dist/browser/editors/generic-drive-explorer/index.js +4 -4
- package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
- package/dist/browser/{folder-view-DNzFnfW2.js → folder-view-Zc--316o.js} +29 -10
- package/dist/browser/folder-view-Zc--316o.js.map +1 -0
- package/dist/browser/{graphql-editor-DWo8N_z4.js → graphql-editor-BYiN6EYX.js} +3 -3
- package/dist/browser/{graphql-editor-DWo8N_z4.js.map → graphql-editor-BYiN6EYX.js.map} +1 -1
- package/dist/browser/index.js +2 -2
- package/dist/browser/{json-editor-CEugjpFj.js → json-editor-BCQBDkoV.js} +3 -3
- package/dist/browser/{json-editor-CEugjpFj.js.map → json-editor-BCQBDkoV.js.map} +1 -1
- package/dist/browser/{lib-CiaHsAaR.js → lib-CZf9FJ-n.js} +2 -2
- package/dist/browser/lib-CZf9FJ-n.js.map +1 -0
- package/dist/browser/{state-schemas-VrticHe4.js → state-schemas-Co7oWTVF.js} +5 -15
- package/dist/browser/state-schemas-Co7oWTVF.js.map +1 -0
- package/dist/node/{linting-BjvRPjCY.mjs → button-Da7CxMn7.mjs} +17 -4
- package/dist/node/button-Da7CxMn7.mjs.map +1 -0
- package/dist/node/{connect-wMkkAckX.mjs → connect-DtLHLVuq.mjs} +49 -7
- package/dist/node/{connect-wMkkAckX.mjs.map → connect-DtLHLVuq.mjs.map} +1 -1
- package/dist/node/{dist-CUHBOv3P.mjs → dist-Co6sAUR3.mjs} +150 -25
- package/dist/node/dist-Co6sAUR3.mjs.map +1 -0
- package/dist/node/{document-drive-CI0J7nMj.mjs → document-drive-CPxMz8lW.mjs} +22 -6
- package/dist/node/document-drive-CPxMz8lW.mjs.map +1 -0
- package/dist/node/document-models/index.mjs +1 -1
- package/dist/node/{editor-aIeTo2EE.mjs → editor-CNTEyfKg.mjs} +5 -5
- package/dist/node/{editor-aIeTo2EE.mjs.map → editor-CNTEyfKg.mjs.map} +1 -1
- package/dist/node/{editor-Cr-mNQca.mjs → editor-Dl-takGb.mjs} +670 -103
- package/dist/node/editor-Dl-takGb.mjs.map +1 -0
- package/dist/node/editors/document-model-editor/module.mjs +1 -1
- package/dist/node/editors/generic-drive-explorer/index.mjs +4 -4
- package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
- package/dist/node/{folder-view-_x1OBYZN.mjs → folder-view-B2qOsImy.mjs} +29 -10
- package/dist/node/folder-view-B2qOsImy.mjs.map +1 -0
- package/dist/node/{graphql-editor-Dd2_z5QJ.mjs → graphql-editor-DsX64AUl.mjs} +3 -3
- package/dist/node/{graphql-editor-Dd2_z5QJ.mjs.map → graphql-editor-DsX64AUl.mjs.map} +1 -1
- package/dist/node/index.mjs +2 -2
- package/dist/node/{json-editor-Dphg6ZeL.mjs → json-editor-H15UPuqD.mjs} +3 -3
- package/dist/node/{json-editor-Dphg6ZeL.mjs.map → json-editor-H15UPuqD.mjs.map} +1 -1
- package/dist/node/{main-Db0ei9wX.mjs → main-7-PK1gTO.mjs} +2 -2
- package/dist/node/main-7-PK1gTO.mjs.map +1 -0
- package/dist/node/{state-schemas-BSLgTw2O.mjs → state-schemas-BEbd8zYo.mjs} +6 -16
- package/dist/{browser/state-schemas-VrticHe4.js.map → node/state-schemas-BEbd8zYo.mjs.map} +1 -1
- package/package.json +6 -6
- package/dist/browser/dist-BatmWBzA.js.map +0 -1
- package/dist/browser/document-drive-D3Z9vXTQ.js.map +0 -1
- package/dist/browser/editor-Bn6uXvxG.js.map +0 -1
- package/dist/browser/folder-view-DNzFnfW2.js.map +0 -1
- package/dist/browser/lib-CiaHsAaR.js.map +0 -1
- package/dist/browser/linting-_AQWr8aE.js.map +0 -1
- package/dist/node/dist-CUHBOv3P.mjs.map +0 -1
- package/dist/node/document-drive-CI0J7nMj.mjs.map +0 -1
- package/dist/node/editor-Cr-mNQca.mjs.map +0 -1
- package/dist/node/folder-view-_x1OBYZN.mjs.map +0 -1
- package/dist/node/linting-BjvRPjCY.mjs.map +0 -1
- package/dist/node/main-Db0ei9wX.mjs.map +0 -1
- package/dist/node/state-schemas-BSLgTw2O.mjs.map +0 -1
|
@@ -1,13 +1,15 @@
|
|
|
1
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, x as url, y as union } from "./dist-B4FWbuEM.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { B as setModelExtension, D as deleteModule, G as setOperationDescription, H as setModelName, I as setAuthorName, J as setOperationSchema, K as setOperationErrorName, L as setAuthorWebsite, O as deleteOperation, P as releaseNewVersion, R as setInitialState, U as setModuleName, V as setModelId, Y as setStateSchema, et as generateId, h as addOperationError, k as deleteOperationError, m as addOperation, p as addModule, q as setOperationName, z as setModelDescription } from "./document-drive-CLF3V3yq.js";
|
|
3
|
+
import { c as Kind, t as parse$1 } from "./parser-CkF6Qt8V.js";
|
|
4
|
+
import { t as print } from "./printer-CEYr4JOg.js";
|
|
5
|
+
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-CuO8Gh3v.js";
|
|
6
|
+
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-Cs9_OfUW.js";
|
|
5
7
|
import { w as twMerge } from "./dist-BAJ5nRDl.js";
|
|
6
|
-
import {
|
|
8
|
+
import { P as usePHToast, m as useSelectedDocumentOfType, y as useSetPHDocumentEditorConfig } from "./dist-Cw08sCbR.js";
|
|
7
9
|
import { t as SchemaContextProvider } from "./schema-context-ZyeclQwy.js";
|
|
8
10
|
import * as React$1 from "react";
|
|
9
11
|
import React, { Suspense, forwardRef, lazy, useCallback, useEffect, useId, useImperativeHandle, useRef, useState } from "react";
|
|
10
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
11
13
|
//#region ../../node_modules/.pnpm/clsx@2.0.0/node_modules/clsx/dist/clsx.mjs
|
|
12
14
|
function r$1(e) {
|
|
13
15
|
var t, f, n = "";
|
|
@@ -756,7 +758,7 @@ function OperationErrors({ operation, addOperationError, deleteOperationError, s
|
|
|
756
758
|
}
|
|
757
759
|
//#endregion
|
|
758
760
|
//#region editors/document-model-editor/components/operation.tsx
|
|
759
|
-
const GraphqlEditor = lazy(() => import("./graphql-editor-
|
|
761
|
+
const GraphqlEditor = lazy(() => import("./graphql-editor-BYiN6EYX.js"));
|
|
760
762
|
function Operation(props) {
|
|
761
763
|
const { operation, module, allOperationNames, lastCreatedOperationId, onAddOperationAndInitialSchema, updateOperationName, deleteOperation, updateOperationSchema, setOperationDescription, addOperationError, deleteOperationError, setOperationErrorName, toggleNoInputRequired } = props;
|
|
762
764
|
const noInputRequired = isEmptyOperationSchema(operation.schema);
|
|
@@ -969,6 +971,226 @@ function Modules({ modules, allOperations, addModule, updateModuleName, deleteMo
|
|
|
969
971
|
});
|
|
970
972
|
}
|
|
971
973
|
//#endregion
|
|
974
|
+
//#region editors/document-model-editor/components/version-controls.tsx
|
|
975
|
+
const compactButtonStyle$1 = "min-h-0 min-w-0 flex-none rounded-lg px-6 py-1.5 text-sm whitespace-nowrap";
|
|
976
|
+
function VersionControls(props) {
|
|
977
|
+
const { specifications, viewedVersion, onViewVersion, onReleaseNewVersion } = props;
|
|
978
|
+
const [showReleaseModal, setShowReleaseModal] = useState(false);
|
|
979
|
+
const latestVersion = specifications[specifications.length - 1].version;
|
|
980
|
+
const nextVersion = latestVersion + 1;
|
|
981
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
982
|
+
className: "mb-4 flex items-center justify-between gap-4",
|
|
983
|
+
children: [
|
|
984
|
+
/* @__PURE__ */ jsxs("div", {
|
|
985
|
+
className: "flex items-center gap-2",
|
|
986
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
987
|
+
className: "rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground",
|
|
988
|
+
"data-testid": "model-version-badge",
|
|
989
|
+
children: ["Version ", viewedVersion]
|
|
990
|
+
}), specifications.length >= 2 && /* @__PURE__ */ jsx("div", {
|
|
991
|
+
"aria-label": "Document model version",
|
|
992
|
+
"data-testid": "model-version-switcher",
|
|
993
|
+
children: /* @__PURE__ */ jsx(ConnectSelect, {
|
|
994
|
+
absolutePositionMenu: true,
|
|
995
|
+
containerClassName: "z-10 [&_svg]:size-4",
|
|
996
|
+
id: "model-version-switcher",
|
|
997
|
+
itemClassName: "gap-1 px-2 py-1 font-mono text-xs leading-none [&_p:empty]:hidden",
|
|
998
|
+
items: specifications.map((spec) => ({
|
|
999
|
+
value: String(spec.version),
|
|
1000
|
+
displayValue: /* @__PURE__ */ jsx("span", {
|
|
1001
|
+
className: "normal-case",
|
|
1002
|
+
children: spec.version === latestVersion ? `v${spec.version} (latest)` : `v${spec.version} (frozen)`
|
|
1003
|
+
})
|
|
1004
|
+
})),
|
|
1005
|
+
listClassName: "border border-t-0 border-border shadow-md",
|
|
1006
|
+
menuClassName: "min-w-0 pr-1.5",
|
|
1007
|
+
onChange: (value) => {
|
|
1008
|
+
const version = Number(value);
|
|
1009
|
+
onViewVersion(version === latestVersion ? "latest" : version);
|
|
1010
|
+
},
|
|
1011
|
+
value: String(viewedVersion)
|
|
1012
|
+
})
|
|
1013
|
+
})]
|
|
1014
|
+
}),
|
|
1015
|
+
/* @__PURE__ */ jsx(Button, {
|
|
1016
|
+
className: "inline-flex h-8 items-center justify-center py-0",
|
|
1017
|
+
"data-testid": "release-new-version-button",
|
|
1018
|
+
onClick: () => setShowReleaseModal(true),
|
|
1019
|
+
type: "button",
|
|
1020
|
+
children: "Release new version"
|
|
1021
|
+
}),
|
|
1022
|
+
/* @__PURE__ */ jsx(Modal, {
|
|
1023
|
+
open: showReleaseModal,
|
|
1024
|
+
onOpenChange: (status) => {
|
|
1025
|
+
if (!status) setShowReleaseModal(false);
|
|
1026
|
+
},
|
|
1027
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1028
|
+
className: "w-[440px] p-6",
|
|
1029
|
+
children: [
|
|
1030
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1031
|
+
className: "pb-2 text-2xl font-bold text-foreground",
|
|
1032
|
+
children: ["Release version ", nextVersion]
|
|
1033
|
+
}),
|
|
1034
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1035
|
+
className: "my-4 rounded-md bg-background p-4 text-left text-sm text-foreground",
|
|
1036
|
+
children: [/* @__PURE__ */ jsxs("p", { children: [
|
|
1037
|
+
"Version ",
|
|
1038
|
+
latestVersion,
|
|
1039
|
+
" will be frozen as-is. Version",
|
|
1040
|
+
" ",
|
|
1041
|
+
nextVersion,
|
|
1042
|
+
" starts as an identical copy, and all further edits apply to version ",
|
|
1043
|
+
nextVersion,
|
|
1044
|
+
"."
|
|
1045
|
+
] }), /* @__PURE__ */ jsxs("p", {
|
|
1046
|
+
className: "mt-3",
|
|
1047
|
+
children: [
|
|
1048
|
+
"Existing version ",
|
|
1049
|
+
latestVersion,
|
|
1050
|
+
" documents will be upgradeable once you define the migration."
|
|
1051
|
+
]
|
|
1052
|
+
})]
|
|
1053
|
+
}),
|
|
1054
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1055
|
+
className: "mt-4 flex justify-between gap-3",
|
|
1056
|
+
children: [/* @__PURE__ */ jsx(ModalButton, {
|
|
1057
|
+
className: compactButtonStyle$1,
|
|
1058
|
+
onClick: () => setShowReleaseModal(false),
|
|
1059
|
+
variant: "cancel",
|
|
1060
|
+
children: "Cancel"
|
|
1061
|
+
}), /* @__PURE__ */ jsxs(ModalButton, {
|
|
1062
|
+
className: compactButtonStyle$1,
|
|
1063
|
+
"data-testid": "confirm-release-button",
|
|
1064
|
+
onClick: () => {
|
|
1065
|
+
setShowReleaseModal(false);
|
|
1066
|
+
onReleaseNewVersion();
|
|
1067
|
+
},
|
|
1068
|
+
variant: "confirm",
|
|
1069
|
+
children: ["Release version ", nextVersion]
|
|
1070
|
+
})]
|
|
1071
|
+
})
|
|
1072
|
+
]
|
|
1073
|
+
})
|
|
1074
|
+
})
|
|
1075
|
+
]
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
function FrozenVersionBanner(props) {
|
|
1079
|
+
const { viewedVersion, latestVersion } = props;
|
|
1080
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1081
|
+
className: "mb-4 rounded-md border border-border bg-muted p-3 text-sm text-foreground",
|
|
1082
|
+
"data-testid": "frozen-version-banner",
|
|
1083
|
+
children: [
|
|
1084
|
+
"Version ",
|
|
1085
|
+
viewedVersion,
|
|
1086
|
+
" is frozen. You're viewing it read-only. Edits go to version ",
|
|
1087
|
+
latestVersion,
|
|
1088
|
+
"."
|
|
1089
|
+
]
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
//#endregion
|
|
1093
|
+
//#region editors/document-model-editor/components/version-advisory-modal.tsx
|
|
1094
|
+
const compactButtonStyle = "min-h-0 min-w-0 flex-none rounded-lg px-4 py-1.5 text-sm whitespace-nowrap";
|
|
1095
|
+
function FieldDiffList(props) {
|
|
1096
|
+
const { label, fields } = props;
|
|
1097
|
+
if (fields.length === 0) return null;
|
|
1098
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1099
|
+
className: "mt-3",
|
|
1100
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
1101
|
+
className: "mb-1.5",
|
|
1102
|
+
children: label
|
|
1103
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1104
|
+
className: "flex flex-col items-start gap-1",
|
|
1105
|
+
children: fields.map((field) => /* @__PURE__ */ jsx("span", {
|
|
1106
|
+
className: "rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground",
|
|
1107
|
+
children: field
|
|
1108
|
+
}, field))
|
|
1109
|
+
})]
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
function VersionAdvisoryModal(props) {
|
|
1113
|
+
const { prompt, onReleaseFirst, onKeepEditing, onCancel } = props;
|
|
1114
|
+
if (!prompt) return null;
|
|
1115
|
+
const { version, reason, diff } = prompt;
|
|
1116
|
+
const nextVersion = version + 1;
|
|
1117
|
+
return /* @__PURE__ */ jsx(Modal, {
|
|
1118
|
+
open: true,
|
|
1119
|
+
onOpenChange: (status) => {
|
|
1120
|
+
if (!status) onCancel();
|
|
1121
|
+
},
|
|
1122
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1123
|
+
className: "w-[440px] p-6",
|
|
1124
|
+
"data-testid": "version-advisory-modal",
|
|
1125
|
+
children: [
|
|
1126
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1127
|
+
className: "pb-2 text-2xl font-bold text-foreground",
|
|
1128
|
+
children: [
|
|
1129
|
+
"Is version ",
|
|
1130
|
+
version,
|
|
1131
|
+
" of this model already in use?"
|
|
1132
|
+
]
|
|
1133
|
+
}),
|
|
1134
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1135
|
+
className: "my-4 rounded-md bg-background p-4 text-left text-sm text-foreground",
|
|
1136
|
+
children: [
|
|
1137
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
1138
|
+
reason,
|
|
1139
|
+
" Documents that were already created with version ",
|
|
1140
|
+
version,
|
|
1141
|
+
" ",
|
|
1142
|
+
"may stop working correctly."
|
|
1143
|
+
] }),
|
|
1144
|
+
diff && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
1145
|
+
/* @__PURE__ */ jsx(FieldDiffList, {
|
|
1146
|
+
fields: diff.addedFields,
|
|
1147
|
+
label: "New fields:"
|
|
1148
|
+
}),
|
|
1149
|
+
/* @__PURE__ */ jsx(FieldDiffList, {
|
|
1150
|
+
fields: diff.removedFields,
|
|
1151
|
+
label: "Removed fields:"
|
|
1152
|
+
}),
|
|
1153
|
+
/* @__PURE__ */ jsx(FieldDiffList, {
|
|
1154
|
+
fields: diff.changedFields,
|
|
1155
|
+
label: "Changed fields:"
|
|
1156
|
+
})
|
|
1157
|
+
] }),
|
|
1158
|
+
/* @__PURE__ */ jsxs("p", {
|
|
1159
|
+
className: "mt-3",
|
|
1160
|
+
children: [
|
|
1161
|
+
"If others are already using version ",
|
|
1162
|
+
version,
|
|
1163
|
+
", release version",
|
|
1164
|
+
" ",
|
|
1165
|
+
nextVersion,
|
|
1166
|
+
" first. Your change will go into version ",
|
|
1167
|
+
nextVersion,
|
|
1168
|
+
", and existing documents can be updated safely."
|
|
1169
|
+
]
|
|
1170
|
+
})
|
|
1171
|
+
]
|
|
1172
|
+
}),
|
|
1173
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1174
|
+
className: "mt-4 flex flex-col gap-2",
|
|
1175
|
+
children: [/* @__PURE__ */ jsx(ModalButton, {
|
|
1176
|
+
className: compactButtonStyle,
|
|
1177
|
+
"data-testid": "advisory-release-first",
|
|
1178
|
+
onClick: onReleaseFirst,
|
|
1179
|
+
variant: "confirm",
|
|
1180
|
+
children: `It's in use — release v${nextVersion} first`
|
|
1181
|
+
}), /* @__PURE__ */ jsxs(ModalButton, {
|
|
1182
|
+
className: compactButtonStyle,
|
|
1183
|
+
"data-testid": "advisory-keep-editing",
|
|
1184
|
+
onClick: onKeepEditing,
|
|
1185
|
+
variant: "cancel",
|
|
1186
|
+
children: ["Still in development — keep editing v", version]
|
|
1187
|
+
})]
|
|
1188
|
+
})
|
|
1189
|
+
]
|
|
1190
|
+
})
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
//#endregion
|
|
972
1194
|
//#region editors/document-model-editor/config.ts
|
|
973
1195
|
const editorConfig = { isExternalControlsEnabled: false };
|
|
974
1196
|
//#endregion
|
|
@@ -977,8 +1199,304 @@ function useSelectedDocumentModelDocument() {
|
|
|
977
1199
|
return useSelectedDocumentOfType("powerhouse/document-model");
|
|
978
1200
|
}
|
|
979
1201
|
//#endregion
|
|
1202
|
+
//#region editors/document-model-editor/utils/change-classification.ts
|
|
1203
|
+
function isShapeTypeNode(node) {
|
|
1204
|
+
return node.kind === Kind.OBJECT_TYPE_DEFINITION || node.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION || node.kind === 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 === 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, 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 = parse$1(oldSdl);
|
|
1265
|
+
newDoc = parse$1(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 = parse$1(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
|
|
980
1496
|
//#region editors/document-model-editor/editor.tsx
|
|
981
|
-
const StateSchemas = lazy(() => import("./state-schemas-
|
|
1497
|
+
const StateSchemas = lazy(() => import("./state-schemas-Co7oWTVF.js"));
|
|
1498
|
+
const noopSetStateSchema = () => void 0;
|
|
1499
|
+
const noopSetInitialState = () => void 0;
|
|
982
1500
|
function Editor() {
|
|
983
1501
|
useSetPHDocumentEditorConfig(editorConfig);
|
|
984
1502
|
const toast = usePHToast();
|
|
@@ -986,9 +1504,17 @@ function Editor() {
|
|
|
986
1504
|
const [scope, setScope] = useState("global");
|
|
987
1505
|
const documentNodeName = document.header.name;
|
|
988
1506
|
const { name: modelName, id: documentType, extension, description, author: { name: authorName, website: authorWebsite } } = document.state.global;
|
|
989
|
-
const
|
|
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;
|
|
990
1514
|
const operations = modules.flatMap((module) => module.operations);
|
|
991
|
-
const
|
|
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);
|
|
992
1518
|
useEffect(() => {
|
|
993
1519
|
if (!shouldSetInitialName.current || !documentNodeName) return;
|
|
994
1520
|
const initialSchemaDoc = initializeModelSchema(documentNodeName);
|
|
@@ -998,41 +1524,59 @@ function Editor() {
|
|
|
998
1524
|
})]);
|
|
999
1525
|
shouldSetInitialName.current = false;
|
|
1000
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
|
+
};
|
|
1001
1545
|
const operationSchemasSdl = operations.flatMap((operation) => operation.schema ?? []).join("\n");
|
|
1002
1546
|
const handleSetModelId = (id) => {
|
|
1003
1547
|
if (compareStringsWithoutWhitespace(id, documentType)) return;
|
|
1004
|
-
|
|
1548
|
+
guardedDispatch([setModelId({ id })]);
|
|
1005
1549
|
};
|
|
1006
1550
|
const handleSetModelDescription = (newDescription) => {
|
|
1007
1551
|
if (compareStringsWithoutWhitespace(newDescription, description)) return;
|
|
1008
|
-
|
|
1552
|
+
guardedDispatch(setModelDescription({ description: newDescription }));
|
|
1009
1553
|
};
|
|
1010
1554
|
const handleSetModelExtension = (newExtension) => {
|
|
1011
1555
|
if (compareStringsWithoutWhitespace(newExtension, extension)) return;
|
|
1012
|
-
|
|
1556
|
+
guardedDispatch(setModelExtension({ extension: newExtension }));
|
|
1013
1557
|
};
|
|
1014
1558
|
const handleSetModelName = (newName) => {
|
|
1015
1559
|
if (compareStringsWithoutWhitespace(newName, modelName)) return;
|
|
1016
|
-
|
|
1560
|
+
guardedDispatch(setModelName({ name: newName }));
|
|
1017
1561
|
};
|
|
1018
1562
|
const handleSetAuthorName = (newAuthorName) => {
|
|
1019
1563
|
if (compareStringsWithoutWhitespace(newAuthorName, authorName)) return;
|
|
1020
|
-
|
|
1564
|
+
guardedDispatch(setAuthorName({ authorName: newAuthorName }));
|
|
1021
1565
|
};
|
|
1022
1566
|
const handleSetAuthorWebsite = (newAuthorWebsite) => {
|
|
1023
1567
|
if (compareStringsWithoutWhitespace(newAuthorWebsite, authorWebsite ?? "")) return;
|
|
1024
|
-
|
|
1568
|
+
guardedDispatch(setAuthorWebsite({ authorWebsite: newAuthorWebsite }));
|
|
1025
1569
|
};
|
|
1026
1570
|
const handleSetStateSchema = (newSchema, scope) => {
|
|
1027
|
-
if (compareStringsWithoutWhitespace(newSchema, scope === "global" ?
|
|
1028
|
-
|
|
1571
|
+
if (compareStringsWithoutWhitespace(newSchema, scope === "global" ? latestGlobalStateSchema : latestLocalStateSchema)) return;
|
|
1572
|
+
guardedDispatch(setStateSchema({
|
|
1029
1573
|
schema: newSchema,
|
|
1030
1574
|
scope
|
|
1031
1575
|
}));
|
|
1032
1576
|
};
|
|
1033
1577
|
const handleSetInitialState = (newInitialValue, scope) => {
|
|
1034
|
-
if (compareStringsWithoutWhitespace(newInitialValue, scope === "global" ?
|
|
1035
|
-
|
|
1578
|
+
if (compareStringsWithoutWhitespace(newInitialValue, scope === "global" ? latestGlobalStateInitialValue : latestLocalStateInitialValue)) return;
|
|
1579
|
+
guardedDispatch(setInitialState({
|
|
1036
1580
|
initialValue: newInitialValue,
|
|
1037
1581
|
scope
|
|
1038
1582
|
}));
|
|
@@ -1040,12 +1584,12 @@ function Editor() {
|
|
|
1040
1584
|
const handleAddModule = (name) => {
|
|
1041
1585
|
return new Promise((resolve) => {
|
|
1042
1586
|
try {
|
|
1043
|
-
if (
|
|
1587
|
+
if (latestModules.some((module) => compareStringsWithoutWhitespace(module.name, name))) {
|
|
1044
1588
|
resolve(void 0);
|
|
1045
1589
|
return;
|
|
1046
1590
|
}
|
|
1047
1591
|
const id = generateId();
|
|
1048
|
-
|
|
1592
|
+
guardedDispatch(addModule({
|
|
1049
1593
|
id,
|
|
1050
1594
|
name
|
|
1051
1595
|
}));
|
|
@@ -1057,19 +1601,19 @@ function Editor() {
|
|
|
1057
1601
|
});
|
|
1058
1602
|
};
|
|
1059
1603
|
const handleSetModuleName = (id, name) => {
|
|
1060
|
-
if (
|
|
1061
|
-
|
|
1604
|
+
if (latestModules.some((module) => compareStringsWithoutWhitespace(module.name, name))) return;
|
|
1605
|
+
guardedDispatch(setModuleName({
|
|
1062
1606
|
id,
|
|
1063
1607
|
name
|
|
1064
1608
|
}));
|
|
1065
1609
|
};
|
|
1066
1610
|
const handleDeleteModule = (id) => {
|
|
1067
|
-
|
|
1611
|
+
guardedDispatch(deleteModule({ id }));
|
|
1068
1612
|
};
|
|
1069
1613
|
const handleAddOperation = (moduleId, name) => {
|
|
1070
1614
|
return new Promise((resolve) => {
|
|
1071
1615
|
const id = generateId();
|
|
1072
|
-
|
|
1616
|
+
guardedDispatch(addOperation({
|
|
1073
1617
|
id,
|
|
1074
1618
|
moduleId,
|
|
1075
1619
|
name,
|
|
@@ -1083,7 +1627,7 @@ function Editor() {
|
|
|
1083
1627
|
});
|
|
1084
1628
|
};
|
|
1085
1629
|
const handleSetOperationName = (id, name) => {
|
|
1086
|
-
|
|
1630
|
+
guardedDispatch(setOperationName({
|
|
1087
1631
|
id,
|
|
1088
1632
|
name
|
|
1089
1633
|
}), (errors) => {
|
|
@@ -1091,44 +1635,44 @@ function Editor() {
|
|
|
1091
1635
|
});
|
|
1092
1636
|
};
|
|
1093
1637
|
const handleSetOperationSchema = (id, newSchema) => {
|
|
1094
|
-
const operation =
|
|
1638
|
+
const operation = latestOperations.find((operation) => operation.id === id);
|
|
1095
1639
|
if (operation?.schema && compareStringsWithoutWhitespace(newSchema, operation.schema)) return;
|
|
1096
|
-
|
|
1640
|
+
guardedDispatch(setOperationSchema({
|
|
1097
1641
|
id,
|
|
1098
1642
|
schema: newSchema
|
|
1099
1643
|
}));
|
|
1100
1644
|
};
|
|
1101
1645
|
const handleToggleNoInputRequired = (id, noInputRequired) => {
|
|
1102
|
-
const operation =
|
|
1646
|
+
const operation = latestOperations.find((op) => op.id === id);
|
|
1103
1647
|
if (!operation?.name) return;
|
|
1104
|
-
if (noInputRequired)
|
|
1648
|
+
if (noInputRequired) guardedDispatch(setOperationSchema({
|
|
1105
1649
|
id,
|
|
1106
1650
|
schema: makeEmptyOperationSchema(operation.name)
|
|
1107
1651
|
}));
|
|
1108
|
-
else
|
|
1652
|
+
else guardedDispatch(setOperationSchema({
|
|
1109
1653
|
id,
|
|
1110
1654
|
schema: makeOperationInitialDoc(operation.name)
|
|
1111
1655
|
}));
|
|
1112
1656
|
};
|
|
1113
1657
|
const handleSetOperationDescription = (id, newDescription) => {
|
|
1114
|
-
if (compareStringsWithoutWhitespace(
|
|
1115
|
-
|
|
1658
|
+
if (compareStringsWithoutWhitespace(latestOperations.find((operation) => operation.id === id)?.description ?? "", newDescription)) return;
|
|
1659
|
+
guardedDispatch(setOperationDescription({
|
|
1116
1660
|
id,
|
|
1117
1661
|
description: newDescription
|
|
1118
1662
|
}));
|
|
1119
1663
|
};
|
|
1120
1664
|
const handleDeleteOperation = (id) => {
|
|
1121
|
-
|
|
1665
|
+
guardedDispatch(deleteOperation({ id }));
|
|
1122
1666
|
};
|
|
1123
1667
|
const handleAddOperationError = (operationId, errorName) => {
|
|
1124
1668
|
return new Promise((resolve) => {
|
|
1125
1669
|
try {
|
|
1126
|
-
if ((
|
|
1670
|
+
if ((latestOperations.find((operation) => operation.id === operationId)?.errors.map((error) => error.name).filter(Boolean) ?? []).some((name) => compareStringsWithoutWhitespace(name, errorName))) {
|
|
1127
1671
|
resolve(void 0);
|
|
1128
1672
|
return;
|
|
1129
1673
|
}
|
|
1130
1674
|
const id = generateId();
|
|
1131
|
-
|
|
1675
|
+
guardedDispatch(addOperationError({
|
|
1132
1676
|
id,
|
|
1133
1677
|
operationId,
|
|
1134
1678
|
errorName,
|
|
@@ -1142,11 +1686,11 @@ function Editor() {
|
|
|
1142
1686
|
});
|
|
1143
1687
|
};
|
|
1144
1688
|
const handleDeleteOperationError = (id) => {
|
|
1145
|
-
|
|
1689
|
+
guardedDispatch(deleteOperationError({ id }));
|
|
1146
1690
|
};
|
|
1147
1691
|
const handleSetOperationErrorName = (operationId, errorId, errorName) => {
|
|
1148
|
-
if ((
|
|
1149
|
-
|
|
1692
|
+
if ((latestOperations.find((operation) => operation.id === operationId)?.errors.map((error) => error.name).filter(Boolean) ?? []).some((name) => compareStringsWithoutWhitespace(name, errorName))) return;
|
|
1693
|
+
guardedDispatch(setOperationErrorName({
|
|
1150
1694
|
id: errorId,
|
|
1151
1695
|
errorName
|
|
1152
1696
|
}));
|
|
@@ -1169,74 +1713,97 @@ function Editor() {
|
|
|
1169
1713
|
};
|
|
1170
1714
|
return /* @__PURE__ */ jsxs("main", {
|
|
1171
1715
|
className: "min-h-dvh bg-background p-6",
|
|
1172
|
-
children: [
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
children:
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
setStateSchema: handleSetStateSchema,
|
|
1205
|
-
setInitialState: handleSetInitialState,
|
|
1206
|
-
currentScope: scope,
|
|
1207
|
-
onScopeChange: setScope
|
|
1208
|
-
}) }),
|
|
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
|
+
}),
|
|
1209
1748
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
1210
|
-
/* @__PURE__ */
|
|
1211
|
-
|
|
1212
|
-
|
|
1749
|
+
isViewingFrozenVersion && /* @__PURE__ */ jsx(FrozenVersionBanner, {
|
|
1750
|
+
latestVersion: latestSpec.version,
|
|
1751
|
+
viewedVersion: viewedSpec.version
|
|
1213
1752
|
}),
|
|
1214
|
-
/* @__PURE__ */
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
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
|
+
]
|
|
1232
1793
|
})
|
|
1233
|
-
]
|
|
1234
|
-
|
|
1794
|
+
]
|
|
1795
|
+
})
|
|
1796
|
+
}),
|
|
1797
|
+
/* @__PURE__ */ jsx(VersionAdvisoryModal, {
|
|
1798
|
+
prompt,
|
|
1799
|
+
onReleaseFirst: releaseFirst,
|
|
1800
|
+
onKeepEditing: keepEditing,
|
|
1801
|
+
onCancel: cancelAdvisory
|
|
1235
1802
|
})
|
|
1236
|
-
|
|
1803
|
+
]
|
|
1237
1804
|
});
|
|
1238
1805
|
}
|
|
1239
1806
|
//#endregion
|
|
1240
1807
|
export { Editor as default };
|
|
1241
1808
|
|
|
1242
|
-
//# sourceMappingURL=editor-
|
|
1809
|
+
//# sourceMappingURL=editor-CRj28xcj.js.map
|