@tinacms/schema-tools 1.4.12 → 1.4.14

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/LICENSE CHANGED
@@ -1,12 +1,4 @@
1
- Copyright (c) 2023-present Forestry.io Holdings Inc.
2
-
3
- Portions of the TinaCMS software are licensed as follows:
4
-
5
- * All software that resides under the "packages/@tinacms/datalayer/" and the "packages/@tinacms/graphql/" directories (the "Tina Data Layer"), is licensed under the license defined in "packages/@tinacms/datalayer/LICENSE".
6
-
7
- * All software outside of the above-mentioned directories is available under the "Apache 2.0" license as set forth below.
8
-
9
- Apache License
1
+ Apache License
10
2
  Version 2.0, January 2004
11
3
  http://www.apache.org/licenses/
12
4
 
package/dist/index.js CHANGED
@@ -231,6 +231,7 @@
231
231
  };
232
232
  this.getCollectionByFullPath = (filepath) => {
233
233
  const fileExtension = filepath.split(".").pop();
234
+ const normalizedPath = filepath.replace(/\\/g, "/");
234
235
  const possibleCollections = this.getCollections().filter((collection) => {
235
236
  var _a, _b;
236
237
  if (fileExtension !== (collection.format || "md")) {
@@ -238,13 +239,13 @@
238
239
  }
239
240
  if (((_a = collection == null ? void 0 : collection.match) == null ? void 0 : _a.include) || ((_b = collection == null ? void 0 : collection.match) == null ? void 0 : _b.exclude)) {
240
241
  const matches = this.getMatches({ collection });
241
- const match = picomatch.isMatch(filepath, matches);
242
+ const match = picomatch.isMatch(normalizedPath, matches);
242
243
  if (!match) {
243
244
  return false;
244
245
  }
245
246
  }
246
247
  const path = collection.path ? collection.path.replace(/\/?$/, "/") : "";
247
- return filepath.replace(/\\/g, "/").startsWith(path);
248
+ return normalizedPath.startsWith(path);
248
249
  });
249
250
  if (possibleCollections.length === 0) {
250
251
  throw new Error(`Unable to find collection for file at ${filepath}`);
@@ -423,7 +424,7 @@
423
424
  if (collection == null ? void 0 : collection.fields) {
424
425
  const template = collection;
425
426
  if (typeof template.fields === "string" || typeof template.fields === "undefined") {
426
- throw new Error("Exptected template to have fields but none were found");
427
+ throw new Error("Expected template to have fields but none were found");
427
428
  }
428
429
  return {
429
430
  namespace: collection.namespace,
@@ -495,6 +496,7 @@
495
496
  field.parser = { type: "markdown" };
496
497
  }
497
498
  }
499
+ field.uid = field.uid || false;
498
500
  });
499
501
  }
