tinacms 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,5 +2,10 @@
2
2
 
3
3
  */
4
4
  /// <reference types="react" />
5
+ import { NavigateFunction } from 'react-router-dom';
6
+ import { TinaCMS } from '@tinacms/toolkit';
7
+ import type { CollectionResponse, DocumentSys } from '../types';
8
+ import type { Collection } from '@tinacms/schema-tools';
9
+ export declare const handleNavigate: (navigate: NavigateFunction, cms: TinaCMS, collection: CollectionResponse, collectionDefinition: Collection<true>, document: DocumentSys) => any;
5
10
  declare const CollectionListPage: () => JSX.Element;
6
11
  export default CollectionListPage;
@@ -1,17 +1,5 @@
1
- /**
2
-
3
- */
4
1
  import { Form } from '@tinacms/toolkit';
5
2
  import type { FormOptions, TinaCMS } from '@tinacms/toolkit';
6
- export declare const transformDocumentIntoMutationRequestPayload: (document: {
7
- [key: string]: unknown;
8
- _collection: string;
9
- __typename?: string;
10
- _template: string;
11
- }, instructions: {
12
- includeCollection?: boolean;
13
- includeTemplate?: boolean;
14
- }) => any;
15
3
  export declare const generateFormCreators: (cms: TinaCMS, showInSidebar?: boolean, global?: boolean | {
16
4
  icon?: any;
17
5
  layout: 'fullscreen' | 'popup';
package/dist/index.es.js CHANGED
@@ -58,12 +58,18 @@ const IndexStatusResponse = z.object({
58
58
  ]).optional(),
59
59
  timestamp: z.number().optional()
60
60
  });
61
- async function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
61
+ function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
62
62
  const endTime = new Date().getTime() + pollTimeout;
