tinacms 3.12.0 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/admin/components/GetDocument.d.ts +1 -1
  2. package/dist/admin/components/UnableToLoadModal.d.ts +4 -0
  3. package/dist/index.js +1798 -1045
  4. package/dist/internalClient/authProvider.d.ts +8 -0
  5. package/dist/internalClient/index.d.ts +14 -2
  6. package/dist/internalClient/types.d.ts +11 -0
  7. package/dist/rich-text/index.js +35 -35
  8. package/dist/rich-text/static.js +40 -37
  9. package/dist/toolkit/alerts/alerts.d.ts +7 -1
  10. package/dist/toolkit/components/media/media-manager.d.ts +3 -1
  11. package/dist/toolkit/components/media/utils.d.ts +12 -0
  12. package/dist/toolkit/core/cms.d.ts +2 -2
  13. package/dist/toolkit/core/errors.d.ts +1 -0
  14. package/dist/toolkit/core/index.d.ts +2 -0
  15. package/dist/toolkit/core/media-store.default.d.ts +41 -15
  16. package/dist/toolkit/core/media.d.ts +18 -0
  17. package/dist/toolkit/core/session-expired.d.ts +6 -0
  18. package/dist/toolkit/fields/components/image-upload/image-upload.d.ts +2 -0
  19. package/dist/toolkit/fields/plugins/blocks-field-plugin/block-selector-big.d.ts +2 -1
  20. package/dist/toolkit/fields/plugins/blocks-field-plugin/block-selector.d.ts +2 -1
  21. package/dist/toolkit/fields/plugins/field-props.d.ts +12 -1
  22. package/dist/toolkit/fields/plugins/group-list-field-plugin.d.ts +2 -1
  23. package/dist/toolkit/fields/plugins/image-field-plugin.d.ts +2 -0
  24. package/dist/toolkit/fields/plugins/mdx-field-plugin/index.d.ts +5 -1
  25. package/dist/toolkit/fields/plugins/mdx-field-plugin/plate/plugins/create-html-block/index.d.ts +2 -2
  26. package/dist/toolkit/form-builder/create-branch-modal.d.ts +2 -1
  27. package/dist/toolkit/form-builder/editorial-workflow-utils.d.ts +2 -0
  28. package/dist/toolkit/index.d.ts +1 -1
  29. package/dist/toolkit/plugin-branch-switcher/branch-switcher-legacy.d.ts +1 -1
  30. package/dist/toolkit/plugin-branch-switcher/branch-switcher.d.ts +6 -2
  31. package/dist/utils/branch-name.d.ts +3 -0
  32. package/package.json +9 -10
  33. package/dist/toolkit/plugin-branch-switcher/format-branch-name.d.ts +0 -8
@@ -3,6 +3,12 @@ type Input = Parameters<AuthProvider['fetchWithToken']>[0];
3
3
  type Init = Parameters<AuthProvider['fetchWithToken']>[1];
4
4
  type FetchReturn = ReturnType<AuthProvider['fetchWithToken']>;