500
502
  /**
@@ -677,6 +679,12 @@
677
679
  component: "rich-text",
678
680
  ...extraFields
679
681
  };
682
+ case "password":
683
+ return {
684
+ component: "password",
685
+ ...field,
686
+ ...extraFields
687
+ };
680
688
  case "reference":
681
689
  return {
682
690
  ...field,
@@ -784,7 +792,8 @@ If you need to use this value in your content you can use the \`nameOverride\` p
784
792
  });
785
793
  const FieldWithList = TinaField.extend({ list: z.z.boolean().optional() });
786
794
  const TinaScalerBase = FieldWithList.extend({
787
- options: z.z.array(Option).optional()
795
+ options: z.z.array(Option).optional(),
796
+ uid: z.z.boolean().optional()
788
797
  });
789
798
  const StringField = TinaScalerBase.extend({
790
799
  type: z.z.literal("string", {
@@ -793,6 +802,12 @@ If you need to use this value in your content you can use the \`nameOverride\` p
793
802
  }),
794
803
  isTitle: z.z.boolean().optional()
795
804
  });
805
+ const PasswordField = TinaScalerBase.extend({
806
+ type: z.z.literal("password", {
807
+ invalid_type_error: typeTypeError,
808
+ required_error: typeRequiredError
809
+ })
810
+ });
796
811
  const BooleanField = TinaScalerBase.extend({
797
812
  type: z.z.literal("boolean", {
798
813
  invalid_type_error: typeTypeError,
@@ -894,7 +909,8 @@ If you need to use this value in your content you can use the \`nameOverride\` p
894
909
  DateTimeField,
895
910
  ReferenceField,
896
911
  ObjectField,
897
- RichTextField
912
+ RichTextField,
913
+ PasswordField
898
914
  ],
899
915
  {
900
916
  errorMap: (issue, ctx) => {
@@ -933,6 +949,32 @@ ${JSON.stringify(
933
949
  null,
934
950
  2
935
951
  )}
952
+ `
953
+ });
954
+ }
955
+ }
956
+ if (val.uid) {
957
+ if (val.list) {
958
+ ctx.addIssue({
959
+ code: z.z.ZodIssueCode.custom,
960
+ message: `Can not have \`list: true\` when using \`uid\`. Error in value
961
+ ${JSON.stringify(
962
+ val,
963
+ null,
964
+ 2
965
+ )}
966
+ `
967
+ });
968
+ }
969
+ if (!val.required) {
970
+ ctx.addIssue({
971
+ code: z.z.ZodIssueCode.custom,
972
+ message: `Must have { required: true } when using \`uid\` Error in value
973
+ ${JSON.stringify(
974
+ val,
975
+ null,
976
+ 2
977
+ )}
936
978
  `
937
979
  });
938
980
  }
@@ -1032,7 +1074,9 @@ ${JSON.stringify(
1032
1074
  });
1033
1075
  }
1034
1076
  }),
1035
- format: z.z.enum(FORMATS).optional()
1077
+ format: z.z.enum(FORMATS).optional(),
1078
+ isAuthCollection: z.z.boolean().optional(),
1079
+ isDetached: z.z.boolean().optional()
1036
1080
  });
1037
1081
  const TinaCloudCollection = CollectionBaseSchema.extend({
1038
1082
  fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
@@ -1052,6 +1096,24 @@ ${JSON.stringify(
1052
1096
  {
1053
1097
  message: "Fields can only have one use of `isTitle`"
1054
1098
  }
1099
+ ).refine(
1100
+ // It is valid if it is 0 or 1
1101
+ (val) => {
1102
+ const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
1103
+ return arr.length < 2;
1104
+ },
1105
+ {
1106
+ message: "Fields can only have one use of `uid`"
1107
+ }
1108
+ ).refine(
1109
+ // It is valid if it is 0 or 1
1110
+ (val) => {
1111
+ const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
1112
+ return arr.length < 2;
1113
+ },
1114
+ {
1115
+ message: "Fields can only have one use of `password` type"
1116
+ }
1055
1117
  ),
1056
1118
  templates: z.z.array(Template).min(1).optional().superRefine((val, ctx) => {
1057
1119
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
@@ -1078,7 +1140,7 @@ ${JSON.stringify(
1078
1140
  collections: z.z.array(TinaCloudCollection),
1079
1141
  config: tinaConfigZod.optional()
1080
1142
  }).superRefine((val, ctx) => {
1081
- var _a, _b, _c;
1143
+ var _a, _b, _c, _d;
1082
1144
  const dups = findDuplicates((_a = val.collections) == null ? void 0 : _a.map((x) => x.name));
1083
1145
  if (dups) {
1084
1146
  ctx.addIssue({
@@ -1087,7 +1149,14 @@ ${JSON.stringify(
1087
1149
  fatal: true
1088
1150
  });
1089
1151
  }
1090
- const media = (_b = val == null ? void 0 : val.config) == null ? void 0 : _b.media;
1152
+ if (((_b = val.collections) == null ? void 0 : _b.filter((x) => x.isAuthCollection).length) > 1) {
1153
+ ctx.addIssue({
1154
+ code: z.z.ZodIssueCode.custom,
1155
+ message: `Only one collection can be marked as isAuthCollection`,
1156
+ fatal: true
1157
+ });
1158
+ }
1159
+ const media = (_c = val == null ? void 0 : val.config) == null ? void 0 : _c.media;
1091
1160
  if (media && media.tina && media.loadCustomStore) {
1092
1161
  ctx.addIssue({
1093
1162
  code: z.z.ZodIssueCode.custom,
@@ -1096,7 +1165,7 @@ ${JSON.stringify(
1096
1165
  path: ["config", "media"]
1097
1166
  });
1098
1167
  }
1099
- const search = (_c = val == null ? void 0 : val.config) == null ? void 0 : _c.search;
1168
+ const search = (_d = val == null ? void 0 : val.config) == null ? void 0 : _d.search;
1100
1169
  if (search && search.tina && search.searchClient) {
1101
1170
  ctx.addIssue({
1102
1171
  code: z.z.ZodIssueCode.custom,
package/dist/index.mjs CHANGED
@@ -214,6 +214,7 @@ class TinaSchema {
214
214
  };
215
215
  this.getCollectionByFullPath = (filepath) => {
216
216
  const fileExtension = filepath.split(".").pop();
217
+ const normalizedPath = filepath.replace(/\\/g, "/");
217
218
  const possibleCollections = this.getCollections().filter((collection) => {
218
219
  var _a, _b;
219
220
  if (fileExtension !== (collection.format || "md")) {
@@ -221,13 +222,13 @@ class TinaSchema {
221
222
  }
222
223
  if (((_a = collection == null ? void 0 : collection.match) == null ? void 0 : _a.include) || ((_b = collection == null ? void 0 : collection.match) == null ? void 0 : _b.exclude)) {
223
224
  const matches = this.getMatches({ collection });
224
- const match = picomatch.isMatch(filepath, matches);
225
+ const match = picomatch.isMatch(normalizedPath, matches);
225
226
  if (!match) {
226
227
  return false;
227
228
  }
228
229
  }
229
230
  const path = collection.path ? collection.path.replace(/\/?$/, "/") : "";
230
- return filepath.replace(/\\/g, "/").startsWith(path);
231
+ return normalizedPath.startsWith(path);
231
232
  });
232
233
  if (possibleCollections.length === 0) {
233
234
  throw new Error(`Unable to find collection for file at ${filepath}`);
@@ -406,7 +407,7 @@ class TinaSchema {
406
407
  if (collection == null ? void 0 : collection.fields) {
407
408
  const template = collection;
408
409
  if (typeof template.fields === "string" || typeof template.fields === "undefined") {
409
- throw new Error("Exptected template to have fields but none were found");
410
+ throw new Error("Expected template to have fields but none were found");
410
411
  }
411
412
  return {
412
413
  namespace: collection.namespace,
@@ -478,6 +479,7 @@ class TinaSchema {
478
479
  field.parser = { type: "markdown" };
479
480
  }
480
481
  }
482
+ field.uid = field.uid || false;
481
483
  });
482
484
  }
483
485
  /**
@@ -660,6 +662,12 @@ const resolveField = (field, schema) => {
660
662
  component: "rich-text",
661
663
  ...extraFields
662
664
  };
665
+ case "password":
666
+ return {
667
+ component: "password",
668
+ ...field,
669
+ ...extraFields
670
+ };
663
671
  case "reference":
664
672
  return {
665
673
  ...field,
@@ -767,7 +775,8 @@ const TinaField = z.object({
767
775
  });
768
776
  const FieldWithList = TinaField.extend({ list: z.boolean().optional() });
769
777
  const TinaScalerBase = FieldWithList.extend({
770
- options: z.array(Option).optional()
778
+ options: z.array(Option).optional(),
779
+ uid: z.boolean().optional()
771
780
  });
772
781
  const StringField = TinaScalerBase.extend({
773
782
  type: z.literal("string", {
@@ -776,6 +785,12 @@ const StringField = TinaScalerBase.extend({
776
785
  }),
777
786
  isTitle: z.boolean().optional()
778
787
  });
788
+ const PasswordField = TinaScalerBase.extend({
789
+ type: z.literal("password", {
790
+ invalid_type_error: typeTypeError,
791
+ required_error: typeRequiredError
792
+ })
793
+ });
779
794
  const BooleanField = TinaScalerBase.extend({
780
795
  type: z.literal("boolean", {
781
796
  invalid_type_error: typeTypeError,
@@ -877,7 +892,8 @@ const TinaFieldZod = z.lazy(() => {
877
892
  DateTimeField,
878
893
  ReferenceField,
879
894
  ObjectField,
880
- RichTextField
895
+ RichTextField,
896
+ PasswordField
881
897
  ],
882
898
  {
883
899
  errorMap: (issue, ctx) => {
@@ -916,6 +932,32 @@ ${JSON.stringify(
916
932
  null,
917
933
  2
918
934
  )}
935
+ `
936
+ });
937
+ }
938
+ }
939
+ if (val.uid) {
940
+ if (val.list) {
941
+ ctx.addIssue({
942
+ code: z.ZodIssueCode.custom,
943
+ message: `Can not have \`list: true\` when using \`uid\`. Error in value
944
+ ${JSON.stringify(
945
+ val,
946
+ null,
947
+ 2
948
+ )}
949
+ `
950
+ });
951
+ }
952
+ if (!val.required) {
953
+ ctx.addIssue({
954
+ code: z.ZodIssueCode.custom,
955
+ message: `Must have { required: true } when using \`uid\` Error in value
956
+ ${JSON.stringify(
957
+ val,
958
+ null,
959
+ 2
960
+ )}
919
961
  `
920
962
  });
921
963
  }
@@ -1015,7 +1057,9 @@ const CollectionBaseSchema = z.object({
1015
1057
  });
1016
1058
  }
1017
1059
  }),
1018
- format: z.enum(FORMATS).optional()
1060
+ format: z.enum(FORMATS).optional(),
1061
+ isAuthCollection: z.boolean().optional(),
1062
+ isDetached: z.boolean().optional()
1019
1063
  });
1020
1064
  const TinaCloudCollection = CollectionBaseSchema.extend({
1021
1065
  fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
@@ -1035,6 +1079,24 @@ const TinaCloudCollection = CollectionBaseSchema.extend({
1035
1079
  {
1036
1080
  message: "Fields can only have one use of `isTitle`"
1037
1081
  }
1082
+ ).refine(
1083
+ // It is valid if it is 0 or 1
1084
+ (val) => {
1085
+ const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
1086
+ return arr.length < 2;
1087
+ },
1088
+ {
1089
+ message: "Fields can only have one use of `uid`"
1090
+ }
1091
+ ).refine(
1092
+ // It is valid if it is 0 or 1
1093
+ (val) => {
1094
+ const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
1095
+ return arr.length < 2;
1096
+ },
1097
+ {
1098
+ message: "Fields can only have one use of `password` type"
1099
+ }
1038
1100
  ),
1039
1101
  templates: z.array(Template).min(1).optional().superRefine((val, ctx) => {
1040
1102
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
@@ -1061,7 +1123,7 @@ const TinaCloudSchemaZod = z.object({
1061
1123
  collections: z.array(TinaCloudCollection),
1062
1124
  config: tinaConfigZod.optional()
1063
1125
  }).superRefine((val, ctx) => {
1064
- var _a, _b, _c;
1126
+ var _a, _b, _c, _d;
1065
1127
  const dups = findDuplicates((_a = val.collections) == null ? void 0 : _a.map((x) => x.name));
1066
1128
  if (dups) {
1067
1129
  ctx.addIssue({
@@ -1070,7 +1132,14 @@ const TinaCloudSchemaZod = z.object({
1070
1132
  fatal: true
1071
1133
  });
1072
1134
  }
1073
- const media = (_b = val == null ? void 0 : val.config) == null ? void 0 : _b.media;
1135
+ if (((_b = val.collections) == null ? void 0 : _b.filter((x) => x.isAuthCollection).length) > 1) {
1136
+ ctx.addIssue({
1137
+ code: z.ZodIssueCode.custom,
1138
+ message: `Only one collection can be marked as isAuthCollection`,
1139
+ fatal: true
1140
+ });
1141
+ }
1142
+ const media = (_c = val == null ? void 0 : val.config) == null ? void 0 : _c.media;
1074
1143
  if (media && media.tina && media.loadCustomStore) {
1075
1144
  ctx.addIssue({
1076
1145
  code: z.ZodIssueCode.custom,
@@ -1079,7 +1148,7 @@ const TinaCloudSchemaZod = z.object({
1079
1148
  path: ["config", "media"]
1080
1149
  });
1081
1150
  }
1082
- const search = (_c = val == null ? void 0 : val.config) == null ? void 0 : _c.search;
1151
+ const search = (_d = val == null ? void 0 : val.config) == null ? void 0 : _d.search;
1083
1152
  if (search && search.tina && search.searchClient) {
1084
1153
  ctx.addIssue({
1085
1154
  code: z.ZodIssueCode.custom,
@@ -1,6 +1,7 @@
1
1
  /**
2
2
 
3
3
  */
