@tinacms/schema-tools 1.3.4 → 1.4.1

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.d.ts CHANGED
@@ -6,3 +6,4 @@ export * from './types/index';
6
6
  export * from './validate';
7
7
  export * from './util/namer';
8
8
  export * from './util/parseURL';
9
+ export * from './util/normalizePath';
package/dist/index.es.js CHANGED
@@ -1,3 +1,4 @@
1
+ import micromatch from "micromatch";
1
2
  import * as yup from "yup";
2
3
  import UrlPattern from "url-pattern";
3
4
  import z$1, { z, ZodError } from "zod";
@@ -143,14 +144,15 @@ const parseURL = (url) => {
143
144
  host: params.host
144
145
  };
145
146
  }
146
- const pattern = new UrlPattern("/content/:clientId/github/*", {
147
- escapeChar: " "
147
+ const pattern = new UrlPattern("/:v/content/:clientId/github/*", {
148
+ escapeChar: " ",
149
+ segmentValueCharset: "a-zA-Z0-9-_~ %."
148
150
  });
149
151
  const result = pattern.match(params.pathname);
150
152
  const branch = result == null ? void 0 : result._;
151
153
  const clientId = result == null ? void 0 : result.clientId;
152
154
  if (!branch || !clientId) {
153
- throw new Error(`Invalid URL format provided. Expected: https://content.tinajs.io/content/<ClientID>/github/<Branch> but but received ${url}`);
155
+ throw new Error(`Invalid URL format provided. Expected: https://content.tinajs.io/<Version>/content/<ClientID>/github/<Branch> but but received ${url}`);
154
156
  }
155
157
  return {
156
158
  host: params.host,
@@ -159,6 +161,7 @@ const parseURL = (url) => {
159
161
  isLocalClient: false
160
162
  };
161
163
  };
164
+ const normalizePath = (filepath) => filepath.replace(/\\/g, "/");
162
165
  class TinaSchema {
163
166
  constructor(config) {
164
167
  this.config = config;
@@ -171,10 +174,6 @@ class TinaSchema {
171
174
  this.getCollectionsByName = (collectionNames) => {
172
175
  return this.schema.collections.filter((collection) => collectionNames.includes(collection.name));
173
176
  };
174
- this.getAllCollectionPaths = () => {
175
- const paths = this.getCollections().map((collection) => `${collection.path}${collection.match || ""}`);
176
- return paths;
177
- };
178
177
  this.getCollection = (collectionName) => {
179
178
  const collection = this.schema.collections.find((collection2) => collection2.name === collectionName);
180
179
  if (!collection) {
@@ -201,7 +200,19 @@ class TinaSchema {
201
200
  return this.schema.collections.map((collection) => this.getCollection(collection.name)) || [];
202
201
  };
203
202
  this.getCollectionByFullPath = (filepath) => {
203
+ const fileExtension = filepath.split(".").pop();
204
204
  const possibleCollections = this.getCollections().filter((collection) => {
205
+ var _a, _b;
206
+ if (fileExtension !== (collection.format || "md")) {
207
+ return false;
208
+ }
209
+ 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)) {
210
+ const matches = this.getMatches({ collection });
211
+ const match = micromatch([filepath], matches).length > 0;
212
+ if (!match) {
213
+ return false;
214
+ }
215
+ }
205
216
  return filepath.replace(/\\/g, "/").startsWith(collection.path.replace(/\/?$/, "/"));
206
217
  });
207
218
  if (possibleCollections.length === 0) {
@@ -357,7 +368,7 @@ class TinaSchema {
357
368
  };
358
369
  this.getTemplatesForCollectable = (collection) => {
359
370
  let extraFields = [];
360
- if (collection.fields) {
371
+ if (collection == null ? void 0 : collection.fields) {
361
372
  const template = collection;
362
373
  if (typeof template.fields === "string" || typeof template.fields === "undefined") {
363
374
  throw new Error("Exptected template to have fields but none were found");
@@ -371,7 +382,7 @@ class TinaSchema {
371
382
  }
372
383
  };
373
384
  } else {
374
- if (collection.templates) {
385
+ if (collection == null ? void 0 : collection.templates) {
375
386
  return {
376
387
  namespace: collection.namespace,
377
388
  type: "union",
@@ -388,7 +399,74 @@ class TinaSchema {
388
399
  }
389
400
  }
390
401
  };
402
+ this.walkFields = (cb) => {
403
+ const walk = (collectionOrObject, collection, path) => {
404
+ if (collectionOrObject.templates) {
405
+ collectionOrObject.templates.forEach((template) => {
406
+ template.fields.forEach((field) => {
407
+ cb({ field, collection, path: [...path, template.name] });
408
+ });
409
+ });
410
+ }
411
+ if (collectionOrObject.fields) {
412
+ collectionOrObject.fields.forEach((field) => {
413
+ cb({ field, collection, path: [...path, field.name] });
414
+ if (field.type === "rich-text" || field.type === "object") {
415
+ walk(field, collection, [...path, field.name]);
416
+ }
417
+ });
418
+ }
419
+ };
420
+ const collections = this.getCollections();
421
+ collections.forEach((collection) => walk(collection, collection, []));
422
+ };
391
423
  this.schema = config;
424
+ this.walkFields(({ field, collection, path }) => {
425
+ var _a;
426
+ if (field.type === "rich-text") {
427
+ if (field.parser) {
428
+ return;
429
+ }
430
+ if (collection.format === "mdx") {
431
+ field.parser = { type: "mdx" };
432
+ } else {
433
+ (_a = field.templates) == null ? void 0 : _a.forEach((template) => {
434
+ if (!template.match) {
435
+ console.warn(`WARNING: Found rich-text template at ${collection.name}.${path.join(".")} with no matches property.
436
+ Visit https://tina.io/docs/reference/types/rich-text/#custom-shortcode-syntax to learn more
437
+ `);
438
+ }
439
+ });
440
+ field.parser = { type: "markdown" };
441
+ }
442
+ }
443
+ });
444
+ }
445
+ getMatches({
446
+ collection: collectionOrString
447
+ }) {
448
+ var _a, _b;
449
+ const collection = typeof collectionOrString === "string" ? this.getCollection(collectionOrString) : collectionOrString;
450
+ const normalPath = normalizePath(collection.path);
451
+ const format = collection.format || "md";
452
+ const matches = [];
453
+ if ((_a = collection == null ? void 0 : collection.match) == null ? void 0 : _a.include) {
454
+ const match = `${normalPath}/${collection.match.include}.${format}`;
455
+ matches.push(match);
456
+ }
457
+ if ((_b = collection == null ? void 0 : collection.match) == null ? void 0 : _b.exclude) {
458
+ const exclude = `!(${normalPath}/${collection.match.exclude}.${format})`;
459
+ matches.push(exclude);
460
+ }
461
+ return matches;
462
+ }
463
+ matchFiles({
464
+ collection,
465
+ files
466
+ }) {
467
+ const matches = this.getMatches({ collection });
468
+ const matchedFiles = micromatch(files, matches);
469
+ return matchedFiles;
392
470
  }
393
471
  }
394
472
  const resolveField = (field, schema) => {
@@ -925,4 +1003,4 @@ const validateSchema = ({ schema }) => {
925
1003
  }
926
1004
  }
927
1005
  };
928
- export { NAMER, TINA_HOST, TinaSchema, TinaSchemaValidationError, addNamespaceToSchema, parseURL, resolveField, resolveForm, validateSchema, validateTinaCloudSchemaConfig };
1006
+ export { NAMER, TINA_HOST, TinaSchema, TinaSchemaValidationError, addNamespaceToSchema, normalizePath, parseURL, resolveField, resolveForm, validateSchema, validateTinaCloudSchemaConfig };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function(global, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("yup"), require("url-pattern"), require("zod")) : typeof define === "function" && define.amd ? define(["exports", "yup", "url-pattern", "zod"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@tinacms/schema-tools"] = {}, global.NOOP, global.NOOP, global.NOOP));
3
- })(this, function(exports2, yup, UrlPattern, z) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("micromatch"), require("yup"), require("url-pattern"), require("zod")) : typeof define === "function" && define.amd ? define(["exports", "micromatch", "yup", "url-pattern", "zod"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@tinacms/schema-tools"] = {}, global.NOOP, global.NOOP, global.NOOP, global.NOOP));
3
+ })(this, function(exports2, micromatch, yup, UrlPattern, z) {
4
4
  "use strict";
5
5
  function _interopDefaultLegacy(e) {
6
6
  return e && typeof e === "object" && "default" in e ? e : { "default": e };
@@ -25,6 +25,7 @@
25
25
  n["default"] = e;
26
26
  return Object.freeze(n);
27
27
  }
28
+ var micromatch__default = /* @__PURE__ */ _interopDefaultLegacy(micromatch);
28
29
  var yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
29
30
  var UrlPattern__default = /* @__PURE__ */ _interopDefaultLegacy(UrlPattern);
30
31
  var z__default = /* @__PURE__ */ _interopDefaultLegacy(z);
@@ -170,14 +171,15 @@
170
171
  host: params.host
171
172
  };
172
173
  }
173
- const pattern = new UrlPattern__default["default"]("/content/:clientId/github/*", {
174
- escapeChar: " "
174
+ const pattern = new UrlPattern__default["default"]("/:v/content/:clientId/github/*", {
175
+ escapeChar: " ",
176
+ segmentValueCharset: "a-zA-Z0-9-_~ %."
175
177
  });
176
178
  const result = pattern.match(params.pathname);
177
179
  const branch = result == null ? void 0 : result._;
178
180
  const clientId = result == null ? void 0 : result.clientId;
179
181
  if (!branch || !clientId) {
180
- throw new Error(`Invalid URL format provided. Expected: https://content.tinajs.io/content/<ClientID>/github/<Branch> but but received ${url}`);
182
+ throw new Error(`Invalid URL format provided. Expected: https://content.tinajs.io/<Version>/content/<ClientID>/github/<Branch> but but received ${url}`);
181
183
  }
182
184
  return {
183
185
  host: params.host,
@@ -186,6 +188,7 @@
186
188
  isLocalClient: false
187
189
  };
188
190
  };
191
+ const normalizePath = (filepath) => filepath.replace(/\\/g, "/");
189
192
  class TinaSchema {
190
193
  constructor(config) {
191
194
  this.config = config;
@@ -198,10 +201,6 @@
198
201
  this.getCollectionsByName = (collectionNames) => {
199
202
  return this.schema.collections.filter((collection) => collectionNames.includes(collection.name));
200
203
  };
201
- this.getAllCollectionPaths = () => {
202
- const paths = this.getCollections().map((collection) => `${collection.path}${collection.match || ""}`);
203
- return paths;
204
- };
205
204
  this.getCollection = (collectionName) => {
206
205
  const collection = this.schema.collections.find((collection2) => collection2.name === collectionName);
207
206
  if (!collection) {
@@ -228,7 +227,19 @@
228
227
  return this.schema.collections.map((collection) => this.getCollection(collection.name)) || [];
229
228
  };
230
229
  this.getCollectionByFullPath = (filepath) => {
230
+ const fileExtension = filepath.split(".").pop();
231
231
  const possibleCollections = this.getCollections().filter((collection) => {
232
+ var _a, _b;
233
+ if (fileExtension !== (collection.format || "md")) {
234
+ return false;
235
+ }
236
+ 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)) {
237
+ const matches = this.getMatches({ collection });
238
+ const match = micromatch__default["default"]([filepath], matches).length > 0;
239
+ if (!match) {
240
+ return false;
241
+ }
242
+ }
232
243
  return filepath.replace(/\\/g, "/").startsWith(collection.path.replace(/\/?$/, "/"));
233
244
  });
234
245
  if (possibleCollections.length === 0) {
@@ -384,7 +395,7 @@
384
395
  };
385
396
  this.getTemplatesForCollectable = (collection) => {
386
397
  let extraFields = [];
387
- if (collection.fields) {
398
+ if (collection == null ? void 0 : collection.fields) {
388
399
  const template = collection;
389
400
  if (typeof template.fields === "string" || typeof template.fields === "undefined") {
390
401
  throw new Error("Exptected template to have fields but none were found");
@@ -398,7 +409,7 @@
398
409
  }
399
410
  };
400
411
  } else {
401
- if (collection.templates) {
412
+ if (collection == null ? void 0 : collection.templates) {
402
413
  return {
403
414
  namespace: collection.namespace,
404
415
  type: "union",
@@ -415,7 +426,74 @@
415
426
  }
416
427
  }
417
428
  };
429
+ this.walkFields = (cb) => {
430
+ const walk = (collectionOrObject, collection, path) => {
431
+ if (collectionOrObject.templates) {
432
+ collectionOrObject.templates.forEach((template) => {
433
+ template.fields.forEach((field) => {
434
+ cb({ field, collection, path: [...path, template.name] });
435
+ });
436
+ });
437
+ }
438
+ if (collectionOrObject.fields) {
439
+ collectionOrObject.fields.forEach((field) => {
440
+ cb({ field, collection, path: [...path, field.name] });
441
+ if (field.type === "rich-text" || field.type === "object") {
442
+ walk(field, collection, [...path, field.name]);
443
+ }
444
+ });
445
+ }
446
+ };
447
+ const collections = this.getCollections();
448
+ collections.forEach((collection) => walk(collection, collection, []));
449
+ };
418
450
  this.schema = config;
451
+ this.walkFields(({ field, collection, path }) => {
452
+ var _a;
453
+ if (field.type === "rich-text") {
454
+ if (field.parser) {
455
+ return;
456
+ }
457
+ if (collection.format === "mdx") {
458
+ field.parser = { type: "mdx" };
459
+ } else {
460
+ (_a = field.templates) == null ? void 0 : _a.forEach((template) => {
461
+ if (!template.match) {
462
+ console.warn(`WARNING: Found rich-text template at ${collection.name}.${path.join(".")} with no matches property.
463
+ Visit https://tina.io/docs/reference/types/rich-text/#custom-shortcode-syntax to learn more
464
+ `);
465
+ }
466
+ });
467
+ field.parser = { type: "markdown" };
468
+ }
469
+ }
470
+ });
471
+ }
472
+ getMatches({
473
+ collection: collectionOrString
474
+ }) {
475
+ var _a, _b;
476
+ const collection = typeof collectionOrString === "string" ? this.getCollection(collectionOrString) : collectionOrString;
477
+ const normalPath = normalizePath(collection.path);
478
+ const format = collection.format || "md";
479
+ const matches = [];
480
+ if ((_a = collection == null ? void 0 : collection.match) == null ? void 0 : _a.include) {
481
+ const match = `${normalPath}/${collection.match.include}.${format}`;
482
+ matches.push(match);
483
+ }
484
+ if ((_b = collection == null ? void 0 : collection.match) == null ? void 0 : _b.exclude) {
485
+ const exclude = `!(${normalPath}/${collection.match.exclude}.${format})`;
486
+ matches.push(exclude);
487
+ }
488
+ return matches;
489
+ }
490
+ matchFiles({
491
+ collection,
492
+ files
493
+ }) {
494
+ const matches = this.getMatches({ collection });
495
+ const matchedFiles = micromatch__default["default"](files, matches);
496
+ return matchedFiles;
419
497
  }
420
498
  }
421
499
  const resolveField = (field, schema) => {
@@ -957,6 +1035,7 @@ ${JSON.stringify(val, null, 2)}
957
1035
  exports2.TinaSchema = TinaSchema;
958
1036
  exports2.TinaSchemaValidationError = TinaSchemaValidationError;
959
1037
  exports2.addNamespaceToSchema = addNamespaceToSchema;
1038
+ exports2.normalizePath = normalizePath;
960
1039
  exports2.parseURL = parseURL;
961
1040
  exports2.resolveField = resolveField;
962
1041
  exports2.resolveForm = resolveForm;
@@ -1,4 +1,4 @@
1
- import { Schema, Collection, Template, Collectable, CollectionTemplateable } from '../types/index';
1
+ import { Schema, Collection, Template, Collectable, CollectionTemplateable, TinaField } from '../types/index';
2
2
  declare type Version = {
3
3
  fullVersion: string;
4
4
  major: string;
@@ -28,7 +28,6 @@ export declare class TinaSchema {
28
28
  } & Schema);
29
29
  getIsTitleFieldName: (collection: string) => string;
30
30
  getCollectionsByName: (collectionNames: string[]) => Collection<true>[];
31
- getAllCollectionPaths: () => string[];
32
31
  getCollection: (collectionName: string) => Collection<true>;
33
32
  getCollections: () => Collection<true>[];
34
33
  getCollectionByFullPath: (filepath: string) => Collection<true>;
@@ -60,5 +59,23 @@ export declare class TinaSchema {
60
59
  *
61
60
  */
62
61
  getTemplatesForCollectable: (collection: Collectable) => CollectionTemplateable;
62
+ walkFields: (cb: (args: {
63
+ field: TinaField;
64
+ collection: Collection;
65
+ path: string[];
66
+ }) => void) => void;
67
+ /**
68
+ * This function returns an array of glob matches for a given collection.
69
+ *
70
+ * @param collection The collection to get the matches for. Can be a string or a collection object.
71
+ * @returns An array of glob matches.
72
+ */
73
+ getMatches({ collection: collectionOrString, }: {
74
+ collection: string | Collection;
75
+ }): string[];
76
+ matchFiles({ collection, files, }: {
77
+ collection: string | Collection;
78
+ files: string[];
79
+ }): string[];
63
80
  }
64
81
  export {};
@@ -344,6 +344,10 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
344
344
  * Configurations for the autogenerated GraphQL HTTP client
345
345
  */
346
346
  client?: {
347
+ /**
348
+ * Skip building the autogenerated client
349
+ */
350
+ skip?: boolean;
347
351
  /**
348
352
  * Autogenerated queries will traverse references to a given depth
349
353
  * @default 2
@@ -467,7 +471,10 @@ interface BaseCollection {
467
471
  * The delimiters used to parse the frontmatter.
468
472
  */
469
473
  frontmatterDelimiters?: [string, string] | string;
470
- match?: string;
474
+ match?: {
475
+ include?: string;
476
+ exclude?: string;
477
+ };
471
478
  }
472
479
  declare type TemplateCollection<WithNamespace extends boolean = false> = {
473
480
  /**
@@ -0,0 +1 @@
1
+ export declare const normalizePath: (filepath: string) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/schema-tools",
3
- "version": "1.3.4",
3
+ "version": "1.4.1",
4
4
  "main": "dist/index.js",
5
5
  "module": "./dist/index.es.js",
6
6
  "exports": {
@@ -23,7 +23,8 @@
23
23
  ]
24
24
  },
25
25
  "devDependencies": {
26
- "@tinacms/scripts": "1.0.4",
26
+ "@tinacms/scripts": "1.1.0",
27
+ "@types/micromatch": "^4.0.2",
27
28
  "@types/yup": "^0.29.10",
28
29
  "jest": "^27.0.6",
29
30
  "react": "17.0.2",
@@ -42,6 +43,7 @@
42
43
  "directory": "packages/@tinacms/cli"
43
44
  },
44
45
  "dependencies": {
46
+ "micromatch": "4.0.5",
45
47
  "url-pattern": "^1.0.3",
46
48
  "zod": "^3.14.3"
47
49
  },