tinacms 3.7.0 → 3.7.2

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/index.js CHANGED
@@ -23,6 +23,7 @@ import { Command as Command$2 } from "cmdk";
23
23
  import * as DialogPrimitive from "@radix-ui/react-dialog";
24
24
  import * as PopoverPrimitive from "@radix-ui/react-popover";
25
25
  import { PopoverAnchor } from "@radix-ui/react-popover";
26
+ import posthog from "posthog-js";
26
27
  import { createSlatePlugin as createSlatePlugin$1, someHtmlElement, findHtmlParentElement, createTSlatePlugin as createTSlatePlugin$1, RangeApi as RangeApi$1, TextApi as TextApi$1, HtmlPlugin as HtmlPlugin$1, NodeApi as NodeApi$1, ElementApi as ElementApi$1, Hotkeys, isHotkey as isHotkey$1, isUrl as isUrl$1, getEditorPlugin as getEditorPlugin$1, bindFirst as bindFirst$1, sanitizeUrl, PathApi as PathApi$1, isDefined as isDefined$1, PointApi as PointApi$1, BaseParagraphPlugin as BaseParagraphPlugin$1, match as match$2, deleteMerge, getPluginTypes, queryNode as queryNode$1, isType, getInjectMatch as getInjectMatch$1, traverseHtmlElements, isHtmlBlockElement as isHtmlBlockElement$1, postCleanHtml, mergeProps } from "@udecode/plate";
27
28
  import { useComboboxContext, Combobox as Combobox$1, useComboboxStore, ComboboxProvider, Portal, ComboboxPopover, ComboboxItem } from "@ariakit/react";
28
29
  import { withTriggerCombobox, filterWords } from "@udecode/plate-combobox";
@@ -46,7 +47,6 @@ import { sortableKeyboardCoordinates, useSortable, SortableContext, verticalList
46
47
  import { CSS } from "@dnd-kit/utilities";
47
48
  import { buildSchema, print, getIntrospectionQuery, buildClientSchema, parse as parse$4 } from "graphql";
48
49
  import { diff as diff$1 } from "@graphql-inspector/core";
49
- import posthog from "posthog-js";
50
50
  import { HexColorPicker } from "react-colorful";
51
51
  import * as dropzone from "react-dropzone";
52
52
  import { Command as Command$3 } from "@udecode/cmdk";
@@ -34754,6 +34754,108 @@ function ItalicIcon(props) {
34754
34754
  ))
34755
34755
  );
34756
34756
  }