4
+ /// <reference types="react" />
4
5
  import type { Template, Collection } from '../types/index';
5
6
  import type { TinaSchema } from './TinaSchema';
6
7
  /**
@@ -19,9 +20,9 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
19
20
  };
20
21
  input: {
21
22
  name: string;
22
- onBlur: (event?: any) => void;
23
- onChange: (event: any) => void;
24
- onFocus: (event?: any) => void;
23
+ onBlur: (event?: import("react").FocusEvent<string, Element>) => void;
24
+ onChange: (event: import("react").ChangeEvent<string>) => void;
25
+ onFocus: (event?: import("react").FocusEvent<string, Element>) => void;
25
26
  type?: string;
26
27
  value: string[];
27
28
  };
@@ -36,9 +37,9 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
36
37
  };
37
38
  input: {
38
39
  name: string;
39
- onBlur: (event?: any) => void;
40
- onChange: (event: any) => void;
41
- onFocus: (event?: any) => void;
40
+ onBlur: (event?: import("react").FocusEvent<number, Element>) => void;
41
+ onChange: (event: import("react").ChangeEvent<number>) => void;
42
+ onFocus: (event?: import("react").FocusEvent<number, Element>) => void;
42
43
  type?: string;
43
44
  value: number[];
44
45
  };
@@ -53,9 +54,9 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
53
54
  };
54
55
  input: {
55
56
  name: string;
56
- onBlur: (event?: any) => void;
57
- onChange: (event: any) => void;
58
- onFocus: (event?: any) => void;
57
+ onBlur: (event?: import("react").FocusEvent<boolean, Element>) => void;
58
+ onChange: (event: import("react").ChangeEvent<boolean>) => void;
59
+ onFocus: (event?: import("react").FocusEvent<boolean, Element>) => void;
59
60
  type?: string;
60
61
  value: boolean[];
61
62
  };
@@ -70,9 +71,18 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
70
71
  };
71
72
  input: {
72
73
  name: string;
73
- onBlur: (event?: any) => void;
74
- onChange: (event: any) => void;
75
- onFocus: (event?: any) => void;
74
+ onBlur: (event?: import("react").FocusEvent<{
75
+ type: "root";
76
+ children: Record<string, unknown>[];
77
+ }, Element>) => void;
78
+ onChange: (event: import("react").ChangeEvent<{
79
+ type: "root";
80
+ children: Record<string, unknown>[];
81
+ }>) => void;
82
+ onFocus: (event?: import("react").FocusEvent<{
83
+ type: "root";
84
+ children: Record<string, unknown>[];
85
+ }, Element>) => void;
76
86
  type?: string;
77
87
  value: {
78
88
  type: "root";
@@ -90,9 +100,9 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
90
100
  };
91
101
  input: {
92
102
  name: string;
93
- onBlur: (event?: any) => void;
94
- onChange: (event: any) => void;
95
- onFocus: (event?: any) => void;
103
+ onBlur: (event?: import("react").FocusEvent<string, Element>) => void;
104
+ onChange: (event: import("react").ChangeEvent<string>) => void;
105
+ onFocus: (event?: import("react").FocusEvent<string, Element>) => void;
96
106
  type?: string;
97
107
  value: string;
98
108
  };
@@ -107,9 +117,9 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
107
117
  };
108
118
  input: {
109
119
  name: string;
110
- onBlur: (event?: any) => void;
111
- onChange: (event: any) => void;
112
- onFocus: (event?: any) => void;
120
+ onBlur: (event?: import("react").FocusEvent<number, Element>) => void;
121
+ onChange: (event: import("react").ChangeEvent<number>) => void;
122
+ onFocus: (event?: import("react").FocusEvent<number, Element>) => void;
113
123
  type?: string;
114
124
  value: number;
115
125
  };
@@ -124,9 +134,9 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
124
134
  };
125
135
  input: {
126
136
  name: string;
127
- onBlur: (event?: any) => void;
128
- onChange: (event: any) => void;
129
- onFocus: (event?: any) => void;
137
+ onBlur: (event?: import("react").FocusEvent<boolean, Element>) => void;
138
+ onChange: (event: import("react").ChangeEvent<boolean>) => void;
139
+ onFocus: (event?: import("react").FocusEvent<boolean, Element>) => void;
130
140
  type?: string;
131
141
  value: boolean;
132
142
  };
@@ -141,9 +151,18 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
141
151
  };
142
152
  input: {
143
153
  name: string;
144
- onBlur: (event?: any) => void;
145
- onChange: (event: any) => void;
146
- onFocus: (event?: any) => void;
154
+ onBlur: (event?: import("react").FocusEvent<{
155
+ type: "root";
156
+ children: Record<string, unknown>[];
157
+ }, Element>) => void;
158
+ onChange: (event: import("react").ChangeEvent<{
159
+ type: "root";
160
+ children: Record<string, unknown>[];
161
+ }>) => void;
162
+ onFocus: (event?: import("react").FocusEvent<{
163
+ type: "root";
164
+ children: Record<string, unknown>[];
165
+ }, Element>) => void;
147
166
  type?: string;
148
167
  value: {
149
168
  type: "root";
@@ -128,6 +128,7 @@ export interface BaseField {
128
128
  nameOverride?: string;
129
129
  description?: string;
130
130
  searchable?: boolean;
131
+ uid?: boolean;
131
132
  }
132
133
  export declare type StringField = (FieldGeneric<string, undefined> | FieldGeneric<string, true> | FieldGeneric<string, false>) & BaseField & SearchableTextField & {
133
134
  type: 'string';
@@ -171,6 +172,9 @@ export declare type ReferenceField = (FieldGeneric<string, undefined> | FieldGen
171
172
  */