63
+ let stop = false;
64
+ const cancel = () => {
65
+ stop = true;
66
+ };
63
67
  const checkCondition = (resolve, reject) => {
64
68
  Promise.resolve(fn()).then((result) => {
65
69
  const now = new Date().getTime();
66
- if (result.done) {
70
+ if (stop) {
71
+ reject(new Error("AsyncPoller: cancelled"));
72
+ } else if (result.done) {
67
73
  resolve(result.data);
68
74
  } else if (now < endTime) {
69
75
  setTimeout(checkCondition, pollInterval, resolve, reject);
@@ -74,7 +80,7 @@ async function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
74
80
  reject(err);
75
81
  });
76
82
  };
77
- return new Promise(checkCondition);
83
+ return [new Promise(checkCondition), cancel];
78
84
  }
79
85
  class Client {
80
86
  constructor({ tokenStorage = "MEMORY", ...options }) {
@@ -231,6 +237,13 @@ mutation addPendingDocumentMutation(
231
237
  if (resBody.message) {
232
238
  errorMessage = `${errorMessage}, Response: ${resBody.message}`;
233
239
  }
240
+ errorMessage = `${errorMessage}, Please check that the following information is correct:
241
+ clientId: ${this.options.clientId}
242
+ branch: ${this.branch}.`;
243
+ if (this.branch !== "main") {
244
+ errorMessage = `${errorMessage}
245
+ Note: This error can occur if the branch does not exist on GitHub or on Tina Cloud`;
246
+ }
234
247
  throw new Error(errorMessage);
235
248
  }
236
249
  const json = await res.json();
@@ -376,15 +389,15 @@ mutation addPendingDocumentMutation(
376
389
  return null;
377
390
  }
378
391
  }
379
- async waitForIndexStatus({ ref }) {
392
+ waitForIndexStatus({ ref }) {
380
393
  try {
381
- const result = await asyncPoll(async () => {
394
+ const [prom, cancel] = asyncPoll(async () => {
382
395
  try {
383
- const result2 = await this.getIndexStatus({ ref });
384
- if (!(result2.status === "inprogress" || result2.status === "unknown")) {
396
+ const result = await this.getIndexStatus({ ref });
397
+ if (!(result.status === "inprogress" || result.status === "unknown")) {
385
398
  return Promise.resolve({
386
399
  done: true,
387
- data: result2
400
+ data: result
388
401
  });
389
402
  } else {
390
403
  return Promise.resolve({
@@ -395,7 +408,7 @@ mutation addPendingDocumentMutation(
395
408
  return Promise.reject(err);
396
409
  }
397
410
  }, 5e3, 9e5);
398
- return result;
411
+ return [prom, cancel];
399
412
  } catch (error) {
400
413
  if (error.message === "AsyncPoller: reached timeout") {
401
414
  console.warn(error);
@@ -3050,7 +3063,20 @@ const GetCollection = ({
3050
3063
  children,
3051
3064
  filterArgs
3052
3065
  }) => {
3066
+ const navigate = useNavigate();
3053
3067
  const { collection, loading, error, reFetchCollection, collectionExtra } = useGetCollection(cms, collectionName, includeDocuments, startCursor || "", sortKey, filterArgs) || {};
3068
+ useEffect(() => {
3069
+ var _a, _b, _c, _d, _e, _f, _g, _h;
3070
+ if (loading)
3071
+ return;
3072
+ const collectionDefinition = cms.api.tina.schema.getCollection(collection.name);
3073
+ const allowCreate = (_c = (_b = (_a = collectionDefinition == null ? void 0 : collectionDefinition.ui) == null ? void 0 : _a.allowedActions) == null ? void 0 : _b.create) != null ? _c : true;
3074
+ const allowDelete = (_f = (_e = (_d = collectionDefinition == null ? void 0 : collectionDefinition.ui) == null ? void 0 : _d.allowedActions) == null ? void 0 : _e.delete) != null ? _f : true;
3075
+ if (!allowCreate && !allowDelete && ((_h = (_g = collection.documents) == null ? void 0 : _g.edges) == null ? void 0 : _h.length) === 1) {
3076
+ const doc = collection.documents.edges[0].node;
3077
+ handleNavigate(navigate, cms, collection, collectionDefinition, doc);
3078
+ }
3079
+ }, [(collection == null ? void 0 : collection.name) || "", loading]);
3054
3080
  if (error) {
3055
3081
  return /* @__PURE__ */ React.createElement(FullscreenError, null);
3056
3082
  }
@@ -3612,42 +3638,6 @@ const RenameModal = ({
3612
3638
  function HiChevronRight(props) {
3613
3639
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 20 20", "fill": "currentColor" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z", "clipRule": "evenodd" } }] })(props);
3614
3640
  }
3615
- const transformDocumentIntoMutationRequestPayload = (document, instructions) => {
3616
- const { _collection, __typename, _template, ...rest } = document;
3617
- const params = transformParams(rest);
3618
- const paramsWithTemplate = instructions.includeTemplate ? { [_template]: params } : params;
3619
- return instructions.includeCollection ? { [_collection]: paramsWithTemplate } : paramsWithTemplate;
3620
- };
3621
- const transformParams = (data) => {
3622
- if (["string", "number", "boolean"].includes(typeof data)) {
3623
- return data;
3624
- }
3625
- if (Array.isArray(data)) {
3626
- return data.map((item) => transformParams(item));
3627
- }
3628
- try {
3629
- assertShape(data, (yup2) => yup2.object({ _template: yup2.string().required() }));
3630
- const { _template, __typename, ...rest } = data;
3631
- const nested = transformParams(rest);
3632
- return { [_template]: nested };
3633
- } catch (e) {
3634
- if (e.message === "Failed to assertShape - _template is a required field") {
3635
- if (!data) {
3636
- return [];
3637
- }
3638
- const accum = {};
3639
- Object.entries(data).map(([keyName, value]) => {
3640
- accum[keyName] = transformParams(value);
3641
- });
3642
- return accum;
3643
- } else {
3644
- if (!data) {
3645
- return [];
3646
- }
3647
- throw e;
3648
- }
3649
- }
3650
- };
3651
3641
  function FaLock(props) {
3652
3642
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 448 512" }, "child": [{ "tag": "path", "attr": { "d": "M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z" } }] })(props);
3653
3643
  }
@@ -3657,15 +3647,11 @@ function FaUnlock(props) {
3657
3647
  const createDocument = async (cms, collection, template, mutationInfo, values) => {
3658
3648
  const api = new TinaAdminApi(cms);
3659
3649
  const { filename, ...leftover } = values;
3660
- const { includeCollection, includeTemplate } = mutationInfo;
3661
3650
  const relativePath = `${filename}.${collection.format}`;
3662
- const params = transformDocumentIntoMutationRequestPayload({
3651
+ const params = api.schema.transformPayload(collection.name, {
3663
3652
  _collection: collection.name,
3664
3653
  ...template && { _template: template.name },
3665
3654
  ...leftover
3666
- }, {
3667
- includeCollection,
3668
- includeTemplate
3669
3655
  });
3670
3656
  if (await api.isAuthenticated()) {
3671
3657
  await api.createDocument(collection.name, relativePath, params);
@@ -3880,11 +3866,7 @@ const GetDocument = ({
3880
3866
  };
3881
3867
  const updateDocument = async (cms, relativePath, collection, mutationInfo, values) => {
3882
3868
  const api = new TinaAdminApi(cms);
3883
- const { includeCollection, includeTemplate } = mutationInfo;
3884
- const params = transformDocumentIntoMutationRequestPayload(values, {
3885
- includeCollection,
3886
- includeTemplate
3887
- });
3869
+ const params = api.schema.transformPayload(collection.name, values);
3888
3870
  if (await api.isAuthenticated()) {
3889
3871
  await api.updateDocument(collection.name, relativePath, params);
3890
3872
  } else {
package/dist/index.js CHANGED
@@ -73,12 +73,18 @@
73
73
  ]).optional(),
74
74
  timestamp: zod.z.number().optional()
75
75
  });
76
- async function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
76
+ function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
77
77
  const endTime = new Date().getTime() + pollTimeout;
78
+ let stop = false;
79
+ const cancel = () => {
80
+ stop = true;
81
+ };
78
82
  const checkCondition = (resolve, reject) => {
79
83
  Promise.resolve(fn()).then((result) => {
80
84
  const now = new Date().getTime();
81
- if (result.done) {
85
+ if (stop) {
86
+ reject(new Error("AsyncPoller: cancelled"));
87
+ } else if (result.done) {
82
88
  resolve(result.data);
83
89
  } else if (now < endTime) {
84
90
  setTimeout(checkCondition, pollInterval, resolve, reject);
@@ -89,7 +95,7 @@
89
95
  reject(err);
90
96
  });
91
97
  };
92
- return new Promise(checkCondition);
98
+ return [new Promise(checkCondition), cancel];
93
99
  }
94
100
  class Client {
95
101
  constructor({ tokenStorage = "MEMORY", ...options }) {
@@ -246,6 +252,13 @@ mutation addPendingDocumentMutation(
246
252
  if (resBody.message) {
247
253
  errorMessage = `${errorMessage}, Response: ${resBody.message}`;
248
254
  }
255
+ errorMessage = `${errorMessage}, Please check that the following information is correct:
256
+ clientId: ${this.options.clientId}
257
+ branch: ${this.branch}.`;
258
+ if (this.branch !== "main") {
259
+ errorMessage = `${errorMessage}
260
+ Note: This error can occur if the branch does not exist on GitHub or on Tina Cloud`;
261
+ }
249
262
  throw new Error(errorMessage);
250
263
  }
251
264
  const json = await res.json();
@@ -391,15 +404,15 @@ mutation addPendingDocumentMutation(
391
404
  return null;
392
405
  }
393
406
  }
394
- async waitForIndexStatus({ ref }) {
407
+ waitForIndexStatus({ ref }) {
395
408
  try {
396
- const result = await asyncPoll(async () => {
409
+ const [prom, cancel] = asyncPoll(async () => {
397
410
  try {
398
- const result2 = await this.getIndexStatus({ ref });
399
- if (!(result2.status === "inprogress" || result2.status === "unknown")) {
411
+ const result = await this.getIndexStatus({ ref });
412
+ if (!(result.status === "inprogress" || result.status === "unknown")) {
400
413
  return Promise.resolve({
401
414
  done: true,
402
- data: result2
415
+ data: result
403
416
  });
404
417
  } else {
405
418
  return Promise.resolve({
@@ -410,7 +423,7 @@ mutation addPendingDocumentMutation(
410
423
  return Promise.reject(err);
411
424
  }
412
425
  }, 5e3, 9e5);
413
- return result;
426
+ return [prom, cancel];
414
427
  } catch (error) {
415
428
  if (error.message === "AsyncPoller: reached timeout") {
416
429
  console.warn(error);
@@ -3065,7 +3078,20 @@ This will work when developing locally but NOT when deployed to production.
3065
3078
  children,
3066
3079
  filterArgs
3067
3080
  }) => {
3081
+ const navigate = reactRouterDom.useNavigate();
3068
3082
  const { collection, loading, error, reFetchCollection, collectionExtra } = useGetCollection(cms, collectionName, includeDocuments, startCursor || "", sortKey, filterArgs) || {};
3083
+ React.useEffect(() => {
3084
+ var _a, _b, _c, _d, _e, _f, _g, _h;
3085
+ if (loading)
3086
+ return;
3087
+ const collectionDefinition = cms.api.tina.schema.getCollection(collection.name);
3088
+ const allowCreate = (_c = (_b = (_a = collectionDefinition == null ? void 0 : collectionDefinition.ui) == null ? void 0 : _a.allowedActions) == null ? void 0 : _b.create) != null ? _c : true;
3089
+ const allowDelete = (_f = (_e = (_d = collectionDefinition == null ? void 0 : collectionDefinition.ui) == null ? void 0 : _d.allowedActions) == null ? void 0 : _e.delete) != null ? _f : true;
3090
+ if (!allowCreate && !allowDelete && ((_h = (_g = collection.documents) == null ? void 0 : _g.edges) == null ? void 0 : _h.length) === 1) {
3091
+ const doc = collection.documents.edges[0].node;
3092
+ handleNavigate(navigate, cms, collection, collectionDefinition, doc);
3093
+ }
3094
+ }, [(collection == null ? void 0 : collection.name) || "", loading]);
3069
3095
  if (error) {
3070
3096
  return /* @__PURE__ */ React__default["default"].createElement(FullscreenError, null);
3071
3097
  }
@@ -3627,42 +3653,6 @@ This will work when developing locally but NOT when deployed to production.
3627
3653
  function HiChevronRight(props) {
3628
3654
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 20 20", "fill": "currentColor" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z", "clipRule": "evenodd" } }] })(props);
3629
3655
  }
3630
- const transformDocumentIntoMutationRequestPayload = (document, instructions) => {
3631
- const { _collection, __typename, _template, ...rest } = document;
3632
- const params = transformParams(rest);
3633
- const paramsWithTemplate = instructions.includeTemplate ? { [_template]: params } : params;
3634
- return instructions.includeCollection ? { [_collection]: paramsWithTemplate } : paramsWithTemplate;
3635
- };
3636
- const transformParams = (data) => {
3637
- if (["string", "number", "boolean"].includes(typeof data)) {
3638
- return data;
3639
- }
3640
- if (Array.isArray(data)) {
3641
- return data.map((item) => transformParams(item));
3642
- }
3643
- try {
3644
- assertShape(data, (yup2) => yup2.object({ _template: yup2.string().required() }));
3645
- const { _template, __typename, ...rest } = data;
3646
- const nested = transformParams(rest);
3647
- return { [_template]: nested };
3648
- } catch (e) {
3649
- if (e.message === "Failed to assertShape - _template is a required field") {
3650
- if (!data) {
3651
- return [];
3652
- }
3653
- const accum = {};
3654
- Object.entries(data).map(([keyName, value]) => {
3655
- accum[keyName] = transformParams(value);
3656
- });
3657
- return accum;
3658
- } else {
3659
- if (!data) {
3660
- return [];
3661
- }
3662
- throw e;
3663
- }
3664
- }
3665
- };
3666
3656
  function FaLock(props) {
3667
3657
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 448 512" }, "child": [{ "tag": "path", "attr": { "d": "M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z" } }] })(props);
3668
3658
  }
@@ -3672,15 +3662,11 @@ This will work when developing locally but NOT when deployed to production.
3672
3662
  const createDocument = async (cms, collection, template, mutationInfo, values) => {
3673
3663
  const api = new TinaAdminApi(cms);
3674
3664
  const { filename, ...leftover } = values;
3675
- const { includeCollection, includeTemplate } = mutationInfo;
3676
3665
  const relativePath = `${filename}.${collection.format}`;
3677
- const params = transformDocumentIntoMutationRequestPayload({
3666
+ const params = api.schema.transformPayload(collection.name, {
3678
3667
  _collection: collection.name,
3679
3668
  ...template && { _template: template.name },
3680
3669
  ...leftover
3681
- }, {
3682
- includeCollection,
3683
- includeTemplate
3684
3670
  });
3685
3671
  if (await api.isAuthenticated()) {
3686
3672
  await api.createDocument(collection.name, relativePath, params);
@@ -3895,11 +3881,7 @@ This will work when developing locally but NOT when deployed to production.
3895
3881
  };
3896
3882
  const updateDocument = async (cms, relativePath, collection, mutationInfo, values) => {
3897
3883
  const api = new TinaAdminApi(cms);
3898
- const { includeCollection, includeTemplate } = mutationInfo;
3899
- const params = transformDocumentIntoMutationRequestPayload(values, {
3900
- includeCollection,
3901
- includeTemplate
3902
- });
3884
+ const params = api.schema.transformPayload(collection.name, values);
3903
3885
  if (await api.isAuthenticated()) {
3904
3886
  await api.updateDocument(collection.name, relativePath, params);
3905
3887
  } else {
@@ -105,7 +105,7 @@ pollInterval?: number,
105
105
  *
106
106
  * Default 30 seconds.
107
107
  */
108
- pollTimeout?: number): Promise<T>;
108
+ pollTimeout?: number): ((() => void) | Promise<T>)[];
109
109
  export declare class Client {
110
110
  onLogin?: OnLoginFunc;
111
111
  onLogout?: () => Promise<void>;
@@ -202,7 +202,9 @@ export declare class Client {
202
202
  }>;
203
203
  waitForIndexStatus({ ref }: {
204
204
  ref: string;
205
- }): Promise<any>;
205
+ }): (Promise<any> | (() => void))[] | {
206
+ status: string;
207
+ };
206
208
  getIndexStatus({ ref }: {
207
209
  ref: string;
208
210
  }): Promise<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tinacms",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "main": "dist/index.js",
5
5
  "module": "./dist/index.es.js",
6
6
  "exports": {
@@ -56,9 +56,9 @@
56
56
  "@headlessui/react": "^1.5.0",
57
57
  "@heroicons/react": "^1.0.4",
58
58
  "@react-hook/window-size": "^3.0.7",
59
- "@tinacms/schema-tools": "1.4.0",
59
+ "@tinacms/schema-tools": "1.4.2",
60
60
  "@tinacms/sharedctx": "1.0.1",
61
- "@tinacms/toolkit": "1.6.0",
61
+ "@tinacms/toolkit": "1.6.1",
62
62
  "crypto-js": "^4.0.0",
63
63
  "encoding": "0.1.13",
64
64
  "fetch-ponyfill": "^7.1.0",