tinacms 1.5.23 → 1.5.25

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.mjs CHANGED
@@ -24,11 +24,12 @@ import * as pkg$1 from "react-color";
24
24
  import * as pkg from "color-string";
25
25
  import * as dropzone from "react-dropzone";
26
26
  import { EditContext, useEditState, setEditing } from "@tinacms/sharedctx";
27
- import { isHotkey } from "is-hotkey";
28
- import { computePosition, flip, shift } from "@floating-ui/dom";
27
+ import get from "lodash.get";
29
28
  import moment from "moment";
30
29
  import { formatDistanceToNow } from "date-fns";
31
30
  import { useWindowWidth } from "@react-hook/window-size";
31
+ import { isHotkey } from "is-hotkey";
32
+ import { computePosition, flip, shift } from "@floating-ui/dom";
32
33
  import { getIntrospectionQuery, buildClientSchema, print, parse as parse$3, buildSchema } from "graphql";
33
34
  import gql$1 from "graphql-tag";
34
35
  import { TinaSchema, addNamespaceToSchema, parseURL, resolveForm, normalizePath, validateSchema } from "@tinacms/schema-tools";
@@ -37,42 +38,6 @@ import * as yup from "yup";
37
38
  import { diff } from "@graphql-inspector/core";
38
39
  import { NavLink, useSearchParams, useNavigate, useLocation, useParams, Link, HashRouter, Routes, Route } from "react-router-dom";
39
40
  import { stringifyMDX } from "@tinacms/mdx";
40
- function popupWindow(url, title, window2, w, h) {
41
- const y = window2.top.outerHeight / 2 + window2.top.screenY - h / 2;
42
- const x = window2.top.outerWidth / 2 + window2.top.screenX - w / 2;
43
- return window2.open(
44
- url,
45
- title,
46
- "toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=no, width=" + w + ", height=" + h + ", top=" + y + ", left=" + x
47
- );
48
- }
49
- const TINA_LOGIN_EVENT = "tinaCloudLogin";
50
- const AUTH_TOKEN_KEY = "tinacms-auth";
51
- const authenticate = (clientId, frontendUrl) => {
52
- return new Promise((resolve) => {
53
- let authTab;
54
- window.addEventListener("message", function(e) {
55
- if (e.data.source === TINA_LOGIN_EVENT) {
56
- if (authTab) {
57
- authTab.close();
58
- }
59
- resolve({
60
- id_token: e.data.id_token,
61
- access_token: e.data.access_token,
62
- refresh_token: e.data.refresh_token
63
- });
64
- }
65
- });
66
- const origin = `${window.location.protocol}//${window.location.host}`;
67
- authTab = popupWindow(
68
- `${frontendUrl}/signin?clientId=${clientId}&origin=${origin}`,
69
- "_blank",
70
- window,
71
- 1e3,
72
- 700
73
- );
74
- });
75
- };
76
41
  const ModalProvider = ({ children }) => {
77
42
  const [modalRootContainerRef, setModalRootContainerRef] = useState(
78
43
  null
@@ -3093,6 +3058,9 @@ function IoMdClose(props) {
3093
3058
  function IoMdRefresh(props) {
3094
3059
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 512 512" }, "child": [{ "tag": "path", "attr": { "d": "M256 388c-72.597 0-132-59.405-132-132 0-72.601 59.403-132 132-132 36.3 0 69.299 15.4 92.406 39.601L278 234h154V80l-51.698 51.702C348.406 99.798 304.406 80 256 80c-96.797 0-176 79.203-176 176s78.094 176 176 176c81.045 0 148.287-54.134 169.401-128H378.85c-18.745 49.561-67.138 84-122.85 84z" } }] })(props);
3095
3060
  }
3061
+ function MdVpnKey(props) {
3062
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0z" } }, { "tag": "path", "attr": { "d": "M12.65 10A5.99 5.99 0 007 6c-3.31 0-6 2.69-6 6s2.69 6 6 6a5.99 5.99 0 005.65-4H17v4h4v-4h2v-4H12.65zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" } }] })(props);
3063
+ }
3096
3064
  function MdKeyboardArrowDown(props) {
3097
3065
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" } }] })(props);
3098
3066
  }
@@ -3154,14 +3122,14 @@ const useBranchData = () => {
3154
3122
  return branchData;
3155
3123
  };
3156
3124
  const textFieldClasses = "shadow-inner focus:shadow-outline focus:border-blue-500 focus:outline-none block text-base placeholder:text-gray-300 px-3 py-2 text-gray-600 w-full bg-white border border-gray-200 transition-all ease-out duration-150 focus:text-gray-900 rounded-md";
3157
- const disabledClasses = "opacity-50 pointer-events-none cursor-not-allowed";
3125
+ const disabledClasses$1 = "opacity-50 pointer-events-none cursor-not-allowed";
3158
3126
  const BaseTextField = React.forwardRef(({ className, disabled, ...rest }, ref) => {
3159
3127
  return /* @__PURE__ */ React.createElement(
3160
3128
  "input",
3161
3129
  {
3162
3130
  ref,
3163
3131
  type: "text",
3164
- className: `${textFieldClasses} ${disabled ? disabledClasses : ""} ${className}`,
3132
+ className: `${textFieldClasses} ${disabled ? disabledClasses$1 : ""} ${className}`,
3165
3133
  ...rest
3166
3134
  }
3167
3135
  );
@@ -3980,6 +3948,20 @@ function toProps(option) {
3980
3948
  return option;
3981
3949
  return { value: option, label: option };
3982
3950
  }
3951
+ const passwordFieldClasses = "shadow-inner focus:shadow-outline focus:border-blue-500 focus:outline-none block text-base placeholder:text-gray-300 px-3 py-2 text-gray-600 w-full bg-white border border-gray-200 transition-all ease-out duration-150 focus:text-gray-900 rounded-md";
3952
+ const disabledClasses = "opacity-50 pointer-events-none cursor-not-allowed";
3953
+ const errorClasses = "border-red-500 focus:border-red-500 focus:shadow-outline-red";
3954
+ const BasePasswordField = React.forwardRef(({ className, disabled, error, ...rest }, ref) => {
3955
+ return /* @__PURE__ */ React.createElement(
3956
+ "input",
3957
+ {
3958
+ ref,
3959
+ type: "password",
3960
+ className: `${passwordFieldClasses} ${disabled ? disabledClasses : ""} ${className} ${error ? errorClasses : ""}`,
3961
+ ...rest
3962
+ }
3963
+ );
3964
+ });
3983
3965
  const Group$1 = wrapFieldWithError(({ tinaForm, field }) => {
3984
3966
  const cms = useCMS$1();
3985
3967
  React.useState(false);
@@ -5066,9 +5048,19 @@ const TextField = wrapFieldsWithMeta(
5066
5048
  const TextFieldPlugin = {
5067
5049
  name: "text",
5068
5050
  Component: TextField,
5069
- validate(value, values, meta, field) {
5051
+ validate(value, allValues, meta, field) {
5052
+ var _a;
5070
5053
  if (field.required && !value)
5071
5054
  return "Required";
5055
+ if (field.uid) {
5056
+ const path = field.name.split(".");
5057
+ const fieldName = path[path.length - 1];
5058
+ const parent = path.slice(0, path.length - 2);
5059
+ const items = get(allValues, parent);
5060
+ if (((_a = items == null ? void 0 : items.filter((item) => item[fieldName] === value)) == null ? void 0 : _a.length) > 1) {
5061
+ return `Item with this unique id already exists`;
5062
+ }
5063
+ }
5072
5064
  },
5073
5065
  parse: parse$2
5074
5066
  };
@@ -5731,7 +5723,7 @@ var testPassiveEventSupport = function testPassiveEventSupport2() {
5731
5723
  }
5732
5724
  var passive = false;
5733
5725
  var options = Object.defineProperty({}, "passive", {
5734
- get: function get() {
5726
+ get: function get2() {
5735
5727
  passive = true;
5736
5728
  }
5737
5729
  });
@@ -6579,6 +6571,111 @@ const HiddenFieldPlugin = {
6579
6571
  Component: HiddenField,
6580
6572
  parse: parse$2
6581
6573
  };
6574
+ const PasswordMask = "********";
6575
+ const PasswordFieldComponent = wrapFieldsWithMeta(({ field, form, meta, input, children }) => {
6576
+ const ref1 = React.useRef(null);
6577
+ const ref2 = React.useRef(null);
6578
+ const [error, setError] = React.useState(false);
6579
+ const [password, setPassword] = React.useState();
6580
+ const [confirmPassword, setConfirmPassword] = React.useState();
6581
+ const [passwordChangeRequired, setPasswordChangeRequired] = React.useState(input.value.passwordChangeRequired);
6582
+ React.useEffect(() => {
6583
+ if (password) {
6584
+ if (password === confirmPassword) {
6585
+ setError(false);
6586
+ form.change(field.name, { value: password, passwordChangeRequired });
6587
+ } else {
6588
+ setError(true);
6589
+ form.change(field.name, void 0);
6590
+ }
6591
+ } else {
6592
+ setError(false);
6593
+ form.change(field.name, { passwordChangeRequired });
6594
+ }
6595
+ }, [password, confirmPassword, passwordChangeRequired]);
6596
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-row space-x-4" }, /* @__PURE__ */ React.createElement(
6597
+ BasePasswordField,
6598
+ {
6599
+ autoComplete: "off",
6600
+ value: password ?? PasswordMask,
6601
+ ref: ref1,
6602
+ disabled: (field == null ? void 0 : field.disabled) ?? false,
6603
+ error,
6604
+ placeholder: field.placeholder || "Password",
6605
+ onKeyDown: (_) => {
6606
+ if (password === void 0) {
6607
+ setPassword("");
6608
+ }
6609
+ if (confirmPassword === void 0) {
6610
+ setConfirmPassword("");
6611
+ }
6612
+ },
6613
+ onChange: (event) => {
6614
+ setPassword(event.target.value);
6615
+ }
6616
+ }
6617
+ ), /* @__PURE__ */ React.createElement(
6618
+ BasePasswordField,
6619
+ {
6620
+ autoComplete: "off",
6621
+ ref: ref2,
6622
+ value: confirmPassword ?? PasswordMask,
6623
+ disabled: (field == null ? void 0 : field.disabled) ?? false,
6624
+ error,
6625
+ placeholder: field.confirmPlaceholder || "Confirm Password",
6626
+ onKeyDown: (_) => {
6627
+ setPasswordChangeRequired(true);
6628
+ if (password === void 0) {
6629
+ setPassword("");
6630
+ }
6631
+ if (confirmPassword === void 0) {
6632
+ setConfirmPassword("");
6633
+ }
6634
+ },
6635
+ onChange: (event) => {
6636
+ setConfirmPassword(event.target.value);
6637
+ }
6638
+ }
6639
+ ), /* @__PURE__ */ React.createElement(
6640
+ Button,
6641
+ {
6642
+ variant: "secondary",
6643
+ disabled: password === void 0 && confirmPassword === void 0,
6644
+ onClick: () => {
6645
+ setError(false);
6646
+ setPassword(void 0);
6647
+ setConfirmPassword(void 0);
6648
+ setPasswordChangeRequired(void 0);
6649
+ form.change(field.name, void 0);
6650
+ }
6651
+ },
6652
+ "Reset"
6653
+ )), /* @__PURE__ */ React.createElement("div", { className: "flex w-full items-center pl-1 pt-3" }, /* @__PURE__ */ React.createElement(
6654
+ Toggle,
6655
+ {
6656
+ field: { name: "passwordChangeRequired", component: "toggle" },
6657
+ input: {
6658
+ value: passwordChangeRequired ?? true,
6659
+ onChange: () => setPasswordChangeRequired(!passwordChangeRequired)
6660
+ },
6661
+ name: "passwordChangeRequired"
6662
+ }
6663
+ ), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { className: "block font-sans text-xs font-semibold text-gray-700 whitespace-normal h-full items-center ml-1" }, "Require Password Change on Next Login"))));
6664
+ });
6665
+ const PasswordFieldPlugin = {
6666
+ name: "password",
6667
+ Component: PasswordFieldComponent,
6668
+ validate(value, values, meta, field) {
6669
+ let password = value;
6670
+ if (Array.isArray(value)) {
6671
+ password = value[0];
6672
+ }
6673
+ if (field.required && (password == null ? void 0 : password.passwordChangeRequired) === void 0) {
6674
+ return "Required";
6675
+ }
6676
+ },
6677
+ parse: parse$2
6678
+ };
6582
6679
  function GrCircleQuestion(props) {
6583
6680
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "stroke": "#000", "strokeWidth": "2", "d": "M12,22 C17.5228475,22 22,17.5228475 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,17.5228475 6.4771525,22 12,22 Z M12,15 L12,14 C12,13 12,12.5 13,12 C14,11.5 15,11 15,9.5 C15,8.5 14,7 12,7 C10,7 9,8.26413718 9,10 M12,16 L12,18" } }] })(props);
6584
6681
  }
