tinacms 3.13.0 → 3.14.1

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
@@ -32,7 +32,7 @@ import { useHTMLInputCursorState, useComboboxInput } from "@udecode/plate-combob
32
32
  import { useComboboxContext, Combobox as Combobox$1, useComboboxStore, ComboboxProvider, Portal, ComboboxPopover, ComboboxItem } from "@ariakit/react";
33
33
  import { filterWords } from "@udecode/plate-combobox";
34
34
  import { toggleList, unwrapList, getListItemEntry } from "@udecode/plate-list";
35
- import { normalizeHeadingLevels, ALL_HEADING_LEVELS, MEDIA_MIME_TYPES, extensionOf, resolveMediaAccept, ASYNC_POLLER_ERROR, MEDIA_CATEGORIES, canonicalPath, ERR_BRANCH_EXISTS, ERR_BRANCH_CONFLICT, isHeadingLevel, TinaSchema, addNamespaceToSchema, parseURL, ERR_HAS_REFERENCES, ERR_ALREADY_EXISTS, isValidRelativePath, RELATIVE_PATH_ALLOWED_CHARS_MESSAGE, resolveForm, RELATIVE_PATH_REGEX, normalizePath, ERR_NOT_INDEXED, validateSchema } from "@tinacms/schema-tools";
35
+ import { normalizeHeadingLevels, ALL_HEADING_LEVELS, MEDIA_MIME_TYPES, extensionOf, resolveMediaAccept, ASYNC_POLLER_ERROR, ERR_BRANCH_EXISTS, ERR_BRANCH_CONFLICT, MEDIA_CATEGORIES, canonicalPath, isHeadingLevel, TinaSchema, addNamespaceToSchema, parseURL, ERR_HAS_REFERENCES, ERR_ALREADY_EXISTS, isValidRelativePath, RELATIVE_PATH_ALLOWED_CHARS_MESSAGE, resolveForm, RELATIVE_PATH_REGEX, normalizePath, ERR_NOT_INDEXED, validateSchema } from "@tinacms/schema-tools";
36
36
  import { NAMER, resolveField } from "@tinacms/schema-tools";
37
37
  import { useBlockSelected, BlockSelectionPlugin } from "@udecode/plate-selection/react";
38
38
  import "@udecode/plate-dnd";