5
5
  export declare abstract class AbstractAuthProvider implements AuthProvider {
6
+ /**
7
+ * Turns a tokened 401 into the auth wall re-arming. The Client assigns this
8
+ * automatically; AbstractAuthProvider.fetchWithToken invokes it. A provider
9
+ * that implements its own fetchWithToken must invoke it itself.
10
+ */
11
+ sessionExpiredListener?: () => void;
6
12
  /**
7
13
  * Wraps the normal fetch function with same API but adds the authorization header token.
8
14
  *
@@ -13,6 +19,7 @@ export declare abstract class AbstractAuthProvider implements AuthProvider {
13
19
  * @param init fetch function init
14
20
  */
15
21
  fetchWithToken(input: Input, init: Init): FetchReturn;
22
+ getAccessToken(): Promise<string | null>;
16
23
  authorize(context?: any): Promise<any>;
17
24
  isAuthorized(context?: any): Promise<boolean>;
18
25
  isAuthenticated(): Promise<boolean>;
@@ -33,6 +40,7 @@ export declare class TinaCloudAuthProvider extends AbstractAuthProvider {
33
40
  identityApiUrl: string;
34
41
  frontendUrl: string;
35
42
  token: TokenObject;
43
+ hasWarnedNoSession: boolean;
36
44
  setToken: (_token: TokenObject | null) => void;
37
45
  getToken: () => Promise<TokenObject>;
38
46
  constructor({ clientId, identityApiUrl, tokenStorage, frontendUrl, ...options }: {
@@ -4,7 +4,7 @@ import { AuthProvider, Schema, TinaSchema, TokenObject } from '@tinacms/schema-t
4
4
  import { FuzzySearchOptions, IndexableDocument, SearchClient, SearchOptions, SearchQueryResponse } from '@tinacms/search/index-client';
5
5
  import gql from 'graphql-tag';
6
6
  import { EditorialWorkflowResult } from '../toolkit/form-builder/editorial-workflow-constants';
7
- import { TinaCloudProject } from './types';
7
+ import { AuthenticatedUser, TinaCloudProject } from './types';
8
8
  export * from './authProvider';
9
9
  interface TinaSearchConfig {
10
10
  stopwordLanguages?: string[];
@@ -59,7 +59,14 @@ export declare class Client {
59
59
  events: EventBus;
60
60
  protectedBranches: string[];
61
61
  usingEditorialWorkflow: boolean;
62
+ user?: AuthenticatedUser | boolean;
62
63
  constructor({ tokenStorage, ...options }: ServerOptions);
64
+ /**
65
+ * Every provider swap must come through here: the listener is what turns a
66
+ * REST 401 into the auth wall re-arming, and a bare field assignment would
67
+ * silently drop it.
68
+ */
69
+ protected adoptAuthProvider(provider: AuthProvider): AuthProvider;
63
70
  get isLocalMode(): boolean;
64
71
  get isCustomContentApi(): boolean;
65
72
  setBranch(branchName: string): void;
@@ -190,12 +197,17 @@ export declare class Client {
190
197
  message?: string;
191
198
  }) => void;
192
199
  }): Promise<EditorialWorkflowResult>;
200
+ /**
201
+ * The server normalises `branchName`, so follow-up calls must use the
202
+ * `branchName` from the response rather than the one they sent.
203
+ */
193
204
  startMediaEditorialWorkflow(options: {
194
205
  branchName: string;
195
206
  baseBranch: string;
196
207
  prTitle?: string;
197
- operation: 'upload' | 'delete';
208
+ operation: 'upload' | 'delete' | 'rename';
198
209
  repoPath: string;
210
+ targetRepoPath?: string;
199
211
  }): Promise<{
200
212
  branchName: string;
201
213
  requestId: string;
@@ -50,3 +50,14 @@ export interface TinaMedia {
50
50
  publicFolder: string;
51
51
  mediaRoot: string;
52
52
  }
53
+ /**
54
+ * The TinaCloud user from `GET /v2/apps/{clientId}/currentUser`.
55
+ * `gitAuthoring` is absent on older TinaCloud deployments.
56
+ */
57
+ export interface AuthenticatedUser {
58
+ fullName?: string;
59
+ email?: string;
60
+ gitAuthoring?: {
61
+ mode: 'bot' | 'user';
62
+ };
63
+ }
@@ -84,7 +84,7 @@ const MemoNode = (props) => {
84
84
  return MNode;
85
85
  };
86
86
  const Node = ({ components, child }) => {
87
- var _a, _b, _c, _d, _e, _f, _g;
87
+ var _a, _b, _c, _d, _e, _f, _g, _h;
88
88
  const { children, ...props } = child;
89
89
  switch (child.type) {
90
90
  case "h1":
@@ -177,33 +177,33 @@ const Node = ({ components, child }) => {
177
177
  } else {
178
178
  if (child.name === "table") {
179
179
  const firstRowHeader = (_a = child.props) == null ? void 0 : _a.firstRowHeader;
180
- const rows2 = (firstRowHeader ? (_b = child.props) == null ? void 0 : _b.tableRows.filter((_, i) => i !== 0) : (_c = child.props) == null ? void 0 : _c.tableRows) || [];
180
+ const rows = (firstRowHeader ? (_b = child.props) == null ? void 0 : _b.tableRows.filter((_, i) => i !== 0) : (_c = child.props) == null ? void 0 : _c.tableRows) || [];
181
181
  const header = (_e = (_d = child.props) == null ? void 0 : _d.tableRows) == null ? void 0 : _e.at(0);
182
- const TableComponent2 = components["table"] || ((props2) => /* @__PURE__ */ React.createElement("table", { ...props2 }));
183
- const TrComponent2 = components["tr"] || ((props2) => /* @__PURE__ */ React.createElement("tr", { ...props2 }));
182
+ const TableComponent = components["table"] || ((props2) => /* @__PURE__ */ React.createElement("table", { ...props2 }));
183
+ const TrComponent = components["tr"] || ((props2) => /* @__PURE__ */ React.createElement("tr", { ...props2 }));
184
184
  const ThComponent = components["th"] || ((props2) => /* @__PURE__ */ React.createElement("th", { style: { textAlign: (props2 == null ? void 0 : props2.align) || "auto" }, ...props2 }));
185
- const TdComponent2 = components["td"] || ((props2) => /* @__PURE__ */ React.createElement("td", { style: { textAlign: (props2 == null ? void 0 : props2.align) || "auto" }, ...props2 }));
186
- const align2 = ((_f = child.props) == null ? void 0 : _f.align) || [];
187
- return /* @__PURE__ */ React.createElement(TableComponent2, null, firstRowHeader && /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement(TrComponent2, null, header.tableCells.map((c, i) => {
185
+ const TdComponent = components["td"] || ((props2) => /* @__PURE__ */ React.createElement("td", { style: { textAlign: (props2 == null ? void 0 : props2.align) || "auto" }, ...props2 }));
186
+ const align = ((_f = child.props) == null ? void 0 : _f.align) || [];
187
+ return /* @__PURE__ */ React.createElement(TableComponent, null, firstRowHeader && /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement(TrComponent, null, header.tableCells.map((c, i) => {
188
188
  return /* @__PURE__ */ React.createElement(
189
189
  TinaMarkdown,
190
190
  {
191
191
  key: i,
192
192
  components: {
193
- p: (props2) => /* @__PURE__ */ React.createElement(ThComponent, { align: align2[i], ...props2 })
193
+ p: (props2) => /* @__PURE__ */ React.createElement(ThComponent, { align: align[i], ...props2 })
194
194
  },
195
195
  content: c.value
196
196
  }
197
197
  );
198
- }))), /* @__PURE__ */ React.createElement("tbody", null, rows2.map((row, i) => {
198
+ }))), /* @__PURE__ */ React.createElement("tbody", null, rows.map((row, i) => {
199
199
  var _a2;
200
- return /* @__PURE__ */ React.createElement(TrComponent2, { key: i }, (_a2 = row == null ? void 0 : row.tableCells) == null ? void 0 : _a2.map((c, i2) => {
200
+ return /* @__PURE__ */ React.createElement(TrComponent, { key: i }, (_a2 = row == null ? void 0 : row.tableCells) == null ? void 0 : _a2.map((c, i2) => {
201
201
  return /* @__PURE__ */ React.createElement(
202
202
  TinaMarkdown,
203
203
  {
204
204
  key: i2,
205
205
  components: {
206
- p: (props2) => /* @__PURE__ */ React.createElement(TdComponent2, { align: align2[i2], ...props2 })
206
+ p: (props2) => /* @__PURE__ */ React.createElement(TdComponent, { align: align[i2], ...props2 })
207
207
  },
208
208
  content: c.value
209
209
  }
@@ -218,37 +218,37 @@ const Node = ({ components, child }) => {
218
218
  return /* @__PURE__ */ React.createElement("span", null, `No component provided for ${child.name}`);
219
219
  }
220
220
  }
221
- case "table":
221
+ case "table": {
222
222
  const rows = child.children || [];
223
- const TableComponent = components["table"] || ((props2) => /* @__PURE__ */ React.createElement("table", { style: { border: "1px solid #EDECF3" }, ...props2 }));
223
+ const [headerRow, ...bodyRows] = rows;
224
+ const TableComponent = components["table"] || ((props2) => /* @__PURE__ */ React.createElement("table", { ...props2 }));
224
225
  const TrComponent = components["tr"] || ((props2) => /* @__PURE__ */ React.createElement("tr", { ...props2 }));
225
- const TdComponent = components["td"] || ((props2) => /* @__PURE__ */ React.createElement(
226
- "td",
226
+ const ThComponent = components["th"] || (({ align: align2, ...props2 }) => /* @__PURE__ */ React.createElement("th", { style: { textAlign: align2 || "auto" }, ...props2 }));
227
+ const TdComponent = components["td"] || (({ align: align2, ...props2 }) => /* @__PURE__ */ React.createElement("td", { style: { textAlign: align2 || "auto" }, ...props2 }));
228
+ const align = ((_g = child.props) == null ? void 0 : _g.align) || [];
229
+ return /* @__PURE__ */ React.createElement(TableComponent, null, headerRow && /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement(TrComponent, null, (_h = headerRow.children) == null ? void 0 : _h.map((cell, i) => /* @__PURE__ */ React.createElement(
230
+ TinaMarkdown,
227
231
  {
228
- style: {
229
- textAlign: (props2 == null ? void 0 : props2.align) || "auto",
230
- border: "1px solid #EDECF3",
231
- padding: "0.25rem"
232
+ key: i,
233
+ components: {
234
+ p: (props2) => /* @__PURE__ */ React.createElement(ThComponent, { align: align[i], ...props2 })
232
235
  },
233
- ...props2
236
+ content: cell.children
234
237
  }
235
- ));
236
- const align = ((_g = child.props) == null ? void 0 : _g.align) || [];
237
- return /* @__PURE__ */ React.createElement(TableComponent, null, /* @__PURE__ */ React.createElement("tbody", null, rows.map((row, i) => {
238
+ )))), /* @__PURE__ */ React.createElement("tbody", null, bodyRows.map((row, i) => {
238
239
  var _a2;
239
- return /* @__PURE__ */ React.createElement(TrComponent, { key: i }, (_a2 = row.children) == null ? void 0 : _a2.map((cell, i2) => {
240
- return /* @__PURE__ */ React.createElement(
241
- TinaMarkdown,
242
- {
243
- key: i2,
244
- components: {
245
- p: (props2) => /* @__PURE__ */ React.createElement(TdComponent, { align: align[i2], ...props2 })
246
- },
247
- content: cell.children
248
- }
249
- );
250
- }));
240
+ return /* @__PURE__ */ React.createElement(TrComponent, { key: i }, (_a2 = row.children) == null ? void 0 : _a2.map((cell, i2) => /* @__PURE__ */ React.createElement(
241
+ TinaMarkdown,
242
+ {
243
+ key: i2,
244
+ components: {
245
+ p: (props2) => /* @__PURE__ */ React.createElement(TdComponent, { align: align[i2], ...props2 })
246
+ },
247
+ content: cell.children
248
+ }
249
+ )));
251
250
  })));
251
+ }
252
252
  case "maybe_mdx":
253
253
  return null;
254
254
  case "html":
@@ -47,7 +47,7 @@ const Node = ({
47
47
  components,
48
48
  child
49
49
  }) => {
50
- var _a, _b, _c, _d, _e, _f, _g;
50
+ var _a, _b, _c, _d, _e, _f, _g, _h;
51
51
  const { children, ...props } = child;
52
52
  switch (child.type) {
53
53
  case "h1":
@@ -140,38 +140,38 @@ const Node = ({
140
140
  } else {
141
141
  if (child.name === "table") {
142
142
  const firstRowHeader = (_a = child.props) == null ? void 0 : _a.firstRowHeader;
143
- const rows2 = (firstRowHeader ? (_b = child.props) == null ? void 0 : _b.tableRows.filter((_, i) => i !== 0) : (_c = child.props) == null ? void 0 : _c.tableRows) || [];
143
+ const rows = (firstRowHeader ? (_b = child.props) == null ? void 0 : _b.tableRows.filter((_, i) => i !== 0) : (_c = child.props) == null ? void 0 : _c.tableRows) || [];
144
144
  const header = (_e = (_d = child.props) == null ? void 0 : _d.tableRows) == null ? void 0 : _e.at(0);
145
- const TableComponent2 = (
145
+ const TableComponent = (
146
146
  //@ts-ignore Same issue with TinaMarkdown
147
147
  components["table"] || ((props2) => /* @__PURE__ */ React.createElement("table", { ...props2 }))
148
148
  );
149
- const TrComponent2 = components["tr"] || ((props2) => /* @__PURE__ */ React.createElement("tr", { ...props2 }));
149
+ const TrComponent = components["tr"] || ((props2) => /* @__PURE__ */ React.createElement("tr", { ...props2 }));
150
150
  const ThComponent = components["th"] || ((props2) => /* @__PURE__ */ React.createElement("th", { style: { textAlign: (props2 == null ? void 0 : props2.align) || "auto" }, ...props2 }));
151
- const TdComponent2 = components["td"] || ((props2) => /* @__PURE__ */ React.createElement("td", { style: { textAlign: (props2 == null ? void 0 : props2.align) || "auto" }, ...props2 }));
152
- const align2 = ((_f = child.props) == null ? void 0 : _f.align) || [];
151
+ const TdComponent = components["td"] || ((props2) => /* @__PURE__ */ React.createElement("td", { style: { textAlign: (props2 == null ? void 0 : props2.align) || "auto" }, ...props2 }));
152
+ const align = ((_f = child.props) == null ? void 0 : _f.align) || [];
153
153
  return (
154
154
  //@ts-ignore Same issue with TinaMarkdown
155
- /* @__PURE__ */ React.createElement(TableComponent2, null, firstRowHeader && /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement(TrComponent2, null, header.tableCells.map((c, i) => {
155
+ /* @__PURE__ */ React.createElement(TableComponent, null, firstRowHeader && /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement(TrComponent, null, header.tableCells.map((c, i) => {
156
156
  return /* @__PURE__ */ React.createElement(
157
157
  StaticTinaMarkdown,
158
158
  {
159
159
  key: i,
160
160
  components: {
161
- p: (props2) => /* @__PURE__ */ React.createElement(ThComponent, { align: align2[i], ...props2 })
161
+ p: (props2) => /* @__PURE__ */ React.createElement(ThComponent, { align: align[i], ...props2 })
162
162
  },
163
163
  content: c.value
164
164
  }
165
165
  );
166
- }))), /* @__PURE__ */ React.createElement("tbody", null, rows2.map((row, i) => {
166
+ }))), /* @__PURE__ */ React.createElement("tbody", null, rows.map((row, i) => {
167
167
  var _a2;
168
- return /* @__PURE__ */ React.createElement(TrComponent2, { key: i }, (_a2 = row == null ? void 0 : row.tableCells) == null ? void 0 : _a2.map((c, i2) => {
168
+ return /* @__PURE__ */ React.createElement(TrComponent, { key: i }, (_a2 = row == null ? void 0 : row.tableCells) == null ? void 0 : _a2.map((c, i2) => {
169
169
  return /* @__PURE__ */ React.createElement(
170
170
  StaticTinaMarkdown,
171
171
  {
172
172
  key: i2,
173
173
  components: {
174
- p: (props2) => /* @__PURE__ */ React.createElement(TdComponent2, { align: align2[i2], ...props2 })
174
+ p: (props2) => /* @__PURE__ */ React.createElement(TdComponent, { align: align[i2], ...props2 })
175
175
  },
176
176
  content: c.value
177
177
  }
@@ -187,40 +187,43 @@ const Node = ({
187
187
  return /* @__PURE__ */ React.createElement("span", null, `No component provided for ${child.name}`);
188
188
  }
189
189
  }
190
- case "table":
190
+ case "table": {
191
191
  const rows = child.children || [];
192
- const TableComponent = components["table"] || ((props2) => /* @__PURE__ */ React.createElement("table", { style: { border: "1px solid #EDECF3" }, ...props2 }));
192
+ const [headerRow, ...bodyRows] = rows;
193
+ const TableComponent = (
194
+ //@ts-ignore Same issue with TinaMarkdown
195
+ components["table"] || ((props2) => /* @__PURE__ */ React.createElement("table", { ...props2 }))
196
+ );
193
197
  const TrComponent = components["tr"] || ((props2) => /* @__PURE__ */ React.createElement("tr", { ...props2 }));
194
- const TdComponent = components["td"] || ((props2) => /* @__PURE__ */ React.createElement(
195
- "td",
196
- {
197
- style: {
198
- textAlign: (props2 == null ? void 0 : props2.align) || "auto",
199
- border: "1px solid #EDECF3",
200
- padding: "0.25rem"
201
- },
202
- ...props2
203
- }
204
- ));
198
+ const ThComponent = components["th"] || (({ align: align2, ...props2 }) => /* @__PURE__ */ React.createElement("th", { style: { textAlign: align2 || "auto" }, ...props2 }));
199
+ const TdComponent = components["td"] || (({ align: align2, ...props2 }) => /* @__PURE__ */ React.createElement("td", { style: { textAlign: align2 || "auto" }, ...props2 }));
205
200
  const align = ((_g = child.props) == null ? void 0 : _g.align) || [];
206
201
  return (
207
202
  //@ts-ignore Same issue with TinaMarkdown
208
- /* @__PURE__ */ React.createElement(TableComponent, null, /* @__PURE__ */ React.createElement("tbody", null, rows.map((row, i) => {
203
+ /* @__PURE__ */ React.createElement(TableComponent, null, headerRow && /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement(TrComponent, null, (_h = headerRow.children) == null ? void 0 : _h.map((cell, i) => /* @__PURE__ */ React.createElement(
204
+ StaticTinaMarkdown,
205
+ {
206
+ key: i,
207
+ components: {
208
+ p: (props2) => /* @__PURE__ */ React.createElement(ThComponent, { align: align[i], ...props2 })
209
+ },
210
+ content: cell.children
211
+ }
212
+ )))), /* @__PURE__ */ React.createElement("tbody", null, bodyRows.map((row, i) => {
209
213
  var _a2;
210
- return /* @__PURE__ */ React.createElement(TrComponent, { key: i }, (_a2 = row.children) == null ? void 0 : _a2.map((cell, i2) => {
211
- return /* @__PURE__ */ React.createElement(
212
- StaticTinaMarkdown,
213
- {
214
- key: i2,
215
- components: {
216
- p: (props2) => /* @__PURE__ */ React.createElement(TdComponent, { align: align[i2], ...props2 })
217
- },
218
- content: cell.children
219
- }
220
- );
221
- }));
214
+ return /* @__PURE__ */ React.createElement(TrComponent, { key: i }, (_a2 = row.children) == null ? void 0 : _a2.map((cell, i2) => /* @__PURE__ */ React.createElement(
215
+ StaticTinaMarkdown,
216
+ {
217
+ key: i2,
218
+ components: {
219
+ p: (props2) => /* @__PURE__ */ React.createElement(TdComponent, { align: align[i2], ...props2 })
220
+ },
221
+ content: cell.children
222
+ }
223
+ )));
222
224
  })))
223
225
  );
226
+ }
224
227
  case "maybe_mdx":
225
228
  return null;
226
229
  case "html":
@@ -1,5 +1,5 @@
1
+ import type { CMSEvent, Callback, EventBus } from '../core';
1
2
  import React from 'react';
2
- import type { EventBus, Callback, CMSEvent } from '../core';
3
3
  export interface EventsToAlerts {
4
4
  [key: string]: ToAlert | AlertArgs;
5
5
  }
@@ -16,6 +16,12 @@ export declare class Alerts {
16
16
  private mapEventToAlert;
17
17
  constructor(events: EventBus, map?: EventsToAlerts);
18
18
  setMap(eventsToAlerts: EventsToAlerts): void;
19
+ /**
20
+ * While suppressed (the window between a session expiring and the user
21
+ * signing back in), new alerts are dropped so nothing paints over the
22
+ * login modal. Alerts already showing are left alone.
23
+ */
24
+ private suppressed;
19
25
  add(level: AlertLevel, message: string | React.FunctionComponent, timeout?: number): () => void;
20
26
  dismiss(alert: Alert): void;
21
27
  subscribe(cb: Callback): () => void;
@@ -1,3 +1,4 @@
1
+ import { type MediaAccept } from '@tinacms/schema-tools';
1
2
  import { Media } from '../../core';
2
3
  import React from 'react';
3
4
  export interface MediaRequest {
@@ -5,6 +6,7 @@ export interface MediaRequest {
5
6
  onSelect?(_media: Media): void;
6
7
  close?(): void;
7
8
  allowDelete?: boolean;
9
+ accept?: MediaAccept | MediaAccept[];
8
10
  }
9
11
  export declare function MediaManager(): React.JSX.Element;
10
- export declare function MediaPicker({ allowDelete, onSelect, close, ...props }: MediaRequest): React.JSX.Element;
12
+ export declare function MediaPicker({ allowDelete, onSelect, close, accept: fieldAccept, ...props }: MediaRequest): React.JSX.Element;
@@ -1,5 +1,17 @@
1
+ import { type MediaExtension } from '@tinacms/schema-tools';
2
+ import type { Accept } from 'react-dropzone';
1
3
  export declare const DEFAULT_MEDIA_UPLOAD_TYPES: string;
2
4
  export declare const dropzoneAcceptFromString: (str: string) => any;
5
+ /**
6
+ * react-dropzone's `accept` shape for a field's resolved extensions, keyed by
7
+ * MIME type with the extensions as values. Bare extension keys would be
8
+ * dropped from the native file picker, which then offers every file and only
9
+ * rejects the choice afterwards.
10
+ *
11
+ * Returns undefined for an empty list so callers fall through to the global
12
+ * `media.accept`.
13
+ */
14
+ export declare const dropzoneAcceptFromExtensions: (extensions: MediaExtension[]) => Accept | undefined;
3
15
  export declare const isImage: (filename: string) => boolean;
4
16
  export declare const isVideo: (filename: string) => boolean;
5
17
  export declare const absoluteImgURL: (str: string) => string;
@@ -4,10 +4,10 @@
4
4
  *
5
5
  * @packageDocumentation
6
6
  */
7
- import { Plugin, PluginTypeManager } from './plugins';
8
7
  import { EventBus } from './event';
9
- import { MediaManager, MediaStore } from './media';
10
8
  import { Flags } from './flags';
9
+ import { MediaManager, MediaStore } from './media';
10
+ import { Plugin, PluginTypeManager } from './plugins';
11
11
  /**
12
12
  * A [[CMS]] is the core object of any content management system.
13
13
  *
@@ -0,0 +1 @@
1
+ export declare const isErrorNamed: (error: unknown, name: string) => boolean;
@@ -1,5 +1,7 @@
1
1
  export * from './cms';
2
+ export * from './errors';
2
3
  export * from './event';
4
+ export * from './session-expired';
3
5
  export * from './subscribable';
4
6
  export * from './plugins';
5
7
  export * from './media';
@@ -1,5 +1,10 @@
1
1
  import type { TinaCMS } from '../tina-cms';
2
2
  import { Media, MediaList, MediaListOptions, MediaStore, MediaUploadOptions } from './media';
3
+ /** Rejecting is how a rename that must resolve to a `Media` says "nothing happened". */
4
+ export declare class MediaRenameCancelled extends Error {
5
+ ERR_TYPE: string;
6
+ constructor();
7
+ }
3
8
  export declare class DummyMediaStore implements MediaStore {
4
9
  accept: string;
5
10
  persist(files: MediaUploadOptions[]): Promise<Media[]>;
@@ -34,10 +39,9 @@ export declare class TinaMediaStore implements MediaStore {
34
39
  private workflowBranchOverride;
35
40
  private mediaWorkflowInProgress;
36
41
  /**
37
- * Renaming is only implemented against the local dev server. This is an
38
- * instance property rather than a prototype method on purpose: the media
42
+ * An instance property rather than a prototype method on purpose: the media
39
43
  * manager decides whether to offer the action by checking whether the store
40
- * defines `rename`, so a cloud-backed instance must not carry one — a
44
+ * defines `rename`, so an instance that cannot rename must not carry one — a
41
45
  * prototype method would advertise support everywhere and surface an action
42
46
  * that always fails.
43
47
  */
@@ -55,21 +59,21 @@ export declare class TinaMediaStore implements MediaStore {
55
59
  isAuthenticated(): Promise<boolean>;
56
60
  accept: string;
57
61
  searchable: boolean;
62
+ /**
63
+ * The v2 cloud endpoint and the local dev server both filter by `ext` before
64
+ * paginating. `staticMedia` is a build-time snapshot with no such pass, and
65
+ * filtering a page client-side would leave a near-empty grid while matches
66
+ * sit further down — so a static store reports no support and the control
67
+ * stays hidden, the same way `searchable` is gated.
68
+ */
69
+ get extensionFilterable(): boolean;
58
70
  maxSize: number;
59
71
  /**
60
- * Returns the workflow branch override or current branch as a single-encoded
61
- * query-param value, or an empty string when no branch is set.
62
- *
63
- * `this.api.branch` is already URL-encoded by `Client.setBranch()`, so we
64
- * decode then re-encode here to defend against double-encoding when this
65
- * value is concatenated into a URL.
66
- *
67
- * `Client.setBranch()` runs the constructor's `options.branch` through
68
- * `encodeURIComponent` without a guard, so an unset `options.branch`
69
- * lands here as the literal string `"undefined"`. We treat that and the
70
- * empty case as no-branch so we don't send `?branch=undefined` to the
71
- * assets-api (which would route the call to a non-existent staging path).
72
+ * `Client.setBranch()` encodes an unset branch to the literal `"undefined"`,
73
+ * which the assets API would read as a real (non-existent) staging path.
72
74
  */
75
+ private currentBranch;
76
+ /** `this.api.branch` arrives encoded, so encode the decoded name once here. */
73
77
  private encodedBranchParam;
74
78
  private shortStableHash;
75
79
  private trimEdges;
@@ -122,6 +126,28 @@ export declare class TinaMediaStore implements MediaStore {
122
126
  * what the delete route receives.
123
127
  */
124
128
  private rename_local;
129
+ /**
130
+ * `from`/`to` are media-root-relative `directory/filename` paths. `to` is
131
+ * already sanitised by `previewRename` and is passed through untouched.
132
+ */
133
+ private rename_cloud;
134
+ /** `currentBranch()` is the workflow branch while one is active. */
135
+ private postCloudRename;
136
+ private renameCloudDirect;
137
+ /**
138
+ * Completion is the workflow status, not the rename request status: only the
139
+ * former waits for the branch, the media index and the pull request.
140
+ */
141
+ private renameCloudViaWorkflow;
142
+ private prepareRenameBranch;
143
+ private splitMediaPath;
144
+ /**
145
+ * The listing is the source of truth for `src` (staging path, per-stage CDN
146
+ * host) and thumbnails; the rename response is the fallback when the entry
147
+ * isn't on the first page.
148
+ */
149
+ private resolveRenamedMedia;
150
+ private toCloudRenameError;
125
151
  private toRenameError;
126
152
  persist(media: MediaUploadOptions[]): Promise<Media[]>;
127
153
  private genThumbnail;
@@ -1,3 +1,4 @@
1
+ import type { MediaAccept, MediaExtension } from '@tinacms/schema-tools';
1
2
  import { EventBus } from './event';
2
3
  /**
3
4
  * Represents an individual file in the MediaStore
@@ -90,6 +91,14 @@ export interface MediaStore {
90
91
  * @default false
91
92
  */
92
93
  searchable?: boolean;
94
+ /**
95
+ * Indicates that `list` honours the `ext` option. Stores that ignore it
96
+ * should leave this unset, so a field declaring `accept` falls back to
97
+ * showing everything rather than silently listing the wrong files.
98
+ *
99
+ * @default false
100
+ */
101
+ extensionFilterable?: boolean;
93
102
  /**
94
103
  * Converts a Media object to the value stored in a form field.
95
104
  *
@@ -112,6 +121,11 @@ export interface MediaListOptions {
112
121
  }[];
113
122
  filesOnly?: boolean;
114
123
  search?: string;
124
+ /**
125
+ * Restricts the listing to these file extensions. Resolved from categories
126
+ * before it reaches the store, so it is always concrete extensions here.
127
+ */
128
+ ext?: MediaExtension[];
115
129
  }
116
130
  /**
117
131
  * The response returned from listing media.
@@ -159,6 +173,10 @@ export interface SelectMediaOptions {
159
173
  allowDelete?: boolean;
160
174
  directory?: string;
161
175
  onSelect?(media: Media): void;
176
+ /**
177
+ * Narrows the picker to these file types, from a field's `accept`.
178
+ */
179
+ accept?: MediaAccept | MediaAccept[];
162
180
  }
163
181
  interface MediaListErrorConfig {
164
182
  title: string;
@@ -0,0 +1,6 @@
1
+ import type { EventBus } from './event';
2
+ export declare class SessionExpiredError extends Error {
3
+ constructor();
4
+ }
5
+ export declare const isSessionExpiredError: (error: unknown) => error is SessionExpiredError;
6
+ export declare const dispatchSessionExpired: (events: EventBus) => void;
@@ -1,6 +1,7 @@
1
1
  /**
2
2
 
3
3
  */
4
+ import { type MediaAccept } from '@tinacms/schema-tools';
4
5
  import * as React from 'react';
5
6
  interface ImageUploadProps {
6
7
  onDrop: (files: any, fileRejections: any) => Promise<void>;
@@ -9,6 +10,7 @@ interface ImageUploadProps {
9
10
  value?: string;
10
11
  src?: string;
11
12
  loading?: boolean;
13
+ accept?: MediaAccept | MediaAccept[];
12
14
  }
13
15
  export declare const StyledImage: ({ src }: {
14
16
  src: any;
@@ -1,9 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import type { BlockTemplate } from '.';
3
- export declare const BlockSelectorBig: ({ templates, addItem, label, }: {
3
+ export declare const BlockSelectorBig: ({ templates, addItem, label, fieldName, }: {
4
4
  templates: {
5
5
  [key: string]: BlockTemplate;
6
6
  };
7
7
  addItem: any;
8
8
  label: string | boolean;
9
+ fieldName?: string;
9
10
  }) => React.JSX.Element;
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import type { BlockTemplate } from '.';
3
- export declare const BlockSelector: ({ templates, addItem, }: {
3
+ export declare const BlockSelector: ({ templates, addItem, fieldName, }: {
4
4
  templates: {
5
5
  [key: string]: BlockTemplate;
6
6
  };
7
7
  addItem: any;
8
+ fieldName?: string;
8
9
  }) => React.JSX.Element;
@@ -1,6 +1,17 @@
1
- import { Field, FormApi } from '../../forms';
1
+ import { Field, Form, FormApi } from '../../forms';
2
2
  import { FieldRenderProps } from '../../form-builder';
3
+ /**
4
+ * Props every field plugin receives.
5
+ *
6
+ * `react-final-form` v6 declared `[otherProp: string]: any` on `FieldRenderProps`,
7
+ * so the extras `FieldsBuilder` passes down type-checked implicitly. v7 dropped
8
+ * that index signature, so they are declared here instead.
9
+ */
3
10
  export interface FieldProps<InputProps> extends FieldRenderProps<any, HTMLElement> {
4
11
  field: Field & InputProps;
5
12
  form: FormApi;
13
+ tinaForm: Form;
14
+ index?: number;
15
+ children?: React.ReactNode;
16
+ experimental_focusIntent?: boolean;
6
17
  }
@@ -48,9 +48,10 @@ export declare const ItemHeader: ({ isDragging, children, provider, ...props }:
48
48
  children: any | any[];
49
49
  provider: any;
50
50
  } & any) => React.JSX.Element;
51
- export declare const ItemDeleteButton: ({ onClick, disabled }: {
51
+ export declare const ItemDeleteButton: ({ onClick, disabled, fieldName, }: {
52
52
  onClick: any;
53
53
  disabled?: boolean;
54
+ fieldName?: string;
54
55
  }) => React.JSX.Element;
55
56
  export declare const DragHandle: ({ isDragging, dragHandleProps, }: {
56
57
  isDragging: boolean;
@@ -1,9 +1,11 @@
1
+ import { type MediaAccept } from '@tinacms/schema-tools';
1
2
  import * as React from 'react';
2
3
  import { InputProps } from '../components';
3
4
  interface ImageProps {
4
5
  path: string;
5
6
  uploadDir?(formValues: any): string;
6
7
  clearable?: boolean;
8
+ accept?: MediaAccept | MediaAccept[];
7
9
  }
8
10
  export declare const ImageField: (props: import("./wrap-field-with-meta").InputFieldType<InputProps, ImageProps>) => React.JSX.Element;
9
11
  export declare const ImageFieldPlugin: {