@mintlify/validation 0.1.264 → 0.1.266

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.
Files changed (29) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +31 -18
  3. package/dist/mint-config/schemas/v2/index.d.ts +640 -340
  4. package/dist/mint-config/schemas/v2/properties/navigation/anchors.js +28 -13
  5. package/dist/mint-config/schemas/v2/properties/navigation/dropdown.js +28 -13
  6. package/dist/mint-config/schemas/v2/properties/navigation/groups.d.ts +96 -17
  7. package/dist/mint-config/schemas/v2/properties/navigation/groups.js +7 -4
  8. package/dist/mint-config/schemas/v2/properties/navigation/index.d.ts +68 -32
  9. package/dist/mint-config/schemas/v2/properties/navigation/languages.js +27 -12
  10. package/dist/mint-config/schemas/v2/properties/navigation/tabs.js +28 -13
  11. package/dist/mint-config/schemas/v2/properties/navigation/version.js +28 -13
  12. package/dist/mint-config/schemas/v2/properties/reusable/color.d.ts +1 -0
  13. package/dist/mint-config/schemas/v2/properties/reusable/index.d.ts +1 -0
  14. package/dist/mint-config/schemas/v2/properties/reusable/index.js +1 -0
  15. package/dist/mint-config/schemas/v2/themes/linden.d.ts +128 -68
  16. package/dist/mint-config/schemas/v2/themes/maple.d.ts +128 -68
  17. package/dist/mint-config/schemas/v2/themes/mint.d.ts +128 -68
  18. package/dist/mint-config/schemas/v2/themes/palm.d.ts +128 -68
  19. package/dist/mint-config/schemas/v2/themes/reusable/index.d.ts +68 -32
  20. package/dist/mint-config/schemas/v2/themes/willow.d.ts +128 -68
  21. package/dist/mint-config/upgrades/updateNavigationToDocsConfig.d.ts +0 -7
  22. package/dist/mint-config/upgrades/updateNavigationToDocsConfig.js +132 -42
  23. package/dist/mint-config/validateConfig.d.ts +300 -180
  24. package/dist/tsconfig.build.tsbuildinfo +1 -1
  25. package/dist/types/index.d.ts +1 -0
  26. package/dist/types/index.js +1 -0
  27. package/dist/types/serverStaticProps.d.ts +18 -0
  28. package/dist/types/serverStaticProps.js +1 -0
  29. package/package.json +3 -3
@@ -1,3 +1,4 @@
1
+ import isAbsoluteUrl from 'is-absolute-url';
1
2
  import _ from 'lodash';