@@ -5361,6 +5361,7 @@ const Toggle = ({
5361
5361
  disabled = false
5362
5362
  }) => {
5363
5363
  const checked = !!(input.value || input.checked);
5364
+ const inputId = name2 ?? input.name;
5364
5365
  let labels = null;
5365
5366
  if (field.toggleLabels) {
5366
5367
  const fieldLabels = typeof field.toggleLabels === "object" && "true" in field.toggleLabels && "false" in field.toggleLabels && field.toggleLabels;
@@ -5375,7 +5376,7 @@ const Toggle = ({
5375
5376
  className: `text-sm ${!checked ? "text-blue-500 font-bold" : "text-gray-300"}`
5376
5377
  },
5377
5378
  labels.false
5378
- ), /* @__PURE__ */ React.createElement("div", { className: "relative w-12 h-7" }, /* @__PURE__ */ React.createElement(ToggleInput, { id: name2, type: "checkbox", ...input }), /* @__PURE__ */ React.createElement(
5379
+ ), /* @__PURE__ */ React.createElement("div", { className: "relative w-12 h-7" }, /* @__PURE__ */ React.createElement(ToggleInput, { type: "checkbox", ...input, id: inputId }), /* @__PURE__ */ React.createElement(
5379
5380
  "label",
5380
5381
  {
5381
5382
  className: "bg-none p-0 outline-none w-12 h-7",
@@ -5383,7 +5384,7 @@ const Toggle = ({
5383
5384
  opacity: disabled ? 0.4 : 1,
5384
5385
  pointerEvents: disabled ? "none" : "inherit"
5385
5386
  },
5386
- htmlFor: name2,
5387
+ htmlFor: inputId,
5387
5388
  role: "switch"
5388
5389
  },
5389
5390
  /* @__PURE__ */ React.createElement("div", { className: "relative w-[48px] h-7 rounded-3xl bg-white shadow-inner border border-gray-200 pointer-events-none -ml-0.5" }, /* @__PURE__ */ React.createElement(
@@ -8912,6 +8913,20 @@ function useLocalStorage(key, initialValue) {
8912
8913
  };
8913
8914
  return [storedValue, setValue];
8914
8915
  }
8916
+ const EditorialWorkflowErrorBox = ({
8917
+ error
8918
+ }) => /* @__PURE__ */ React__default.createElement("div", { className: "flex items-start gap-1 text-red-700 py-2 px-3 mb-4 bg-red-50 border border-red-200 rounded" }, /* @__PURE__ */ React__default.createElement(CircleAlert, { className: "w-5 h-auto text-red-400 flex-shrink-0" }), /* @__PURE__ */ React__default.createElement("span", { className: "text-sm whitespace-pre-line" }, /* @__PURE__ */ React__default.createElement("b", null, "Error:"), " ", error.messageParts.map(
8919
+ (part, index) => part.emphasis ? /* @__PURE__ */ React__default.createElement("b", { key: index }, part.text) : /* @__PURE__ */ React__default.createElement(React__default.Fragment, { key: index }, part.text)
8920
+ ), error.link && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, " ", /* @__PURE__ */ React__default.createElement(
8921
+ "a",
8922
+ {
8923
+ className: "underline text-tina-orange-dark font-medium",
8924
+ href: error.link.url,
8925
+ target: "_blank",
8926
+ rel: "noreferrer"
8927
+ },
8928
+ error.link.label
8929
+ ))));
8915
8930
  const Badge = ({
8916
8931
  children,
8917
8932
  calloutStyle = "warning",
@@ -10244,8 +10259,10 @@ const EDITORIAL_WORKFLOW_STATUS = {
10244
10259
  const EDITORIAL_WORKFLOW_ERROR = {
10245
10260
  BRANCH_EXISTS: "BRANCH_EXISTS",
10246
10261
  BRANCH_HIERARCHY_CONFLICT: "BRANCH_HIERARCHY_CONFLICT",
10247
- VALIDATION_FAILED: "VALIDATION_FAILED"
10262
+ VALIDATION_FAILED: "VALIDATION_FAILED",
10263
+ INDEXING_FAILED: "INDEXING_FAILED"
10248
10264
  };
10265
+ const EDITORIAL_WORKFLOW_EVENT_LOG_DOCS_URL = "https://tina.io/docs/tinacloud/dashboard/event-log#common-causes";
10249
10266
  const getEditorialWorkflowPrTitle = (branchName) => `${branchName.replace("tina/", "").replaceAll("-", " ")} (PR from TinaCMS)`;
10250
10267
  const TARGET_BRANCH_EXISTS_ERROR = "A branch with this name already exists";
10251
10268
  const checkBranchExists = async (tinaApi, branchName, debugLabel, branchType, fallback, signal) => {
@@ -10301,6 +10318,71 @@ const checkBranchGuard = async (tinaApi, baseBranch, targetBranch, debugLabel, s
10301
10318
  return { baseBranchExists: true, targetBranchExists: false };
10302
10319
  }
10303
10320
  };
10321
+ const plainMessage = (text) => [
10322
+ { text }
10323
+ ];
10324
+ const messageText = (parts) => parts.map((part) => part.text).join("");
10325
+ const pageNameFrom = (file) => {
10326
+ var _a;
10327
+ return ((_a = file.split("/").pop()) == null ? void 0 : _a.replace(/\.[^.]+$/, "")) || file;
10328
+ };
10329
+ const indexingFailureCopy = (file, collectionLabel) => {
10330
+ const subject = file ? `“${pageNameFrom(file)}”` : "your content";
10331
+ const messageParts = [
10332
+ { text: "We couldn't save your changes, because there's a problem with " },
10333
+ { text: subject, emphasis: true },
10334
+ ...collectionLabel ? [{ text: " in " }, { text: collectionLabel, emphasis: true }] : [],
10335
+ { text: ".\n\nFix that page, then save again." }
10336
+ ];
10337
+ return {
10338
+ messageParts,
10339
+ link: {
10340
+ url: EDITORIAL_WORKFLOW_EVENT_LOG_DOCS_URL,
10341
+ label: "How to resolve this"
10342
+ }
10343
+ };
10344
+ };
10345
+ const collectionLabelResolver = (schema) => (file) => {
10346
+ var _a;
10347
+ try {
10348
+ const collection = (_a = schema == null ? void 0 : schema.getCollectionByFullPath) == null ? void 0 : _a.call(schema, file);
10349
+ return (collection == null ? void 0 : collection.label) || (collection == null ? void 0 : collection.name);
10350
+ } catch {
10351
+ return void 0;
10352
+ }
10353
+ };
10354
+ const getEditorialWorkflowError = (e, resolveCollectionLabel) => {
10355
+ let errMessage = "Branch operation failed. Talking to GitHub was unsuccessful, please try again. If the problem persists please contact support at https://tina.io/support 🦙";
10356
+ const err = e;
10357
+ if (err.errorCode) {
10358
+ switch (err.errorCode) {
10359
+ case EDITORIAL_WORKFLOW_ERROR.BRANCH_EXISTS:
10360
+ errMessage = "A branch with this name already exists";
10361
+ break;
10362
+ case EDITORIAL_WORKFLOW_ERROR.BRANCH_HIERARCHY_CONFLICT:
10363
+ errMessage = err.message || "Branch name conflicts with an existing branch";
10364
+ break;
10365
+ case EDITORIAL_WORKFLOW_ERROR.VALIDATION_FAILED:
10366
+ errMessage = err.message || "Invalid branch name";
10367
+ break;
10368
+ case EDITORIAL_WORKFLOW_ERROR.INDEXING_FAILED:
10369
+ return indexingFailureCopy(
10370
+ err.file,
10371
+ err.file ? resolveCollectionLabel == null ? void 0 : resolveCollectionLabel(err.file) : void 0
10372
+ );
10373
+ default:
10374
+ errMessage = err.message || errMessage;
10375
+ break;
10376
+ }
10377
+ } else if (err.message) {
10378
+ if (err.message.toLowerCase().includes(ERR_BRANCH_EXISTS)) {
10379
+ errMessage = "A branch with this name already exists";
10380
+ } else if (err.message.toLowerCase().includes(ERR_BRANCH_CONFLICT)) {
10381
+ errMessage = err.message;
10382
+ }
10383
+ }
10384
+ return { messageParts: plainMessage(errMessage) };
10385
+ };
10304
10386
  const MEDIA_WORKFLOW_STEP = {
10305
10387
  BRANCH: 1,
10306
10388
  CONTENT: 2,
@@ -10604,7 +10686,8 @@ class TinaMediaStore {
10604
10686
  dispatchMediaWorkflowError(err) {
10605
10687
  this.cms.events.dispatch({
10606
10688
  type: "media:workflow:error",
10607
- message: err instanceof Error ? err.message : String(err)
10689
+ message: err instanceof Error ? err.message : String(err),
10690
+ error: err
10608
10691
  });
10609
10692
  }
10610
10693
  async runMediaOpWithWorkflow(decision, op) {
@@ -11115,7 +11198,7 @@ class TinaMediaStore {
11115
11198
  if (!this.isLocal) {
11116
11199
  const encodedBranch = this.encodedBranchParam();
11117
11200
  res = await this.api.authProvider.fetchWithToken(
11118
- `${this.listUrl}/list/${options.directory || ""}?limit=${options.limit || 20}${options.offset ? `&cursor=${options.offset}` : ""}${encodedBranch ? `&branch=${encodedBranch}` : ""}${options.search ? `&search=${encodeURIComponent(options.search)}` : ""}${((_a = options.ext) == null ? void 0 : _a.length) ? `&ext=${encodeURIComponent(options.ext.join(","))}` : ""}`
11201
+ `${this.listUrl}/list/${options.directory || ""}?limit=${options.limit || 20}${options.offset ? `&cursor=${encodeURIComponent(options.offset)}` : ""}${encodedBranch ? `&branch=${encodedBranch}` : ""}${options.search ? `&search=${encodeURIComponent(options.search)}` : ""}${((_a = options.ext) == null ? void 0 : _a.length) ? `&ext=${encodeURIComponent(options.ext.join(","))}` : ""}`
11119
11202
  );
11120
11203
  if (res.status == 401) {
11121
11204
  throw E_UNAUTHORIZED;
@@ -11125,7 +11208,7 @@ class TinaMediaStore {
11125
11208
  }
11126
11209
  } else {
11127
11210
  res = await this.fetchFunction(
11128
- `${this.url}/list/${options.directory || ""}?limit=${options.limit || 20}${options.offset ? `&cursor=${options.offset}` : ""}${options.search ? `&search=${encodeURIComponent(options.search)}` : ""}${((_b = options.ext) == null ? void 0 : _b.length) ? `&ext=${encodeURIComponent(options.ext.join(","))}` : ""}`
11211
+ `${this.url}/list/${options.directory || ""}?limit=${options.limit || 20}${options.offset ? `&cursor=${encodeURIComponent(options.offset)}` : ""}${options.search ? `&search=${encodeURIComponent(options.search)}` : ""}${((_b = options.ext) == null ? void 0 : _b.length) ? `&ext=${encodeURIComponent(options.ext.join(","))}` : ""}`
11129
11212
  );
11130
11213
  if (res.status == 404) {
11131
11214
  throw E_BAD_ROUTE;
@@ -14005,6 +14088,70 @@ function createCloudConfig({
14005
14088
  ...options
14006
14089
  };
14007
14090
  }
14091
+ const LOADING_MESSAGES = [
14092
+ "Hang tight, TinaCMS is looking for llamas 🦙 🦙 🦙",
14093
+ "Reticulating llama splines 🦙",
14094
+ "Herding llamas into collections 🦙",
14095
+ "Brushing llama fur 🦙 🦙",
14096
+ "Teaching a llama to write frontmatter 🦙",
14097
+ "Feeding the GraphQL llama 🦙",
14098
+ "Counting llamas in your content folder 🦙",
14099
+ "Asking a llama what changed in git 🦙",
14100
+ "Llamas are proofreading your schema 🦙",
14101
+ "Untangling markdown with llama teeth 🦙",
14102
+ "Waking the llamas in the media library 🦙",
14103
+ "Alphabetising llamas by collection 🦙",
14104
+ "Convincing a llama that MDX is fine 🦙",
14105
+ "Saddling up the content layer 🦙",
14106
+ "Polishing the sidebar, llama style 🦙",
14107
+ "One more llama, almost there 🦙"
14108
+ ];
14109
+ const CYCLE_MS = 2e3;
14110
+ const FADE_MS = 200;
14111
+ const prefersReducedMotion = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
14112
+ const pickOther = (current, length) => {
14113
+ if (length < 2) return 0;
14114
+ const offset2 = 1 + Math.floor(Math.random() * (length - 1));
14115
+ return (current + offset2) % length;
14116
+ };
14117
+ const LoadingMessage = ({
14118
+ className,
14119
+ style,
14120
+ messages = LOADING_MESSAGES
14121
+ }) => {
14122
+ const [index, setIndex] = React__default.useState(0);
14123
+ const [visible, setVisible] = React__default.useState(false);
14124
+ const [reducedMotion] = React__default.useState(prefersReducedMotion);
14125
+ React__default.useEffect(() => {
14126
+ setIndex((current) => pickOther(current, messages.length));
14127
+ setVisible(true);
14128
+ }, [messages.length]);
14129
+ React__default.useEffect(() => {
14130
+ const fadeOut = setTimeout(() => setVisible(false), CYCLE_MS - FADE_MS);
14131
+ const next = setTimeout(() => {
14132
+ setIndex((current) => pickOther(current, messages.length));
14133
+ setVisible(true);
14134
+ }, CYCLE_MS);
14135
+ return () => {
14136
+ clearTimeout(fadeOut);
14137
+ clearTimeout(next);
14138
+ };
14139
+ }, [index, messages.length]);
14140
+ return /* @__PURE__ */ React__default.createElement(
14141
+ "p",
14142
+ {
14143
+ className,
14144
+ "aria-live": "polite",
14145
+ style: {
14146
+ ...style,
14147
+ opacity: reducedMotion || visible ? 1 : 0,
14148
+ transform: reducedMotion || visible ? "none" : "translateY(4px)",
14149
+ transition: reducedMotion ? void 0 : `opacity ${FADE_MS}ms ease-out, transform ${FADE_MS}ms ease-out`
14150
+ }
14151
+ },
14152
+ messages[index]
14153
+ );
14154
+ };
14008
14155
  const SidebarLoadingPlaceholder = () => /* @__PURE__ */ React.createElement(
14009
14156
  "div",
14010
14157
  {
@@ -14018,7 +14165,7 @@ const SidebarLoadingPlaceholder = () => /* @__PURE__ */ React.createElement(
14018
14165
  animationDuration: "150ms"
14019
14166
  }
14020
14167
  },
14021
- /* @__PURE__ */ React.createElement("p", { className: "block pb-5" }, "Please wait while TinaCMS", /* @__PURE__ */ React.createElement("br", null), "loads your content"),
14168
+ /* @__PURE__ */ React.createElement(LoadingMessage, { className: "block pb-5" }),
14022
14169
  /* @__PURE__ */ React.createElement(LoadingDots, { color: "var(--tina-color-primary)" })
14023
14170
  );
14024
14171
  class SidebarState {
@@ -14158,12 +14305,12 @@ const FormModal = ({ plugin, close: close2 }) => {
14158
14305
  const name = "tinacms";
14159
14306
  const type = "module";
14160
14307
  const typings = "dist/index.d.ts";
14161
- const version = "3.13.0";
14308
+ const version = "3.14.1";
14162
14309
  const main = "dist/index.js";
14163
14310
  const module$1 = "./dist/index.js";
14164
- const exports$1 = { ".": "./dist/index.js", "./dist/client": "./dist/client.js", "./react": "./dist/react.js", "./dist/react": "./dist/react.js", "./tina-field": "./dist/tina-field.js", "./dist/tina-field": "./dist/tina-field.js", "./dist/rich-text": "./dist/rich-text/index.js", "./dist/rich-text/static": "./dist/rich-text/static.js", "./dist/rich-text/prism": "./dist/rich-text/prism.js" };
14311
+ const exports$1 = { ".": "./dist/index.js", "./dist/client": { "types": "./dist/client.d.ts", "browser": "./dist/client.browser.js", "default": "./dist/client.js" }, "./react": "./dist/react.js", "./dist/react": "./dist/react.js", "./tina-field": "./dist/tina-field.js", "./dist/tina-field": "./dist/tina-field.js", "./dist/rich-text": "./dist/rich-text/index.js", "./dist/rich-text/static": "./dist/rich-text/static.js", "./dist/rich-text/prism": "./dist/rich-text/prism.js" };
14165
14312
  const files = ["dist"];
14166
- const buildConfig = { "entryPoints": ["src/index.ts", "src/rich-text/index.tsx", "src/rich-text/static.tsx", "src/rich-text/prism.tsx", "src/react.tsx", "src/tina-field.ts", { "name": "src/client.ts", "target": "node" }] };
14313
+ const buildConfig = { "entryPoints": ["src/index.ts", "src/rich-text/index.tsx", "src/rich-text/static.tsx", "src/rich-text/prism.tsx", "src/react.tsx", "src/tina-field.ts", { "name": "src/client.ts", "target": "node" }, "src/client.browser.ts"] };
14167
14314
  const license = "Apache-2.0";
14168
14315
  const scripts = { "types": "pnpm tsc && pnpm tsc-alias", "build": "tinacms-scripts build", "test": "vitest run", "test-watch": "vitest" };
14169
14316
  const dependencies = { "@ariakit/react": "catalog:", "@dnd-kit/core": "catalog:", "@dnd-kit/sortable": "catalog:", "@dnd-kit/utilities": "catalog:", "@floating-ui/dom": "catalog:", "@floating-ui/react-dom": "catalog:", "@graphql-inspector/core": "^6.2.1", "@radix-ui/react-dialog": "catalog:", "@radix-ui/react-dropdown-menu": "catalog:", "@radix-ui/react-popover": "catalog:", "@radix-ui/react-select": "catalog:", "@radix-ui/react-separator": "catalog:", "@radix-ui/react-slot": "catalog:", "@radix-ui/react-toolbar": "catalog:", "@radix-ui/react-tooltip": "catalog:", "@react-hook/window-size": "catalog:", "@tanstack/react-table": "^8.21.3", "@tinacms/bridge": "workspace:^", "@tinacms/mdx": "workspace:^", "@tinacms/schema-tools": "workspace:^", "@tinacms/search": "workspace:^", "@udecode/cmdk": "catalog:", "@udecode/cn": "catalog:", "@udecode/plate": "catalog:", "@udecode/plate-autoformat": "catalog:", "@udecode/plate-basic-marks": "catalog:", "@udecode/plate-block-quote": "catalog:", "@udecode/plate-break": "catalog:", "@udecode/plate-code-block": "catalog:", "@udecode/plate-combobox": "catalog:", "@udecode/plate-dnd": "catalog:", "@udecode/plate-floating": "catalog:", "@udecode/plate-heading": "catalog:", "@udecode/plate-highlight": "catalog:", "@udecode/plate-horizontal-rule": "catalog:", "@udecode/plate-indent-list": "catalog:", "@udecode/plate-link": "catalog:", "@udecode/plate-list": "catalog:", "@udecode/plate-node-id": "catalog:", "@udecode/plate-reset-node": "catalog:", "@udecode/plate-resizable": "catalog:", "@udecode/plate-selection": "catalog:", "@udecode/plate-slash-command": "catalog:", "@udecode/plate-table": "catalog:", "@udecode/plate-trailing-block": "catalog:", "class-variance-authority": "catalog:", "clsx": "catalog:", "cmdk": "catalog:", "color-string": "catalog:", "date-fns": "4.1.0", "es-toolkit": "^1.42.0", "final-form": "catalog:", "final-form-arrays": "catalog:", "final-form-set-field-data": "catalog:", "graphql": "15.8.0", "graphql-tag": "catalog:", "is-hotkey": "catalog:", "lucide-react": "catalog:", "mermaid": "catalog:", "posthog-js": "^1.347.1", "prism-react-renderer": "catalog:", "prop-types": "catalog:", "react-colorful": "catalog:", "react-day-picker": "^9.13.0", "react-dnd": "catalog:", "react-dnd-html5-backend": "catalog:", "react-dropzone": "catalog:", "react-final-form": "catalog:", "react-router-dom": "catalog:", "react-use": "catalog:", "tailwind-merge": "^2.6.0", "webfontloader": "catalog:", "yup": "^1.6.1", "zod": "catalog:" };
@@ -16553,6 +16700,9 @@ const useFieldReference = (fieldName) => {
16553
16700
  } else {
16554
16701
  doc = document;
16555
16702
  }
16703
+ if (!doc) {
16704
+ return;
16705
+ }
16556
16706
  const fieldEle = doc.querySelector(
16557
16707
  `[data-tinafield="${fieldName}"]`
16558
16708
  );
@@ -17210,39 +17360,12 @@ const formatTime = (seconds) => {
17210
17360
  const secs = seconds % 60;
17211
17361
  return `${mins}:${secs.toString().padStart(2, "0")}`;
17212
17362
  };
17213
- const getEditorialWorkflowErrorMessage = (e) => {
17214
- let errMessage = "Branch operation failed. Talking to GitHub was unsuccessful, please try again. If the problem persists please contact support at https://tina.io/support 🦙";
17215
- const err = e;
17216
- if (err.errorCode) {
17217
- switch (err.errorCode) {
17218
- case EDITORIAL_WORKFLOW_ERROR.BRANCH_EXISTS:
17219
- errMessage = "A branch with this name already exists";
17220
- break;
17221
- case EDITORIAL_WORKFLOW_ERROR.BRANCH_HIERARCHY_CONFLICT:
17222
- errMessage = err.message || "Branch name conflicts with an existing branch";
17223
- break;
17224
- case EDITORIAL_WORKFLOW_ERROR.VALIDATION_FAILED:
17225
- errMessage = err.message || "Invalid branch name";
17226
- break;
17227
- default:
17228
- errMessage = err.message || errMessage;
17229
- break;
17230
- }
17231
- } else if (err.message) {
17232
- if (err.message.toLowerCase().includes(ERR_BRANCH_EXISTS)) {
17233
- errMessage = "A branch with this name already exists";
17234
- } else if (err.message.toLowerCase().includes(ERR_BRANCH_CONFLICT)) {
17235
- errMessage = err.message;
17236
- }
17237
- }
17238
- return errMessage;
17239
- };
17240
17363
  function useEditorialWorkflow() {
17241
17364
  const cms = useCMS$1();
17242
17365
  const tinaApi = cms.api.tina;
17243
17366
  const { setCurrentBranch } = useBranchData();
17244
17367
  const [isExecuting, setIsExecuting] = React.useState(false);
17245
- const [errorMessage, setErrorMessage] = React.useState("");
17368
+ const [error, setError] = React.useState(void 0);
17246
17369
  const [currentStep, setCurrentStep] = React.useState(0);
17247
17370
  const [elapsedTime, setElapsedTime] = React.useState(0);
17248
17371
  React.useEffect(() => {
@@ -17259,7 +17382,7 @@ function useEditorialWorkflow() {
17259
17382
  };
17260
17383
  }, [isExecuting, currentStep]);
17261
17384
  const reset = () => {
17262
- setErrorMessage("");
17385
+ setError(void 0);
17263
17386
  setIsExecuting(false);
17264
17387
  setCurrentStep(0);
17265
17388
  };
@@ -17285,7 +17408,7 @@ function useEditorialWorkflow() {
17285
17408
  );
17286
17409
  if (signal == null ? void 0 : signal.aborted) return { success: false };
17287
17410
  if (targetBranchExists) {
17288
- setErrorMessage(TARGET_BRANCH_EXISTS_ERROR);
17411
+ setError({ messageParts: plainMessage(TARGET_BRANCH_EXISTS_ERROR) });
17289
17412
  setIsExecuting(false);
17290
17413
  setCurrentStep(0);
17291
17414
  return { success: false, error: TARGET_BRANCH_EXISTS_ERROR };
@@ -17363,16 +17486,19 @@ function useEditorialWorkflow() {
17363
17486
  return { success: true };
17364
17487
  } catch (e) {
17365
17488
  console.error(e);
17366
- const errMessage = getEditorialWorkflowErrorMessage(e);
17367
- setErrorMessage(errMessage);
17489
+ const copy = getEditorialWorkflowError(
17490
+ e,
17491
+ collectionLabelResolver(cms.api.tina.schema)
17492
+ );
17493
+ setError(copy);
17368
17494
  setIsExecuting(false);
17369
17495
  setCurrentStep(0);
17370
- return { success: false, error: errMessage };
17496
+ return { success: false, error: messageText(copy.messageParts) };
17371
17497
  }
17372
17498
  };
17373
17499
  return {
17374
17500
  isExecuting,
17375
- errorMessage,
17501
+ error,
17376
17502
  currentStep,
17377
17503
  elapsedTime,
17378
17504
  executeWorkflow,
@@ -17489,7 +17615,7 @@ const CreateBranchModal = ({
17489
17615
  const branchGuardAbortRef = React.useRef(null);
17490
17616
  const {
17491
17617
  isExecuting,
17492
- errorMessage,
17618
+ error,
17493
17619
  currentStep,
17494
17620
  elapsedTime,
17495
17621
  executeWorkflow,
@@ -17531,7 +17657,7 @@ const CreateBranchModal = ({
17531
17657
  return;
17532
17658
  }
17533
17659
  setIsBranchGuardChecking(false);
17534
- const { success, error } = await executeWorkflow({
17660
+ const { success, error: error2 } = await executeWorkflow({
17535
17661
  branchName: targetBranch,
17536
17662
  baseBranch,
17537
17663
  path,
@@ -17549,7 +17675,7 @@ const CreateBranchModal = ({
17549
17675
  captureEvent(EditorialWorkflowSaveEvent, {
17550
17676
  choice: isDraft ? "draft" : "review",
17551
17677
  success,
17552
- error
17678
+ error: error2
17553
17679
  });
17554
17680
  if (success) {
17555
17681
  close2();
@@ -17573,7 +17699,7 @@ const CreateBranchModal = ({
17573
17699
  abortBranchGuard();
17574
17700
  close2();
17575
17701
  },
17576
- errorMessage,
17702
+ error,
17577
17703
  disabled: normalizedBranchName === "" || isBranchGuardChecking,
17578
17704
  onBranchNameChange: (value) => {
17579
17705
  abortBranchGuard();
@@ -17624,7 +17750,7 @@ const CreateBranchPromptModal = ({
17624
17750
  branchName,
17625
17751
  close: close2,
17626
17752
  disabled,
17627
- errorMessage,
17753
+ error,
17628
17754
  onBranchNameChange,
17629
17755
  onCreateBranch,
17630
17756
  onSaveToProtectedBranch,
@@ -17658,7 +17784,7 @@ const CreateBranchPromptModal = ({
17658
17784
  };
17659
17785
  const mainChoice = choices[main2] ?? choices.draft;
17660
17786
  const MainIcon = mainChoice.Icon;
17661
- return /* @__PURE__ */ React.createElement(Modal, { className: "flex" }, /* @__PURE__ */ React.createElement(PopupModal, { className: "w-auto" }, /* @__PURE__ */ React.createElement(ModalHeader, { close: close2 }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between w-full" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center" }, "Save changes to new branch"))), /* @__PURE__ */ React.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React.createElement("div", { className: "max-w-sm" }, errorMessage && /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1 text-red-700 py-2 px-3 mb-4 bg-red-50 border border-red-200 rounded" }, /* @__PURE__ */ React.createElement(CircleAlert, { className: "w-5 h-auto text-red-400 flex-shrink-0" }), /* @__PURE__ */ React.createElement("span", { className: "text-sm" }, /* @__PURE__ */ React.createElement("b", null, "Error:"), " ", errorMessage)), /* @__PURE__ */ React.createElement("p", { className: "text-lg text-gray-700 font-bold mb-2" }, "First, let's create a copy"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-700 mb-4 max-w-sm" }, "To make changes, you need to create a copy then get it approved and merged for it to go live.", /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("span", { className: "text-gray-500" }, "Learn more about "), /* @__PURE__ */ React.createElement(
17787
+ return /* @__PURE__ */ React.createElement(Modal, { className: "flex" }, /* @__PURE__ */ React.createElement(PopupModal, { className: "w-auto" }, /* @__PURE__ */ React.createElement(ModalHeader, { close: close2 }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between w-full" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center" }, "Save changes to new branch"))), /* @__PURE__ */ React.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React.createElement("div", { className: "max-w-sm" }, error && /* @__PURE__ */ React.createElement(EditorialWorkflowErrorBox, { error }), /* @__PURE__ */ React.createElement("p", { className: "text-lg text-gray-700 font-bold mb-2" }, "First, let's create a copy"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-700 mb-4 max-w-sm" }, "To make changes, you need to create a copy then get it approved and merged for it to go live.", /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("span", { className: "text-gray-500" }, "Learn more about "), /* @__PURE__ */ React.createElement(
17662
17788
  "a",
17663
17789
  {
17664
17790
  className: "underline text-tina-orange-dark font-medium",
@@ -17785,7 +17911,7 @@ const BranchDeletedModal = ({
17785
17911
  const baseBranch = tinaApi.protectedBranches[0] || cms.api.tina.schema.config.config.repoProvider.defaultBranchName || "main";
17786
17912
  const {
17787
17913
  isExecuting,
17788
- errorMessage,
17914
+ error,
17789
17915
  currentStep,
17790
17916
  elapsedTime,
17791
17917
  executeWorkflow,
@@ -17815,7 +17941,7 @@ const BranchDeletedModal = ({
17815
17941
  className: "w-4 h-4 mt-0.5 flex-shrink-0 text-yellow-600",
17816
17942
  style: { fill: "none" }
17817
17943
  }
17818
- ), /* @__PURE__ */ React.createElement("span", null, "The branch", " ", /* @__PURE__ */ React.createElement("span", { className: "font-mono font-semibold" }, branchName), " ", "no longer exists. It may have been merged or deleted. Your changes cannot be pushed to it.")), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-700 mb-4" }, "Create a new branch from", " ", /* @__PURE__ */ React.createElement("span", { className: "font-mono font-semibold" }, baseBranch), " to continue editing, or cancel and switch to an existing branch from the branch menu."), errorMessage && /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1 text-red-700 py-2 px-3 mb-4 bg-red-50 border border-red-200 rounded" }, /* @__PURE__ */ React.createElement(CircleAlert, { className: "w-5 h-auto text-red-400 flex-shrink-0" }), /* @__PURE__ */ React.createElement("span", { className: "text-sm" }, /* @__PURE__ */ React.createElement("b", null, "Error:"), " ", errorMessage)), /* @__PURE__ */ React.createElement(
17944
+ ), /* @__PURE__ */ React.createElement("span", null, "The branch", " ", /* @__PURE__ */ React.createElement("span", { className: "font-mono font-semibold" }, branchName), " ", "no longer exists. It may have been merged or deleted. Your changes cannot be pushed to it.")), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-700 mb-4" }, "Create a new branch from", " ", /* @__PURE__ */ React.createElement("span", { className: "font-mono font-semibold" }, baseBranch), " to continue editing, or cancel and switch to an existing branch from the branch menu."), error && /* @__PURE__ */ React.createElement(EditorialWorkflowErrorBox, { error }), /* @__PURE__ */ React.createElement(
17819
17945
  PrefixedTextField,
17820
17946
  {
17821
17947
  name: "new-branch-name",
@@ -71598,12 +71724,15 @@ const MediaWorkflowOverlay = () => {
71598
71724
  const offComplete = cms.events.subscribe("media:workflow:complete", (event) => {
71599
71725
  setCurrentBranch(event.branchName);
71600
71726
  });
71601
- const offError = cms.events.subscribe(
71602
- "media:workflow:error",
71603
- (event) => {
71604
- setState({ phase: "error", message: event.message });
71605
- }
71606
- );
71727
+ const offError = cms.events.subscribe("media:workflow:error", (event) => {
71728
+ setState({
71729
+ phase: "error",
71730
+ error: event.error === void 0 ? { messageParts: plainMessage(event.message) } : getEditorialWorkflowError(
71731
+ event.error,
71732
+ collectionLabelResolver(cms.api.tina.schema)
71733
+ )
71734
+ });
71735
+ });
71607
71736
  const offFinish = cms.events.subscribe("media:workflow:finish", () => {
71608
71737
  setState({ phase: "idle" });
71609
71738
  });
@@ -71637,7 +71766,7 @@ const MediaWorkflowOverlay = () => {
71637
71766
  setState({
71638
71767
  ...confirmState,
71639
71768
  isChecking: true,
71640
- errorMessage: ""
71769
+ error: void 0
71641
71770
  });
71642
71771
  const { baseBranchExists, targetBranchExists } = await checkBranchGuard(
71643
71772
  cms.api.tina,
@@ -71655,7 +71784,11 @@ const MediaWorkflowOverlay = () => {
71655
71784
  ...confirmState,
71656
71785
  branchName,
71657
71786
  isChecking: false,
71658
- errorMessage: `The branch ${confirmState.baseBranch} no longer exists. It may have been merged or deleted. Your changes cannot be pushed to it.`
71787
+ error: {
71788
+ messageParts: plainMessage(
71789
+ `The branch ${confirmState.baseBranch} no longer exists. It may have been merged or deleted. Your changes cannot be pushed to it.`
71790
+ )
71791
+ }
71659
71792
  });
71660
71793
  return;
71661
71794
  }
@@ -71667,7 +71800,7 @@ const MediaWorkflowOverlay = () => {
71667
71800
  ...confirmState,
71668
71801
  branchName,
71669
71802
  isChecking: false,
71670
- errorMessage: TARGET_BRANCH_EXISTS_ERROR
71803
+ error: { messageParts: plainMessage(TARGET_BRANCH_EXISTS_ERROR) }
71671
71804
  });
71672
71805
  return;
71673
71806
  }
@@ -71683,7 +71816,10 @@ const MediaWorkflowOverlay = () => {
71683
71816
  ...confirmState,
71684
71817
  branchName,
71685
71818
  isChecking: false,
71686
- errorMessage: getEditorialWorkflowErrorMessage(e)
71819
+ error: getEditorialWorkflowError(
71820
+ e,
71821
+ collectionLabelResolver(cms.api.tina.schema)
71822
+ )
71687
71823
  });
71688
71824
  }
71689
71825
  };
@@ -71699,14 +71835,14 @@ const MediaWorkflowOverlay = () => {
71699
71835
  setState({ phase: "idle" });
71700
71836
  },
71701
71837
  disabled: normalizeBranchName(state.branchName) === "" || state.isChecking,
71702
- errorMessage: state.errorMessage,
71838
+ error: state.error,
71703
71839
  onBranchNameChange: (branchName) => {
71704
71840
  abortPreflight();
71705
71841
  setState(
71706
71842
  (prev) => prev.phase === "confirming" ? {
71707
71843
  ...prev,
71708
71844
  branchName,
71709
- errorMessage: void 0,
71845
+ error: void 0,
71710
71846
  isChecking: false
71711
71847
  } : prev
71712
71848
  );
@@ -71732,7 +71868,7 @@ const MediaWorkflowOverlay = () => {
71732
71868
  );
71733
71869
  }
71734
71870
  const dismissError = () => setState({ phase: "idle" });
71735
- return /* @__PURE__ */ React.createElement(Modal, { className: "flex" }, /* @__PURE__ */ React.createElement(PopupModal, { className: "w-auto" }, /* @__PURE__ */ React.createElement(ModalHeader, { close: dismissError }, "Branch creation failed"), /* @__PURE__ */ React.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1 text-red-700 py-2 px-3 bg-red-50 border border-red-200 rounded max-w-sm" }, /* @__PURE__ */ React.createElement(CircleAlert, { className: "w-5 h-auto text-red-400 flex-shrink-0" }), /* @__PURE__ */ React.createElement("span", { className: "text-sm" }, /* @__PURE__ */ React.createElement("b", null, "Error:"), " ", state.message)))));
71871
+ return /* @__PURE__ */ React.createElement(Modal, { className: "flex" }, /* @__PURE__ */ React.createElement(PopupModal, { className: "w-auto" }, /* @__PURE__ */ React.createElement(ModalHeader, { close: dismissError }, "Branch creation failed"), /* @__PURE__ */ React.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React.createElement("div", { className: "max-w-sm" }, /* @__PURE__ */ React.createElement(EditorialWorkflowErrorBox, { error: state.error })))));
71736
71872
  };
71737
71873
  function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
71738
71874
  const endTime = (/* @__PURE__ */ new Date()).getTime() + pollTimeout;
@@ -71901,6 +72037,7 @@ async function authenticate(clientId, identityApiUrl, frontendUrl) {
71901
72037
  const DefaultSessionProvider = ({
71902
72038
  children
71903
72039
  }) => /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, children);
72040
+ const bearerToken = (token) => (token == null ? void 0 : token.id_token) ?? (token == null ? void 0 : token.access_token) ?? null;
71904
72041
  class AbstractAuthProvider {
71905
72042
  constructor() {
71906
72043
  /**
@@ -71936,8 +72073,7 @@ class AbstractAuthProvider {
71936
72073
  return res;
71937
72074
  }
71938
72075
  async getAccessToken() {
71939
- const token = await this.getToken();
71940
- return (token == null ? void 0 : token.access_token) ?? (token == null ? void 0 : token.id_token) ?? null;
72076
+ return bearerToken(await this.getToken());
71941
72077
  }
71942
72078
  async authorize(context) {
71943
72079
  return this.getToken();
@@ -72342,7 +72478,7 @@ mutation addPendingDocumentMutation(
72342
72478
  const headers = {
72343
72479
  "Content-Type": "application/json"
72344
72480
  };
72345
- const accessToken = (token == null ? void 0 : token.id_token) ?? (token == null ? void 0 : token.access_token);
72481
+ const accessToken = bearerToken(token);
72346
72482
  if (accessToken) {
72347
72483
  headers["Authorization"] = "Bearer " + accessToken;
72348
72484
  }
@@ -72688,6 +72824,9 @@ mutation addPendingDocumentMutation(
72688
72824
  statusResponseBody.message || "Editorial workflow failed"
72689
72825
  );
72690
72826
  error.errorCode = statusResponseBody.errorCode || "WORKFLOW_FAILED";
72827
+ if (statusResponseBody.file) {
72828
+ error.file = statusResponseBody.file;
72829
+ }
72691
72830
  throw error;
72692
72831
  }
72693
72832
  if (statusResponse.status === 200) {
@@ -72728,6 +72867,9 @@ mutation addPendingDocumentMutation(
72728
72867
  if (responseBody == null ? void 0 : responseBody.conflictingBranch) {
72729
72868
  error.conflictingBranch = responseBody.conflictingBranch;
72730
72869
  }
72870
+ if (responseBody == null ? void 0 : responseBody.file) {
72871
+ error.file = responseBody.file;
72872
+ }
72731
72873
  return error;
72732
72874
  }
72733
72875
  async postEditorialWorkflow(url, body, errorFallback) {
@@ -73902,7 +74044,7 @@ const Loader = (props) => {
73902
74044
  ))
73903
74045
  ),
73904
74046
  /* @__PURE__ */ React__default.createElement(
73905
- "p",
74047
+ LoadingMessage,
73906
74048
  {
73907
74049
  style: {
73908
74050
  fontSize: "18px",
@@ -73912,8 +74054,7 @@ const Loader = (props) => {
73912
74054
  fontFamily: "'Inter', sans-serif",
73913
74055
  fontWeight: "normal"
73914
74056
  }
73915
- },
73916
- "Please wait, Tina is loading data..."
74057
+ }
73917
74058
  )
73918
74059
  )
73919
74060
  ), props.children);
@@ -74214,7 +74355,7 @@ const LoadingPage = () => /* @__PURE__ */ React__default.createElement(React__de
74214
74355
  ))
74215
74356
  ),
74216
74357
  /* @__PURE__ */ React__default.createElement(
74217
- "p",
74358
+ LoadingMessage,
74218
74359
  {
74219
74360
  style: {
74220
74361
  fontSize: "16px",
@@ -74224,8 +74365,7 @@ const LoadingPage = () => /* @__PURE__ */ React__default.createElement(React__de
74224
74365
  fontFamily: "'Inter', sans-serif",
74225
74366
  fontWeight: "normal"
74226
74367
  }
74227
- },
74228
- "Please wait, Tina is loading data..."
74368
+ }
74229
74369
  )
74230
74370
  )
74231
74371
  ));
@@ -76172,6 +76312,24 @@ const ScreenPage = () => {
76172
76312
  } })));
76173
76313
  });
76174
76314
  };
76315
+ function resolvePreviewPath(splat, baseOrigin = typeof window !== "undefined" ? window.location.origin : "") {
76316
+ if (!baseOrigin || !splat) {
76317
+ return { path: "/", offOrigin: false };
76318
+ }
76319
+ try {
76320
+ const resolved = new URL(`/${splat}`, baseOrigin);
76321
+ if (resolved.origin !== baseOrigin) {
76322
+ return { path: "/", offOrigin: true };
76323
+ }
76324
+ const path = `${resolved.pathname}${resolved.search}${resolved.hash}`;
76325
+ if (new URL(path, baseOrigin).origin !== baseOrigin) {
76326
+ return { path: "/", offOrigin: true };
76327
+ }
76328
+ return { path, offOrigin: false };
76329
+ } catch {
76330
+ return { path: "/", offOrigin: true };
76331
+ }
76332
+ }
76175
76333
  const TROUBLESHOOTING_URL = "https://tina.io/docs/tinacloud/troubleshooting";
76176
76334
  const ErrorModalContent = (props) => {
76177
76335
  const { title, message } = props;
@@ -76251,12 +76409,23 @@ const SetPreviewFlag = ({
76251
76409
  return null;
76252
76410
  };
76253
76411
  const PreviewInner = ({ preview, config }) => {
76412
+ const cms = useCMS$1();
76254
76413
  const params = useParams();
76255
76414
  const navigate = useNavigate();
76256
- const [url, setURL] = React__default.useState(`/${params["*"]}`);
76415
+ const splat = params["*"];
76416
+ const { path: paramURL, offOrigin } = resolvePreviewPath(splat);
76417
+ const [url, setURL] = React__default.useState(paramURL);
76257
76418
  const [reportedURL, setReportedURL] = useState(null);
76258
76419
  const ref = React__default.useRef(null);
76259
- const paramURL = `/${params["*"]}`;
76420
+ React__default.useEffect(() => {
76421
+ if (!offOrigin) {
76422
+ return;
76423
+ }
76424
+ cms.alerts.warn(
76425
+ "This preview link points to a different site, so it was not opened."
76426
+ );
76427
+ navigate(`/~${paramURL}`, { replace: true });
76428
+ }, [splat, offOrigin]);
76260
76429
  React__default.useEffect(() => {
76261
76430
  if (reportedURL !== paramURL && paramURL) {
76262
76431
  setURL(paramURL);
@@ -0,0 +1,2 @@
1
+ import type { TokenObject } from '@tinacms/schema-tools';
2
+ export declare const bearerToken: (token: TokenObject | null | undefined) => string;