@@ -7533,14 +7630,19 @@ class TinaMediaStore {
7533
7630
  if (!this.api) {
7534
7631
  this.api = (_b = (_a = this.cms) == null ? void 0 : _a.api) == null ? void 0 : _b.tina;
7535
7632
  this.isLocal = !!this.api.isLocalMode;
7536
- const contentApiUrl = new URL(this.api.contentApiUrl);
7537
- this.url = `${contentApiUrl.origin}/media`;
7538
- if (!this.isLocal) {
7539
- if ((_d = (_c = this.api.options) == null ? void 0 : _c.tinaioConfig) == null ? void 0 : _d.assetsApiUrlOverride) {
7540
- const url = new URL(this.api.assetsApiUrl);
7541
- this.url = `${url.origin}/v1/${this.api.clientId}`;
7542
- } else {
7543
- this.url = `${contentApiUrl.origin.replace("content", "assets")}/v1/${this.api.clientId}`;
7633
+ if (!this.isStatic) {
7634
+ const contentApiUrl = new URL(this.api.contentApiUrl);
7635
+ this.url = `${contentApiUrl.origin}/media`;
7636
+ if (!this.isLocal) {
7637
+ if ((_d = (_c = this.api.options) == null ? void 0 : _c.tinaioConfig) == null ? void 0 : _d.assetsApiUrlOverride) {
7638
+ const url = new URL(this.api.assetsApiUrl);
7639
+ this.url = `${url.origin}/v1/${this.api.clientId}`;
7640
+ } else {
7641
+ this.url = `${contentApiUrl.origin.replace(
7642
+ "content",
7643
+ "assets"
7644
+ )}/v1/${this.api.clientId}`;
7645
+ }
7544
7646
  }
7545
7647
  }
7546
7648
  }
@@ -7680,6 +7782,38 @@ class TinaMediaStore {
7680
7782
  }
7681
7783
  async list(options) {
7682
7784
  this.setup();
7785
+ if (this.staticMedia) {
7786
+ const offset = options.offset || 0;
7787
+ const media = this.staticMedia[String(offset)];
7788
+ let hasMore = false;
7789
+ if (this.staticMedia[String(Number(offset) + 20)]) {
7790
+ hasMore = true;
7791
+ }
7792
+ if (options.directory) {
7793
+ let depth = 0;
7794
+ const pathToDirectory = options.directory.split("/");
7795
+ let currentFolder = media;
7796
+ let hasMore2 = false;
7797
+ while (depth < pathToDirectory.length) {
7798
+ const nextFolder = currentFolder.find(
7799
+ (item) => item.type === "dir" && item.filename === pathToDirectory[depth]
7800
+ );
7801
+ if (nextFolder) {
7802
+ const offset2 = options.offset || 0;
7803
+ currentFolder = nextFolder.children[String(offset2)];
7804
+ if (nextFolder.children[String(Number(offset2) + 20)]) {
7805
+ hasMore2 = true;
7806
+ }
7807
+ }
7808
+ depth++;
7809
+ }
7810
+ return {
7811
+ items: currentFolder,
7812
+ nextOffset: hasMore2 ? Number(offset) + 20 : null
7813
+ };
7814
+ }
7815
+ return { items: media, nextOffset: hasMore ? Number(offset) + 20 : null };
7816
+ }
7683
7817
  let res;
7684
7818
  if (!this.isLocal) {
7685
7819
  if (await this.isAuthenticated()) {
@@ -7732,38 +7866,6 @@ class TinaMediaStore {
7732
7866
  filename: dir
7733
7867
  });
7734
7868
  }
7735
- if (this.staticMedia) {
7736
- const offset = options.offset || 0;
7737
- const media = this.staticMedia[String(offset)];
7738
- let hasMore = false;
7739
- if (this.staticMedia[String(Number(offset) + 20)]) {
7740
- hasMore = true;
7741
- }
7742
- if (options.directory) {
7743
- let depth = 0;
7744
- const pathToDirectory = options.directory.split("/");
7745
- let currentFolder = media;
7746
- let hasMore2 = false;
7747
- while (depth < pathToDirectory.length) {
7748
- const nextFolder = currentFolder.find(
7749
- (item) => item.type === "dir" && item.filename === pathToDirectory[depth]
7750
- );
7751
- if (nextFolder) {
7752
- const offset2 = options.offset || 0;
7753
- currentFolder = nextFolder.children[String(offset2)];
7754
- if (nextFolder.children[String(Number(offset2) + 20)]) {
7755
- hasMore2 = true;
7756
- }
7757
- }
7758
- depth++;
7759
- }
7760
- return {
7761
- items: currentFolder,
7762
- nextOffset: hasMore2 ? Number(offset) + 20 : null
7763
- };
7764
- }
7765
- return { items: media, nextOffset: hasMore ? Number(offset) + 20 : null };
7766
- }
7767
7869
  return {
7768
7870
  items,
7769
7871
  nextOffset: cursor || 0
@@ -8429,6 +8531,9 @@ const FormHeader = ({ activeForm }) => {
8429
8531
  function ImFilesEmpty(props) {
8430
8532
  return GenIcon({ "tag": "svg", "attr": { "version": "1.1", "viewBox": "0 0 16 16" }, "child": [{ "tag": "path", "attr": { "d": "M14.341 5.579c-0.347-0.473-0.831-1.027-1.362-1.558s-1.085-1.015-1.558-1.362c-0.806-0.591-1.197-0.659-1.421-0.659h-5.75c-0.689 0-1.25 0.561-1.25 1.25v11.5c0 0.689 0.561 1.25 1.25 1.25h9.5c0.689 0 1.25-0.561 1.25-1.25v-7.75c0-0.224-0.068-0.615-0.659-1.421zM12.271 4.729c0.48 0.48 0.856 0.912 1.134 1.271h-2.406v-2.405c0.359 0.278 0.792 0.654 1.271 1.134v0zM14 14.75c0 0.136-0.114 0.25-0.25 0.25h-9.5c-0.136 0-0.25-0.114-0.25-0.25v-11.5c0-0.135 0.114-0.25 0.25-0.25 0 0 5.749-0 5.75 0v3.5c0 0.276 0.224 0.5 0.5 0.5h3.5v7.75z" } }, { "tag": "path", "attr": { "d": "M9.421 0.659c-0.806-0.591-1.197-0.659-1.421-0.659h-5.75c-0.689 0-1.25 0.561-1.25 1.25v11.5c0 0.604 0.43 1.109 1 1.225v-12.725c0-0.135 0.115-0.25 0.25-0.25h7.607c-0.151-0.124-0.297-0.238-0.437-0.341z" } }] })(props);
8431
8533
  }
8534
+ function ImUsers(props) {
8535
+ return GenIcon({ "tag": "svg", "attr": { "version": "1.1", "viewBox": "0 0 18 16" }, "child": [{ "tag": "path", "attr": { "d": "M12 12.041v-0.825c1.102-0.621 2-2.168 2-3.716 0-2.485 0-4.5-3-4.5s-3 2.015-3 4.5c0 1.548 0.898 3.095 2 3.716v0.825c-3.392 0.277-6 1.944-6 3.959h14c0-2.015-2.608-3.682-6-3.959z" } }, { "tag": "path", "attr": { "d": "M5.112 12.427c0.864-0.565 1.939-0.994 3.122-1.256-0.235-0.278-0.449-0.588-0.633-0.922-0.475-0.863-0.726-1.813-0.726-2.748 0-1.344 0-2.614 0.478-3.653 0.464-1.008 1.299-1.633 2.488-1.867-0.264-1.195-0.968-1.98-2.841-1.98-3 0-3 2.015-3 4.5 0 1.548 0.898 3.095 2 3.716v0.825c-3.392 0.277-6 1.944-6 3.959h4.359c0.227-0.202 0.478-0.393 0.753-0.573z" } }] })(props);
8536
+ }
8432
8537
  const LocalWarning = () => {
8433
8538
  return /* @__PURE__ */ React.createElement(
8434
8539
  "a",
@@ -8516,10 +8621,10 @@ const useGetEvents = (cms, cursor, existingEvents) => {
8516
8621
  const [error, setError] = useState(void 0);
8517
8622
  React.useEffect(() => {
8518
8623
  const fetchEvents = async () => {
8519
- var _a, _b, _c, _d;
8624
+ var _a, _b, _c, _d, _e;
8520
8625
  let doFetchEvents = false;
8521
8626
  if (!((_b = (_a = cms.api) == null ? void 0 : _a.tina) == null ? void 0 : _b.isCustomContentApi)) {
8522
- doFetchEvents = await ((_d = (_c = cms.api) == null ? void 0 : _c.tina) == null ? void 0 : _d.isAuthenticated());
8627
+ doFetchEvents = await ((_e = (_d = (_c = cms.api) == null ? void 0 : _c.tina) == null ? void 0 : _d.authProvider) == null ? void 0 : _e.isAuthenticated());
8523
8628
  }
8524
8629
  if (doFetchEvents) {
8525
8630
  try {
@@ -8678,17 +8783,40 @@ const Nav = ({
8678
8783
  RenderNavSite,
8679
8784
  RenderNavCloud,
8680
8785
  RenderNavCollection,
8786
+ AuthRenderNavCollection,
8681
8787
  ...props
8682
8788
  }) => {
8683
8789
  const cms = useCMS$1();
8684
8790
  const { setEdit } = useEditState();
8685
8791
  const [eventsOpen, setEventsOpen] = React.useState(false);
8792
+ const { contentCollections, authCollection } = collectionsInfo.collections.reduce(
8793
+ (acc, collection) => {
8794
+ if (collection.isAuthCollection) {
8795
+ acc.authCollection = collection;
8796
+ } else {
8797
+ acc.contentCollections.push(collection);
8798
+ }
8799
+ return acc;
8800
+ },
8801
+ {
8802
+ contentCollections: []
8803
+ }
8804
+ );
8686
8805
  function closeEventsModal() {
8687
8806
  setEventsOpen(false);
8688
8807
  }
8689
8808
  const WrappedSyncStatus = React.forwardRef(
8690
8809
  (props2, ref) => /* @__PURE__ */ React.createElement(SyncStatus, { ...props2 })
8691
8810
  );
8811
+ const screenCategories = screens.reduce(
8812
+ (acc, screen) => {
8813
+ const category = screen.navCategory || "Site";
8814
+ acc[category] = acc[category] || [];
8815
+ acc[category].push(screen);
8816
+ return acc;
8817
+ },
8818
+ { Site: [] }
8819
+ );
8692
8820
  return /* @__PURE__ */ React.createElement(
8693
8821
  "div",
8694
8822
  {
@@ -8734,18 +8862,21 @@ const Nav = ({
8734
8862
  {
8735
8863
  className: `text-lg px-4 py-2 first:pt-3 last:pb-3 tracking-wide whitespace-nowrap flex items-center opacity-80 text-gray-600 hover:text-blue-400 hover:bg-gray-50 hover:opacity-100`,
8736
8864
  onClick: async () => {
8737
- var _a, _b, _c, _d, _e, _f;
8865
+ var _a, _b, _c, _d, _e, _f, _g, _h;
8738
8866
  updateBodyDisplacement({
8739
8867
  displayState: "closed",
8740
8868
  sidebarWidth: null,
8741
8869
  resizingSidebar: false
8742
8870
  });
8743
8871
  try {
8744
- if ((_b = (_a = cms == null ? void 0 : cms.api) == null ? void 0 : _a.tina) == null ? void 0 : _b.logout) {
8745
- await cms.api.tina.logout();
8746
- if ((_d = (_c = cms == null ? void 0 : cms.api) == null ? void 0 : _c.tina) == null ? void 0 : _d.onLogout) {
8747
- await ((_f = (_e = cms == null ? void 0 : cms.api) == null ? void 0 : _e.tina) == null ? void 0 : _f.onLogout());
8872
+ if ((_c = (_b = (_a = cms == null ? void 0 : cms.api) == null ? void 0 : _a.tina) == null ? void 0 : _b.authProvider) == null ? void 0 : _c.logout) {
8873
+ await ((_d = cms.api.tina) == null ? void 0 : _d.authProvider.logout());
8874
+ if ((_f = (_e = cms == null ? void 0 : cms.api) == null ? void 0 : _e.tina) == null ? void 0 : _f.onLogout) {
8875
+ await ((_h = (_g = cms == null ? void 0 : cms.api) == null ? void 0 : _g.tina) == null ? void 0 : _h.onLogout());
8748
8876
  }
8877
+ window.location.href = new URL(
8878
+ window.location.href
8879
+ ).pathname;
8749
8880
  }
8750
8881
  setEdit(false);
8751
8882
  } catch (e) {
@@ -8778,13 +8909,25 @@ const Nav = ({
8778
8909
  CollectionsList,
8779
8910
  {
8780
8911
  RenderNavCollection,
8781
- ...collectionsInfo
8912
+ collections: contentCollections
8782
8913
  }
8783
- )), (screens.length > 0 || contentCreators.length) > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, "Site"), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, screens.map((view) => {
8914
+ )), (screenCategories.Site.length > 0 || contentCreators.length) > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, "Site"), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, screenCategories.Site.map((view) => {
8784
8915
  return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${view.name}` }, /* @__PURE__ */ React.createElement(RenderNavSite, { view }));
8785
8916
  }), contentCreators.map((plugin, idx) => {
8786
8917
  return /* @__PURE__ */ React.createElement(CreateContentNavItem, { key: `plugin-${idx}`, plugin });
8787
- }))), !!(cloudConfigs == null ? void 0 : cloudConfigs.length) && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, "Cloud"), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, cloudConfigs.map((config) => {
8918
+ }), authCollection && /* @__PURE__ */ React.createElement(
8919
+ CollectionsList,
8920
+ {
8921
+ RenderNavCollection: AuthRenderNavCollection,
8922
+ collections: [authCollection]
8923
+ }
8924
+ ))), Object.entries(screenCategories).map(([category, screens2]) => {
8925
+ if (category !== "Site") {
8926
+ return /* @__PURE__ */ React.createElement("div", { key: category }, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, category), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, screens2.map((view) => {
8927
+ return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${view.name}` }, /* @__PURE__ */ React.createElement(RenderNavSite, { view }));
8928
+ })));
8929
+ }
8930
+ }), !!(cloudConfigs == null ? void 0 : cloudConfigs.length) && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, "Cloud"), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, cloudConfigs.map((config) => {
8788
8931
  return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${config.name}` }, /* @__PURE__ */ React.createElement(RenderNavCloud, { config }));
8789
8932
  }))))
8790
8933
  );
@@ -8941,6 +9084,12 @@ const Sidebar$1 = ({
8941
9084
  const [activeScreen, setActiveView] = useState(null);
8942
9085
  const [sidebarWidth, setSidebarWidth] = React.useState(defaultWidth);
8943
9086
  const [formIsPristine, setFormIsPristine] = React.useState(true);
9087
+ const activeScreens = allScreens.filter(
9088
+ (screen) => {
9089
+ var _a2, _b2;
9090
+ return screen.navCategory !== "Account" || ((_b2 = (_a2 = cms.api.tina) == null ? void 0 : _a2.authProvider) == null ? void 0 : _b2.getLoginStrategy()) === "UsernamePassword";
9091
+ }
9092
+ );
8944
9093
  const setDisplayState = (value) => cms.dispatch({ type: "sidebar:set-display-state", value });
8945
9094
  const displayState = cms.state.sidebarDisplayState;
8946
9095
  React.useEffect(() => {
@@ -9036,7 +9185,7 @@ const Sidebar$1 = ({
9036
9185
  isLocalMode: (_b = (_a = cms.api) == null ? void 0 : _a.tina) == null ? void 0 : _b.isLocalMode,
9037
9186
  showCollections: isTinaAdminEnabled,
9038
9187
  collectionsInfo,
9039
- screens: allScreens,
9188
+ screens: activeScreens,
9040
9189
  cloudConfigs: allConfigs,
9041
9190
  contentCreators,
9042
9191
  sidebarWidth,
@@ -9059,6 +9208,16 @@ const Sidebar$1 = ({
9059
9208
  },
9060
9209
  collection
9061
9210
  }
9211
+ ),
9212
+ AuthRenderNavCollection: ({ collection }) => /* @__PURE__ */ React.createElement(
9213
+ SidebarCollectionLink,
9214
+ {
9215
+ onClick: () => {
9216
+ setMenuIsOpen(false);
9217
+ },
9218
+ collection,
9219
+ Icon: ImUsers
9220
+ }
9062
9221
  )
9063
9222
  }
9064
9223
  ), /* @__PURE__ */ React.createElement(SidebarBody, null, /* @__PURE__ */ React.createElement(
@@ -9093,7 +9252,7 @@ const Sidebar$1 = ({
9093
9252
  className: "rounded-r-md",
9094
9253
  showCollections: isTinaAdminEnabled,
9095
9254
  collectionsInfo,
9096
- screens: allScreens,
9255
+ screens: activeScreens,
9097
9256
  cloudConfigs: allConfigs,
9098
9257
  contentCreators,
9099
9258
  sidebarWidth,
@@ -9116,6 +9275,16 @@ const Sidebar$1 = ({
9116
9275
  },
9117
9276
  collection
9118
9277
  }
9278
+ ),
9279
+ AuthRenderNavCollection: ({ collection }) => /* @__PURE__ */ React.createElement(
9280
+ SidebarCollectionLink,
9281
+ {
9282
+ onClick: () => {
9283
+ setMenuIsOpen(false);
9284
+ },
9285
+ collection,
9286
+ Icon: ImUsers
9287
+ }
9119
9288
  )
9120
9289
  },
9121
9290
  /* @__PURE__ */ React.createElement("div", { className: "absolute top-8 right-0 transform translate-x-full overflow-hidden" }, /* @__PURE__ */ React.createElement(
@@ -9277,6 +9446,7 @@ const SidebarCloudLink$1 = ({ config }) => {
9277
9446
  return /* @__PURE__ */ React.createElement("span", { className: "text-base tracking-wide text-gray-500 hover:text-blue-600 flex items-center opacity-90 hover:opacity-100" }, /* @__PURE__ */ React.createElement(config.Icon, { className: "mr-2 h-6 opacity-80 w-auto" }), /* @__PURE__ */ React.createElement("a", { target: "_blank", href: config.link.href }, config.link.text));
9278
9447
  };
9279
9448
  const SidebarCollectionLink = ({
9449
+ Icon = ImFilesEmpty,
9280
9450
  collection,
9281
9451
  onClick
9282
9452
  }) => {
@@ -9289,7 +9459,7 @@ const SidebarCollectionLink = ({
9289
9459
  href: `${tinaPreview ? `/${tinaPreview}/index.html#` : "/admin#"}/collections/${collection.name}/~`,
9290
9460
  className: "text-base tracking-wide text-gray-500 hover:text-blue-600 flex items-center opacity-90 hover:opacity-100"
9291
9461
  },
9292
- /* @__PURE__ */ React.createElement(ImFilesEmpty, { className: "mr-2 h-6 opacity-80 w-auto" }),
9462
+ /* @__PURE__ */ React.createElement(Icon, { className: "mr-2 h-6 opacity-80 w-auto" }),
9293
9463
  " ",
9294
9464
  collection.label ? collection.label : collection.name
9295
9465
  );
@@ -10005,7 +10175,9 @@ const SyncStatusContainer = ({ children }) => {
10005
10175
  setSyncStatus(project.mediaBranch ? "synced" : "needs-sync");
10006
10176
  }
10007
10177
  };
10008
- checkSyncStatus();
10178
+ if (!cms.media.store.isStatic) {
10179
+ checkSyncStatus();
10180
+ }
10009
10181
  }, []);
10010
10182
  return syncStatus == "needs-sync" ? /* @__PURE__ */ React__default.createElement("div", { className: "h-full flex items-center justify-center p-6 bg-gradient-to-t from-gray-200 to-transparent" }, /* @__PURE__ */ React__default.createElement("div", { className: "rounded-lg border shadow-sm px-4 lg:px-6 py-3 lg:py-4 bg-gradient-to-r from-yellow-50 to-yellow-100 border-yellow-200 mx-auto mb-12" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex items-start sm:items-center gap-2" }, /* @__PURE__ */ React__default.createElement(
10011
10183
  BiError,
@@ -10095,6 +10267,108 @@ const MediaManagerScreenPlugin = createScreen({
10095
10267
  allowDelete: true
10096
10268
  }
10097
10269
  });
10270
+ function UpdatePassword(props) {
10271
+ const cms = useCMS$1();
10272
+ const client = cms.api.tina;
10273
+ const [password, setPassword] = useState("");
10274
+ const [confirmPassword, setConfirmPassword] = useState("");
10275
+ const [dirty, setDirty] = useState(false);
10276
+ const [result, setResult] = useState(null);
10277
+ const [formState, setFormState] = useState("idle");
10278
+ const [passwordChangeRequired, setPasswordChangeRequired] = useState(false);
10279
+ useEffect(() => {
10280
+ var _a;
10281
+ (_a = client == null ? void 0 : client.authProvider) == null ? void 0 : _a.getUser().then(
10282
+ (user) => setPasswordChangeRequired((user == null ? void 0 : user.passwordChangeRequired) ?? false)
10283
+ );
10284
+ }, []);
10285
+ let err = null;
10286
+ if (dirty && password !== confirmPassword) {
10287
+ err = "Passwords do not match";
10288
+ }
10289
+ if (dirty && !password) {
10290
+ err = "Please enter a password";
10291
+ }
10292
+ const updatePassword = async () => {
10293
+ var _a;
10294
+ setResult(null);
10295
+ setFormState("busy");
10296
+ const res = await cms.api.tina.request(
10297
+ `mutation($password: String!) { updatePassword(password: $password) }`,
10298
+ {
10299
+ variables: {
10300
+ password
10301
+ }
10302
+ }
10303
+ );
10304
+ if (!(res == null ? void 0 : res.updatePassword)) {
10305
+ setResult("Error updating password");
10306
+ } else {
10307
+ setDirty(false);
10308
+ setPassword("");
10309
+ setConfirmPassword("");
10310
+ setResult("Password updated");
10311
+ setPasswordChangeRequired(false);
10312
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
10313
+ (_a = client == null ? void 0 : client.authProvider) == null ? void 0 : _a.logout().then(async () => {
10314
+ if (typeof (client == null ? void 0 : client.onLogout) === "function") {
10315
+ await client.onLogout();
10316
+ }
10317
+ window.location.href = new URL(window.location.href).pathname;
10318
+ }).catch((e) => console.error(e));
10319
+ }
10320
+ setFormState("idle");
10321
+ };
10322
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", { className: "flex justify-center items-center h-full" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex flex-col space-y-8 p-6" }, passwordChangeRequired && /* @__PURE__ */ React__default.createElement("div", { className: "text-center text-red-500" }, "Your password has expired. Please update your password."), /* @__PURE__ */ React__default.createElement("label", { className: "block" }, /* @__PURE__ */ React__default.createElement("span", { className: "text-gray-700" }, "New Password"), /* @__PURE__ */ React__default.createElement(
10323
+ BaseTextField,
10324
+ {
10325
+ type: "password",
10326
+ name: "password",
10327
+ id: "password",
10328
+ placeholder: "Enter password",
10329
+ className: err ? "border-red-500" : "border-gray-300 focus:ring-indigo-500 focus:border-indigo-500",
10330
+ value: password,
10331
+ onKeyDown: () => {
10332
+ setDirty(true);
10333
+ setResult(null);
10334
+ },
10335
+ onChange: (e) => setPassword(e.target.value),
10336
+ required: true
10337
+ }
10338
+ )), /* @__PURE__ */ React__default.createElement("label", { className: "block" }, /* @__PURE__ */ React__default.createElement("span", { className: "text-gray-700" }, "Confirm New Password"), /* @__PURE__ */ React__default.createElement(
10339
+ BaseTextField,
10340
+ {
10341
+ type: "password",
10342
+ name: "confirmPassword",
10343
+ id: "confirmPassword",
10344
+ placeholder: "Confirm password",
10345
+ className: err ? "border-red-500" : "border-gray-300 focus:ring-indigo-500 focus:border-indigo-500",
10346
+ value: confirmPassword,
10347
+ onKeyDown: () => {
10348
+ setDirty(true);
10349
+ setResult(null);
10350
+ },
10351
+ onChange: (e) => setConfirmPassword(e.target.value),
10352
+ required: true
10353
+ }
10354
+ )), result && /* @__PURE__ */ React__default.createElement("div", { className: "text-center text-sm text-gray-500" }, result), err && /* @__PURE__ */ React__default.createElement("div", { className: "text-center text-sm text-red-500" }, err), /* @__PURE__ */ React__default.createElement(
10355
+ Button,
10356
+ {
10357
+ onClick: updatePassword,
10358
+ disabled: err,
10359
+ variant: "primary",
10360
+ busy: formState === "busy"
10361
+ },
10362
+ "Update"
10363
+ ))));
10364
+ }
10365
+ const PasswordScreenPlugin = createScreen({
10366
+ name: "Change Password",
10367
+ Component: UpdatePassword,
10368
+ Icon: MdVpnKey,
10369
+ layout: "fullscreen",
10370
+ navCategory: "Account"
10371
+ });
10098
10372
  function createCloudConfig({
10099
10373
  ...options
10100
10374
  }) {
@@ -10124,7 +10398,8 @@ const DEFAULT_FIELDS = [
10124
10398
  CheckboxGroupFieldPlugin,
10125
10399
  ReferenceFieldPlugin,
10126
10400
  ButtonToggleFieldPlugin,
10127
- HiddenFieldPlugin
10401
+ HiddenFieldPlugin,
10402
+ PasswordFieldPlugin
10128
10403
  ];
10129
10404
  class TinaCMS extends CMS {
10130
10405
  constructor({
@@ -10163,6 +10438,7 @@ class TinaCMS extends CMS {
10163
10438
  }
10164
10439
  });
10165
10440
  this.plugins.add(MediaManagerScreenPlugin);
10441
+ this.plugins.add(PasswordScreenPlugin);
10166
10442
  if (isLocalClient !== true) {
10167
10443
  if (clientId) {
10168
10444
  this.plugins.add(
@@ -26392,25 +26668,6 @@ const parseSearchIndexResponse = (data, options) => {
26392
26668
  };
26393
26669
  }
26394
26670
  };
26395
- const captureBranchName = /^refs\/heads\/(.*)/;
26396
- const parseRefForBranchName = (ref) => {
26397
- const matches = ref.match(captureBranchName);
26398
- return matches[1];
26399
- };
26400
- const ListBranchResponse = z.object({
26401
- name: z.string(),
26402
- protected: z.boolean().optional().default(false),
26403
- githubPullRequestUrl: z.string().optional()
26404
- }).array().nonempty();
26405
- const IndexStatusResponse = z.object({
26406
- status: z.union([
26407
- z.literal("complete"),
26408
- z.literal("unknown"),
26409
- z.literal("failed"),
26410
- z.literal("inprogress")
26411
- ]).optional(),
26412
- timestamp: z.number().optional()
26413
- });
26414
26671
  function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
26415
26672
  const endTime = (/* @__PURE__ */ new Date()).getTime() + pollTimeout;
26416
26673
  let stop = false;
@@ -26435,19 +26692,261 @@ function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
26435
26692
  };
26436
26693
  return [new Promise(checkCondition), cancel];
26437
26694
  }
26438
- class Client {
26439
- constructor({ tokenStorage = "MEMORY", ...options }) {
26440
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X;
26441
- this.events = new EventBus();
26442
- this.protectedBranches = [];
26443
- this.usingEditorialWorkflow = false;
26444
- this.addPendingContent = async (props) => {
26445
- const mutation = `#graphql
26446
- mutation addPendingDocumentMutation(
26447
- $relativePath: String!
26448
- $collection: String!
26449
- $template: String
26450
- ) {
26695
+ function popupWindow(url, title, window2, w, h) {
26696
+ const y = window2.top.outerHeight / 2 + window2.top.screenY - h / 2;
26697
+ const x = window2.top.outerWidth / 2 + window2.top.screenX - w / 2;
26698
+ return window2.open(
26699
+ url,
26700
+ title,
26701
+ "toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=no, width=" + w + ", height=" + h + ", top=" + y + ", left=" + x
26702
+ );
26703
+ }
26704
+ const TINA_LOGIN_EVENT = "tinaCloudLogin";
26705
+ const AUTH_TOKEN_KEY = "tinacms-auth";
26706
+ const authenticate = (clientId, frontendUrl) => {
26707
+ return new Promise((resolve) => {
26708
+ let authTab;
26709
+ window.addEventListener("message", function(e) {
26710
+ if (e.data.source === TINA_LOGIN_EVENT) {
26711
+ if (authTab) {
26712
+ authTab.close();
26713
+ }
26714
+ resolve({
26715
+ id_token: e.data.id_token,
26716
+ access_token: e.data.access_token,
26717
+ refresh_token: e.data.refresh_token
26718
+ });
26719
+ }
26720
+ });
26721
+ const origin = `${window.location.protocol}//${window.location.host}`;
26722
+ authTab = popupWindow(
26723
+ `${frontendUrl}/signin?clientId=${clientId}&origin=${origin}`,
26724
+ "_blank",
26725
+ window,
26726
+ 1e3,
26727
+ 700
26728
+ );
26729
+ });
26730
+ };
26731
+ const DefaultSessionProvider = ({
26732
+ children
26733
+ }) => /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, children);
26734
+ class AbstractAuthProvider {
26735
+ /**
26736
+ * Wraps the normal fetch function with same API but adds the authorization header token.
26737
+ *
26738
+ * @example
26739
+ * const test = await tinaCloudClient.fetchWithToken(`/mycustomAPI/thing/one`) // the token will be passed in the authorization header
26740
+ *
26741
+ * @param input fetch function input
26742
+ * @param init fetch function init
26743
+ */
26744
+ async fetchWithToken(input, init) {
26745
+ const headers2 = (init == null ? void 0 : init.headers) || {};
26746
+ const token = await this.getToken();
26747
+ if (token == null ? void 0 : token.id_token) {
26748
+ headers2["Authorization"] = "Bearer " + (token == null ? void 0 : token.id_token);
26749
+ }
26750
+ return await fetch(input, {
26751
+ ...init || {},
26752
+ headers: new Headers(headers2)
26753
+ });
26754
+ }
26755
+ async authorize(context) {
26756
+ return this.getToken();
26757
+ }
26758
+ async isAuthorized(context) {
26759
+ return !!await this.authorize(context);
26760
+ }
26761
+ async isAuthenticated() {
26762
+ return !!await this.getUser();
26763
+ }
26764
+ getLoginStrategy() {
26765
+ return "Redirect";
26766
+ }
26767
+ getSessionProvider() {
26768
+ return DefaultSessionProvider;
26769
+ }
26770
+ }
26771
+ class TinaCloudAuthProvider extends AbstractAuthProvider {
26772
+ constructor({
26773
+ clientId,
26774
+ identityApiUrl,
26775
+ tokenStorage = "MEMORY",
26776
+ frontendUrl,
26777
+ ...options
26778
+ }) {
26779
+ super();
26780
+ this.frontendUrl = frontendUrl;
26781
+ this.clientId = clientId;
26782
+ this.identityApiUrl = identityApiUrl;
26783
+ switch (tokenStorage) {
26784
+ case "LOCAL_STORAGE":
26785
+ this.getToken = async function() {
26786
+ const tokens = localStorage.getItem(AUTH_TOKEN_KEY) || null;
26787
+ if (tokens) {
26788
+ return await this.getRefreshedToken(tokens);
26789
+ } else {
26790
+ return {
26791
+ access_token: null,
26792
+ id_token: null,
26793
+ refresh_token: null
26794
+ };
26795
+ }
26796
+ };
26797
+ this.setToken = function(token) {
26798
+ localStorage.setItem(AUTH_TOKEN_KEY, JSON.stringify(token, null, 2));
26799
+ };
26800
+ break;
26801
+ case "MEMORY":
26802
+ this.getToken = async () => {
26803
+ if (this.token) {
26804
+ return await this.getRefreshedToken(this.token);
26805
+ } else {
26806
+ return {
26807
+ access_token: null,
26808
+ id_token: null,
26809
+ refresh_token: null
26810
+ };
26811
+ }
26812
+ };
26813
+ this.setToken = (token) => {
26814
+ this.token = JSON.stringify(token, null, 2);
26815
+ };
26816
+ break;
26817
+ case "CUSTOM":
26818
+ if (!options.getTokenFn) {
26819
+ throw new Error(
26820
+ "When CUSTOM token storage is selected, a getTokenFn must be provided"
26821
+ );
26822
+ }
26823
+ this.getToken = options.getTokenFn;
26824
+ break;
26825
+ }
26826
+ }
26827
+ async authenticate() {
26828
+ const token = await authenticate(this.clientId, this.frontendUrl);
26829
+ this.setToken(token);
26830
+ return token;
26831
+ }
26832
+ async getUser() {
26833
+ if (!this.clientId) {
26834
+ return null;
26835
+ }
26836
+ const url = `${this.identityApiUrl}/v2/apps/${this.clientId}/currentUser`;
26837
+ try {
26838
+ const res = await this.fetchWithToken(url, {
26839
+ method: "GET"
26840
+ });
26841
+ const val = await res.json();
26842
+ if (!res.status.toString().startsWith("2")) {
26843
+ console.error(val.error);
26844
+ return null;
26845
+ }
26846
+ return val;
26847
+ } catch (e) {
26848
+ console.error(e);
26849
+ return null;
26850
+ }
26851
+ }
26852
+ async logout() {
26853
+ this.setToken(null);
26854
+ }
26855
+ async getRefreshedToken(tokens) {
26856
+ const { access_token, id_token, refresh_token } = JSON.parse(tokens);
26857
+ const { exp, iss, client_id } = this.parseJwt(access_token);
26858
+ if (Date.now() / 1e3 >= exp - 120) {
26859
+ const refreshResponse = await fetch(iss, {
26860
+ method: "POST",
26861
+ headers: {
26862
+ "Content-Type": "application/x-amz-json-1.1",
26863
+ "x-amz-target": "AWSCognitoIdentityProviderService.InitiateAuth"
26864
+ },
26865
+ body: JSON.stringify({
26866
+ ClientId: client_id,
26867
+ AuthFlow: "REFRESH_TOKEN_AUTH",
26868
+ AuthParameters: {
26869
+ REFRESH_TOKEN: refresh_token,
26870
+ DEVICE_KEY: null
26871
+ }
26872
+ })
26873
+ });
26874
+ if (refreshResponse.status !== 200) {
26875
+ throw new Error("Unable to refresh auth tokens");
26876
+ }
26877
+ const responseJson = await refreshResponse.json();
26878
+ const newToken = {
26879
+ access_token: responseJson.AuthenticationResult.AccessToken,
26880
+ id_token: responseJson.AuthenticationResult.IdToken,
26881
+ refresh_token
26882
+ };
26883
+ this.setToken(newToken);
26884
+ return Promise.resolve(newToken);
26885
+ }
26886
+ return Promise.resolve({ access_token, id_token, refresh_token });
26887
+ }
26888
+ parseJwt(token) {
26889
+ const base64Url = token.split(".")[1];
26890
+ const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
26891
+ const jsonPayload = decodeURIComponent(
26892
+ atob(base64).split("").map(function(c) {
26893
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
26894
+ }).join("")
26895
+ );
26896
+ return JSON.parse(jsonPayload);
26897
+ }
26898
+ }
26899
+ const LOCAL_CLIENT_KEY = "tina.local.isLogedIn";
26900
+ class LocalAuthProvider extends AbstractAuthProvider {
26901
+ constructor() {
26902
+ super();
26903
+ }
26904
+ async authenticate() {
26905
+ localStorage.setItem(LOCAL_CLIENT_KEY, "true");
26906
+ return { access_token: "LOCAL", id_token: "LOCAL", refresh_token: "LOCAL" };
26907
+ }
26908
+ async getUser() {
26909
+ return localStorage.getItem(LOCAL_CLIENT_KEY) === "true";
26910
+ }
26911
+ async getToken() {
26912
+ return Promise.resolve({ id_token: "" });
26913
+ }
26914
+ async logout() {
26915
+ localStorage.removeItem(LOCAL_CLIENT_KEY);
26916
+ }
26917
+ }
26918
+ const captureBranchName = /^refs\/heads\/(.*)/;
26919
+ const parseRefForBranchName = (ref) => {
26920
+ const matches = ref.match(captureBranchName);
26921
+ return matches[1];
26922
+ };
26923
+ const ListBranchResponse = z.object({
26924
+ name: z.string(),
26925
+ protected: z.boolean().optional().default(false),
26926
+ githubPullRequestUrl: z.string().optional()
26927
+ }).array().nonempty();
26928
+ const IndexStatusResponse = z.object({
26929
+ status: z.union([
26930
+ z.literal("complete"),
26931
+ z.literal("unknown"),
26932
+ z.literal("failed"),
26933
+ z.literal("inprogress")
26934
+ ]).optional(),
26935
+ timestamp: z.number().optional()
26936
+ });
26937
+ class Client {
26938
+ constructor({ tokenStorage = "MEMORY", ...options }) {
26939
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
26940
+ this.events = new EventBus();
26941
+ this.protectedBranches = [];
26942
+ this.usingEditorialWorkflow = false;
26943
+ this.addPendingContent = async (props) => {
26944
+ const mutation = `#graphql
26945
+ mutation addPendingDocumentMutation(
26946
+ $relativePath: String!
26947
+ $collection: String!
26948
+ $template: String
26949
+ ) {
26451
26950
  addPendingDocument(
26452
26951
  relativePath: $relativePath
26453
26952
  template: $template
@@ -26491,20 +26990,8 @@ mutation addPendingDocumentMutation(
26491
26990
  return parse$3(data.getOptimizedQuery);
26492
26991
  };
26493
26992
  this.tinaGraphQLVersion = options.tinaGraphQLVersion;
26494
- this.onLogin = (_d = (_c = (_b = (_a = options.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.admin) == null ? void 0 : _c.auth) == null ? void 0 : _d.onLogin;
26495
- this.onLogout = (_h = (_g = (_f = (_e = options.schema) == null ? void 0 : _e.config) == null ? void 0 : _f.admin) == null ? void 0 : _g.auth) == null ? void 0 : _h.onLogout;
26496
- if ((_l = (_k = (_j = (_i = options.schema) == null ? void 0 : _i.config) == null ? void 0 : _j.admin) == null ? void 0 : _k.auth) == null ? void 0 : _l.logout) {
26497
- this.onLogout = (_p = (_o = (_n = (_m = options.schema) == null ? void 0 : _m.config) == null ? void 0 : _n.admin) == null ? void 0 : _o.auth) == null ? void 0 : _p.logout;
26498
- }
26499
- if ((_t = (_s = (_r = (_q = options.schema) == null ? void 0 : _q.config) == null ? void 0 : _r.admin) == null ? void 0 : _s.auth) == null ? void 0 : _t.getUser) {
26500
- this.getUser = (_x = (_w = (_v = (_u = options.schema) == null ? void 0 : _u.config) == null ? void 0 : _v.admin) == null ? void 0 : _w.auth) == null ? void 0 : _x.getUser;
26501
- }
26502
- if ((_B = (_A = (_z = (_y = options.schema) == null ? void 0 : _y.config) == null ? void 0 : _z.admin) == null ? void 0 : _A.auth) == null ? void 0 : _B.authenticate) {
26503
- this.authenticate = (_F = (_E = (_D = (_C = options.schema) == null ? void 0 : _C.config) == null ? void 0 : _D.admin) == null ? void 0 : _E.auth) == null ? void 0 : _F.authenticate;
26504
- }
26505
- if ((_J = (_I = (_H = (_G = options.schema) == null ? void 0 : _G.config) == null ? void 0 : _H.admin) == null ? void 0 : _I.auth) == null ? void 0 : _J.authorize) {
26506
- this.authorize = (_N = (_M = (_L = (_K = options.schema) == null ? void 0 : _K.config) == null ? void 0 : _L.admin) == null ? void 0 : _M.auth) == null ? void 0 : _N.authorize;
26507
- }
26993
+ this.onLogin = ((_d = (_c = (_b = (_a = options.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.admin) == null ? void 0 : _c.authHooks) == null ? void 0 : _d.onLogin) || ((_h = (_g = (_f = (_e = options.schema) == null ? void 0 : _e.config) == null ? void 0 : _f.admin) == null ? void 0 : _g.auth) == null ? void 0 : _h.onLogin);
26994
+ this.onLogout = ((_l = (_k = (_j = (_i = options.schema) == null ? void 0 : _i.config) == null ? void 0 : _j.admin) == null ? void 0 : _k.authHooks) == null ? void 0 : _l.onLogout) || ((_p = (_o = (_n = (_m = options.schema) == null ? void 0 : _m.config) == null ? void 0 : _n.admin) == null ? void 0 : _o.auth) == null ? void 0 : _p.onLogout);
26508
26995
  if (options.schema) {
26509
26996
  const enrichedSchema = new TinaSchema({
26510
26997
  version: { fullVersion: "", major: "", minor: "", patch: "" },
@@ -26514,7 +27001,7 @@ mutation addPendingDocumentMutation(
26514
27001
  this.schema = enrichedSchema;
26515
27002
  }
26516
27003
  this.options = options;
26517
- if ((_P = (_O = options.schema) == null ? void 0 : _O.config) == null ? void 0 : _P.contentApiUrlOverride) {
27004
+ if ((_r = (_q = options.schema) == null ? void 0 : _q.config) == null ? void 0 : _r.contentApiUrlOverride) {
26518
27005
  this.options.customContentApiUrl = options.schema.config.contentApiUrlOverride;
26519
27006
  }
26520
27007
  this.setBranch(options.branch);
@@ -26525,52 +27012,13 @@ mutation addPendingDocumentMutation(
26525
27012
  }
26526
27013
  );
26527
27014
  this.clientId = options.clientId;
26528
- switch (tokenStorage) {
26529
- case "LOCAL_STORAGE":
26530
- this.getToken = async function() {
26531
- const tokens = localStorage.getItem(AUTH_TOKEN_KEY) || null;
26532
- if (tokens) {
26533
- return await this.getRefreshedToken(tokens);
26534
- } else {
26535
- return {
26536
- access_token: null,
26537
- id_token: null,
26538
- refresh_token: null
26539
- };
26540
- }
26541
- };
26542
- this.setToken = function(token) {
26543
- localStorage.setItem(AUTH_TOKEN_KEY, JSON.stringify(token, null, 2));
26544
- };
26545
- break;
26546
- case "MEMORY":
26547
- this.getToken = async () => {
26548
- if (this.token) {
26549
- return await this.getRefreshedToken(this.token);
26550
- } else {
26551
- return {
26552
- access_token: null,
26553
- id_token: null,
26554
- refresh_token: null
26555
- };
26556
- }
26557
- };
26558
- this.setToken = (token) => {
26559
- this.token = JSON.stringify(token, null, 2);
26560
- };
26561
- break;
26562
- case "CUSTOM":
26563
- if (!options.getTokenFn) {
26564
- throw new Error(
26565
- "When CUSTOM token storage is selected, a getTokenFn must be provided"
26566
- );
26567
- }
26568
- this.getToken = options.getTokenFn;
26569
- break;
26570
- }
26571
- if ((_T = (_S = (_R = (_Q = options.schema) == null ? void 0 : _Q.config) == null ? void 0 : _R.admin) == null ? void 0 : _S.auth) == null ? void 0 : _T.getToken) {
26572
- this.getToken = (_X = (_W = (_V = (_U = options.schema) == null ? void 0 : _U.config) == null ? void 0 : _V.admin) == null ? void 0 : _W.auth) == null ? void 0 : _X.getToken;
26573
- }
27015
+ this.authProvider = ((_u = (_t = (_s = this.schema) == null ? void 0 : _s.config) == null ? void 0 : _t.config) == null ? void 0 : _u.authProvider) || new TinaCloudAuthProvider({
27016
+ clientId: options.clientId,
27017
+ identityApiUrl: this.identityApiUrl,
27018
+ getTokenFn: options.getTokenFn,
27019
+ tokenStorage,
27020
+ frontendUrl: this.frontendUrl
27021
+ });
26574
27022
  }
26575
27023
  get isLocalMode() {
26576
27024
  return false;
@@ -26587,12 +27035,16 @@ mutation addPendingDocumentMutation(
26587
27035
  this.identityApiUrl = ((_c = this.options.tinaioConfig) == null ? void 0 : _c.identityApiUrlOverride) || "https://identity.tinajs.io";
26588
27036
  this.contentApiBase = ((_d = this.options.tinaioConfig) == null ? void 0 : _d.contentApiUrlOverride) || `https://content.tinajs.io`;
26589
27037
  this.contentApiUrl = this.options.customContentApiUrl || `${this.contentApiBase}/${this.tinaGraphQLVersion}/content/${this.options.clientId}/github/${encodedBranch}`;
27038
+ if (this.authProvider instanceof TinaCloudAuthProvider) {
27039
+ this.authProvider.identityApiUrl = this.identityApiUrl;
27040
+ this.authProvider.frontendUrl = this.frontendUrl;
27041
+ }
26590
27042
  }
26591
27043
  getBranch() {
26592
27044
  return this.branch;
26593
27045
  }
26594
27046
  async request(query, { variables }) {
26595
- const token = await this.getToken();
27047
+ const token = await this.authProvider.getToken();
26596
27048
  const headers2 = {
26597
27049
  "Content-Type": "application/json"
26598
27050
  };
@@ -26639,7 +27091,7 @@ mutation addPendingDocumentMutation(
26639
27091
  async checkSyncStatus({
26640
27092
  assetsSyncing
26641
27093
  }) {
26642
- const res = await this.fetchWithToken(
27094
+ const res = await this.authProvider.fetchWithToken(
26643
27095
  `${this.assetsApiUrl}/v1/${this.clientId}/syncStatus`,
26644
27096
  {
26645
27097
  method: "POST",
@@ -26653,7 +27105,7 @@ mutation addPendingDocumentMutation(
26653
27105
  return jsonRes;
26654
27106
  }
26655
27107
  async getProject() {
26656
- const res = await this.fetchWithToken(
27108
+ const res = await this.authProvider.fetchWithToken(
26657
27109
  `${this.identityApiUrl}/v2/apps/${this.clientId}`,
26658
27110
  {
26659
27111
  method: "GET"
@@ -26669,7 +27121,7 @@ mutation addPendingDocumentMutation(
26669
27121
  }) {
26670
27122
  const url = `${this.contentApiBase}/github/${this.clientId}/create_pull_request`;
26671
27123
  try {
26672
- const res = await this.fetchWithToken(url, {
27124
+ const res = await this.authProvider.fetchWithToken(url, {
26673
27125
  method: "POST",
26674
27126
  body: JSON.stringify({
26675
27127
  baseBranch,
@@ -26698,119 +27150,19 @@ mutation addPendingDocumentMutation(
26698
27150
  events: []
26699
27151
  };
26700
27152
  } else {
26701
- return (await this.fetchWithToken(
27153
+ return (await this.authProvider.fetchWithToken(
26702
27154
  `${this.contentApiBase}/events/${this.clientId}/${this.branch}?limit=${limit || 1}${cursor ? `&cursor=${cursor}` : ""}`,
26703
27155
  { method: "GET" }
26704
27156
  )).json();
26705
27157
  }
26706
27158
  }
26707
- parseJwt(token) {
26708
- const base64Url = token.split(".")[1];
26709
- const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
26710
- const jsonPayload = decodeURIComponent(
26711
- atob(base64).split("").map(function(c) {
26712
- return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
26713
- }).join("")
26714
- );
26715
- return JSON.parse(jsonPayload);
26716
- }
26717
- async getRefreshedToken(tokens) {
26718
- const { access_token, id_token, refresh_token } = JSON.parse(tokens);
26719
- const { exp, iss, client_id } = this.parseJwt(access_token);
26720
- if (Date.now() / 1e3 >= exp - 120) {
26721
- const refreshResponse = await fetch(iss, {
26722
- method: "POST",
26723
- headers: {
26724
- "Content-Type": "application/x-amz-json-1.1",
26725
- "x-amz-target": "AWSCognitoIdentityProviderService.InitiateAuth"
26726
- },
26727
- body: JSON.stringify({
26728
- ClientId: client_id,
26729
- AuthFlow: "REFRESH_TOKEN_AUTH",
26730
- AuthParameters: {
26731
- REFRESH_TOKEN: refresh_token,
26732
- DEVICE_KEY: null
26733
- }
26734
- })
26735
- });
26736
- if (refreshResponse.status !== 200) {
26737
- throw new Error("Unable to refresh auth tokens");
26738
- }
26739
- const responseJson = await refreshResponse.json();
26740
- const newToken = {
26741
- access_token: responseJson.AuthenticationResult.AccessToken,
26742
- id_token: responseJson.AuthenticationResult.IdToken,
26743
- refresh_token
26744
- };
26745
- this.setToken(newToken);
26746
- return Promise.resolve(newToken);
26747
- }
26748
- return Promise.resolve({ access_token, id_token, refresh_token });
26749
- }
26750
- async isAuthorized(context) {
26751
- return !!await this.authorize(context);
26752
- }
26753
- async isAuthenticated() {
26754
- return !!await this.getUser();
26755
- }
26756
- async logout() {
26757
- this.setToken(null);
26758
- }
26759
- async authenticate() {
26760
- const token = await authenticate(this.clientId, this.frontendUrl);
26761
- this.setToken(token);
26762
- return token;
26763
- }
26764
- async authorize(context) {
26765
- return this.getToken();
26766
- }
26767
- /**
26768
- * Wraps the normal fetch function with same API but adds the authorization header token.
26769
- *
26770
- * @example
26771
- * const test = await tinaCloudClient.fetchWithToken(`/mycustomAPI/thing/one`) // the token will be passed in the authorization header
26772
- *
26773
- * @param input fetch function input
26774
- * @param init fetch function init
26775
- */
26776
- async fetchWithToken(input, init) {
26777
- const headers2 = (init == null ? void 0 : init.headers) || {};
26778
- const token = await this.getToken();
26779
- if (token == null ? void 0 : token.id_token) {
26780
- headers2["Authorization"] = "Bearer " + (token == null ? void 0 : token.id_token);
26781
- }
26782
- return await fetch(input, {
26783
- ...init,
26784
- headers: new Headers(headers2)
26785
- });
26786
- }
26787
- async getUser() {
26788
- if (!this.clientId) {
26789
- return null;
26790
- }
26791
- const url = `${this.identityApiUrl}/v2/apps/${this.clientId}/currentUser`;
26792
- try {
26793
- const res = await this.fetchWithToken(url, {
26794
- method: "GET"
26795
- });
26796
- const val = await res.json();
26797
- if (!res.status.toString().startsWith("2")) {
26798
- console.error(val.error);
26799
- return null;
26800
- }
26801
- return val;
26802
- } catch (e) {
26803
- console.error(e);
26804
- return null;
26805
- }
26806
- }
26807
27159
  async getBillingState() {
26808
27160
  if (!this.clientId) {
26809
27161
  return null;
26810
27162
  }
26811
27163
  const url = `${this.identityApiUrl}/v2/apps/${this.clientId}/billing/state`;
26812
27164
  try {
26813
- const res = await this.fetchWithToken(url, {
27165
+ const res = await this.authProvider.fetchWithToken(url, {
26814
27166
  method: "GET"
26815
27167
  });
26816
27168
  const val = await res.json();
@@ -26876,7 +27228,7 @@ mutation addPendingDocumentMutation(
26876
27228
  }
26877
27229
  async getIndexStatus({ ref }) {
26878
27230
  const url = `${this.contentApiBase}/db/${this.clientId}/status/${ref}`;
26879
- const res = await this.fetchWithToken(url);
27231
+ const res = await this.authProvider.fetchWithToken(url);
26880
27232
  const result = await res.json();
26881
27233
  const parsedResult = IndexStatusResponse.parse(result);
26882
27234
  return parsedResult;
@@ -26884,7 +27236,7 @@ mutation addPendingDocumentMutation(
26884
27236
  async listBranches(args) {
26885
27237
  try {
26886
27238
  const url = `${this.contentApiBase}/github/${this.clientId}/list_branches`;
26887
- const res = await this.fetchWithToken(url, {
27239
+ const res = await this.authProvider.fetchWithToken(url, {
26888
27240
  method: "GET"
26889
27241
  });
26890
27242
  const branches = await res.json();
@@ -26914,7 +27266,7 @@ mutation addPendingDocumentMutation(
26914
27266
  async createBranch({ baseBranch, branchName }) {
26915
27267
  const url = `${this.contentApiBase}/github/${this.clientId}/create_branch`;
26916
27268
  try {
26917
- const res = await this.fetchWithToken(url, {
27269
+ const res = await this.authProvider.fetchWithToken(url, {
26918
27270
  method: "POST",
26919
27271
  body: JSON.stringify({
26920
27272
  baseBranch,
@@ -26938,9 +27290,9 @@ mutation addPendingDocumentMutation(
26938
27290
  }
26939
27291
  }
26940
27292
  const DEFAULT_LOCAL_TINA_GQL_SERVER_URL = "http://localhost:4001/graphql";
26941
- const LOCAL_CLIENT_KEY = "tina.local.isLogedIn";
26942
27293
  class LocalClient extends Client {
26943
27294
  constructor(props) {
27295
+ var _a, _b, _c;
26944
27296
  const clientProps = {
26945
27297
  ...props,
26946
27298
  clientId: "",
@@ -26949,21 +27301,11 @@ class LocalClient extends Client {
26949
27301
  customContentApiUrl: props && props.customContentApiUrl ? props.customContentApiUrl : DEFAULT_LOCAL_TINA_GQL_SERVER_URL
26950
27302
  };
26951
27303
  super(clientProps);
27304
+ this.authProvider = ((_c = (_b = (_a = this.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.config) == null ? void 0 : _c.authProvider) || new LocalAuthProvider();
26952
27305
  }
26953
27306
  get isLocalMode() {
26954
27307
  return true;
26955
27308
  }
26956
- // These functions allow the local client to have a login state so that we can correctly call the "OnLogin" callback. This is important for things like preview mode
26957
- async logout() {
26958
- localStorage.removeItem(LOCAL_CLIENT_KEY);
26959
- }
26960
- async authenticate() {
26961
- localStorage.setItem(LOCAL_CLIENT_KEY, "true");
26962
- return { access_token: "LOCAL", id_token: "LOCAL", refresh_token: "LOCAL" };
26963
- }
26964
- async getUser() {
26965
- return localStorage.getItem(LOCAL_CLIENT_KEY) === "true";
26966
- }
26967
27309
  }
26968
27310
  class TinaCMSSearchClient {
26969
27311
  constructor(client, tinaSearchConfig) {
@@ -26978,13 +27320,13 @@ class TinaCMSSearchClient {
26978
27320
  );
26979
27321
  const opt = optionsToSearchIndexOptions(options);
26980
27322
  const optionsParam = opt["PAGE"] ? `&options=${JSON.stringify(opt)}` : "";
26981
- const res = await this.client.fetchWithToken(
27323
+ const res = await this.client.authProvider.fetchWithToken(
26982
27324
  `${this.client.contentApiBase}/searchIndex/${this.client.clientId}/${this.client.getBranch()}?q=${JSON.stringify(q)}${optionsParam}`
26983
27325
  );
26984
27326
  return parseSearchIndexResponse(await res.json(), options);
26985
27327
  }
26986
27328
  async del(ids) {
26987
- const res = await this.client.fetchWithToken(
27329
+ const res = await this.client.authProvider.fetchWithToken(
26988
27330
  `${this.client.contentApiBase}/searchIndex/${this.client.clientId}/${this.client.getBranch()}?ids=${ids.join(",")}`,
26989
27331
  {
26990
27332
  method: "DELETE"
@@ -26995,7 +27337,7 @@ class TinaCMSSearchClient {
26995
27337
  }
26996
27338
  }
26997
27339
  async put(docs) {
26998
- const res = await this.client.fetchWithToken(
27340
+ const res = await this.client.authProvider.fetchWithToken(
26999
27341
  `${this.client.contentApiBase}/searchIndex/${this.client.clientId}/${this.client.getBranch()}`,
27000
27342
  {
27001
27343
  method: "POST",
@@ -27021,7 +27363,7 @@ class LocalSearchClient {
27021
27363
  const q = queryToSearchIndexQuery(query);
27022
27364
  const opt = optionsToSearchIndexOptions(options);
27023
27365
  const optionsParam = opt["PAGE"] ? `&options=${JSON.stringify(opt)}` : "";
27024
- const res = await this.client.fetchWithToken(
27366
+ const res = await this.client.authProvider.fetchWithToken(
27025
27367
  `http://localhost:4001/searchIndex?q=${JSON.stringify(q)}${optionsParam}`
27026
27368
  );
27027
27369
  return parseSearchIndexResponse(await res.json(), options);
@@ -27037,12 +27379,19 @@ class LocalSearchClient {
27037
27379
  }
27038
27380
  }
27039
27381
  function ModalBuilder(modalProps) {
27040
- return /* @__PURE__ */ React__default.createElement(Modal, null, /* @__PURE__ */ React__default.createElement(ModalPopup, null, /* @__PURE__ */ React__default.createElement(ModalHeader, null, modalProps.title), /* @__PURE__ */ React__default.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React__default.createElement("p", null, modalProps.message), modalProps.error && /* @__PURE__ */ React__default.createElement(ErrorLabel, null, modalProps.error)), /* @__PURE__ */ React__default.createElement(ModalActions, null, modalProps.actions.map((action) => /* @__PURE__ */ React__default.createElement(AsyncButton, { key: action.name, ...action })))));
27382
+ return /* @__PURE__ */ React__default.createElement(Modal, null, /* @__PURE__ */ React__default.createElement(ModalPopup, null, /* @__PURE__ */ React__default.createElement(ModalHeader, null, modalProps.title), /* @__PURE__ */ React__default.createElement(ModalBody, { padded: true }, modalProps.message && /* @__PURE__ */ React__default.createElement("p", null, modalProps.message), modalProps.error && /* @__PURE__ */ React__default.createElement(ErrorLabel, null, modalProps.error), modalProps.children), /* @__PURE__ */ React__default.createElement(ModalActions, null, modalProps.actions.map((action) => /* @__PURE__ */ React__default.createElement(AsyncButton, { key: action.name, ...action })))));
27041
27383
  }
27042
27384
  const ErrorLabel = ({ style = {}, ...props }) => /* @__PURE__ */ React__default.createElement("p", { style: { ...style, color: "var(--tina-color-error)" }, ...props });
27043
27385
  const AsyncButton = ({ name, primary, action }) => {
27044
27386
  const [submitting, setSubmitting] = useState(false);
27387
+ const [mounted, setMounted] = useState(false);
27388
+ useEffect(() => {
27389
+ setMounted(true);
27390
+ return () => setMounted(false);
27391
+ }, []);
27045
27392
  const onClick = useCallback(async () => {
27393
+ if (!mounted)
27394
+ return;
27046
27395
  setSubmitting(true);
27047
27396
  try {
27048
27397
  await action();
@@ -27051,7 +27400,7 @@ const AsyncButton = ({ name, primary, action }) => {
27051
27400
  setSubmitting(false);
27052
27401
  throw e;
27053
27402
  }
27054
- }, [action, setSubmitting]);
27403
+ }, [action, setSubmitting, mounted]);
27055
27404
  return /* @__PURE__ */ React__default.createElement(
27056
27405
  Button,
27057
27406
  {
@@ -27127,7 +27476,7 @@ class TinaAdminApi {
27127
27476
  }
27128
27477
  }
27129
27478
  async isAuthenticated() {
27130
- return await this.api.isAuthenticated();
27479
+ return await this.api.authProvider.isAuthenticated();
27131
27480
  }
27132
27481
  async checkGraphqlSchema({ localSchema }) {
27133
27482
  const schemaFromCloud = await this.api.getSchema();
@@ -27449,17 +27798,29 @@ const AuthWallInner = ({
27449
27798
  loginScreen,
27450
27799
  getModalActions
27451
27800
  }) => {
27452
- var _a, _b, _c, _d, _e;
27801
+ var _a, _b, _c;
27453
27802
  const client = cms.api.tina;
27454
- const isTinaCloud = !client.isLocalMode && !((_e = (_d = (_c = (_b = (_a = client.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.config) == null ? void 0 : _c.admin) == null ? void 0 : _d.auth) == null ? void 0 : _e.customAuth);
27803
+ const isTinaCloud = !client.isLocalMode && !((_c = (_b = (_a = client.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.config) == null ? void 0 : _c.contentApiUrlOverride);
27804
+ const loginStrategy = client.authProvider.getLoginStrategy();
27455
27805
  const [activeModal, setActiveModal] = useState(null);
27456
27806
  const [errorMessage, setErrorMessage] = useState();
27457
27807
  const [showChildren, setShowChildren] = useState(false);
27808
+ const [authProps, setAuthProps] = useState({ username: "", password: "" });
27809
+ const [authenticated, setAuthenticated] = useState(false);
27458
27810
  React__default.useEffect(() => {
27459
- client.isAuthenticated().then((isAuthenticated) => {
27811
+ let mounted = true;
27812
+ client.authProvider.isAuthenticated().then((isAuthenticated) => {
27813
+ if (!mounted)
27814
+ return;
27460
27815
  if (isAuthenticated) {
27461
- client.isAuthorized().then((isAuthorized) => {
27816
+ client.authProvider.isAuthorized().then(async (isAuthorized) => {
27817
+ if (!mounted)
27818
+ return;
27462
27819
  if (isAuthorized) {
27820
+ const user = await client.authProvider.getUser();
27821
+ if (user.passwordChangeRequired) {
27822
+ window.location.hash = "#/screens/change_password";
27823
+ }
27463
27824
  setShowChildren(true);
27464
27825
  cms.enable();
27465
27826
  } else {
@@ -27470,6 +27831,8 @@ const AuthWallInner = ({
27470
27831
  setActiveModal("error");
27471
27832
  }
27472
27833
  }).catch((e) => {
27834
+ if (!mounted)
27835
+ return;
27473
27836
  console.error(e);
27474
27837
  setErrorMessage({ title: "Unexpected Error:", message: `${e}` });
27475
27838
  setActiveModal("error");
@@ -27480,33 +27843,59 @@ const AuthWallInner = ({
27480
27843
  });
27481
27844
  }
27482
27845
  }).catch((e) => {
27846
+ if (!mounted)
27847
+ return;
27483
27848
  console.error(e);
27484
27849
  setErrorMessage({ title: "Unexpected Error:", message: `${e}` });
27485
27850
  setActiveModal("error");
27486
27851
  });
27487
- }, []);
27852
+ return () => {
27853
+ mounted = false;
27854
+ };
27855
+ }, [authenticated]);
27488
27856
  const onAuthenticated = async () => {
27489
- if (await client.isAuthorized()) {
27490
- setShowChildren(true);
27491
- setActiveModal(null);
27492
- cms.events.dispatch({ type: "cms:login" });
27493
- } else {
27494
- setErrorMessage({
27495
- title: "Access Denied:",
27496
- message: "Not Authorized To Edit"
27497
- });
27498
- setActiveModal("error");
27499
- }
27857
+ setAuthenticated(true);
27858
+ setActiveModal(null);
27859
+ cms.events.dispatch({ type: "cms:login" });
27500
27860
  };
27501
27861
  const otherModalActions = getModalActions ? getModalActions({
27502
27862
  closeModal: () => {
27503
27863
  setActiveModal(null);
27504
27864
  }
27505
27865
  }) : [];
27506
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, activeModal === "authenticate" && /* @__PURE__ */ React__default.createElement(
27866
+ const handleAuthenticate = async () => {
27867
+ try {
27868
+ setAuthenticated(false);
27869
+ const token = await client.authProvider.authenticate(authProps);
27870
+ if (typeof (client == null ? void 0 : client.onLogin) === "function") {
27871
+ await (client == null ? void 0 : client.onLogin({ token }));
27872
+ }
27873
+ return onAuthenticated();
27874
+ } catch (e) {
27875
+ console.error(e);
27876
+ setActiveModal("error");
27877
+ setErrorMessage({
27878
+ title: "Authentication Error",
27879
+ message: `${e}`
27880
+ });
27881
+ }
27882
+ };
27883
+ let modalTitle = "Tina Cloud Authorization";
27884
+ if (activeModal === "authenticate" && loginStrategy === "Redirect" && !isTinaCloud) {
27885
+ modalTitle = "Enter into edit mode";
27886
+ } else if (activeModal === "authenticate" && loginStrategy === "UsernamePassword") {
27887
+ modalTitle = "Sign in to Tina";
27888
+ } else if (activeModal === "error") {
27889
+ if (loginStrategy === "Redirect" && !isTinaCloud) {
27890
+ modalTitle = "Enter into edit mode";
27891
+ } else if (loginStrategy === "UsernamePassword") {
27892
+ modalTitle = "Sign in to Tina";
27893
+ }
27894
+ }
27895
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, activeModal === "authenticate" && loginStrategy === "Redirect" && /* @__PURE__ */ React__default.createElement(
27507
27896
  ModalBuilder,
27508
27897
  {
27509
- title: isTinaCloud ? "Tina Cloud Authorization" : "Enter into edit mode",
27898
+ title: modalTitle,
27510
27899
  message: isTinaCloud ? "To save edits, Tina Cloud authorization is required. On save, changes will get committed using your account." : "To save edits, enter into edit mode. On save, changes will saved to the local filesystem.",
27511
27900
  close,
27512
27901
  actions: [
@@ -27521,30 +27910,61 @@ const AuthWallInner = ({
27521
27910
  },
27522
27911
  {
27523
27912
  name: isTinaCloud ? "Continue to Tina Cloud" : "Enter Edit Mode",
27524
- action: async () => {
27525
- try {
27526
- const token = await client.authenticate();
27527
- if (typeof (client == null ? void 0 : client.onLogin) === "function") {
27528
- await (client == null ? void 0 : client.onLogin({ token }));
27529
- }
27530
- return onAuthenticated();
27531
- } catch (e) {
27532
- console.error(e);
27533
- setActiveModal("error");
27534
- setErrorMessage({
27535
- title: "Unexpected Error:",
27536
- message: `${e}`
27537
- });
27538
- }
27539
- },
27913
+ action: handleAuthenticate,
27540
27914
  primary: true
27541
27915
  }
27542
27916
  ]
27543
27917
  }
27918
+ ), activeModal === "authenticate" && loginStrategy === "UsernamePassword" && /* @__PURE__ */ React__default.createElement(
27919
+ ModalBuilder,
27920
+ {
27921
+ title: modalTitle,
27922
+ message: "",
27923
+ close,
27924
+ actions: [
27925
+ ...otherModalActions,
27926
+ {
27927
+ name: "Login",
27928
+ action: handleAuthenticate,
27929
+ primary: true
27930
+ }
27931
+ ]
27932
+ },
27933
+ /* @__PURE__ */ React__default.createElement("div", { className: "flex items-center justify-center bg-gray-50 px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React__default.createElement("div", { className: "max-w-md w-full space-y-6" }, /* @__PURE__ */ React__default.createElement("label", { className: "block" }, /* @__PURE__ */ React__default.createElement("span", { className: "text-gray-700" }, "Username"), /* @__PURE__ */ React__default.createElement(
27934
+ BaseTextField,
27935
+ {
27936
+ id: "username",
27937
+ name: "username",
27938
+ type: "text",
27939
+ autoComplete: "username",
27940
+ required: true,
27941
+ placeholder: "Username",
27942
+ value: authProps.username,
27943
+ onChange: (e) => setAuthProps((prevState) => ({
27944
+ ...prevState,
27945
+ username: e.target.value
27946
+ }))
27947
+ }
27948
+ )), /* @__PURE__ */ React__default.createElement("label", { className: "block" }, /* @__PURE__ */ React__default.createElement("span", { className: "text-gray-700" }, "Password"), /* @__PURE__ */ React__default.createElement(
27949
+ BaseTextField,
27950
+ {
27951
+ id: "password",
27952
+ name: "password",
27953
+ type: "password",
27954
+ autoComplete: "current-password",
27955
+ required: true,
27956
+ placeholder: "Password",
27957
+ value: authProps.password,
27958
+ onChange: (e) => setAuthProps((prevState) => ({
27959
+ ...prevState,
27960
+ password: e.target.value
27961
+ }))
27962
+ }
27963
+ ))))
27544
27964
  ), activeModal === "error" && errorMessage && /* @__PURE__ */ React__default.createElement(
27545
27965
  ModalBuilder,
27546
27966
  {
27547
- title: isTinaCloud ? "Tina Cloud Authorization" : "Enter into edit mode",
27967
+ title: modalTitle,
27548
27968
  message: errorMessage.title,
27549
27969
  error: errorMessage.message,
27550
27970
  close,
@@ -27556,13 +27976,12 @@ const AuthWallInner = ({
27556
27976
  try {
27557
27977
  setActiveModal(null);
27558
27978
  setErrorMessage(void 0);
27559
- await client.logout();
27560
- await client.onLogout();
27561
- const token = await client.authenticate();
27562
- if (typeof (client == null ? void 0 : client.onLogin) === "function") {
27563
- await (client == null ? void 0 : client.onLogin({ token }));
27979
+ const { authProvider } = client;
27980
+ await authProvider.logout();
27981
+ if (typeof (client == null ? void 0 : client.onLogout) === "function") {
27982
+ await client.onLogout();
27564
27983
  }
27565
- return onAuthenticated();
27984
+ window.location.href = new URL(window.location.href).pathname;
27566
27985
  } catch (e) {
27567
27986
  console.error(e);
27568
27987
  setActiveModal("error");
@@ -27579,7 +27998,7 @@ const AuthWallInner = ({
27579
27998
  ), showChildren ? children : loginScreen ? loginScreen : null);
27580
27999
  };
27581
28000
  const TinaCloudProvider = (props) => {
27582
- var _a, _b, _c, _d, _e;
28001
+ var _a, _b, _c;
27583
28002
  const baseBranch = props.branch || "main";
27584
28003
  const [currentBranch, setCurrentBranch] = useLocalStorage(
27585
28004
  "tinacms-current-branch",
@@ -27602,7 +28021,7 @@ const TinaCloudProvider = (props) => {
27602
28021
  cms.api.tina.setBranch(currentBranch);
27603
28022
  }
27604
28023
  useEffect(() => {
27605
- var _a2, _b2, _c2, _d2, _e2, _f;
28024
+ var _a2, _b2, _c2, _d, _e, _f;
27606
28025
  let searchClient;
27607
28026
  if (props.isLocalClient) {
27608
28027
  searchClient = new LocalSearchClient(cms.api.tina);
@@ -27611,10 +28030,10 @@ const TinaCloudProvider = (props) => {
27611
28030
  if (hasTinaSearch) {
27612
28031
  searchClient = new TinaCMSSearchClient(
27613
28032
  cms.api.tina,
27614
- (_d2 = (_c2 = props.schema.config) == null ? void 0 : _c2.search) == null ? void 0 : _d2.tina
28033
+ (_d = (_c2 = props.schema.config) == null ? void 0 : _c2.search) == null ? void 0 : _d.tina
27615
28034
  );
27616
28035
  } else {
27617
- searchClient = (_f = (_e2 = props.schema.config) == null ? void 0 : _e2.search) == null ? void 0 : _f.searchClient;
28036
+ searchClient = (_f = (_e = props.schema.config) == null ? void 0 : _e.search) == null ? void 0 : _f.searchClient;
27618
28037
  }
27619
28038
  }
27620
28039
  if (searchClient) {
@@ -27625,7 +28044,7 @@ const TinaCloudProvider = (props) => {
27625
28044
  cms.registerApi("admin", new TinaAdminApi(cms));
27626
28045
  }
27627
28046
  const setupMedia = async (staticMedia) => {
27628
- var _a2, _b2, _c2, _d2, _e2, _f, _g;
28047
+ var _a2, _b2, _c2, _d, _e, _f, _g;
27629
28048
  const hasTinaMedia = Boolean((_b2 = (_a2 = props.schema.config) == null ? void 0 : _a2.media) == null ? void 0 : _b2.tina);
27630
28049
  if (hasTinaMedia) {
27631
28050
  cms.media.store = new TinaMediaStore(cms, staticMedia);
@@ -27633,9 +28052,9 @@ const TinaCloudProvider = (props) => {
27633
28052
  /*
27634
28053
  Has tina custom media (set up in the schema or define schema)
27635
28054
  */
27636
- ((_d2 = (_c2 = props.schema.config) == null ? void 0 : _c2.media) == null ? void 0 : _d2.loadCustomStore) || props.mediaStore
28055
+ ((_d = (_c2 = props.schema.config) == null ? void 0 : _c2.media) == null ? void 0 : _d.loadCustomStore) || props.mediaStore
27637
28056
  ) {
27638
- const mediaStoreFromProps = ((_f = (_e2 = props.schema.config) == null ? void 0 : _e2.media) == null ? void 0 : _f.loadCustomStore) || props.mediaStore;
28057
+ const mediaStoreFromProps = ((_f = (_e = props.schema.config) == null ? void 0 : _e.media) == null ? void 0 : _f.loadCustomStore) || props.mediaStore;
27639
28058
  if ((_g = mediaStoreFromProps.prototype) == null ? void 0 : _g.persist) {
27640
28059
  cms.media.store = new mediaStoreFromProps(cms.api.tina);
27641
28060
  } else {
@@ -27647,7 +28066,8 @@ const TinaCloudProvider = (props) => {
27647
28066
  }
27648
28067
  };
27649
28068
  const client = cms.api.tina;
27650
- const isTinaCloud = !client.isLocalMode && !((_e = (_d = (_c = (_b = (_a = client.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.config) == null ? void 0 : _c.admin) == null ? void 0 : _d.auth) == null ? void 0 : _e.customAuth);
28069
+ const isTinaCloud = !client.isLocalMode && !((_c = (_b = (_a = client.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.config) == null ? void 0 : _c.contentApiUrlOverride);
28070
+ const SessionProvider = client.authProvider.getSessionProvider();
27651
28071
  const handleListBranches = async () => {
27652
28072
  const branches = await cms.api.tina.listBranches({
27653
28073
  includeIndexStatus: true
@@ -27661,7 +28081,9 @@ const TinaCloudProvider = (props) => {
27661
28081
  const newBranch = await cms.api.tina.createBranch(data);
27662
28082
  return newBranch;
27663
28083
  };
27664
- setupMedia(props.staticMedia);
28084
+ setupMedia(props.staticMedia).catch((e) => {
28085
+ console.error(e);
28086
+ });
27665
28087
  const [branchingEnabled, setBranchingEnabled] = React__default.useState(
27666
28088
  () => cms.flags.get("branch-switcher")
27667
28089
  );
@@ -27714,7 +28136,7 @@ const TinaCloudProvider = (props) => {
27714
28136
  });
27715
28137
  return unsubscribe;
27716
28138
  }, [isTinaCloud, cms]);
27717
- return /* @__PURE__ */ React__default.createElement(
28139
+ return /* @__PURE__ */ React__default.createElement(SessionProvider, { basePath: "/api/tina/auth" }, /* @__PURE__ */ React__default.createElement(
27718
28140
  BranchDataProvider,
27719
28141
  {
27720
28142
  currentBranch,
@@ -27723,7 +28145,7 @@ const TinaCloudProvider = (props) => {
27723
28145
  }
27724
28146
  },
27725
28147
  /* @__PURE__ */ React__default.createElement(TinaProvider, { cms }, /* @__PURE__ */ React__default.createElement(AuthWallInner, { ...props, cms }))
27726
- );
28148
+ ));
27727
28149
  };
27728
28150
  const TinaCloudAuthWall = TinaCloudProvider;
27729
28151
  class ContentCreatorPlugin {
@@ -28002,14 +28424,13 @@ const TinaCMSProvider2 = ({
28002
28424
  schema,
28003
28425
  ...props
28004
28426
  }) => {
28005
- var _a, _b, _c, _d, _e, _f;
28427
+ var _a, _b, _c;
28006
28428
  if (props == null ? void 0 : props.apiURL) {
28007
28429
  console.warn(
28008
28430
  "The apiURL prop is deprecated. Please see https://tina.io/blog/tina-v-0.68.14 for information on how to upgrade to the new API"
28009
28431
  );
28010
28432
  }
28011
28433
  const apiURL = ((_a = props == null ? void 0 : props.client) == null ? void 0 : _a.apiUrl) || (props == null ? void 0 : props.apiURL);
28012
- const isLocalOverride = (_d = (_c = (_b = schema == null ? void 0 : schema.config) == null ? void 0 : _b.admin) == null ? void 0 : _c.auth) == null ? void 0 : _d.useLocalAuth;
28013
28434
  const { branch, clientId, isLocalClient } = apiURL ? parseURL(apiURL) : {
28014
28435
  branch: props.branch,
28015
28436
  clientId: props.clientId,
@@ -28035,10 +28456,10 @@ const TinaCMSProvider2 = ({
28035
28456
  TinaCloudProvider,
28036
28457
  {
28037
28458
  branch,
28038
- clientId: clientId || ((_e = schema == null ? void 0 : schema.config) == null ? void 0 : _e.clientId),
28459
+ clientId: clientId || ((_b = schema == null ? void 0 : schema.config) == null ? void 0 : _b.clientId),
28039
28460
  tinaioConfig: props.tinaioConfig,
28040
- isLocalClient: isLocalOverride || isLocalClient,
28041
- isSelfHosted: !!((_f = schema == null ? void 0 : schema.config) == null ? void 0 : _f.contentApiUrlOverride),
28461
+ isLocalClient,
28462
+ isSelfHosted: !!((_c = schema == null ? void 0 : schema.config) == null ? void 0 : _c.contentApiUrlOverride),
28042
28463
  cmsCallback: props.cmsCallback,
28043
28464
  mediaStore: props.mediaStore,
28044
28465
  apiUrl: apiURL,
@@ -28242,6 +28663,12 @@ const Sidebar = ({ cms }) => {
28242
28663
  const navBreakpoint2 = 1e3;
28243
28664
  const windowWidth = useWindowWidth();
28244
28665
  const renderDesktopNav = windowWidth > navBreakpoint2;
28666
+ const activeScreens = screens.filter(
28667
+ (screen) => {
28668
+ var _a2;
28669
+ return screen.navCategory !== "Account" || ((_a2 = cms.api.tina.authProvider) == null ? void 0 : _a2.getLoginStrategy()) === "UsernamePassword";
28670
+ }
28671
+ );
28245
28672
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, renderDesktopNav && /* @__PURE__ */ React__default.createElement(
28246
28673
  Nav,
28247
28674
  {
@@ -28249,7 +28676,7 @@ const Sidebar = ({ cms }) => {
28249
28676
  sidebarWidth: 360,
28250
28677
  showCollections: true,
28251
28678
  collectionsInfo,
28252
- screens,
28679
+ screens: activeScreens,
28253
28680
  cloudConfigs,
28254
28681
  contentCreators: [],
28255
28682
  RenderNavSite: ({ view }) => /* @__PURE__ */ React__default.createElement(
@@ -28268,6 +28695,14 @@ const Sidebar = ({ cms }) => {
28268
28695
  to: `/collections/${collection.name}/~`,
28269
28696
  Icon: ImFilesEmpty
28270
28697
  }
28698
+ ),
28699
+ AuthRenderNavCollection: ({ collection }) => /* @__PURE__ */ React__default.createElement(
28700
+ SidebarLink,
28701
+ {
28702
+ label: collection.label ? collection.label : collection.name,
28703
+ to: `/collections/${collection.name}/~`,
28704
+ Icon: ImUsers
28705
+ }
28271
28706
  )
28272
28707
  }
28273
28708
  ), !renderDesktopNav && /* @__PURE__ */ React__default.createElement(Transition, { show: menuIsOpen }, /* @__PURE__ */ React__default.createElement(
@@ -28289,7 +28724,7 @@ const Sidebar = ({ cms }) => {
28289
28724
  sidebarWidth: 360,
28290
28725
  showCollections: true,
28291
28726
  collectionsInfo,
28292
- screens,
28727
+ screens: activeScreens,
28293
28728
  cloudConfigs,
28294
28729
  contentCreators: [],
28295
28730
  RenderNavSite: ({ view }) => /* @__PURE__ */ React__default.createElement(
@@ -28314,6 +28749,17 @@ const Sidebar = ({ cms }) => {
28314
28749
  setMenuIsOpen(false);
28315
28750
  }
28316
28751
  }
28752
+ ),
28753
+ AuthRenderNavCollection: ({ collection }) => /* @__PURE__ */ React__default.createElement(
28754
+ SidebarLink,
28755
+ {
28756
+ label: collection.label ? collection.label : collection.name,
28757
+ to: `/collections/${collection.name}/~`,
28758
+ Icon: ImUsers,
28759
+ onClick: () => {
28760
+ setMenuIsOpen(false);
28761
+ }
28762
+ }
28317
28763
  )
28318
28764
  },
28319
28765
  /* @__PURE__ */ React__default.createElement("div", { className: "absolute top-8 right-0 transform translate-x-full overflow-hidden" }, /* @__PURE__ */ React__default.createElement(
@@ -28452,11 +28898,11 @@ const LogoutRedirect = () => {
28452
28898
  const [searchParams] = useSearchParams();
28453
28899
  const slug = searchParams.get("slug") || "/";
28454
28900
  const logout2 = async () => {
28455
- var _a, _b, _c, _d, _e, _f;
28456
- if ((_b = (_a = cms == null ? void 0 : cms.api) == null ? void 0 : _a.tina) == null ? void 0 : _b.logout) {
28457
- await cms.api.tina.logout();
28458
- if ((_d = (_c = cms == null ? void 0 : cms.api) == null ? void 0 : _c.tina) == null ? void 0 : _d.onLogout) {
28459
- await ((_f = (_e = cms == null ? void 0 : cms.api) == null ? void 0 : _e.tina) == null ? void 0 : _f.onLogout());
28901
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
28902
+ if ((_c = (_b = (_a = cms == null ? void 0 : cms.api) == null ? void 0 : _a.tina) == null ? void 0 : _b.authProvider) == null ? void 0 : _c.logout) {
28903
+ await ((_f = (_e = (_d = cms == null ? void 0 : cms.api) == null ? void 0 : _d.tina) == null ? void 0 : _e.authProvider) == null ? void 0 : _f.logout());
28904
+ if ((_h = (_g = cms == null ? void 0 : cms.api) == null ? void 0 : _g.tina) == null ? void 0 : _h.onLogout) {
28905
+ await ((_j = (_i = cms == null ? void 0 : cms.api) == null ? void 0 : _i.tina) == null ? void 0 : _j.onLogout());
28460
28906
  }
28461
28907
  }
28462
28908
  setEdit(false);
@@ -30660,6 +31106,7 @@ const defineStaticConfig = (config) => {
30660
31106
  };
30661
31107
  const defineConfig = defineStaticConfig;
30662
31108
  export {
31109
+ AbstractAuthProvider,
30663
31110
  ActionButton,
30664
31111
  AddIcon,
30665
31112
  AlertIcon,
@@ -30668,6 +31115,7 @@ export {
30668
31115
  AlignLeft,
30669
31116
  AlignRight,
30670
31117
  AuthWallInner,
31118
+ BasePasswordField,
30671
31119
  BaseTextField,
30672
31120
  BillingWarning,
30673
31121
  BlocksField,
@@ -30762,6 +31210,7 @@ export {
30762
31210
  ListField,
30763
31211
  ListFieldPlugin,
30764
31212
  LoadingDots,
31213
+ LocalAuthProvider,
30765
31214
  LocalClient,
30766
31215
  LocalSearchClient,
30767
31216
  LocalWarning,
@@ -30790,6 +31239,8 @@ export {
30790
31239
  OverflowMenu$1 as OverflowMenu,
30791
31240
  PanelBody,
30792
31241
  PanelHeader$1 as PanelHeader,
31242
+ PasswordFieldComponent,
31243
+ PasswordFieldPlugin,
30793
31244
  PopupModal,
30794
31245
  PrefixedTextField,
30795
31246
  PullRequestIcon,
@@ -30831,6 +31282,7 @@ export {
30831
31282
  TinaCMSProvider,
30832
31283
  TinaCMSProvider2,
30833
31284
  TinaCMSSearchClient,
31285
+ TinaCloudAuthProvider,
30834
31286
  TinaCloudAuthWall,
30835
31287
  TinaCloudProvider,
30836
31288
  TinaField,
@@ -30849,7 +31301,6 @@ export {
30849
31301
  UploadIcon,
30850
31302
  WarningIcon,
30851
31303
  assertShape,
30852
- asyncPoll,
30853
31304
  classNames,
30854
31305
  createClient,
30855
31306
  TinaCMSProvider2 as default,
@@ -30861,6 +31312,7 @@ export {
30861
31312
  getFilteredBranchList,
30862
31313
  getStaticPropsForTina,
30863
31314
  gql,
31315
+ passwordFieldClasses,
30864
31316
  resolveField,
30865
31317
  safeAssertShape,
30866
31318
  selectFieldClasses,