172
173
  collections: string[];
173
174
  };
175
+ export declare type PasswordField = (FieldGeneric<string, undefined> | FieldGeneric<string, false>) & BaseField & {
176
+ type: 'password';
177
+ };
174
178
  declare type RichTextAst = {
175
179
  type: 'root';
176
180
  children: Record<string, unknown>[];
@@ -240,7 +244,7 @@ export declare type ObjectField<WithNamespace extends boolean = false> = (FieldG
240
244
  templates: Template<WithNamespace>[];
241
245
  templateKey?: string;
242
246
  });
243
- declare type Field<WithNamespace extends boolean = false> = (StringField | NumberField | BooleanField | DateTimeField | ImageField | ReferenceField | RichTextField<WithNamespace> | ObjectField<WithNamespace>) & MaybeNamespace<WithNamespace>;
247
+ declare type Field<WithNamespace extends boolean = false> = (StringField | NumberField | BooleanField | DateTimeField | ImageField | ReferenceField | RichTextField<WithNamespace> | ObjectField<WithNamespace> | PasswordField) & MaybeNamespace<WithNamespace>;
244
248
  export declare type TinaField<WithNamespace extends boolean = false> = Field<WithNamespace> & MaybeNamespace<WithNamespace>;
245
249
  declare type MaybeNamespace<WithNamespace extends boolean = false> = WithNamespace extends true ? {
246
250
  namespace: string[];
@@ -284,59 +288,68 @@ declare type TokenObject = {
284
288
  access_token?: string;
285
289
  refresh_token?: string;
286
290
  };
291
+ export declare type LoginStrategy = 'UsernamePassword' | 'Redirect';
292
+ export interface AuthProvider {
293
+ /**
294
+ * Used for getting the token from the custom auth provider
295
+ *
296
+ * @returns {Promise<TokenObject | null>}
297
+ **/
298
+ getToken: () => Promise<TokenObject | null>;
299
+ /**
300
+ * Used to logout from the custom auth provider
301
+ *
302
+ **/
303
+ logout: () => Promise<void>;
304
+ /**
305
+ * Used for getting the user from the custom auth provider. If this returns a truthy value, the user will be logged in and the CMS will be enabled.
306
+ *
307
+ * If this returns a falsy value, the user will be logged out and the CMS will be disabled.
308
+ *
309
+ **/
310
+ getUser: () => Promise<any | null | boolean>;
311
+ /**
312
+ * Used to authorize the user with the custom auth provider.
313
+ *
314
+ * If this returns a truthy value, the user will be logged in and the CMS will be enabled.
315
+ *
316
+ * If not provided, the existence of a user will be enough to authorize the user.
317
+ *
318
+ * @param context
319
+ */
320
+ authorize: (context?: any) => Promise<any | null>;
321
+ /**
322
+ * Used to authenticate the user with the custom auth provider. This is called when the user clicks the login button.
323
+ *
324
+ **/
325
+ authenticate: (props?: Record<string, any>) => Promise<any | null>;
326
+ fetchWithToken: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
327
+ isAuthorized: (context?: any) => Promise<boolean>;
328
+ isAuthenticated: () => Promise<boolean>;
329
+ getLoginStrategy: () => LoginStrategy;
330
+ getSessionProvider: () => FC<{
331
+ basePath?: string;
332
+ }>;
333
+ }
334
+ interface AuthHooks {
335
+ onLogin?: (args: {
336
+ token: TokenObject;
337
+ }) => Promise<void>;
338
+ onLogout?: () => Promise<void>;
339
+ }
340
+ declare type AuthOptions = AuthHooks & AuthProvider;
287
341
  export interface Config<CMSCallback = undefined, FormifyCallback = undefined, DocumentCreatorCallback = undefined, Store = undefined, SearchClient = undefined> {
288
342
  contentApiUrlOverride?: string;
343
+ authProvider?: AuthProvider;
289
344
  admin?: {
290
- auth?: {
291
- /**
292
- * If you wish to use the local auth provider, set this to true
293
- *
294
- * This will take precedence over the customAuth option (if set to true)
295
- *
296
- **/
297
- useLocalAuth?: boolean;
298
- /**
299
- * If you are using a custom auth provider, set this to true
300
- **/
301
- customAuth?: boolean;
302
- /**
303
- * Used for getting the token from the custom auth provider
304
- *
305
- * @returns {Promise<TokenObject | null>}
306
- **/
307
- getToken?: () => Promise<TokenObject | null>;
308
- /**
309
- * Used to logout from the custom auth provider
310
- *
311
- **/
312
- logout?: () => Promise<void>;
313
- /**
314
- * Used for getting the user from the custom auth provider. If this returns a truthy value, the user will be logged in and the CMS will be enabled.
315
- *
316
- * If this returns a falsy value, the user will be logged out and the CMS will be disabled.
317
- *
318
- **/
319
- getUser?: () => Promise<any | null>;
320
- /**
321
- * Used to authorize the user with the custom auth provider.
322
- *
323
- * If this returns a truthy value, the user will be logged in and the CMS will be enabled.
324
- *
325
- * If not provided, the existence of a user will be enough to authorize the user.
326
- *
327
- * @param context
328
- */
329
- authorize?: (context?: any) => Promise<any | null>;
330
- /**
331
- * Used to authenticate the user with the custom auth provider. This is called when the user clicks the login button.
332
- *
333
- **/
334
- authenticate?: () => Promise<any | null>;
335
- onLogin?: (args: {
336
- token: TokenObject;
337
- }) => Promise<void>;
338
- onLogout?: () => Promise<void>;
339
- };
345
+ /**
346
+ * @deprecated use `authProvider`and admin.authHooks instead
347
+ */
348
+ auth?: AuthOptions;
349
+ /**
350
+ * Hook functions that can be used to run logic when certain events happen
351
+ */
352
+ authHooks?: AuthHooks;
340
353
  };
341
354
  /**
342
355
  * The Schema is used to define the shape of the content.
@@ -397,6 +410,12 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
397
410
  * @default 2
398
411
  */
399
412
  referenceDepth?: number;
413
+ /**
414
+ * Determines how the client will handle errors. If it is set to `throw` the client will throw an error when a query fails. If it is set to `include` the client will return the error in the response.
415
+ *
416
+ * @default 'throw'
417
+ */
418
+ errorPolicy?: 'throw' | 'include';
400
419
  };
401
420
  /**
402
421
  *
@@ -561,6 +580,8 @@ interface BaseCollection {
561
580
  include?: string;
562
581
  exclude?: string;
563
582
  };
583
+ isDetached?: boolean;
584
+ isAuthCollection?: boolean;
564
585
  }
565
586
  declare type TemplateCollection<WithNamespace extends boolean = false> = {
566
587
  /**
@@ -7,16 +7,22 @@ export declare const CollectionBaseSchema: z.ZodObject<{
7
7
  name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
8
8
  path: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
9
9
  format: z.ZodOptional<z.ZodEnum<["json", "md", "markdown", "mdx", "toml", "yaml", "yml"]>>;
10
+ isAuthCollection: z.ZodOptional<z.ZodBoolean>;
11
+ isDetached: z.ZodOptional<z.ZodBoolean>;
10
12
  }, "strip", z.ZodTypeAny, {
11
13
  name?: string;
12
14
  label?: string;
13
15
  path?: string;
14
16
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
17
+ isDetached?: boolean;
18
+ isAuthCollection?: boolean;
15
19
  }, {
16
20
  name?: string;
17
21
  label?: string;
18
22
  path?: string;
19
23
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
24
+ isDetached?: boolean;
25
+ isAuthCollection?: boolean;
20
26
  }>;
21
27
  export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
22
28
  collections: z.ZodArray<z.ZodEffects<z.ZodObject<z.extendShape<{
@@ -24,8 +30,10 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
24
30
  name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
25
31
  path: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
26
32
  format: z.ZodOptional<z.ZodEnum<["json", "md", "markdown", "mdx", "toml", "yaml", "yml"]>>;
33
+ isAuthCollection: z.ZodOptional<z.ZodBoolean>;
34
+ isDetached: z.ZodOptional<z.ZodBoolean>;
27
35
  }, {
28
- fields: z.ZodEffects<z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodType<import("..").TinaField<false>, z.ZodTypeDef, import("..").TinaField<false>>, "many">>, import("..").TinaField<false>[], import("..").TinaField<false>[]>, import("..").TinaField<false>[], import("..").TinaField<false>[]>;
36
+ fields: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodType<import("..").TinaField<false>, z.ZodTypeDef, import("..").TinaField<false>>, "many">>, import("..").TinaField<false>[], import("..").TinaField<false>[]>, import("..").TinaField<false>[], import("..").TinaField<false>[]>, import("..").TinaField<false>[], import("..").TinaField<false>[]>, import("..").TinaField<false>[], import("..").TinaField<false>[]>;
29
37
  templates: z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodObject<{
30
38
  label: z.ZodString;
31
39
  name: z.ZodEffects<z.ZodString, string, string>;
@@ -66,6 +74,8 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
66
74
  label?: string;
67
75
  path?: string;
68
76
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
77
+ isDetached?: boolean;
78
+ isAuthCollection?: boolean;
69
79
  }, {
70
80
  name?: string;
71
81
  templates?: {
@@ -77,6 +87,8 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
77
87
  label?: string;
78
88
  path?: string;
79
89
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
90
+ isDetached?: boolean;
91
+ isAuthCollection?: boolean;
80
92
  }>, {
81
93
  name?: string;
82
94
  templates?: {
@@ -88,6 +100,8 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
88
100
  label?: string;
89
101
  path?: string;
90
102
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
103
+ isDetached?: boolean;
104
+ isAuthCollection?: boolean;
91
105
  }, {
92
106
  name?: string;
93
107
  templates?: {
@@ -99,6 +113,8 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
99
113
  label?: string;
100
114
  path?: string;
101
115
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
116
+ isDetached?: boolean;
117
+ isAuthCollection?: boolean;
102
118
  }>, "many">;
103
119
  config: z.ZodOptional<z.ZodObject<{
104
120
  client: z.ZodOptional<z.ZodObject<{
@@ -231,6 +247,8 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
231
247
  label?: string;
232
248
  path?: string;
233
249
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
250
+ isDetached?: boolean;
251
+ isAuthCollection?: boolean;
234
252
  }[];
235
253
  config?: {
236
254
  search?: {
@@ -267,6 +285,8 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
267
285
  label?: string;
268
286
  path?: string;
269
287
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
288
+ isDetached?: boolean;
289
+ isAuthCollection?: boolean;
270
290
  }[];
271
291
  config?: {
272
292
  search?: {
@@ -303,6 +323,8 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
303
323
  label?: string;
304
324
  path?: string;
305
325
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
326
+ isDetached?: boolean;
327
+ isAuthCollection?: boolean;
306
328
  }[];
307
329
  config?: {
308
330
  search?: {
@@ -339,6 +361,8 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
339
361
  label?: string;
340
362
  path?: string;
341
363
  format?: "markdown" | "mdx" | "json" | "md" | "yaml" | "yml" | "toml";
364
+ isDetached?: boolean;
365
+ isAuthCollection?: boolean;
342
366
  }[];
343
367
  config?: {
344
368
  search?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/schema-tools",
3
- "version": "1.4.12",
3
+ "version": "1.4.14",
4
4
  "main": "dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "exports": {
@@ -23,7 +23,8 @@
23
23
  ]
24
24
  },
25
25
  "devDependencies": {
26
- "@tinacms/scripts": "1.1.2",
26
+ "@types/react": "17.0.2",
27
+ "@tinacms/scripts": "1.1.3",
27
28
  "@types/micromatch": "^4.0.2",
28
29
  "@types/yup": "^0.29.10",
29
30
  "jest": "^29.5.0",