tinacms 3.14.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.
@@ -0,0 +1 @@
1
+ export * from './unifiedClient';
@@ -0,0 +1,175 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ class AsyncLock {
5
+ constructor() {
6
+ __publicField(this, "queues", /* @__PURE__ */ new Map());
7
+ }
8
+ acquire(key, fn) {
9
+ const prev = this.queues.get(key) ?? Promise.resolve();
10
+ const next = prev.then(fn);
11
+ this.queues.set(
12
+ key,
13
+ next.then(
14
+ () => void 0,
15
+ () => void 0
16
+ )
17
+ );
18
+ return next;
19
+ }
20
+ }
21
+ const TINA_HOST = "content.tinajs.io";
22
+ function replaceGithubPathSplit(url, replacement) {
23
+ const parts = url.split("github/");
24
+ if (parts.length > 1 && replacement) {
25
+ return parts[0] + "github/" + replacement;
26
+ } else {
27
+ return url;
28
+ }
29
+ }
30
+ function isEdgeRuntimeWithoutFs() {
31
+ if (typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers") {
32
+ return true;
33
+ }
34
+ if (typeof globalThis.EdgeRuntime !== "undefined") {
35
+ return true;
36
+ }
37
+ return false;
38
+ }
39
+ class TinaClient {
40
+ constructor({
41
+ token,
42
+ url,
43
+ queries,
44
+ errorPolicy,
45
+ cacheDir,
46
+ cache
47
+ }) {
48
+ __publicField(this, "apiUrl");
49
+ __publicField(this, "readonlyToken");
50
+ __publicField(this, "queries");
51
+ __publicField(this, "errorPolicy");
52
+ __publicField(this, "initialized", false);
53
+ __publicField(this, "cacheLock");
54
+ __publicField(this, "cacheDir");
55
+ __publicField(this, "cache");
56
+ __publicField(this, "cacheEnabled");
57
+ this.apiUrl = url;
58
+ this.readonlyToken = token == null ? void 0 : token.trim();
59
+ this.queries = queries(this);
60
+ this.errorPolicy = errorPolicy || "throw";
61
+ this.cacheDir = cacheDir || "";
62
+ this.cacheEnabled = cache !== false;
63
+ }
64
+ async init() {
65
+ if (this.initialized) {
66
+ return;
67
+ }
68
+ try {
69
+ if (this.cacheEnabled && this.cacheDir && typeof window === "undefined" && !isEdgeRuntimeWithoutFs()) {
70
+ this.cache = await this.createCache(this.cacheDir);
71
+ if (this.cache) {
72
+ this.cacheLock = new AsyncLock();
73
+ }
74
+ }
75
+ } catch (e) {
76
+ console.error(e);
77
+ }
78
+ this.initialized = true;
79
+ }
80
+ async createCache(_dir) {
81
+ return null;
82
+ }
83
+ async request({ errorPolicy, ...args }, options) {
84
+ var _a;
85
+ await this.init();
86
+ const errorPolicyDefined = errorPolicy || this.errorPolicy;
87
+ const headers = new Headers();
88
+ if (this.readonlyToken) {
89
+ headers.append("X-API-KEY", this.readonlyToken);
90
+ }
91
+ headers.append("Content-Type", "application/json");
92
+ if (options == null ? void 0 : options.fetchOptions) {
93
+ if ((_a = options == null ? void 0 : options.fetchOptions) == null ? void 0 : _a.headers) {
94
+ Object.entries(options.fetchOptions.headers).forEach(([key2, value]) => {
95
+ headers.append(key2, value);
96
+ });
97
+ }
98
+ }
99
+ const { headers: _, ...providedFetchOptions } = (options == null ? void 0 : options.fetchOptions) || {};
100
+ const bodyString = JSON.stringify({
101
+ query: args.query,
102
+ variables: (args == null ? void 0 : args.variables) || {}
103
+ });
104
+ const optionsObject = {
105
+ method: "POST",
106
+ headers,
107
+ body: bodyString,
108
+ redirect: "follow",
109
+ ...providedFetchOptions
110
+ };
111
+ const draftBranch = headers.get("x-branch");
112
+ const url = replaceGithubPathSplit((args == null ? void 0 : args.url) || this.apiUrl, draftBranch);
113
+ let key = "";
114
+ let result;
115
+ if (this.cache) {
116
+ key = this.cache.makeKey(bodyString);
117
+ await this.cacheLock.acquire(key, async () => {
118
+ result = await this.cache.get(key);
119
+ if (!result) {
120
+ result = await requestFromServer(
121
+ url,
122
+ args.query,
123
+ optionsObject,
124
+ errorPolicyDefined
125
+ );
126
+ await this.cache.set(key, result);
127
+ }
128
+ });
129
+ } else {
130
+ result = await requestFromServer(
131
+ url,
132
+ args.query,
133
+ optionsObject,
134
+ errorPolicyDefined
135
+ );
136
+ }
137
+ return result;
138
+ }
139
+ }
140
+ async function requestFromServer(url, query, optionsObject, errorPolicyDefined) {
141
+ const res = await fetch(url, optionsObject);
142
+ if (!res.ok) {
143
+ let additionalInfo = "";
144
+ if (res.status === 401) {
145
+ additionalInfo = "Please check that your client ID, URL and read only token are configured properly.";
146
+ }
147
+ throw new Error(
148
+ `Server responded with status code ${res.status}, ${res.statusText}. ${additionalInfo ? additionalInfo : ""} Please see our FAQ for more information: https://tina.io/docs/r/FAQ/`
149
+ );
150
+ }
151
+ const json = await res.json();
152
+ if (json.errors && errorPolicyDefined === "throw") {
153
+ throw new Error(
154
+ `Unable to fetch, please see our FAQ for more information: https://tina.io/docs/r/FAQ/
155
+ Errors:
156
+ ${json.errors.map((error) => error.message).join("\n")}`
157
+ );
158
+ }
159
+ const result = {
160
+ data: json == null ? void 0 : json.data,
161
+ errors: (json == null ? void 0 : json.errors) || null,
162
+ query
163
+ };
164
+ return result;
165
+ }
166
+ function createClient(args) {
167
+ const client = new TinaClient(args);
168
+ return client;
169
+ }
170
+ export {
171
+ AsyncLock,
172
+ TINA_HOST,
173
+ TinaClient,
174
+ createClient
175
+ };
package/dist/client.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- /**
2
-
3
- */
4
1
  export * from './unifiedClient';
