@tinacms/schema-tools 1.0.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -164,13 +164,24 @@ class TinaSchema {
164
164
  return globalTemplate;
165
165
  };
166
166
  this.getCollectionByFullPath = (filepath) => {
167
- const collection = this.getCollections().find((collection2) => {
168
- return filepath.replace(/\\/g, "/").startsWith(collection2.path.replace(/\/?$/, "/"));
167
+ const possibleCollections = this.getCollections().filter((collection) => {
168
+ return filepath.replace(/\\/g, "/").startsWith(collection.path.replace(/\/?$/, "/"));
169
169
  });
170
- if (!collection) {
170
+ if (possibleCollections.length === 0) {
171
171
  throw new Error(`Unable to find collection for file at ${filepath}`);
172
172
  }
173
- return collection;
173
+ if (possibleCollections.length === 1) {
174
+ return possibleCollections[0];
175
+ }
176
+ if (possibleCollections.length > 1) {
177
+ const longestMatch = possibleCollections.reduce((acc, collection) => {
178
+ if (collection.path.length > acc.path.length) {
179
+ return collection;
180
+ }
181
+ return acc;
182
+ });
183
+ return longestMatch;
184
+ }
174
185
  };
175
186
  this.getCollectionAndTemplateByFullPath = (filepath, templateName) => {
176
187
  let template;
@@ -378,11 +389,19 @@ const resolveField = (field, schema) => {
378
389
  options: field.options
379
390
  };
380
391
  }
392
+ if (field.options[0] && typeof field.options[0] === "object" && field.options[0].icon) {
393
+ return {
394
+ component: "button-toggle",
395
+ ...field,
396
+ ...extraFields,
397
+ options: field.options
398
+ };
399
+ }
381
400
  return {
382
401
  component: "select",
383
402
  ...field,
384
403
  ...extraFields,
385
- options: [{ label: `Choose an option`, value: "" }, ...field.options]
404
+ options: field.ui && field.ui.component !== "select" ? field.options : [{ label: `Choose an option`, value: "" }, ...field.options]
386
405
  };
387
406
  }
388
407
  if (field.list) {
@@ -540,16 +559,20 @@ const nameProp = z.string({
540
559
  fatal: true
541
560
  });
542
561
  });
543
- const Option = z.union([z.string(), z.object({ label: z.string(), value: z.string() })], {
562
+ const Option = z.union([
563
+ z.string(),
564
+ z.object({ label: z.string(), value: z.string() }),
565
+ z.object({ icon: z.any(), value: z.string() })
566
+ ], {
544
567
  errorMap: () => {
545
568
  return {
546
- message: "Invalid option array. Must be a string[] or {label: string, value: string}[]"
569
+ message: "Invalid option array. Must be a string[] or {label: string, value: string}[] or {icon: React.ComponentType<any>, value: string}[]"
547
570
  };
548
571
  }
549
572
  });
550
573
  const TinaField = z.object({
551
574
  name: nameProp,
552
- label: z.string().optional(),
575
+ label: z.string().or(z.boolean()).optional(),
553
576
  description: z.string().optional(),
554
577
  required: z.boolean().optional()
555
578
  });
@@ -603,7 +626,8 @@ const TinaFieldZod = z.lazy(() => {
603
626
  fields: z.array(TinaFieldZod),
604
627
  match: z.object({
605
628
  start: z.string(),
606
- end: z.string()
629
+ end: z.string(),
630
+ name: z.string().optional()
607
631
  }).optional()
608
632
  }).superRefine((val, ctx) => {
609
633
  const dups = findDuplicates(val == null ? void 0 : val.fields.map((x) => x.name));
@@ -733,7 +757,7 @@ const validateTinaCloudSchemaConfig = (config) => {
733
757
  const newConfig = tinaConfigZod.parse(config);
734
758
  return newConfig;
735
759
  };
736
- const FORMATS = ["json", "md", "markdown", "mdx"];
760
+ const FORMATS = ["json", "md", "markdown", "mdx", "toml", "yaml"];
737
761
  const Template = z.object({
738
762
  label: z.string({
739
763
  invalid_type_error: "label must be a string",
package/dist/index.js CHANGED
@@ -191,13 +191,24 @@
191
191
  return globalTemplate;
192
192
  };
193
193
  this.getCollectionByFullPath = (filepath) => {
194
- const collection = this.getCollections().find((collection2) => {
195
- return filepath.replace(/\\/g, "/").startsWith(collection2.path.replace(/\/?$/, "/"));
194
+ const possibleCollections = this.getCollections().filter((collection) => {
195
+ return filepath.replace(/\\/g, "/").startsWith(collection.path.replace(/\/?$/, "/"));
196
196
  });
197
- if (!collection) {
197
+ if (possibleCollections.length === 0) {
198
198
  throw new Error(`Unable to find collection for file at ${filepath}`);
199
199
  }
200
- return collection;
200
+ if (possibleCollections.length === 1) {
201
+ return possibleCollections[0];
202
+ }
203
+ if (possibleCollections.length > 1) {
204
+ const longestMatch = possibleCollections.reduce((acc, collection) => {
205
+ if (collection.path.length > acc.path.length) {
206
+ return collection;
207
+ }
208
+ return acc;
209
+ });
210
+ return longestMatch;
211
+ }
201
212
  };
202
213
  this.getCollectionAndTemplateByFullPath = (filepath, templateName) => {
203
214
  let template;
@@ -405,11 +416,19 @@
405
416
  options: field.options
406
417
  };
407
418
  }
419
+ if (field.options[0] && typeof field.options[0] === "object" && field.options[0].icon) {
420
+ return {
421
+ component: "button-toggle",
422
+ ...field,
423
+ ...extraFields,
424
+ options: field.options
425
+ };
426
+ }
408
427
  return {
409
428
  component: "select",
410
429
  ...field,
411
430
  ...extraFields,
412
- options: [{ label: `Choose an option`, value: "" }, ...field.options]
431
+ options: field.ui && field.ui.component !== "select" ? field.options : [{ label: `Choose an option`, value: "" }, ...field.options]
413
432
  };
414
433
  }
415
434
  if (field.list) {
@@ -567,16 +586,20 @@
567
586
  fatal: true
568
587
  });
569
588
  });
570
- const Option = z.z.union([z.z.string(), z.z.object({ label: z.z.string(), value: z.z.string() })], {
589
+ const Option = z.z.union([
590
+ z.z.string(),
591
+ z.z.object({ label: z.z.string(), value: z.z.string() }),
592
+ z.z.object({ icon: z.z.any(), value: z.z.string() })
593
+ ], {
571
594
  errorMap: () => {
572
595
  return {
573
- message: "Invalid option array. Must be a string[] or {label: string, value: string}[]"
596
+ message: "Invalid option array. Must be a string[] or {label: string, value: string}[] or {icon: React.ComponentType<any>, value: string}[]"
574
597
  };
575
598
  }
576
599
  });
577
600
  const TinaField = z.z.object({
578
601
  name: nameProp,
579
- label: z.z.string().optional(),
602
+ label: z.z.string().or(z.z.boolean()).optional(),
580
603
  description: z.z.string().optional(),
581
604
  required: z.z.boolean().optional()
582
605
  });
@@ -630,7 +653,8 @@
630
653
  fields: z.z.array(TinaFieldZod),
631
654
  match: z.z.object({
632
655
  start: z.z.string(),
633
- end: z.z.string()
656
+ end: z.z.string(),
657
+ name: z.z.string().optional()
634
658
  }).optional()
635
659
  }).superRefine((val, ctx) => {
636
660
  const dups = findDuplicates(val == null ? void 0 : val.fields.map((x) => x.name));
@@ -760,7 +784,7 @@ ${JSON.stringify(val, null, 2)}
760
784
  const newConfig = tinaConfigZod.parse(config);
761
785
  return newConfig;
762
786
  };
763
- const FORMATS = ["json", "md", "markdown", "mdx"];
787
+ const FORMATS = ["json", "md", "markdown", "mdx", "toml", "yaml"];
764
788
  const Template = z.z.object({
765
789
  label: z.z.string({
766
790
  invalid_type_error: "label must be a string",
@@ -123,6 +123,14 @@ interface BaseCollection {
123
123
  defaultItem?: DefaultItem<Record<string, any>>;
124
124
  indexes?: TinaIndex[];
125
125
  format?: FormatType;
126
+ /**
127
+ * This format will be used to parse the markdown frontmatter
128
+ */
129
+ frontmatterFormat?: 'yaml' | 'toml' | 'json';
130
+ /**
131
+ * The delimiters used to parse the frontmatter.
132
+ */
133
+ frontmatterDelimiters?: [string, string] | string;
126
134
  ui?: UICollection;
127
135
  match?: string;
128
136
  }
@@ -173,7 +181,8 @@ export interface TinaField {
173
181
  }
174
182
  declare type ScalarType<WithNamespace extends boolean> = WithNamespace extends true ? ScalarTypeWithNamespace : ScalarTypeInner;
175
183
  export declare type Option = string | {
176
- label: string;
184
+ label?: string;
185
+ icon?: FC;
177
186
  value: string;
178
187
  };
179
188
  declare type ScalarTypeInner = TinaField & TinaScalarField & {
@@ -409,6 +418,7 @@ export declare type Template<WithNamespace extends boolean> = WithNamespace exte
409
418
  match?: {
410
419
  start: string;
411
420
  end: string;
421
+ name?: string;
412
422
  };
413
423
  ui?: object | (UIField<any, any> & {
414
424
  previewSrc: string;
@@ -424,6 +434,7 @@ export declare type Template<WithNamespace extends boolean> = WithNamespace exte
424
434
  match?: {
425
435
  start: string;
426
436
  end: string;
437
+ name?: string;
427
438
  };
428
439
  };
429
440
  export declare type CollectionTemplateableUnion = {
@@ -108,6 +108,7 @@ declare type Template = {
108
108
  match?: {
109
109
  start: string;
110
110
  end: string;
111
+ name?: string;
111
112
  };
112
113
  };
113
114
  declare type WithTemplates<Optional extends boolean = false> = Optional extends true ? {
@@ -245,6 +245,7 @@ export declare type RichTextField = (FieldGeneric<RichTextAst, undefined> | Fiel
245
245
  match?: {
246
246
  start: string;
247
247
  end: string;
248
+ name?: string;
248
249
  };
249
250
  })[];
250
251
  };
package/dist/types.d.ts CHANGED
@@ -109,6 +109,8 @@ declare type Component<Type, List> = (props: {
109
109
  meta: Meta;
110
110
  }) => any;
111
111
  declare type UIField<Type, List extends boolean> = {
112
+ max?: List extends true ? number : never;
113
+ min?: List extends true ? number : never;
112
114
  /**
113
115
  * Override the label from parent object
114
116
  */
@@ -193,7 +195,7 @@ declare type FieldGeneric<Type, List extends boolean | undefined, ExtraFieldUIPr
193
195
  ui?: UIField<Type, false> & ExtraFieldUIProps;
194
196
  };
195
197
  export interface BaseField {
196
- label?: string;
198
+ label?: string | boolean;
197
199
  required?: boolean;
198
200
  name: string;
199
201
  description?: string;
@@ -273,6 +275,7 @@ export declare type RichTextField = (FieldGeneric<RichTextAst, undefined> | Fiel
273
275
  match?: {
274
276
  start: string;
275
277
  end: string;
278
+ name?: string;
276
279
  };
277
280
  })[];
278
281
  };
@@ -330,7 +333,15 @@ export interface FieldCollection {
330
333
  label?: string;
331
334
  name: string;
332
335
  path: string;
333
- format?: 'json' | 'md' | 'markdown' | 'mdx';
336
+ format?: 'json' | 'md' | 'markdown' | 'mdx' | 'yaml' | 'toml';
337
+ /**
338
+ * This format will be used to parse the markdown frontmatter
339
+ */
340
+ frontmatterFormat?: 'yaml' | 'toml' | 'json';
341
+ /**
342
+ * The delimiters used to parse the frontmatter.
343
+ */
344
+ frontmatterDelimiters?: [string, string] | string;
334
345
  ui?: UICollection & {
335
346
  defaultItem?: DefaultItem<Record<string, any>>;
336
347
  };
@@ -350,7 +361,7 @@ export interface TemplateCollection {
350
361
  label?: string;
351
362
  name: string;
352
363
  path: string;
353
- format?: 'json' | 'md' | 'markdown' | 'mdx';
364
+ format?: 'json' | 'md' | 'markdown' | 'mdx' | 'yaml' | 'toml';
354
365
  ui?: UICollection;
355
366
  /**
356
367
  * @deprecated - use `ui.defaultItem` on the each `template` instead
@@ -432,6 +443,13 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
432
443
  * Note that for most framworks you can omit the `index.html` portion, for Next.js see the [rewrites section](https://nextjs.org/docs/api-reference/next.config.js/rewrites)
433
444
  */
434
445
  outputFolder: string;
446
+ /**
447
+ *
448
+ * the host option for the vite config. This is useful when trying to run tinacms dev in a docker container.
449
+ *
450
+ * See https://vitejs.dev/config/server-options.html#server-host for more details
451
+ */
452
+ host?: string | boolean;
435
453
  };
436
454
  media?: {
437
455
  /**
@@ -15,7 +15,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
15
15
  collections: z.ZodArray<z.ZodEffects<z.ZodObject<z.extendShape<{
16
16
  label: z.ZodOptional<z.ZodString>;
17
17
  name: z.ZodEffects<z.ZodString, string, string>;
18
- format: z.ZodOptional<z.ZodEnum<["json", "md", "markdown", "mdx"]>>;
18
+ format: z.ZodOptional<z.ZodEnum<["json", "md", "markdown", "mdx", "toml", "yaml"]>>;
19
19
  }, {
20
20
  fields: z.ZodEffects<z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodType<import("..").TinaFieldInner<false>, z.ZodTypeDef, import("..").TinaFieldInner<false>>, "many">>, import("..").TinaFieldInner<false>[], import("..").TinaFieldInner<false>[]>, import("..").TinaFieldInner<false>[], import("..").TinaFieldInner<false>[]>;
21
21
  templates: z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodObject<{
@@ -55,7 +55,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
55
55
  fields?: import("..").TinaFieldInner<false>[];
56
56
  label?: string;
57
57
  }[];
58
- format?: "json" | "md" | "markdown" | "mdx";
58
+ format?: "json" | "md" | "markdown" | "mdx" | "yaml" | "toml";
59
59
  label?: string;
60
60
  }, {
61
61
  name?: string;
@@ -65,7 +65,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
65
65
  fields?: import("..").TinaFieldInner<false>[];
66
66
  label?: string;
67
67
  }[];
68
- format?: "json" | "md" | "markdown" | "mdx";
68
+ format?: "json" | "md" | "markdown" | "mdx" | "yaml" | "toml";
69
69
  label?: string;
70
70
  }>, {
71
71
  name?: string;
@@ -75,7 +75,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
75
75
  fields?: import("..").TinaFieldInner<false>[];
76
76
  label?: string;
77
77
  }[];
78
- format?: "json" | "md" | "markdown" | "mdx";
78
+ format?: "json" | "md" | "markdown" | "mdx" | "yaml" | "toml";
79
79
  label?: string;
80
80
  }, {
81
81
  name?: string;
@@ -85,7 +85,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
85
85
  fields?: import("..").TinaFieldInner<false>[];
86
86
  label?: string;
87
87
  }[];
88
- format?: "json" | "md" | "markdown" | "mdx";
88
+ format?: "json" | "md" | "markdown" | "mdx" | "yaml" | "toml";
89
89
  label?: string;
90
90
  }>, "many">;
91
91
  config: z.ZodOptional<z.ZodObject<{
@@ -153,7 +153,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
153
153
  fields?: import("..").TinaFieldInner<false>[];
154
154
  label?: string;
155
155
  }[];
156
- format?: "json" | "md" | "markdown" | "mdx";
156
+ format?: "json" | "md" | "markdown" | "mdx" | "yaml" | "toml";
157
157
  label?: string;
158
158
  }[];
159
159
  config?: {
@@ -177,7 +177,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
177
177
  fields?: import("..").TinaFieldInner<false>[];
178
178
  label?: string;
179
179
  }[];
180
- format?: "json" | "md" | "markdown" | "mdx";
180
+ format?: "json" | "md" | "markdown" | "mdx" | "yaml" | "toml";
181
181
  label?: string;
182
182
  }[];
183
183
  config?: {
@@ -201,7 +201,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
201
201
  fields?: import("..").TinaFieldInner<false>[];
202
202
  label?: string;
203
203
  }[];
204
- format?: "json" | "md" | "markdown" | "mdx";
204
+ format?: "json" | "md" | "markdown" | "mdx" | "yaml" | "toml";
205
205
  label?: string;
206
206
  }[];
207
207
  config?: {
@@ -225,7 +225,7 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
225
225
  fields?: import("..").TinaFieldInner<false>[];
226
226
  label?: string;
227
227
  }[];
228
- format?: "json" | "md" | "markdown" | "mdx";
228
+ format?: "json" | "md" | "markdown" | "mdx" | "yaml" | "toml";
229
229
  label?: string;
230
230
  }[];
231
231
  config?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/schema-tools",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "./dist/index.es.js",
6
6
  "exports": {
@@ -31,7 +31,7 @@
31
31
  ]
32
32
  },
33
33
  "devDependencies": {
34
- "@tinacms/scripts": "1.0.0",
34
+ "@tinacms/scripts": "1.0.1",
35
35
  "@types/yup": "^0.29.10",
36
36
  "jest": "^27.0.6",
37
37
  "react": "17.0.2",