2
3
  const DEFAULT_TAB = {
3
4
  tab: 'Documentation',
@@ -52,8 +53,8 @@ const findPagesForPrefix = (groups, division, versionName, ignoredDivisions = []
52
53
  if (isGroupVersionMatch) {
53
54
  group.pages.forEach((page) => {
54
55
  if (typeof page === 'string') {
55
- if ((!prefix || page.startsWith(prefix)) &&
56
- !ignoredDivisions.some((d) => page.startsWith(d.url))) {
56
+ if ((!prefix || ensureLeadingSlash(page).startsWith(ensureLeadingSlash(prefix))) &&
57
+ !ignoredDivisions.some((d) => ensureLeadingSlash(page).startsWith(ensureLeadingSlash(d.url)))) {
57
58
  groupPages.push(page);
58
59
  }
59
60
  else {
@@ -78,8 +79,7 @@ const findPagesForPrefix = (groups, division, versionName, ignoredDivisions = []
78
79
  });
79
80
  return { matchedGroups, unmatchedGroups };
80
81
  };
81
- const processDivisions = (type, divisions = [], navigationGroups = [], shouldInsertRemainingGroups = false, versionName, config) => {
82
- var _a, _b;
82
+ const processDivisions = (type, divisions = [], navigationGroups = [], shouldInsertRemainingGroups = false, versionName, config, otherDivisions) => {
83
83
  let remainingGroups = filterGroupsByVersion(navigationGroups, versionName);
84
84
  const result = divisions
85
85
  .map((division) => {
@@ -100,26 +100,41 @@ const processDivisions = (type, divisions = [], navigationGroups = [], shouldIns
100
100
  };
101
101
  }
102
102
  }
103
- const ignoredDivisions = divisions.filter((d) => d.url.startsWith(division.url) && d.url !== division.url);
103
+ const ignoredDivisions = divisions.filter((d) => ensureLeadingSlash(d.url).startsWith(ensureLeadingSlash(division.url)) &&
104
+ d.url !== division.url);
105
+ let moreTabs = [];
106
+ let moreAnchors = [];
107
+ // process the other divisions
108
+ if (otherDivisions === null || otherDivisions === void 0 ? void 0 : otherDivisions.length) {
109
+ const matchedDivisions = otherDivisions.filter((d) => {
110
+ return ensureLeadingSlash(d.url).startsWith(ensureLeadingSlash(division.url));
111
+ });
112
+ if (matchedDivisions.length) {
113
+ const { tabs, anchors } = processDivisions(type === 'tabs' ? 'anchors' : 'tabs', matchedDivisions, navigationGroups, false, versionName, config);
114
+ moreTabs = tabs;
115
+ moreAnchors = anchors;
116
+ }
117
+ }
104
118
  const { matchedGroups, unmatchedGroups } = findPagesForPrefix(remainingGroups, division, versionName, ignoredDivisions);
105
119
  remainingGroups = unmatchedGroups;
106
120
  if (matchedGroups.length) {
107
- return Object.assign(Object.assign({}, _.omit(baseDivision, 'href')), { groups: matchedGroups });
121
+ if (matchedGroups.length) {
122
+ const divisionWithoutHref = _.omit(baseDivision, 'href');
123
+ if (moreTabs.length)
124
+ return Object.assign(Object.assign({}, divisionWithoutHref), { tabs: moreTabs });
125
+ if (moreAnchors.length)
126
+ return Object.assign(Object.assign({}, divisionWithoutHref), { anchors: moreAnchors });
127
+ return Object.assign(Object.assign({}, divisionWithoutHref), { groups: matchedGroups });
128
+ }
108
129
  }
130
+ if (!matchedGroups.length && !isAbsoluteUrl(division.url))
131
+ return undefined;
109
132
  return baseDivision;
110
133
  })
111
134
  .filter(Boolean);
112
135
  if (remainingGroups.length && shouldInsertRemainingGroups) {
113
136
  const { matchedGroups } = findPagesForPrefix(remainingGroups, undefined, versionName, []);
114
- if (type === 'tabs') {
115
- result.unshift(Object.assign(Object.assign({}, (((_a = config === null || config === void 0 ? void 0 : config.primaryTab) === null || _a === void 0 ? void 0 : _a.name)
116
- ? Object.assign({ tab: config.primaryTab.name }, (config.primaryTab.isDefaultHidden !== undefined && {
117
- hidden: config.primaryTab.isDefaultHidden,
118
- })) : DEFAULT_TAB)), { groups: matchedGroups }));
119
- }
120
- else {
121
- result.push(Object.assign(Object.assign({}, (((_b = config === null || config === void 0 ? void 0 : config.topAnchor) === null || _b === void 0 ? void 0 : _b.name) ? { anchor: config.topAnchor.name } : DEFAULT_ANCHOR)), { groups: matchedGroups }));
122
- }
137
+ result.unshift(Object.assign(Object.assign({}, getPrimaryConfig(type === 'tabs' ? 'tab' : 'anchor', config)), { groups: matchedGroups }));
123
138
  }
124
139
  if (type === 'tabs') {
125
140
  return { tabs: result, anchors: [], remainingGroups };
@@ -162,9 +177,12 @@ const processVersionsOrLanguages = (versions = [], navigationGroups = [], prefix
162
177
  }
163
178
  else {
164
179
  const versionName = typeof version === 'string' ? version : version.name;
180
+ const versionHref = typeof version === 'string' ? undefined : version.url;
165
181
  const baseVersion = {
166
182
  version: versionName,
167
183
  };
184
+ if (versionHref)
185
+ return Object.assign(Object.assign({}, baseVersion), { href: versionHref });
168
186
  const { matchedGroups } = findPagesForVersionOrLanguage(navigationGroups, versionName, prefixes);
169
187
  return Object.assign(Object.assign({}, baseVersion), { groups: matchedGroups });
170
188
  }
@@ -174,36 +192,57 @@ const processVersionsOrLanguages = (versions = [], navigationGroups = [], prefix
174
192
  versions: result,
175
193
  };
176
194
  };
177
- /**
178
- * Priority
179
- * 1. versions (including locales)
180
- * 2. anchors (global anchors)
181
- * 3. tabs (tabs)
182
- * 4. groups
183
- */
184
195
  export const updateNavigationToDocsConfig = (config) => {
185
- const { navigation: groups, tabs, anchors, versions } = config;
196
+ let { tabs, anchors, versions } = config;
197
+ const groups = config.navigation;
186
198
  const { tabs: globalTabs, anchors: globalAnchors, versions: globalVersions, } = getGlobalDivisions(config);
199
+ const hasTabs = tabs === null || tabs === void 0 ? void 0 : tabs.length;
200
+ const hasAnchors = anchors === null || anchors === void 0 ? void 0 : anchors.length;
201
+ tabs = (globalTabs === null || globalTabs === void 0 ? void 0 : globalTabs.length) ? [] : tabs;
202
+ anchors = (globalAnchors === null || globalAnchors === void 0 ? void 0 : globalAnchors.length) ? [] : anchors;
203
+ versions = (globalVersions === null || globalVersions === void 0 ? void 0 : globalVersions.length) ? [] : versions;
187
204
  // process divisions
188
- const getUpdatedNavigation = (groups, tabs, anchors, versionName, config) => {
189
- var _a, _b;
190
- if ((anchors === null || anchors === void 0 ? void 0 : anchors.length) && !(globalAnchors === null || globalAnchors === void 0 ? void 0 : globalAnchors.length)) {
191
- const { anchors: anchorsResult, remainingGroups } = processDivisions('anchors', anchors, groups, false, versionName, config);
192
- if (remainingGroups.length || (tabs === null || tabs === void 0 ? void 0 : tabs.length)) {
193
- if ((tabs === null || tabs === void 0 ? void 0 : tabs.length) && !(globalTabs === null || globalTabs === void 0 ? void 0 : globalTabs.length)) {
194
- const { tabs: tabsResult } = processDivisions('tabs', tabs, remainingGroups.length ? remainingGroups : groups, true, versionName, config);
195
- anchorsResult.push(Object.assign(Object.assign({}, (((_a = config === null || config === void 0 ? void 0 : config.topAnchor) === null || _a === void 0 ? void 0 : _a.name) ? { anchor: config.topAnchor.name } : DEFAULT_ANCHOR)), { tabs: tabsResult }));
196
- }
197
- else {
198
- const { matchedGroups } = findPagesForPrefix(remainingGroups, undefined, versionName);
199
- anchorsResult.push(Object.assign(Object.assign({}, (((_b = config === null || config === void 0 ? void 0 : config.topAnchor) === null || _b === void 0 ? void 0 : _b.name) ? { anchor: config.topAnchor.name } : DEFAULT_ANCHOR)), { groups: matchedGroups }));
205
+ const getUpdatedNavigation = (groups, config, versionName) => {
206
+ const topLevelDivision = findMostInclusiveDivision(tabs, anchors);
207
+ if (topLevelDivision === 'anchors') {
208
+ if (hasAnchors) {
209
+ const { anchors: anchorsResult, remainingGroups } = processDivisions('anchors', anchors, groups, false, versionName, config, tabs);
210
+ if (remainingGroups.length || (tabs === null || tabs === void 0 ? void 0 : tabs.length)) {
211
+ if (tabs === null || tabs === void 0 ? void 0 : tabs.length) {
212
+ const { tabs: tabsResult } = processDivisions('tabs', tabs, remainingGroups.length ? remainingGroups : groups, true, versionName, config);
213
+ anchorsResult.unshift(Object.assign(Object.assign({}, getPrimaryConfig('anchor', config)), { tabs: tabsResult }));
214
+ }
215
+ else {
216
+ const { matchedGroups } = findPagesForPrefix(remainingGroups, undefined, versionName);
217
+ anchorsResult.unshift(Object.assign(Object.assign({}, getPrimaryConfig('anchor', config)), { groups: matchedGroups }));
218
+ }
200
219
  }
220
+ return { anchors: anchorsResult };
221
+ }
222
+ if (hasTabs) {
223
+ const { tabs: tabsResult } = processDivisions('tabs', tabs, groups, true, versionName, config);
224
+ return { tabs: tabsResult };
201
225
  }
202
- return { anchors: anchorsResult };
203
226
  }
204
- if ((tabs === null || tabs === void 0 ? void 0 : tabs.length) && !(globalTabs === null || globalTabs === void 0 ? void 0 : globalTabs.length)) {
205
- const { tabs: tabsResult } = processDivisions('tabs', tabs, groups, true, versionName, config);
206
- return { tabs: tabsResult };
227
+ else {
228
+ if (hasTabs) {
229
+ const { tabs: tabsResult, remainingGroups } = processDivisions('tabs', tabs, groups, false, versionName, config, anchors);
230
+ if (remainingGroups.length || (anchors === null || anchors === void 0 ? void 0 : anchors.length)) {
231
+ if (anchors === null || anchors === void 0 ? void 0 : anchors.length) {
232
+ const { anchors: anchorsResult } = processDivisions('anchors', anchors, remainingGroups.length ? remainingGroups : groups, true, versionName, config);
233
+ tabsResult.unshift(Object.assign(Object.assign({}, getPrimaryConfig('tab', config)), { anchors: anchorsResult }));
234
+ }
235
+ else {
236
+ const { matchedGroups } = findPagesForPrefix(remainingGroups, undefined, versionName);
237
+ tabsResult.unshift(Object.assign(Object.assign({}, getPrimaryConfig('tab', config)), { groups: matchedGroups }));
238
+ }
239
+ }
240
+ return { tabs: tabsResult };
241
+ }
242
+ if (hasAnchors) {
243
+ const { anchors: anchorsResult } = processDivisions('anchors', anchors, groups, true, versionName, config);
244
+ return { anchors: anchorsResult };
245
+ }
207
246
  }
208
247
  if (groups.length) {
209
248
  const parsedGroups = filterGroupsByVersion(groups, versionName).map((group) => (Object.assign({ group: group.group, pages: group.pages }, (group.icon ? { icon: formatIcon(group.icon, group.iconType) } : {}))));
@@ -212,6 +251,7 @@ export const updateNavigationToDocsConfig = (config) => {
212
251
  return undefined;
213
252
  };
214
253
  if ((versions === null || versions === void 0 ? void 0 : versions.length) && !(globalVersions === null || globalVersions === void 0 ? void 0 : globalVersions.length)) {
254
+ // divisions that match the versions
215
255
  const prefixes = versions.reduce((acc, version) => {
216
256
  const versionName = typeof version === 'string' ? version : version.name;
217
257
  const anchorPrefixes = anchors === null || anchors === void 0 ? void 0 : anchors.filter((anchor) => anchor.version === versionName && !isRemoteUrl(anchor.url));
@@ -223,11 +263,20 @@ export const updateNavigationToDocsConfig = (config) => {
223
263
  const { versions: versionsResult, isLocale } = processVersionsOrLanguages(versions, groups, prefixes);
224
264
  versionsResult.forEach((version, index) => {
225
265
  var _a;
266
+ if (typeof version === 'object' && 'href' in version) {
267
+ return;
268
+ }
226
269
  const versionName = typeof versions[index] === 'string'
227
270
  ? version.version
228
271
  : ((_a = versions[index]) === null || _a === void 0 ? void 0 : _a.name) || version.language;
229
- if ('groups' in version) {
230
- const updatedNavigationPerVersion = getUpdatedNavigation(version.groups, tabs, anchors, versionName, config);
272
+ if ('groups' in version && version.groups.length) {
273
+ const updatedNavigationPerVersion = getUpdatedNavigation(version.groups, config, versionName);
274
+ if (updatedNavigationPerVersion) {
275
+ versionsResult[index] = Object.assign(Object.assign({}, _.omit(version, 'groups')), updatedNavigationPerVersion);
276
+ }
277
+ }
278
+ else {
279
+ const updatedNavigationPerVersion = getUpdatedNavigation(groups, config, versionName);
231
280
  if (updatedNavigationPerVersion) {
232
281
  versionsResult[index] = Object.assign(Object.assign({}, _.omit(version, 'groups')), updatedNavigationPerVersion);
233
282
  }
@@ -239,7 +288,7 @@ export const updateNavigationToDocsConfig = (config) => {
239
288
  }
240
289
  return navigationConfig;
241
290
  }
242
- const navigationConfig = (getUpdatedNavigation(groups, tabs, anchors, undefined, config) || {
291
+ const navigationConfig = (getUpdatedNavigation(groups, config) || {
243
292
  groups: [],
244
293
  });
245
294
  if ((globalTabs === null || globalTabs === void 0 ? void 0 : globalTabs.length) || (globalAnchors === null || globalAnchors === void 0 ? void 0 : globalAnchors.length)) {
@@ -247,3 +296,44 @@ export const updateNavigationToDocsConfig = (config) => {
247
296
  }
248
297
  return navigationConfig;
249
298
  };
299
+ /**
300
+ * Decide which division is most relevant to the top level navigation
301
+ * 1. if tabs doesn't exist, return anchors, vice versa
302
+ * 2. if both exist, return the most inclusive division
303
+ * 2.1 if tabs are more inclusive, return tabs
304
+ * 2.2 if anchors are more inclusive, return anchors
305
+ */
306
+ function findMostInclusiveDivision(tabs, anchors) {
307
+ if (!(tabs === null || tabs === void 0 ? void 0 : tabs.length))
308
+ return 'anchors';
309
+ if (!(anchors === null || anchors === void 0 ? void 0 : anchors.length))
310
+ return 'tabs';
311
+ const inclusiveTabs = tabs.filter((tab) => {
312
+ return anchors.some((anchor) => ensureLeadingSlash(tab.url).startsWith(ensureLeadingSlash(anchor.url)));
313
+ });
314
+ const inclusiveAnchors = anchors.filter((anchor) => {
315
+ return tabs.some((tab) => ensureLeadingSlash(anchor.url).startsWith(ensureLeadingSlash(tab.url)));
316
+ });
317
+ // this means that there is a division that covers all paths
318
+ if (inclusiveTabs.length === tabs.length)
319
+ return 'tabs';
320
+ if (inclusiveAnchors.length === anchors.length)
321
+ return 'anchors';
322
+ // compare the number of inclusive divisions
323
+ return inclusiveTabs.length > inclusiveAnchors.length ? 'tabs' : 'anchors';
324
+ }
325
+ function ensureLeadingSlash(path) {
326
+ return path.startsWith('/') ? path : `/${path}`;
327
+ }
328
+ const getPrimaryConfig = (type, config) => {
329
+ var _a, _b;
330
+ if (type === 'anchor') {
331
+ return Object.assign(Object.assign({}, (((_a = config === null || config === void 0 ? void 0 : config.topAnchor) === null || _a === void 0 ? void 0 : _a.name) ? { anchor: config.topAnchor.name } : DEFAULT_ANCHOR)), (((_b = config === null || config === void 0 ? void 0 : config.topAnchor) === null || _b === void 0 ? void 0 : _b.icon)
332
+ ? { icon: formatIcon(config.topAnchor.icon, config.topAnchor.iconType) }
333
+ : {}));
334
+ }
335
+ return Object.assign({}, ((config === null || config === void 0 ? void 0 : config.primaryTab)
336
+ ? Object.assign({ tab: config.primaryTab.name }, (config.primaryTab.isDefaultHidden !== undefined && {
337
+ hidden: config.primaryTab.isDefaultHidden,
338
+ })) : DEFAULT_TAB));
339
+ };