2
+ import { TinaClient as BaseTinaClient } from './unifiedClient';
3
+ import type { TinaClientArgs } from './unifiedClient';
4
+ export declare class TinaClient<GenQueries> extends BaseTinaClient<GenQueries> {
5
+ protected createCache(dir: string): Promise<import("./cache").Cache>;
6
+ }
7
+ export declare function createClient<GenQueries>(args: TinaClientArgs<GenQueries>): TinaClient<GenQueries>;
package/dist/client.js CHANGED
@@ -1,125 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __esm = (fn, res, err) => function __init() {
4
- if (err) throw err[0];
5
- try {
6
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
- } catch (e) {
8
- throw err = [e], e;
9
- }
10
- };
11
- var __export = (target, all) => {
12
- for (var name in all)
13
- __defProp(target, name, { get: all[name], enumerable: true });
14
- };
15
-
16
- // src/cache/node-cache.ts
17
- var node_cache_exports = {};
18
- __export(node_cache_exports, {
19
- NodeCache: () => NodeCache,
20
- makeCacheDir: () => makeCacheDir
21
- });
22
- var resolveModule, getRootPath, makeCacheDir, NodeCache;
23
- var init_node_cache = __esm({
24
- "src/cache/node-cache.ts"() {
25
- resolveModule = (mod) => {
26
- if (mod && typeof mod === "object" && "default" in mod && mod.default) {
27
- return mod.default;
28
- }
29
- return mod;
30
- };
31
- getRootPath = (pathParts, pathArg) => {
32
- if (pathParts.length === 0) return null;
33
- const isWindows = pathArg.sep === "\\";
34
- const root = pathParts[0];
35
- return isWindows ? `${root}${pathArg.sep}` : `${pathArg.sep}${root}`;
36
- };
37
- makeCacheDir = (dir, fsArg, pathArg, osArg) => {
38
- const normalizedDir = pathArg.normalize(dir);
39
- const pathParts = normalizedDir.split(pathArg.sep).filter(Boolean);
40
- const cacheHash = pathParts[pathParts.length - 1];
41
- const rootPath = getRootPath(pathParts, pathArg);
42
- const rootExists = rootPath && fsArg.existsSync(rootPath);
43
- const cacheDir = rootExists ? normalizedDir : pathArg.join(osArg.tmpdir(), cacheHash);
44
- try {
45
- fsArg.mkdirSync(cacheDir, { recursive: true });
46
- } catch (error) {
47
- console.warn(
48
- `Warning: Failed to create cache directory: ${error.message}. Caching will be disabled.`
49
- );
50
- return null;
51
- }
52
- return cacheDir;
53
- };
54
- NodeCache = async (dir) => {
55
- try {
56
- const [fsModule, pathModule, osModule, cryptoModule] = await Promise.all([
57
- import("node:fs"),
58
- import("node:path"),
59
- import("node:os"),
60
- import("node:crypto")
61
- ]);
62
- const fs = resolveModule(fsModule);
63
- const path = resolveModule(pathModule);
64
- const os = resolveModule(osModule);
65
- const crypto = resolveModule(cryptoModule);
66
- if (typeof path?.join !== "function") {
67
- console.warn(
68
- "Warning: Node.js path module not available. Caching will be disabled."
69
- );
70
- return null;
71
- }
72
- const cacheDir = makeCacheDir(dir, fs, path, os);
73
- if (cacheDir === null) {
74
- return null;
75
- }
76
- return {
77
- makeKey: (key) => {
78
- const input = key && key instanceof Object ? JSON.stringify(key) : key || "";
79
- return crypto.createHash("sha256").update(input).digest("hex");
80
- },
81
- get: async (key) => {
82
- let readValue;
83
- const cacheFilename = path.join(cacheDir, key);
84
- try {
85
- const data = await fs.promises.readFile(cacheFilename, "utf-8");
86
- readValue = JSON.parse(data);
87
- } catch (e) {
88
- if (e.code !== "ENOENT") {
89
- console.warn(
90
- `Warning: Failed to read cache file ${cacheFilename}: ${e.message}`
91
- );
92
- }
93
- }
94
- return readValue;
95
- },
96
- set: async (key, value) => {
97
- const cacheFilename = path.join(cacheDir, key);
98
- try {
99
- await fs.promises.writeFile(cacheFilename, JSON.stringify(value), {
100
- encoding: "utf-8",
101
- flag: "wx"
102
- });
103
- } catch (e) {
104
- if (e.code !== "EEXIST") {
105
- console.warn(
106
- `Warning: Failed to write cache file ${cacheFilename}: ${e.message}`
107
- );
108
- }
109
- }
110
- }
111
- };
112
- } catch (e) {
113
- console.warn(
114
- "Warning: Failed to initialize cache. Caching will be disabled.",
115
- e.message
116
- );
117
- return null;
118
- }
119
- };
120
- }
121
- });
122
-
123
1
  // src/unifiedClient/asyncLock.ts