34757
+ const BranchSwitchedEvent = "branch-switched";
34758
+ const BranchSwitcherOpenedEvent = "branch-switcher-opened";
34759
+ const BranchSwitcherSearchEvent = "branch-switcher-search";
34760
+ const BranchSwitcherDropDownEvent = "branch-switcher-dropdown";
34761
+ const BranchSwitcherPRClickedEvent = "branch-switcher-pr-clicked";
34762
+ const SavedContentEvent = "saved-content";
34763
+ const SaveContentErrorEvent = "save-content-error";
34764
+ const FormResetEvent = "form-reset";
34765
+ const MediaManagerContentUploadedEvent = "media-manager-content-uploaded";
34766
+ const MediaManagerContentDeletedEvent = "media-manager-content-deleted";
34767
+ const RichTextEditorSwitchedEvent = "rich-text-editor-switched";
34768
+ const EventLogPageViewedEvent = "event-log-page-viewed";
34769
+ const TinaCMSStartedEvent = "tina-cms-started";
34770
+ const CollectionListPageItemClickedEvent = "collection-list-page-item-clicked";
34771
+ const CollectionListPageSortEvent = "collection-list-page-sort";
34772
+ const CollectionListPageSearchEvent = "collection-list-page-search";
34773
+ const CloudConfigNavComponentClickedEvent = "cloud-config-nav-component-clicked";
34774
+ const SlashCommandOpenedEvent = "slash-command-opened";
34775
+ const SlashCommandUsedEvent = "slash-command-used";
34776
+ const MediaUsageDashboardOpenedEvent = "media-dashboard-opened";
34777
+ const MediaUsageDashboardRefreshedEvent = "media-dashboard-refreshed";
34778
+ const MediaUsageDashboardTypeFilterEvent = "media-dashboard-type-filter-changed";
34779
+ const MediaUsageDashboardUsageFilterChangedEvent = "media-dashboard-usage-filter-changed";
34780
+ const MediaUsageDashboardRowExpandedEvent = "media-dashboard-row-expanded";
34781
+ const MediaUsageDashboardPreviewOpenedEvent = "media-dashboard-preview-opened";
34782
+ const MediaUsageDashboardDocumentLinkClickedEvent = "media-dashboard-document-link-clicked";
34783
+ let posthogClient = null;
34784
+ let isInitialized = false;
34785
+ let initializationPromise = null;
34786
+ const POSTHOG_CONFIG_ENDPOINT = "https://identity-v2.tinajs.io/v2/posthog-token";
34787
+ async function fetchPostHogConfig() {
34788
+ try {
34789
+ const response = await fetch(POSTHOG_CONFIG_ENDPOINT, {
34790
+ method: "GET",
34791
+ headers: {
34792
+ "Content-Type": "application/json"
34793
+ }
34794
+ });
34795
+ if (!response.ok) {
34796
+ console.warn(`Failed to fetch PostHog config: ${response.statusText}`);
34797
+ return {};
34798
+ }
34799
+ return await response.json();
34800
+ } catch (error2) {
34801
+ console.warn(
34802
+ "Failed to fetch PostHog config:",
34803
+ error2 instanceof Error ? error2.message : "Unknown error"
34804
+ );
34805
+ return {};
34806
+ }
34807
+ }
34808
+ async function initializePostHog(mode = "anonymous") {
34809
+ if (isInitialized) {
34810
+ return posthogClient;
34811
+ }
34812
+ if (initializationPromise) {
34813
+ return initializationPromise;
34814
+ }
34815
+ if (mode === "disabled") {
34816
+ isInitialized = true;
34817
+ return null;
34818
+ }
34819
+ if (process.env.TINA_DEV === "true") {
34820
+ isInitialized = true;
34821
+ return null;
34822
+ }
34823
+ initializationPromise = (async () => {
34824
+ const config = await fetchPostHogConfig();
34825
+ if (!config.api_key) {
34826
+ console.warn(
34827
+ "PostHog API key not found. PostHog tracking will be disabled."
34828
+ );
34829
+ isInitialized = true;
34830
+ return null;
34831
+ }
34832
+ posthog.init(config.api_key, {
34833
+ api_host: config.host || "https://us.i.posthog.com",
34834
+ persistence: "localStorage",
34835
+ autocapture: false,
34836
+ capture_pageview: false,
34837
+ disable_session_recording: true,
34838
+ disable_compression: true
34839
+ });
34840
+ posthogClient = posthog;
34841
+ isInitialized = true;
34842
+ return posthogClient;
34843
+ })();
34844
+ return initializationPromise;
34845
+ }
34846
+ function captureEvent(event, properties2) {
34847
+ if (!posthogClient) {
34848
+ return;
34849
+ }
34850
+ try {
34851
+ posthogClient.capture(event, {
34852
+ ...properties2,
34853
+ system: "tinacms/tinacms"
34854
+ });
34855
+ } catch (error2) {
34856
+ console.error("Error capturing PostHog event:", error2);
34857
+ }
34858
+ }
34757
34859
  var useComboboxInput = ({
34758
34860
  autoFocus = true,
34759
34861
  cancelInputOnArrowLeftRight = true,
@@ -34903,7 +35005,7 @@ const InlineCombobox = ({
34903
35005
  },
34904
35006
  [setValueProp, hasValueProp]
34905
35007
  );
34906
- const [insertPoint, setInsertPoint] = useState(null);
35008
+ const insertPoint = React__default.useRef(null);
34907
35009
  useEffect(() => {
34908
35010
  const path3 = editor.api.findPath(element);
34909
35011
  if (!path3)
@@ -34912,7 +35014,7 @@ const InlineCombobox = ({
34912
35014
  if (!point3)
34913
35015
  return;
34914
35016
  const pointRef3 = editor.api.pointRef(point3);
34915
- setInsertPoint(pointRef3);
35017
+ insertPoint.current = pointRef3.current;
34916
35018
  return () => {
34917
35019
  pointRef3.unref();
34918
35020
  };
@@ -34926,12 +35028,6 @@ const InlineCombobox = ({
34926
35028
  at: (insertPoint == null ? void 0 : insertPoint.current) ?? void 0
34927
35029
  });
34928
35030
  }
34929
- if (cause === "arrowLeft" || cause === "arrowRight") {
34930
- editor.tf.move({
34931
- distance: 1,
34932
- reverse: cause === "arrowLeft"
34933
- });
34934
- }
34935
35031
  },
34936
35032
  ref: inputRef
34937
35033
  });
@@ -35129,6 +35225,9 @@ const rules = [
35129
35225
  const SlashInputElement = withRef$1(
35130
35226
  ({ className, ...props }, ref) => {
35131
35227
  const { children, editor, element } = props;
35228
+ useEffect(() => {
35229
+ captureEvent(SlashCommandOpenedEvent);
35230
+ }, []);
35132
35231
  return /* @__PURE__ */ React__default.createElement(
35133
35232
  PlateElement,
35134
35233
  {
@@ -35142,7 +35241,12 @@ const SlashInputElement = withRef$1(
35142
35241
  {
35143
35242
  key: value,
35144
35243
  keywords: keywords2,
35145
- onClick: () => onSelect(editor),
35244
+ onClick: () => {
35245
+ onSelect(editor);
35246
+ captureEvent(SlashCommandUsedEvent, {
35247
+ command: value
35248
+ });
35249
+ },
35146
35250
  value
35147
35251
  },
35148
35252
  /* @__PURE__ */ React__default.createElement(Icon, { "aria-hidden": true, className: "mr-2 size-4" }),
@@ -41516,7 +41620,15 @@ const Blocks = ({
41516
41620
  meta,
41517
41621
  index
41518
41622
  }) => {
41519
- const addItem = React.useCallback(
41623
+ const [newObjects, setNewObjects] = useState(/* @__PURE__ */ new Set());
41624
+ const prevPristine = useRef(meta.pristine);
41625
+ useEffect(() => {
41626
+ if (!prevPristine.current && meta.pristine) {
41627
+ setNewObjects(/* @__PURE__ */ new Set());
41628
+ }
41629
+ prevPristine.current = meta.pristine;
41630
+ }, [meta.pristine]);
41631
+ const addItem = useCallback(
41520
41632
  (name2, template) => {
41521
41633
  let obj = {};
41522
41634
  if (typeof template.defaultItem === "function") {
@@ -41525,6 +41637,7 @@ const Blocks = ({
41525
41637
  obj = template.defaultItem || {};
41526
41638
  }
41527
41639
  obj._template = name2;
41640
+ setNewObjects((prev) => new Set(prev).add(obj));
41528
41641
  form.mutators.push(field.name, obj);
41529
41642
  },
41530
41643
  [field.name, form.mutators]
@@ -41587,6 +41700,7 @@ const Blocks = ({
41587
41700
  tinaForm,
41588
41701
  isMin,
41589
41702
  fixedLength,
41703
+ isNew: newObjects.has(block2),
41590
41704
  ...itemProps(block2)
41591
41705
  }
41592
41706
  );
@@ -41601,7 +41715,8 @@ const BlockListItem = ({
41601
41715
  index,
41602
41716
  template,
41603
41717
  isMin,
41604
- fixedLength
41718
+ fixedLength,
41719
+ isNew
41605
41720
  }) => {
41606
41721
  const cms = useCMS$1();
41607
41722
  const removeItem = React.useCallback(() => {
@@ -41645,6 +41760,7 @@ const BlockListItem = ({
41645
41760
  onMouseOut: () => setHoveredField({ id: null, fieldName: null })
41646
41761
  },
41647
41762
  /* @__PURE__ */ React.createElement(GroupLabel, null, label || template.label),
41763
+ isNew && /* @__PURE__ */ React.createElement("span", { className: "mr-1.5 inline-flex items-center px-1.5 py-0.5 rounded text-[10px] border-[0.5px] border-tina-orange/50 font-semibold bg-tina-orange/10 text-tina-orange leading-none" }, "NEW"),
41648
41764
  /* @__PURE__ */ React.createElement(BiPencil, { className: "h-5 w-auto fill-current text-gray-200 group-hover:text-inherit transition-colors duration-150 ease-out" })
41649
41765
  ), (!fixedLength || fixedLength && !isMin) && /* @__PURE__ */ React.createElement(ItemDeleteButton, { disabled: isMin, onClick: removeItem }))));
41650
41766
  };
@@ -44016,99 +44132,6 @@ const TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PU
44016
44132
  }
44017
44133
  ));
44018
44134
  TableCaption.displayName = "TableCaption";
44019
- let posthogClient = null;
44020
- let isInitialized = false;
44021
- let initializationPromise = null;
44022
- const POSTHOG_CONFIG_ENDPOINT = "https://identity-v2.tinajs.io/v2/posthog-token";
44023
- async function fetchPostHogConfig() {
44024
- try {
44025
- const response = await fetch(POSTHOG_CONFIG_ENDPOINT, {
44026
- method: "GET",
44027
- headers: {
44028
- "Content-Type": "application/json"
44029
- }
44030
- });
44031
- if (!response.ok) {
44032
- console.warn(`Failed to fetch PostHog config: ${response.statusText}`);
44033
- return {};
44034
- }
44035
- return await response.json();
44036
- } catch (error2) {
44037
- console.warn(
44038
- "Failed to fetch PostHog config:",
44039
- error2 instanceof Error ? error2.message : "Unknown error"
44040
- );
44041
- return {};
44042
- }
44043
- }
44044
- async function initializePostHog(mode = "anonymous") {
44045
- if (isInitialized) {
44046
- return posthogClient;
44047
- }
44048
- if (initializationPromise) {
44049
- return initializationPromise;
44050
- }
44051
- if (mode === "disabled") {
44052
- isInitialized = true;
44053
- return null;
44054
- }
44055
- if (process.env.TINA_DEV === "true") {
44056
- isInitialized = true;
44057
- return null;
44058
- }
44059
- initializationPromise = (async () => {
44060
- const config = await fetchPostHogConfig();
44061
- if (!config.api_key) {
44062
- console.warn(
44063
- "PostHog API key not found. PostHog tracking will be disabled."
44064
- );
44065
- isInitialized = true;
44066
- return null;
44067
- }
44068
- posthog.init(config.api_key, {
44069
- api_host: config.host || "https://us.i.posthog.com",
44070
- persistence: "localStorage",
44071
- autocapture: false,
44072
- capture_pageview: false,
44073
- disable_session_recording: true,
44074
- disable_compression: true
44075
- });
44076
- posthogClient = posthog;
44077
- isInitialized = true;
44078
- return posthogClient;
44079
- })();
44080
- return initializationPromise;
44081
- }
44082
- function captureEvent(event, properties2) {
44083
- if (!posthogClient) {
44084
- return;
44085
- }
44086
- try {
44087
- posthogClient.capture(event, {
44088
- ...properties2,
44089
- system: "tinacms/tinacms"
44090
- });
44091
- } catch (error2) {
44092
- console.error("Error capturing PostHog event:", error2);
44093
- }
44094
- }
44095
- const BranchSwitchedEvent = "branch-switched";
44096
- const BranchSwitcherOpenedEvent = "branch-switcher-opened";
44097
- const BranchSwitcherSearchEvent = "branch-switcher-search";
44098
- const BranchSwitcherDropDownEvent = "branch-switcher-dropdown";
44099
- const BranchSwitcherPRClickedEvent = "branch-switcher-pr-clicked";
44100
- const SavedContentEvent = "saved-content";
44101
- const SaveContentErrorEvent = "save-content-error";
44102
- const FormResetEvent = "form-reset";
44103
- const MediaManagerContentUploadedEvent = "media-manager-content-uploaded";
44104
- const MediaManagerContentDeletedEvent = "media-manager-content-deleted";
44105
- const RichTextEditorSwitchedEvent = "rich-text-editor-switched";
44106
- const EventLogPageViewedEvent = "event-log-page-viewed";
44107
- const TinaCMSStartedEvent = "tina-cms-started";
44108
- const CollectionListPageItemClickedEvent = "collection-list-page-item-clicked";
44109
- const CollectionListPageSortEvent = "collection-list-page-sort";
44110
- const CollectionListPageSearchEvent = "collection-list-page-search";
44111
- const CloudConfigNavComponentClickedEvent = "cloud-config-nav-component-clicked";
44112
44135
  const IndexStatus$1 = ({ indexingStatus }) => {
44113
44136
  const styles = {
44114
44137
  complete: {
@@ -46031,7 +46054,7 @@ function ListMediaItem({ item, onClick, active }) {
46031
46054
  return /* @__PURE__ */ React__default.createElement(
46032
46055
  "li",
46033
46056
  {
46034
- className: `group relative flex shrink-0 items-center transition duration-150 ease-out cursor-pointer border-b border-gray-150 ${active ? "bg-gradient-to-r from-white to-gray-50/50 text-blue-500 hover:bg-gray-50" : "bg-white hover:bg-gray-50/50 hover:text-blue-500"}`,
46057
+ className: `group relative flex shrink-0 items-center transition duration-150 ease-out cursor-pointer border-b border-gray-150 ${active ? "bg-gradient-to-r from-white to-gray-50/50 text-tina-orange hover:bg-gray-50" : "bg-white hover:bg-gray-50/50 hover:text-tina-orange"}`,
46035
46058
  onClick: () => {
46036
46059
  if (!active) {
46037
46060
  onClick(item);
@@ -46049,7 +46072,12 @@ function ListMediaItem({ item, onClick, active }) {
46049
46072
  src: thumbnail,
46050
46073
  alt: item.filename
46051
46074
  }
46052
- ) : /* @__PURE__ */ React__default.createElement(FileIcon, { className: "w-1/2 h-full fill-gray-300" })),
46075
+ ) : /* @__PURE__ */ React__default.createElement(
46076
+ FileIcon,
46077
+ {
46078
+ className: `w-1/2 h-full ${item.type === "dir" ? "fill-tina-orange" : "fill-gray-300"}`
46079
+ }
46080
+ )),
46053
46081
  /* @__PURE__ */ React__default.createElement(
46054
46082
  "span",
46055
46083
  {
@@ -46072,9 +46100,10 @@ function GridMediaItem({ item, active, onClick }) {
46072
46100
  "button",
46073
46101
  {
46074
46102
  className: cn(
46075
- "relative flex flex-col items-center justify-center w-full",
46103
+ "relative flex flex-col items-center justify-center w-full outline-none",
46076
46104
  {
46077
46105
  "shadow hover:shadow-md hover:scale-103 hover:border-gray-150": !active,
46106
+ "ring-2 ring-tina-orange": active,
46078
46107
  "cursor-pointer": item.type === "dir"
46079
46108
  }
46080
46109
  ),
@@ -46091,7 +46120,7 @@ function GridMediaItem({ item, active, onClick }) {
46091
46120
  {
46092
46121
  className: cn(
46093
46122
  "absolute bottom-0 left-0 w-full text-xs text-white px-2 py-1 truncate z-10",
46094
- active ? "bg-blue-500/60" : "bg-black/60"
46123
+ active ? "bg-tina-orange/60" : "bg-black/60"
46095
46124
  ),
46096
46125
  style: { pointerEvents: "none" }
46097
46126
  },
@@ -46102,14 +46131,19 @@ function GridMediaItem({ item, active, onClick }) {
46102
46131
  "img",
46103
46132
  {
46104
46133
  className: cn(
46105
- "block overflow-hidden object-center object-contain max-w-full max-h-[16rem] m-auto shadow",
46106
- { "border border-blue-500": active }
46134
+ "block overflow-hidden object-center object-contain max-w-full max-h-[16rem] m-auto shadow"
46107
46135
  ),
46108
46136
  style: checkerboardStyle,
46109
46137
  src: thumbnail,
46110
46138
  alt: item.filename
46111
46139
  }
46112
- )) : /* @__PURE__ */ React__default.createElement("div", { className: "p-4 w-full flex flex-col gap-4 items-center justify-center" }, /* @__PURE__ */ React__default.createElement(FileIcon, { className: "w-[40%] h-auto fill-gray-300", size: 40 })))
46140
+ )) : /* @__PURE__ */ React__default.createElement("div", { className: "p-4 w-full flex flex-col gap-4 items-center justify-center" }, /* @__PURE__ */ React__default.createElement(
46141
+ FileIcon,
46142
+ {
46143
+ className: `w-[40%] h-auto ${item.type === "dir" ? "fill-tina-orange" : "fill-gray-300"}`,
46144
+ size: 40
46145
+ }
46146
+ )))
46113
46147
  ));
46114
46148
  }
46115
46149
  const DeleteModal$1 = ({
@@ -46514,7 +46548,7 @@ function MediaPicker({
46514
46548
  className: "whitespace-nowrap"
46515
46549
  },
46516
46550
  "New Folder",
46517
- /* @__PURE__ */ React__default.createElement(BiFolder, { className: "w-6 h-full ml-2 opacity-70 text-blue-500" })
46551
+ /* @__PURE__ */ React__default.createElement(BiFolder, { className: "w-6 h-full ml-2 opacity-70 text-tina-orange" })
46518
46552
  ), /* @__PURE__ */ React__default.createElement(UploadButton, { onClick, uploading }))), /* @__PURE__ */ React__default.createElement("div", { className: "flex h-full overflow-hidden bg-white" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex w-full flex-col h-full @container" }, /* @__PURE__ */ React__default.createElement(
46519
46553
  "ul",
46520
46554
  {
@@ -46908,7 +46942,7 @@ const getDocumentEditUrl = async (cms, document2) => {
46908
46942
  return editUrl;
46909
46943
  };
46910
46944
  const scanDocumentForMedia = (documentContent, mediaUsages) => {
46911
- const matchedIds = /* @__PURE__ */ new Set();
46945
+ const matchedSrcs = /* @__PURE__ */ new Set();
46912
46946
  for (const mediaUsage of mediaUsages) {
46913
46947
  const src = JSON.stringify(mediaUsage.media.src).slice(1, -1);
46914
46948
  let index = documentContent.indexOf(src);
@@ -46918,18 +46952,18 @@ const scanDocumentForMedia = (documentContent, mediaUsages) => {
46918
46952
  const isPrevValid = !prevChar || !/[a-zA-Z0-9_.%~+-]/.test(prevChar);
46919
46953
  const isNextValid = !nextChar || !/[a-zA-Z0-9_.%~+-]/.test(nextChar);
46920
46954
  if (isPrevValid && isNextValid) {
46921
- matchedIds.add(mediaUsage.media.id);
46955
+ matchedSrcs.add(mediaUsage.media.src);
46922
46956
  break;
46923
46957
  }
46924
46958
  index = documentContent.indexOf(src, index + 1);
46925
46959
  }
46926
46960
  }
46927
- return matchedIds;
46961
+ return matchedSrcs;
46928
46962
  };
46929
46963
  const THUMBNAIL_SIZES = [MEDIA_USAGE_THUMBNAIL_SIZE];
46930
46964
  const BATCH_SIZE = 100;
46931
46965
  const UI_YIELD_INTERVAL = 50;
46932
- const collectAllMedia = async (cms, mediaIdToUsageMap, currentDirectory) => {
46966
+ const collectAllMedia = async (cms, mediaSrcToUsageMap, currentDirectory) => {
46933
46967
  const subDirectories = [];
46934
46968
  let currentOffset = void 0;
46935
46969
  let moreOffsetsAvailable = true;
@@ -46945,7 +46979,7 @@ const collectAllMedia = async (cms, mediaIdToUsageMap, currentDirectory) => {
46945
46979
  const isImg = isImage(item.filename);
46946
46980
  const isVid = isVideo(item.filename);
46947
46981
  const type2 = isImg ? "image" : isVid ? "video" : "other";
46948
- mediaIdToUsageMap[item.id] = {
46982
+ mediaSrcToUsageMap[item.src] = {
46949
46983
  media: item,
46950
46984
  type: type2,
46951
46985
  usedIn: []
@@ -46965,15 +46999,15 @@ const collectAllMedia = async (cms, mediaIdToUsageMap, currentDirectory) => {
46965
46999
  }
46966
47000
  if (subDirectories.length > 0) {
46967
47001
  await Promise.all(
46968
- subDirectories.map((dir) => collectAllMedia(cms, mediaIdToUsageMap, dir))
47002
+ subDirectories.map((dir) => collectAllMedia(cms, mediaSrcToUsageMap, dir))
46969
47003
  );
46970
47004
  }
46971
47005
  };
46972
- const scanCollectionForMediaUsage = async (cms, collectionMeta, mediaIdToUsageMap) => {
47006
+ const scanCollectionForMediaUsage = async (cms, collectionMeta, mediaSrcToUsageMap) => {
46973
47007
  var _a2, _b;
46974
47008
  let hasNextPage = true;
46975
47009
  let after3 = void 0;
46976
- const mediaUsages = Object.values(mediaIdToUsageMap);
47010
+ const mediaUsages = Object.values(mediaSrcToUsageMap);
46977
47011
  const listQuery = `
46978
47012
  query($after: String, $first: Float) {
46979
47013
  collectionConnection: ${collectionMeta.name}Connection(first: $first, after: $after) {
@@ -47019,15 +47053,15 @@ const scanCollectionForMediaUsage = async (cms, collectionMeta, mediaIdToUsageMa
47019
47053
  await new Promise((resolve) => setTimeout(resolve, 0));
47020
47054
  }
47021
47055
  const edge = edges2[i2];
47022
- const matchedIds = scanDocumentForMedia(
47056
+ const matchedSrcs = scanDocumentForMedia(
47023
47057
  JSON.stringify(edge.node._values),
47024
47058
  mediaUsages
47025
47059
  );
47026
- if (matchedIds.size === 0)
47060
+ if (matchedSrcs.size === 0)
47027
47061
  continue;
47028
47062
  const editUrl = await getDocumentEditUrl(cms, edge.node);
47029
- matchedIds.forEach((mediaId) => {
47030
- const usage = mediaIdToUsageMap[mediaId];
47063
+ matchedSrcs.forEach((mediaSrc) => {
47064
+ const usage = mediaSrcToUsageMap[mediaSrc];
47031
47065
  if (usage) {
47032
47066
  usage.usedIn.push({
47033
47067
  collectionName: collectionMeta.name,
@@ -47046,18 +47080,18 @@ const scanCollectionForMediaUsage = async (cms, collectionMeta, mediaIdToUsageMa
47046
47080
  }
47047
47081
  };
47048
47082
  const scanAllMedia = async (cms, onProgress) => {
47049
- const mediaIdToUsageMap = {};
47050
- await collectAllMedia(cms, mediaIdToUsageMap, "");
47083
+ const mediaSrcToUsageMap = {};
47084
+ await collectAllMedia(cms, mediaSrcToUsageMap, "");
47051
47085
  const collectionMetas = cms.api.tina.schema.getCollections();
47052
47086
  for (let i2 = 0; i2 < collectionMetas.length; i2++) {
47053
47087
  await scanCollectionForMediaUsage(
47054
47088
  cms,
47055
47089
  collectionMetas[i2],
47056
- mediaIdToUsageMap
47090
+ mediaSrcToUsageMap
47057
47091
  );
47058
47092
  onProgress == null ? void 0 : onProgress((i2 + 1) / collectionMetas.length * 100);
47059
47093
  }
47060
- return Object.values(mediaIdToUsageMap);
47094
+ return Object.values(mediaSrcToUsageMap);
47061
47095
  };
47062
47096
  const useMediaUsageScanner = () => {
47063
47097
  const cms = useCMS$1();
@@ -47191,6 +47225,9 @@ const MediaLightbox = ({
47191
47225
  const usageCount = item.usedIn.length;
47192
47226
  const mediaSrc = item.media.src;
47193
47227
  const directory = item.media.directory || "/";
47228
+ useEffect(() => {
47229
+ captureEvent(MediaUsageDashboardPreviewOpenedEvent);
47230
+ }, []);
47194
47231
  return /* @__PURE__ */ React__default.createElement(Dialog, { open: true, onOpenChange: (isOpen) => !isOpen && onClose() }, /* @__PURE__ */ React__default.createElement(DialogContent, { className: "w-auto max-w-[95vw] border border-gray-200 bg-white px-4 pt-12 pb-4 shadow-xl sm:max-w-fit" }, /* @__PURE__ */ React__default.createElement(DialogTitle, { className: "sr-only" }, "Preview: ", item.media.filename), /* @__PURE__ */ React__default.createElement(DialogDescription, { className: "sr-only" }, usageCount > 0 ? `Used in ${usageCount} ${usageCount === 1 ? "document" : "documents"}` : "Unused media file"), /* @__PURE__ */ React__default.createElement("div", { className: "mx-auto w-fit max-w-full rounded-lg border border-gray-200 bg-gray-50 p-2 sm:p-3" }, item.type === "video" ? /* @__PURE__ */ React__default.createElement(
47195
47232
  VideoLightboxContent,
47196
47233
  {
@@ -47432,7 +47469,7 @@ const MediaUsageTable = ({
47432
47469
  const table = useReactTable({
47433
47470
  data: mediaItems,
47434
47471
  columns,
47435
- getRowId: (row) => row.media.id,
47472
+ getRowId: (row) => row.media.src,
47436
47473
  initialState: { columnVisibility: { type: false } },
47437
47474
  state: { sorting, columnFilters, expanded },
47438
47475
  onColumnFiltersChange: setColumnFilters,
@@ -47521,7 +47558,13 @@ const MediaUsageTable = ({
47521
47558
  TableRow,
47522
47559
  {
47523
47560
  style: { contentVisibility: "auto" },
47524
- onClick: getUsageCount(row.original) > 0 ? row.getToggleExpandedHandler() : void 0,
47561
+ onClick: () => {
47562
+ getUsageCount(row.original) > 0;
47563
+ {
47564
+ row.toggleExpanded();
47565
+ captureEvent(MediaUsageDashboardRowExpandedEvent);
47566
+ }
47567
+ },
47525
47568
  className: getUsageCount(row.original) > 0 ? row.getIsExpanded() ? "cursor-pointer bg-[#FFF8F6] hover:bg-[#FFF8F6]" : "cursor-pointer" : ""
47526
47569
  },
47527
47570
  row.getVisibleCells().map((cell) => /* @__PURE__ */ React__default.createElement(
@@ -47562,7 +47605,12 @@ const MediaFilters = ({
47562
47605
  Select,
47563
47606
  {
47564
47607
  value: typeFilter,
47565
- onValueChange: (value) => setTypeFilter(value)
47608
+ onValueChange: (value) => {
47609
+ setTypeFilter(value);
47610
+ captureEvent(MediaUsageDashboardTypeFilterEvent, {
47611
+ type: value
47612
+ });
47613
+ }
47566
47614
  },
47567
47615
  /* @__PURE__ */ React__default.createElement(
47568
47616
  SelectTrigger,
@@ -47577,7 +47625,12 @@ const MediaFilters = ({
47577
47625
  Select,
47578
47626
  {
47579
47627
  value: usageFilter,
47580
- onValueChange: (value) => setUsageFilter(value)
47628
+ onValueChange: (value) => {
47629
+ setUsageFilter(value);
47630
+ captureEvent(MediaUsageDashboardUsageFilterChangedEvent, {
47631
+ usage: value
47632
+ });
47633
+ }
47581
47634
  },
47582
47635
  /* @__PURE__ */ React__default.createElement(
47583
47636
  SelectTrigger,
@@ -47609,7 +47662,10 @@ const ExpandedRowContent = ({
47609
47662
  "a",
47610
47663
  {
47611
47664
  href: `#/collections/${doc.collectionName}/~`,
47612
- onClick: () => onClose == null ? void 0 : onClose(),
47665
+ onClick: () => {
47666
+ onClose == null ? void 0 : onClose();
47667
+ captureEvent(MediaUsageDashboardDocumentLinkClickedEvent);
47668
+ },
47613
47669
  className: "underline hover:text-tina-orange-dark transition-colors"
47614
47670
  },
47615
47671
  doc.collectionLabel
@@ -47618,7 +47674,12 @@ const ExpandedRowContent = ({
47618
47674
  "a",
47619
47675
  {
47620
47676
  href: doc.editUrl,
47621
- onClick: () => onClose == null ? void 0 : onClose(),
47677
+ onClick: () => {
47678
+ onClose == null ? void 0 : onClose();
47679
+ captureEvent(
47680
+ MediaUsageDashboardDocumentLinkClickedEvent
47681
+ );
47682
+ },
47622
47683
  className: "underline hover:text-tina-orange-dark transition-colors break-all"
47623
47684
  },
47624
47685
  breadcrumb
@@ -47629,6 +47690,10 @@ const ExpandedRowContent = ({
47629
47690
  const MediaUsageDashboard = ({
47630
47691
  close: onClose
47631
47692
  }) => {
47693
+ useEffect(() => {
47694
+ console.log("MediaUsageDashboard");
47695
+ captureEvent(MediaUsageDashboardOpenedEvent);
47696
+ }, []);
47632
47697
  const { mediaItems, isLoading, errorOccurred, progress, refresh } = useMediaUsageScanner();
47633
47698
  const [lightboxImage, setLightboxImage] = useState(null);
47634
47699
  const stats = useMemo(() => {
@@ -47663,7 +47728,13 @@ const MediaUsageDashboard = ({
47663
47728
  Button,
47664
47729
  {
47665
47730
  variant: "outline",
47666
- onClick: refresh,
47731
+ onClick: async () => {
47732
+ await refresh();
47733
+ const payload = {
47734
+ errorOccured: errorOccurred
47735
+ };
47736
+ captureEvent(MediaUsageDashboardRefreshedEvent, payload);
47737
+ },
47667
47738
  disabled: isLoading,
47668
47739
  className: "flex items-center gap-2 shadow-sm font-medium transition-colors"
47669
47740
  },
@@ -47933,7 +48004,7 @@ const NavProvider = ({
47933
48004
  const name = "tinacms";
47934
48005
  const type = "module";
47935
48006
  const typings = "dist/index.d.ts";
47936
- const version$1 = "3.7.0";
48007
+ const version$1 = "3.7.2";
47937
48008
  const main = "dist/index.js";
47938
48009
  const module = "./dist/index.js";
47939
48010
  const exports = {
@@ -48043,6 +48114,8 @@ const dependencies = {
48043
48114
  "react-colorful": "catalog:",
48044
48115
  "react-datetime": "catalog:",
48045
48116
  "react-day-picker": "^9.13.0",
48117
+ "react-dnd": "catalog:",
48118
+ "react-dnd-html5-backend": "catalog:",
48046
48119
  "react-dropzone": "catalog:",
48047
48120
  "react-final-form": "catalog:",
48048
48121
  "react-icons": "^5.4.0",
@@ -48980,11 +49053,11 @@ const FormLists = (props) => {
48980
49053
  "input",
48981
49054
  {
48982
49055
  type: "checkbox",
48983
- checked: !showReferences,
48984
- onChange: (e3) => setShowReferences(!e3.target.checked),
49056
+ checked: showReferences,
49057
+ onChange: (e3) => setShowReferences(e3.target.checked),
48985
49058
  className: "w-4 h-4 text-orange-500 border-gray-300 rounded focus:ring-orange-500"
48986
49059
  }
48987
- ), /* @__PURE__ */ React.createElement("span", null, "Direct references only"))), /* @__PURE__ */ React.createElement("div", { className: "flex-1 overflow-x-auto overflow-y-auto min-h-0" }, cms.state.formLists.map((formList, index) => /* @__PURE__ */ React.createElement("div", { key: `${formList.id}-${index}` }, /* @__PURE__ */ React.createElement(
49060
+ ), /* @__PURE__ */ React.createElement("span", null, "Show all references"))), /* @__PURE__ */ React.createElement("div", { className: "flex-1 overflow-x-auto overflow-y-auto min-h-0" }, cms.state.formLists.map((formList, index) => /* @__PURE__ */ React.createElement("div", { key: `${formList.id}-${index}` }, /* @__PURE__ */ React.createElement(
48988
49061
  FormList,
48989
49062
  {
48990
49063
  setActiveFormId: (id2) => {
@@ -66099,6 +66172,12 @@ const CreateBranchModal = ({
66099
66172
  throw new Error("Branch creation failed.");
66100
66173
  }
66101
66174
  setCurrentBranch(result.branchName);
66175
+ if (result.warning) {
66176
+ cms.alerts.warn(
66177
+ `${result.warning} Please reconnect GitHub authoring here: ${tinaApi.gitSettingsLink}`,
66178
+ 0
66179
+ );
66180
+ }
66102
66181
  cms.alerts.success(
66103
66182
  `Branch created successfully - Pull Request at ${result.pullRequestUrl}`,
66104
66183
  0
@@ -66110,7 +66189,7 @@ const CreateBranchModal = ({
66110
66189
  close2();
66111
66190
  } catch (e3) {
66112
66191
  console.error(e3);
66113
- let errorMessage2 = "Branch operation failed, please try again. If the problem persists please contact support.";
66192
+ let errorMessage2 = "Branch operation failed. Talking to GitHub was unsuccessful, please try again. If the problem persists please contact support at https://tina.io/support 🦙";
66114
66193
  const err = e3;
66115
66194
  if (err.errorCode) {
66116
66195
  switch (err.errorCode) {
@@ -66123,6 +66202,9 @@ const CreateBranchModal = ({
66123
66202
  case EDITORIAL_WORKFLOW_ERROR.VALIDATION_FAILED:
66124
66203
  errorMessage2 = err.message || "Invalid branch name";
66125
66204
  break;
66205
+ default:
66206
+ errorMessage2 = err.message || errorMessage2;
66207
+ break;
66126
66208
  }
66127
66209
  } else if (err.message) {
66128
66210
  if (err.message.toLowerCase().includes("already exists")) {
@@ -121575,6 +121657,9 @@ mutation addPendingDocumentMutation(
121575
121657
  get appDashboardLink() {
121576
121658
  return `${this.frontendUrl}/projects/${this.clientId}`;
121577
121659
  }
121660
+ get gitSettingsLink() {
121661
+ return `${this.frontendUrl}/account/git`;
121662
+ }
121578
121663
  async checkSyncStatus({
121579
121664
  assetsSyncing
121580
121665
  }) {
@@ -121854,29 +121939,50 @@ mutation addPendingDocumentMutation(
121854
121939
  while (attempts < maxAttempts) {
121855
121940
  await new Promise((resolve) => setTimeout(resolve, pollInterval));
121856
121941
  attempts++;
121857
- const statusUrl = `${this.contentApiBase}/editorial-workflow/${this.clientId}/status/${requestId}`;
121858
- const statusResponse = await this.authProvider.fetchWithToken(statusUrl);
121859
- if (!statusResponse.ok) {
121860
- throw new Error(
121861
- `Failed to check workflow status: ${statusResponse.statusText}`
121862
- );
121863
- }
121864
- const statusResponseBody = await statusResponse.json();
121865
- if (options.onStatusUpdate) {
121866
- options.onStatusUpdate({
121867
- status: statusResponseBody.status,
121868
- message: statusResponseBody.message || `Status: ${statusResponseBody.status}`
121869
- });
121870
- }
121871
- if (statusResponse.status === 200) {
121872
- return {
121873
- branchName: statusResponseBody.branchName,
121874
- pullRequestUrl: statusResponseBody.pullRequestUrl
121875
- };
121876
- }
121877
- if (!statusResponse.ok) {
121878
- throw new Error(
121879
- statusResponseBody.message || "Editorial workflow failed"
121942
+ try {
121943
+ const statusUrl = `${this.contentApiBase}/editorial-workflow/${this.clientId}/status/${requestId}`;
121944
+ const statusResponse = await this.authProvider.fetchWithToken(statusUrl);
121945
+ const statusResponseBody = await statusResponse.json();
121946
+ if (options.onStatusUpdate) {
121947
+ options.onStatusUpdate({
121948
+ status: statusResponseBody.status,
121949
+ message: statusResponseBody.message || `Status: ${statusResponseBody.status}`
121950
+ });
121951
+ }
121952
+ if (statusResponseBody.status === EDITORIAL_WORKFLOW_STATUS.ERROR || statusResponse.status === 500) {
121953
+ if (statusResponseBody.pullRequestUrl) {
121954
+ return {
121955
+ branchName: statusResponseBody.branchName,
121956
+ pullRequestUrl: statusResponseBody.pullRequestUrl,
121957
+ warning: statusResponseBody.message
121958
+ };
121959
+ }
121960
+ const error2 = new Error(
121961
+ statusResponseBody.message || "Editorial workflow failed"
121962
+ );
121963
+ error2.errorCode = statusResponseBody.errorCode || "WORKFLOW_FAILED";
121964
+ throw error2;
121965
+ }
121966
+ if (statusResponse.status === 200) {
121967
+ return {
121968
+ branchName: statusResponseBody.branchName,
121969
+ pullRequestUrl: statusResponseBody.pullRequestUrl
121970
+ };
121971
+ }
121972
+ if (statusResponse.status !== 202) {
121973
+ const error2 = new Error(
121974
+ statusResponseBody.message || `Failed to check workflow status: ${statusResponse.statusText}`
121975
+ );
121976
+ error2.errorCode = "WORKFLOW_STATUS_FAILED";
121977
+ throw error2;
121978
+ }
121979
+ } catch (error2) {
121980
+ if (error2.errorCode) {
121981
+ throw error2;
121982
+ }
121983
+ console.warn(
121984
+ `Editorial workflow status poll failed (attempt ${attempts}/${maxAttempts}), retrying...`,
121985
+ error2
121880
121986
  );
121881
121987
  }
121882
121988
  }
@@ -122103,7 +122209,7 @@ const AuthWallInner = ({
122103
122209
  const loginScreen = client.authProvider.getLoginScreen();
122104
122210
  if (loginStrategy === "LoginScreen" && !loginScreen) {
122105
122211
  throw new Error(
122106
- "LoginScreen is set as the login strategy but no login screen component was provided"
122212
+ "LoginScreen is set as the login strategy but no login screen component was provided."
122107
122213
  );
122108
122214
  }
122109
122215
  const [activeModal, setActiveModal] = useState(null);
@@ -122130,7 +122236,7 @@ const AuthWallInner = ({
122130
122236
  } else {
122131
122237
  setErrorMessage({
122132
122238
  title: "Access Denied:",
122133
- message: "Not Authorized To Edit"
122239
+ message: "Not authorized to edit."
122134
122240
  });
122135
122241
  setActiveModal("error");
122136
122242
  }
@@ -122189,16 +122295,16 @@ const AuthWallInner = ({
122189
122295
  });
122190
122296
  }
122191
122297
  };
122192
- let modalTitle = "Let’s get you editing with TinaCMS...";
122298
+ let modalTitle = "Let’s get you editing with TinaCMS!";
122193
122299
  if (activeModal === "authenticate" && loginStrategy === "Redirect" && !isTinaCloud) {
122194
122300
  modalTitle = "Enter into edit mode";
122195
122301
  } else if (activeModal === "authenticate" && loginStrategy === "UsernamePassword") {
122196
- modalTitle = "Let’s get you editing with TinaCMS...";
122302
+ modalTitle = "Let’s get you editing with TinaCMS!";
122197
122303
  } else if (activeModal === "error") {
122198
122304
  if (loginStrategy === "Redirect" && !isTinaCloud) {
122199
122305
  modalTitle = "Enter into edit mode";
122200
122306
  } else if (loginStrategy === "UsernamePassword") {
122201
- modalTitle = "Let’s get you editing with TinaCMS...";
122307
+ modalTitle = "Let’s get you editing with TinaCMS!";
122202
122308
  }
122203
122309
  }
122204
122310
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, activeModal === "authenticate" && loginStrategy === "Redirect" && /* @__PURE__ */ React__default.createElement(
@@ -122212,7 +122318,7 @@ const AuthWallInner = ({
122212
122318
  alt: "Tina the Llama playing a large orange key like a guitar.",
122213
122319
  width: 816,
122214
122320
  height: 816,
122215
- style: { maxWidth: "100%", margin: "0 auto", display: "block" }
122321
+ style: { width: "16rem", margin: "0 auto", display: "block" }
122216
122322
  }
122217
122323
  ) : "When you save, changes will be saved to the local filesystem.",
122218
122324
  close,
@@ -9,6 +9,7 @@ interface TinaSearchConfig {
9
9
  fuzzyOptions?: FuzzySearchOptions;
10
10
  }
11
11
  import gql from 'graphql-tag';
12
+ import { EditorialWorkflowResult } from '../toolkit/form-builder/editorial-workflow-constants';
12
13
  import { TinaCloudProject } from './types';
13
14
  export * from './authProvider';
14
15
  export type OnLoginFunc = (args: {
@@ -86,6 +87,7 @@ export declare class Client {
86
87
  variables: object;
87
88
  }): Promise<ReturnType>;
88
89
  get appDashboardLink(): string;
90
+ get gitSettingsLink(): string;
89
91
  checkSyncStatus({ assetsSyncing, }: {
90
92
  assetsSyncing: string[];
91
93
  }): Promise<{
@@ -165,7 +167,7 @@ export declare class Client {
165
167
  status: string;
166
168
  message?: string;
167
169
  }) => void;
168
- }): Promise<any>;
170
+ }): Promise<EditorialWorkflowResult>;
169
171
  }
170
172
  export declare const DEFAULT_LOCAL_TINA_GQL_SERVER_URL = "http://localhost:4001/graphql";
171
173
  export declare class LocalClient extends Client {
@@ -66,3 +66,29 @@ export declare const CloudConfigNavComponentClickedEvent: string;
66
66
  export type CloudConfigNavComponentClickedPayload = {
67
67
  itemType: 'Project Config' | 'User Management' | 'Support';
68
68
  };
69
+ export declare const SlashCommandOpenedEvent: string;
70
+ export type SlashInputElementOpenedPayload = Record<string, never>;
71
+ export declare const SlashCommandUsedEvent: string;
72
+ export type SlashCommandUsedPayload = {
73
+ command: string;
74
+ };
75
+ export declare const MediaUsageDashboardOpenedEvent: string;
76
+ export type MediaUsageDashboardOpenedPayload = Record<string, never>;
77
+ export declare const MediaUsageDashboardRefreshedEvent: string;
78
+ export type MediaUsageDashboardRefreshedPayload = {
79
+ errorOccured?: boolean;
80
+ };
81
+ export declare const MediaUsageDashboardTypeFilterEvent: string;
82
+ export type MediaUsageDashboardTypeFilterPayload = {
83
+ type: 'all' | 'image' | 'video' | 'other';
84
+ };
85
+ export declare const MediaUsageDashboardUsageFilterChangedEvent: string;
86
+ export type MediaUsageDashboardUsageFilterChangedPayload = {
87
+ usage: 'all' | 'used' | 'unused';
88
+ };
89
+ export declare const MediaUsageDashboardRowExpandedEvent: string;
90
+ export type MediaUsageDashboardRowExpandedEvent = Record<string, never>;
91
+ export declare const MediaUsageDashboardPreviewOpenedEvent: string;
92
+ export type MediaUsageDashboardPreviewOpenedPayload = Record<string, never>;
93
+ export declare const MediaUsageDashboardDocumentLinkClickedEvent: string;
94
+ export type MediaUsageDashboardDocumentLinkClickedEvent = Record<string, never>;
@@ -1,4 +1,5 @@
1
- export type ToolbarOverrideType = 'heading' | 'link' | 'image' | 'quote' | 'ul' | 'ol' | 'code' | 'codeBlock' | 'bold' | 'italic' | 'strikethrough' | 'highlight' | 'mermaid' | 'raw' | 'embed' | 'table' | 'hr';
1
+ import type { ToolbarOverrideType } from '@tinacms/schema-tools';
2
+ export type { ToolbarOverrideType };
2
3
  export declare const STANDARD_ICON_WIDTH = 32;
3
4
  export declare const HEADING_ICON_WITH_TEXT = 127;
4
5
  export declare const HEADING_ICON_ONLY = 58;
@@ -32,3 +32,11 @@ export type EditorialWorkflowErrorDetails = Error & {
32
32
  errorCode?: string;
33
33
  conflictingBranch?: string;
34
34
  };
35
+ /**
36
+ * Result from a completed editorial workflow operation
37
+ */
38
+ export interface EditorialWorkflowResult {
39
+ branchName: string;
40
+ pullRequestUrl: string;
41
+ warning?: string;
42
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "tinacms",
3
3
  "type": "module",
4
4
  "typings": "dist/index.d.ts",
5
- "version": "3.7.0",
5
+ "version": "3.7.2",
6
6
  "main": "dist/index.js",
7
7
  "module": "./dist/index.js",
8
8
  "exports": {
@@ -103,6 +103,8 @@
103
103
  "react-colorful": "^5.6.1",
104
104
  "react-datetime": "^3.3.1",
105
105
  "react-day-picker": "^9.13.0",
106
+ "react-dnd": "^16.0.1",
107
+ "react-dnd-html5-backend": "^16.0.1",
106
108
  "react-dropzone": "14.2.3",
107
109
  "react-final-form": "^6.5.9",
108
110
  "react-icons": "^5.4.0",
@@ -112,9 +114,9 @@
112
114
  "webfontloader": "1.6.28",
113
115
  "yup": "^1.6.1",
114
116
  "zod": "^3.24.2",
115
- "@tinacms/mdx": "2.1.0",
116
- "@tinacms/schema-tools": "2.7.0",
117
- "@tinacms/search": "1.2.7"
117
+ "@tinacms/mdx": "2.1.1",
118
+ "@tinacms/schema-tools": "2.7.1",
119
+ "@tinacms/search": "1.2.9"
118
120
  },
119
121
  "devDependencies": {
120
122
  "@graphql-tools/utils": "^10.8.1",