124
2
  var AsyncLock = class {
125
3
  queues = /* @__PURE__ */ new Map();
@@ -187,8 +65,7 @@ var TinaClient = class {
187
65
  }
188
66
  try {
189
67
  if (this.cacheEnabled && this.cacheDir && typeof window === "undefined" && !isEdgeRuntimeWithoutFs()) {
190
- const { NodeCache: NodeCache2 } = await Promise.resolve().then(() => (init_node_cache(), node_cache_exports));
191
- this.cache = await NodeCache2(this.cacheDir);
68
+ this.cache = await this.createCache(this.cacheDir);
192
69
  if (this.cache) {
193
70
  this.cacheLock = new AsyncLock();
194
71
  }
@@ -198,6 +75,9 @@ var TinaClient = class {
198
75
  }
199
76
  this.initialized = true;
200
77
  }
78
+ async createCache(_dir) {
79
+ return null;
80
+ }
201
81
  async request({ errorPolicy, ...args }, options) {
202
82
  await this.init();
203
83
  const errorPolicyDefined = errorPolicy || this.errorPolicy;
@@ -280,13 +160,116 @@ async function requestFromServer(url, query, optionsObject, errorPolicyDefined)
280
160
  };
281
161
  return result;
282
162
  }
163
+
164
+ // src/cache/node-cache.ts
165
+ var resolveModule = (mod) => {
166
+ if (mod && typeof mod === "object" && "default" in mod && mod.default) {
167
+ return mod.default;
168
+ }
169
+ return mod;
170
+ };
171
+ var getRootPath = (pathParts, pathArg) => {
172
+ if (pathParts.length === 0) return null;
173
+ const isWindows = pathArg.sep === "\\";
174
+ const root = pathParts[0];
175
+ return isWindows ? `${root}${pathArg.sep}` : `${pathArg.sep}${root}`;
176
+ };
177
+ var makeCacheDir = (dir, fsArg, pathArg, osArg) => {
178
+ const normalizedDir = pathArg.normalize(dir);
179
+ const pathParts = normalizedDir.split(pathArg.sep).filter(Boolean);
180
+ const cacheHash = pathParts[pathParts.length - 1];
181
+ const rootPath = getRootPath(pathParts, pathArg);
182
+ const rootExists = rootPath && fsArg.existsSync(rootPath);
183
+ const cacheDir = rootExists ? normalizedDir : pathArg.join(osArg.tmpdir(), cacheHash);
184
+ try {
185
+ fsArg.mkdirSync(cacheDir, { recursive: true });
186
+ } catch (error) {
187
+ console.warn(
188
+ `Warning: Failed to create cache directory: ${error.message}. Caching will be disabled.`
189
+ );
190
+ return null;
191
+ }
192
+ return cacheDir;
193
+ };
194
+ var NodeCache = async (dir) => {
195
+ try {
196
+ const [fsModule, pathModule, osModule, cryptoModule] = await Promise.all([
197
+ import("node:fs"),
198
+ import("node:path"),
199
+ import("node:os"),
200
+ import("node:crypto")
201
+ ]);
202
+ const fs = resolveModule(fsModule);
203
+ const path = resolveModule(pathModule);
204
+ const os = resolveModule(osModule);
205
+ const crypto = resolveModule(cryptoModule);
206
+ if (typeof path?.join !== "function") {
207
+ console.warn(
208
+ "Warning: Node.js path module not available. Caching will be disabled."
209
+ );
210
+ return null;
211
+ }
212
+ const cacheDir = makeCacheDir(dir, fs, path, os);
213
+ if (cacheDir === null) {
214
+ return null;
215
+ }
216
+ return {
217
+ makeKey: (key) => {
218
+ const input = key && key instanceof Object ? JSON.stringify(key) : key || "";
219
+ return crypto.createHash("sha256").update(input).digest("hex");
220
+ },
221
+ get: async (key) => {
222
+ let readValue;
223
+ const cacheFilename = path.join(cacheDir, key);
224
+ try {
225
+ const data = await fs.promises.readFile(cacheFilename, "utf-8");
226
+ readValue = JSON.parse(data);
227
+ } catch (e) {
228
+ if (e.code !== "ENOENT") {
229
+ console.warn(
230
+ `Warning: Failed to read cache file ${cacheFilename}: ${e.message}`
231
+ );
232
+ }
233
+ }
234
+ return readValue;
235
+ },
236
+ set: async (key, value) => {
237
+ const cacheFilename = path.join(cacheDir, key);
238
+ try {
239
+ await fs.promises.writeFile(cacheFilename, JSON.stringify(value), {
240
+ encoding: "utf-8",
241
+ flag: "wx"
242
+ });
243
+ } catch (e) {
244
+ if (e.code !== "EEXIST") {
245
+ console.warn(
246
+ `Warning: Failed to write cache file ${cacheFilename}: ${e.message}`
247
+ );
248
+ }
249
+ }
250
+ }
251
+ };
252
+ } catch (e) {
253
+ console.warn(
254
+ "Warning: Failed to initialize cache. Caching will be disabled.",
255
+ e.message
256
+ );
257
+ return null;
258
+ }
259
+ };
260
+
261
+ // src/client.ts
262
+ var TinaClient2 = class extends TinaClient {
263
+ createCache(dir) {
264
+ return NodeCache(dir);
265
+ }
266
+ };
283
267
  function createClient(args) {
284
- const client = new TinaClient(args);
285
- return client;
268
+ return new TinaClient2(args);
286
269
  }
287
270
  export {
288
271
  AsyncLock,
289
272
  TINA_HOST,
290
- TinaClient,
273
+ TinaClient2 as TinaClient,
291
274
  createClient
292
275
  };
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) {
@@ -14222,12 +14305,12 @@ const FormModal = ({ plugin, close: close2 }) => {
14222
14305
  const name = "tinacms";
14223
14306
  const type = "module";
14224
14307
  const typings = "dist/index.d.ts";
14225
- const version = "3.14.0";
14308
+ const version = "3.14.1";
14226
14309
  const main = "dist/index.js";
14227
14310
  const module$1 = "./dist/index.js";
14228
- 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" };
14229
14312
  const files = ["dist"];
14230
- 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"] };
14231
14314
  const license = "Apache-2.0";
14232
14315
  const scripts = { "types": "pnpm tsc && pnpm tsc-alias", "build": "tinacms-scripts build", "test": "vitest run", "test-watch": "vitest" };
14233
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:" };
@@ -17277,39 +17360,12 @@ const formatTime = (seconds) => {
17277
17360
  const secs = seconds % 60;
17278
17361
  return `${mins}:${secs.toString().padStart(2, "0")}`;
17279
17362
  };
17280
- const getEditorialWorkflowErrorMessage = (e) => {
17281
- 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 🦙";
17282
- const err = e;
17283
- if (err.errorCode) {
17284
- switch (err.errorCode) {
17285
- case EDITORIAL_WORKFLOW_ERROR.BRANCH_EXISTS:
17286
- errMessage = "A branch with this name already exists";
17287
- break;
17288
- case EDITORIAL_WORKFLOW_ERROR.BRANCH_HIERARCHY_CONFLICT:
17289
- errMessage = err.message || "Branch name conflicts with an existing branch";
17290
- break;
17291
- case EDITORIAL_WORKFLOW_ERROR.VALIDATION_FAILED:
17292
- errMessage = err.message || "Invalid branch name";
17293
- break;
17294
- default:
17295
- errMessage = err.message || errMessage;
17296
- break;
17297
- }
17298
- } else if (err.message) {
17299
- if (err.message.toLowerCase().includes(ERR_BRANCH_EXISTS)) {
17300
- errMessage = "A branch with this name already exists";
17301
- } else if (err.message.toLowerCase().includes(ERR_BRANCH_CONFLICT)) {
17302
- errMessage = err.message;
17303
- }
17304
- }
17305
- return errMessage;
17306
- };
17307
17363
  function useEditorialWorkflow() {
17308
17364
  const cms = useCMS$1();
17309
17365
  const tinaApi = cms.api.tina;
17310
17366
  const { setCurrentBranch } = useBranchData();
17311
17367
  const [isExecuting, setIsExecuting] = React.useState(false);
17312
- const [errorMessage, setErrorMessage] = React.useState("");
17368
+ const [error, setError] = React.useState(void 0);
17313
17369
  const [currentStep, setCurrentStep] = React.useState(0);
17314
17370
  const [elapsedTime, setElapsedTime] = React.useState(0);
17315
17371
  React.useEffect(() => {
@@ -17326,7 +17382,7 @@ function useEditorialWorkflow() {
17326
17382
  };
17327
17383
  }, [isExecuting, currentStep]);
17328
17384
  const reset = () => {
17329
- setErrorMessage("");
17385
+ setError(void 0);
17330
17386
  setIsExecuting(false);
17331
17387
  setCurrentStep(0);
17332
17388
  };
@@ -17352,7 +17408,7 @@ function useEditorialWorkflow() {
17352
17408
  );
17353
17409
  if (signal == null ? void 0 : signal.aborted) return { success: false };
17354
17410
  if (targetBranchExists) {
17355
- setErrorMessage(TARGET_BRANCH_EXISTS_ERROR);
17411
+ setError({ messageParts: plainMessage(TARGET_BRANCH_EXISTS_ERROR) });
17356
17412
  setIsExecuting(false);
17357
17413
  setCurrentStep(0);
17358
17414
  return { success: false, error: TARGET_BRANCH_EXISTS_ERROR };
@@ -17430,16 +17486,19 @@ function useEditorialWorkflow() {
17430
17486
  return { success: true };
17431
17487
  } catch (e) {
17432
17488
  console.error(e);
17433
- const errMessage = getEditorialWorkflowErrorMessage(e);
17434
- setErrorMessage(errMessage);
17489
+ const copy = getEditorialWorkflowError(
17490
+ e,
17491
+ collectionLabelResolver(cms.api.tina.schema)
17492
+ );
17493
+ setError(copy);
17435
17494
  setIsExecuting(false);
17436
17495
  setCurrentStep(0);
17437
- return { success: false, error: errMessage };
17496
+ return { success: false, error: messageText(copy.messageParts) };
17438
17497
  }
17439
17498
  };
17440
17499
  return {
17441
17500
  isExecuting,
17442
- errorMessage,
17501
+ error,
17443
17502
  currentStep,
17444
17503
  elapsedTime,
17445
17504
  executeWorkflow,
@@ -17556,7 +17615,7 @@ const CreateBranchModal = ({
17556
17615
  const branchGuardAbortRef = React.useRef(null);
17557
17616
  const {
17558
17617
  isExecuting,
17559
- errorMessage,
17618
+ error,
17560
17619
  currentStep,
17561
17620
  elapsedTime,
17562
17621
  executeWorkflow,
@@ -17598,7 +17657,7 @@ const CreateBranchModal = ({
17598
17657
  return;
17599
17658
  }
17600
17659
  setIsBranchGuardChecking(false);
17601
- const { success, error } = await executeWorkflow({
17660
+ const { success, error: error2 } = await executeWorkflow({
17602
17661
  branchName: targetBranch,
17603
17662
  baseBranch,
17604
17663
  path,
@@ -17616,7 +17675,7 @@ const CreateBranchModal = ({
17616
17675
  captureEvent(EditorialWorkflowSaveEvent, {
17617
17676
  choice: isDraft ? "draft" : "review",
17618
17677
  success,
17619
- error
17678
+ error: error2
17620
17679
  });
17621
17680
  if (success) {
17622
17681
  close2();
@@ -17640,7 +17699,7 @@ const CreateBranchModal = ({
17640
17699
  abortBranchGuard();
17641
17700
  close2();
17642
17701
  },
17643
- errorMessage,
17702
+ error,
17644
17703
  disabled: normalizedBranchName === "" || isBranchGuardChecking,
17645
17704
  onBranchNameChange: (value) => {
17646
17705
  abortBranchGuard();
@@ -17691,7 +17750,7 @@ const CreateBranchPromptModal = ({
17691
17750
  branchName,
17692
17751
  close: close2,
17693
17752
  disabled,
17694
- errorMessage,
17753
+ error,
17695
17754
  onBranchNameChange,
17696
17755
  onCreateBranch,
17697
17756
  onSaveToProtectedBranch,
@@ -17725,7 +17784,7 @@ const CreateBranchPromptModal = ({
17725
17784
  };
17726
17785
  const mainChoice = choices[main2] ?? choices.draft;
17727
17786
  const MainIcon = mainChoice.Icon;
17728
- 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(
17729
17788
  "a",
17730
17789
  {
17731
17790
  className: "underline text-tina-orange-dark font-medium",
@@ -17852,7 +17911,7 @@ const BranchDeletedModal = ({
17852
17911
  const baseBranch = tinaApi.protectedBranches[0] || cms.api.tina.schema.config.config.repoProvider.defaultBranchName || "main";
17853
17912
  const {
17854
17913
  isExecuting,
17855
- errorMessage,
17914
+ error,
17856
17915
  currentStep,
17857
17916
  elapsedTime,
17858
17917
  executeWorkflow,
@@ -17882,7 +17941,7 @@ const BranchDeletedModal = ({
17882
17941
  className: "w-4 h-4 mt-0.5 flex-shrink-0 text-yellow-600",
17883
17942
  style: { fill: "none" }
17884
17943
  }
17885
- ), /* @__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(
17886
17945
  PrefixedTextField,
17887
17946
  {
17888
17947
  name: "new-branch-name",
@@ -71665,12 +71724,15 @@ const MediaWorkflowOverlay = () => {
71665
71724
  const offComplete = cms.events.subscribe("media:workflow:complete", (event) => {
71666
71725
  setCurrentBranch(event.branchName);
71667
71726
  });
71668
- const offError = cms.events.subscribe(
71669
- "media:workflow:error",
71670
- (event) => {
71671
- setState({ phase: "error", message: event.message });
71672
- }
71673
- );
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
+ });
71674
71736
  const offFinish = cms.events.subscribe("media:workflow:finish", () => {
71675
71737
  setState({ phase: "idle" });
71676
71738
  });
@@ -71704,7 +71766,7 @@ const MediaWorkflowOverlay = () => {
71704
71766
  setState({
71705
71767
  ...confirmState,
71706
71768
  isChecking: true,
71707
- errorMessage: ""
71769
+ error: void 0
71708
71770
  });
71709
71771
  const { baseBranchExists, targetBranchExists } = await checkBranchGuard(
71710
71772
  cms.api.tina,
@@ -71722,7 +71784,11 @@ const MediaWorkflowOverlay = () => {
71722
71784
  ...confirmState,
71723
71785
  branchName,
71724
71786
  isChecking: false,
71725
- 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
+ }
71726
71792
  });
71727
71793
  return;
71728
71794
  }
@@ -71734,7 +71800,7 @@ const MediaWorkflowOverlay = () => {
71734
71800
  ...confirmState,
71735
71801
  branchName,
71736
71802
  isChecking: false,
71737
- errorMessage: TARGET_BRANCH_EXISTS_ERROR
71803
+ error: { messageParts: plainMessage(TARGET_BRANCH_EXISTS_ERROR) }
71738
71804
  });
71739
71805
  return;
71740
71806
  }
@@ -71750,7 +71816,10 @@ const MediaWorkflowOverlay = () => {
71750
71816
  ...confirmState,
71751
71817
  branchName,
71752
71818
  isChecking: false,
71753
- errorMessage: getEditorialWorkflowErrorMessage(e)
71819
+ error: getEditorialWorkflowError(
71820
+ e,
71821
+ collectionLabelResolver(cms.api.tina.schema)
71822
+ )
71754
71823
  });
71755
71824
  }
71756
71825
  };
@@ -71766,14 +71835,14 @@ const MediaWorkflowOverlay = () => {
71766
71835
  setState({ phase: "idle" });
71767
71836
  },
71768
71837
  disabled: normalizeBranchName(state.branchName) === "" || state.isChecking,
71769
- errorMessage: state.errorMessage,
71838
+ error: state.error,
71770
71839
  onBranchNameChange: (branchName) => {
71771
71840
  abortPreflight();
71772
71841
  setState(
71773
71842
  (prev) => prev.phase === "confirming" ? {
71774
71843
  ...prev,
71775
71844
  branchName,
71776
- errorMessage: void 0,
71845
+ error: void 0,
71777
71846
  isChecking: false
71778
71847
  } : prev
71779
71848
  );
@@ -71799,7 +71868,7 @@ const MediaWorkflowOverlay = () => {
71799
71868
  );
71800
71869
  }
71801
71870
  const dismissError = () => setState({ phase: "idle" });
71802
- 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 })))));
71803
71872
  };
71804
71873
  function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
71805
71874
  const endTime = (/* @__PURE__ */ new Date()).getTime() + pollTimeout;
@@ -71968,6 +72037,7 @@ async function authenticate(clientId, identityApiUrl, frontendUrl) {
71968
72037
  const DefaultSessionProvider = ({
71969
72038
  children
71970
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;
71971
72041
  class AbstractAuthProvider {
71972
72042
  constructor() {
71973
72043
  /**
@@ -72003,8 +72073,7 @@ class AbstractAuthProvider {
72003
72073
  return res;
72004
72074
  }
72005
72075
  async getAccessToken() {
72006
- const token = await this.getToken();
72007
- return (token == null ? void 0 : token.access_token) ?? (token == null ? void 0 : token.id_token) ?? null;
72076
+ return bearerToken(await this.getToken());
72008
72077
  }
72009
72078
  async authorize(context) {
72010
72079
  return this.getToken();
@@ -72409,7 +72478,7 @@ mutation addPendingDocumentMutation(
72409
72478
  const headers = {
72410
72479
  "Content-Type": "application/json"
72411
72480
  };
72412
- const accessToken = (token == null ? void 0 : token.id_token) ?? (token == null ? void 0 : token.access_token);
72481
+ const accessToken = bearerToken(token);
72413
72482
  if (accessToken) {
72414
72483
  headers["Authorization"] = "Bearer " + accessToken;
72415
72484
  }
@@ -72755,6 +72824,9 @@ mutation addPendingDocumentMutation(
72755
72824
  statusResponseBody.message || "Editorial workflow failed"
72756
72825
  );
72757
72826
  error.errorCode = statusResponseBody.errorCode || "WORKFLOW_FAILED";
72827
+ if (statusResponseBody.file) {
72828
+ error.file = statusResponseBody.file;
72829
+ }
72758
72830
  throw error;
72759
72831
  }
72760
72832
  if (statusResponse.status === 200) {
@@ -72795,6 +72867,9 @@ mutation addPendingDocumentMutation(
72795
72867
  if (responseBody == null ? void 0 : responseBody.conflictingBranch) {
72796
72868
  error.conflictingBranch = responseBody.conflictingBranch;
72797
72869
  }
72870
+ if (responseBody == null ? void 0 : responseBody.file) {
72871
+ error.file = responseBody.file;
72872
+ }
72798
72873
  return error;
72799
72874
  }
72800
72875
  async postEditorialWorkflow(url, body, errorFallback) {
@@ -0,0 +1,2 @@
1
+ import type { TokenObject } from '@tinacms/schema-tools';
2
+ export declare const bearerToken: (token: TokenObject | null | undefined) => string;
@@ -2,7 +2,7 @@ import { FC } from 'react';
2
2
  import * as React from 'react';
3
3
  import { Field } from '../../forms';
4
4
  export interface ToggleProps {
5
- name: string;
5
+ name?: string;
6
6
  input: any;
7
7
  field: ToggleFieldDefinition;
8
8
  disabled?: boolean;
@@ -10,7 +10,7 @@ export interface ToggleProps {
10
10
  onChange?: <T>(_event: React.ChangeEvent<T> | any) => void;
11
11
  onFocus?: <T>(_event?: React.FocusEvent<T>) => void;
12
12
  }
13
- interface ToggleFieldDefinition extends Field {
13
+ export interface ToggleFieldDefinition extends Field {
14
14
  component: 'toggle';
15
15
  toggleLabels?: boolean | FieldLabels;
16
16
  }
@@ -1,7 +1,7 @@
1
- export declare const ToggleField: (props: import("./wrap-field-with-meta").InputFieldType<import("..").ToggleProps, {}>) => import("react").JSX.Element;
1
+ export declare const ToggleField: (props: import("./wrap-field-with-meta").InputFieldType<import("..").ToggleProps, import("..").ToggleFieldDefinition>) => import("react").JSX.Element;
2
2
  export declare const ToggleFieldPlugin: {
3
3
  name: string;
4
4
  type: string;
5
- Component: (props: import("./wrap-field-with-meta").InputFieldType<import("..").ToggleProps, {}>) => import("react").JSX.Element;
5
+ Component: (props: import("./wrap-field-with-meta").InputFieldType<import("..").ToggleProps, import("..").ToggleFieldDefinition>) => import("react").JSX.Element;
6
6
  validate(value: any, values: any, meta: any, field: any): string;
7
7
  };
@@ -1,5 +1,6 @@
1
1
  import { Form } from '../forms';
2
2
  import * as React from 'react';
3
+ import { type EditorialWorkflowErrorCopy } from './editorial-workflow-utils';
3
4
  import { type SaveChoice } from './save-options';
4
5
  export declare const CreateBranchModal: ({ close, safeSubmit, path, values, crudType, tinaForm, onBaseBranchDeleted, }: {
5
6
  safeSubmit: (editorialWorkflowChoice?: SaveChoice) => Promise<void>;
@@ -10,11 +11,11 @@ export declare const CreateBranchModal: ({ close, safeSubmit, path, values, crud
10
11
  tinaForm?: Form;
11
12
  onBaseBranchDeleted?: () => void;
12
13
  }) => React.JSX.Element;
13
- export declare const CreateBranchPromptModal: ({ branchName, close, disabled, errorMessage, onBranchNameChange, onCreateBranch, onSaveToProtectedBranch, showSaveOptions, disablePublish, allowSaveToProtectedBranch, }: {
14
+ export declare const CreateBranchPromptModal: ({ branchName, close, disabled, error, onBranchNameChange, onCreateBranch, onSaveToProtectedBranch, showSaveOptions, disablePublish, allowSaveToProtectedBranch, }: {
14
15
  branchName: string;
15
16
  close: () => void;
16
17
  disabled?: boolean;
17
- errorMessage?: string;
18
+ error?: EditorialWorkflowErrorCopy;
18
19
  onBranchNameChange: (value: string) => void;
19
20
  onCreateBranch: (isDraft: boolean) => void;
20
21
  onSaveToProtectedBranch: () => void;
@@ -23,6 +23,7 @@ export declare const EDITORIAL_WORKFLOW_ERROR: {
23
23
  readonly BRANCH_EXISTS: "BRANCH_EXISTS";
24
24
  readonly BRANCH_HIERARCHY_CONFLICT: "BRANCH_HIERARCHY_CONFLICT";
25
25
  readonly VALIDATION_FAILED: "VALIDATION_FAILED";
26
+ readonly INDEXING_FAILED: "INDEXING_FAILED";
26
27
  };
27
28
  export type EditorialWorkflowError = (typeof EDITORIAL_WORKFLOW_ERROR)[keyof typeof EDITORIAL_WORKFLOW_ERROR];
28
29
  /**
@@ -31,7 +32,9 @@ export type EditorialWorkflowError = (typeof EDITORIAL_WORKFLOW_ERROR)[keyof typ
31
32
  export type EditorialWorkflowErrorDetails = Error & {
32
33
  errorCode?: string;
33
34
  conflictingBranch?: string;
35
+ file?: string;
34
36
  };
37
+ export declare const EDITORIAL_WORKFLOW_EVENT_LOG_DOCS_URL = "https://tina.io/docs/tinacloud/dashboard/event-log#common-causes";
35
38
  /**
36
39
  * Result from a completed editorial workflow operation
37
40
  */
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { EditorialWorkflowErrorCopy } from './editorial-workflow-utils';
3
+ export declare const EditorialWorkflowErrorBox: ({ error, }: {
4
+ error: EditorialWorkflowErrorCopy;
5
+ }) => React.JSX.Element;
@@ -1,3 +1,4 @@
1
+ import { type TinaSchema } from '@tinacms/schema-tools';
1
2
  export interface MediaWorkflowConfirmBranchEvent {
2
3
  type: 'media:workflow:confirm-branch';
3
4
  branchName: string;
@@ -24,3 +25,19 @@ export declare const checkBranchGuard: (tinaApi: {
24
25
  signal?: AbortSignal;
25
26
  }) => Promise<Record<string, boolean>>;
26
27
  }, baseBranch: string, targetBranch: string, debugLabel: string, signal?: AbortSignal) => Promise<BranchGuardResult>;
28
+ export interface EditorialWorkflowErrorLink {
29
+ url: string;
30
+ label: string;
31
+ }
32
+ export interface EditorialWorkflowMessagePart {
33
+ text: string;
34
+ emphasis?: boolean;
35
+ }
36
+ export interface EditorialWorkflowErrorCopy {
37
+ messageParts: EditorialWorkflowMessagePart[];
38
+ link?: EditorialWorkflowErrorLink;
39
+ }
40
+ export declare const plainMessage: (text: string) => EditorialWorkflowMessagePart[];
41
+ export declare const messageText: (parts: EditorialWorkflowMessagePart[]) => string;
42
+ export declare const collectionLabelResolver: (schema?: Pick<TinaSchema, "getCollectionByFullPath">) => (file: string) => string | undefined;
43
+ export declare const getEditorialWorkflowError: (e: unknown, resolveCollectionLabel?: (file: string) => string | undefined) => EditorialWorkflowErrorCopy;
@@ -1,4 +1,6 @@
1
1
  import { Form } from '../forms';
2
+ import { type EditorialWorkflowErrorCopy } from './editorial-workflow-utils';
3
+ export { collectionLabelResolver, getEditorialWorkflowError, plainMessage, } from './editorial-workflow-utils';
2
4
  export declare const WORKFLOW_STEPS: {
3
5
  id: number;
4
6
  name: string;
@@ -18,7 +20,7 @@ export interface ExecuteWorkflowOptions {
18
20
  }
19
21
  export interface UseEditorialWorkflowResult {
20
22
  isExecuting: boolean;
21
- errorMessage: string;
23
+ error?: EditorialWorkflowErrorCopy;
22
24
  currentStep: number;
23
25
  elapsedTime: number;
24
26
  /** Resolves with the outcome; on failure `error` holds the message. */
@@ -29,5 +31,4 @@ export interface UseEditorialWorkflowResult {
29
31
  /** Reset error/executing state so the form can be retried */
30
32
  reset: () => void;
31
33
  }
32
- export declare const getEditorialWorkflowErrorMessage: (e: unknown) => string;
33
34
  export declare function useEditorialWorkflow(): UseEditorialWorkflowResult;
@@ -41,6 +41,7 @@ export declare class TinaClient<GenQueries> {
41
41
  cacheEnabled: boolean;
42
42
  constructor({ token, url, queries, errorPolicy, cacheDir, cache, }: TinaClientArgs<GenQueries>);
43
43
  init(): Promise<void>;
44
+ protected createCache(_dir: string): Promise<Cache | null>;
44
45
  request<DataType extends Record<string, any> = any>({ errorPolicy, ...args }: TinaClientRequestArgs, options: {
45
46
  fetchOptions?: Parameters<typeof fetch>[1];
46
47
  }): Promise<{
package/package.json CHANGED
@@ -2,12 +2,16 @@
2
2
  "name": "tinacms",
3
3
  "type": "module",
4
4
  "typings": "dist/index.d.ts",
5
- "version": "3.14.0",
5
+ "version": "3.14.1",
6
6
  "main": "dist/index.js",
7
7
  "module": "./dist/index.js",
8
8
  "exports": {
9
9
  ".": "./dist/index.js",
10
- "./dist/client": "./dist/client.js",
10
+ "./dist/client": {
11
+ "types": "./dist/client.d.ts",
12
+ "browser": "./dist/client.browser.js",
13
+ "default": "./dist/client.js"
14
+ },
11
15
  "./react": "./dist/react.js",
12
16
  "./dist/react": "./dist/react.js",
13
17
  "./tina-field": "./dist/tina-field.js",
@@ -30,7 +34,8 @@
30
34
  {
31
35
  "name": "src/client.ts",
32
36
  "target": "node"
33
- }
37
+ },
38
+ "src/client.browser.ts"
34
39
  ]
35
40
  },
36
41
  "license": "Apache-2.0",
@@ -107,8 +112,8 @@
107
112
  "zod": "^3.24.2",
108
113
  "@tinacms/bridge": "^0.3.1",
109
114
  "@tinacms/mdx": "^2.2.3",
110
- "@tinacms/search": "^1.2.25",
111
- "@tinacms/schema-tools": "^2.10.0"
115
+ "@tinacms/schema-tools": "^2.10.0",
116
+ "@tinacms/search": "^1.2.25"
112
117
  },
113
118
  "devDependencies": {
114
119
  "@graphql-tools/utils": "^10.8.1",