@mintlify/common 1.0.844 → 1.0.846

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.
@@ -1,6 +1,7 @@
1
1
  import { divisions } from '@mintlify/validation';
2
2
  import { isPage } from '../navigation/isPage.js';
3
3
  import { optionallyRemoveLeadingSlash } from '../optionallyRemoveLeadingSlash.js';
4
+ import { iterateObjectArrayProperty } from './iterateObjectArrayProperty.js';
4
5
  /**
5
6
  * Generates a map from page paths to their hidden status based on navigation hierarchy.
6
7
  * A page is hidden if any parent group/division has hidden: true
@@ -38,13 +39,6 @@ function generatePathToHiddenDictRecursive(pathToHiddenDict, nav, parentHidden)
38
39
  }
39
40
  }
40
41
  for (const key of ['groups', ...divisions]) {
41
- if (key in nav) {
42
- const items = nav[key];
43
- if (Array.isArray(items)) {
44
- for (const item of items) {
45
- generatePathToHiddenDictRecursive(pathToHiddenDict, item, effectiveHidden);
46
- }
47
- }
48
- }
42
+ iterateObjectArrayProperty(nav, key, (item) => generatePathToHiddenDictRecursive(pathToHiddenDict, item, effectiveHidden));
49
43
  }
50
44
  }
@@ -1,5 +1,6 @@
1
1
  import { divisions, } from '@mintlify/validation';
2
2
  import { optionallyRemoveLeadingSlash } from '../optionallyRemoveLeadingSlash.js';
3
+ import { iterateObjectArrayProperty } from './iterateObjectArrayProperty.js';
3
4
  export function generatePathToLanguageDict(nav) {
4
5
  const pathToLanguageDict = new Map();
5
6
  traverseNavigation(pathToLanguageDict, nav, undefined);
@@ -15,10 +16,7 @@ function traverseNavigation(pathToLanguageDict, nav, nearestLanguage) {
15
16
  return;
16
17
  }
17
18
  for (const division of ['groups', ...divisions]) {
18
- if (division in nav && Array.isArray(nav[division])) {
19
- const items = nav[division];
20
- items.forEach((item) => traverseNavigation(pathToLanguageDict, item, currentLanguage));
21
- }
19
+ iterateObjectArrayProperty(nav, division, (item) => traverseNavigation(pathToLanguageDict, item, currentLanguage));
22
20
  }
23
21
  }
24
22
  function traverseGroup(pathToLanguageDict, entry, nearestLanguage) {
@@ -1,6 +1,7 @@
1
1
  import { divisions } from '@mintlify/validation';
2
2
  import { isPage } from '../navigation/isPage.js';
3
3
  import { optionallyRemoveLeadingSlash } from '../optionallyRemoveLeadingSlash.js';
4
+ import { iterateObjectArrayProperty } from './iterateObjectArrayProperty.js';
4
5
  /**
5
6
  * Generates a map from page paths to their public status based on navigation hierarchy.
6
7
  * A page is public if it or any parent group/division has public: true.
@@ -37,13 +38,6 @@ function generatePathToPublicDictRecursive(pathToPublicDict, nav, parentPublic)
37
38
  }
38
39
  }
39
40
  for (const key of ['groups', ...divisions]) {
40
- if (key in nav) {
41
- const items = nav[key];
42
- if (Array.isArray(items)) {
43
- for (const item of items) {
44
- generatePathToPublicDictRecursive(pathToPublicDict, item, effectivePublic);
45
- }
46
- }
47
- }
41
+ iterateObjectArrayProperty(nav, key, (item) => generatePathToPublicDictRecursive(pathToPublicDict, item, effectivePublic));
48
42
  }
49
43
  }
@@ -1,6 +1,7 @@
1
1
  import { divisions, } from '@mintlify/validation';
2
2
  import { isPage } from '../navigation/isPage.js';
3
3
  import { optionallyRemoveLeadingSlash } from '../optionallyRemoveLeadingSlash.js';
4
+ import { iterateObjectArrayProperty } from './iterateObjectArrayProperty.js';
4
5
  /**
5
6
  * Assumes page hrefs in navWithPageContext have a leading / but config page paths do not.
6
7
  * Outputted dictionary will NOT have a leading / in the dictionary keys.
@@ -34,16 +35,11 @@ function generatePathToVersionDictRecursive(pathToVersionDict, nav, nearestVersi
34
35
  }
35
36
  }
36
37
  for (const key of ['groups', ...divisions]) {
37
- if (key in nav) {
38
- const items = nav[key];
39
- if (Array.isArray(items)) {
40
- for (const item of items) {
41
- let version = nearestVersion;
42
- if (key === 'versions')
43
- version = item.version;
44
- generatePathToVersionDictRecursive(pathToVersionDict, item, version);
45
- }
46
- }
47
- }
38
+ iterateObjectArrayProperty(nav, key, (item) => {
39
+ let version = nearestVersion;
40
+ if (key === 'versions')
41
+ version = item.version;
42
+ generatePathToVersionDictRecursive(pathToVersionDict, item, version);
43
+ });
48
44
  }
49
45
  }
@@ -1,5 +1,6 @@
1
1
  import { divisions } from '@mintlify/validation';
2
2
  import { optionallyRemoveLeadingSlash } from '../optionallyRemoveLeadingSlash.js';
3
+ import { iterateObjectArrayProperty } from './iterateObjectArrayProperty.js';
3
4
  export function generatePathToVersionDictForDocsConfig(nav) {
4
5
  const pathToVersionDict = new Map();
5
6
  traverseNavigation(pathToVersionDict, nav, undefined);
@@ -15,10 +16,7 @@ function traverseNavigation(pathToVersionDict, nav, nearestVersion) {
15
16
  return;
16
17
  }
17
18
  for (const division of ['groups', 'tabs', ...divisions]) {
18
- if (division in nav) {
19
- const items = nav[division];
20
- items.forEach((item) => traverseNavigation(pathToVersionDict, item, currentVersion));
21
- }
19
+ iterateObjectArrayProperty(nav, division, (item) => traverseNavigation(pathToVersionDict, item, currentVersion));
22
20
  }
23
21
  }
24
22
  function traverseGroup(pathToVersionDict, entry, nearestVersion) {
@@ -1,3 +1,4 @@
1
+ export * from './iterateObjectArrayProperty.js';
1
2
  export * from './generatePathToHiddenDict.js';
2
3
  export * from './generatePathToVersionDict.js';
3
4
  export * from './generatePathToVersionDictForDocsConfig.js';
@@ -1,3 +1,4 @@
1
+ export * from './iterateObjectArrayProperty.js';
1
2
  export * from './generatePathToHiddenDict.js';
2
3
  export * from './generatePathToVersionDict.js';
3
4
  export * from './generatePathToVersionDictForDocsConfig.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Reads `obj[key]` when `key` is only known at runtime.
3
+ *
4
+ * Navigation config types such as `DecoratedNavigationConfig` are large discriminated unions
5
+ * (`{ languages: … } | { versions: … } | …`). TypeScript cannot type `obj[key]` for `key: string`
6
+ * without collapsing the union. Call sites pass validated config from Zod; we narrow with
7
+ * `Array.isArray` and `typeof item === 'object'`, then assert each element to `T` once.
8
+ */
9
+ export declare function readObjectArrayProperty<T extends object>(obj: object, key: string): T[] | undefined;
10
+ export declare function iterateObjectArrayProperty<T extends object>(obj: object, key: string, visit: (element: T) => void): void;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Reads `obj[key]` when `key` is only known at runtime.
3
+ *
4
+ * Navigation config types such as `DecoratedNavigationConfig` are large discriminated unions
5
+ * (`{ languages: … } | { versions: … } | …`). TypeScript cannot type `obj[key]` for `key: string`
6
+ * without collapsing the union. Call sites pass validated config from Zod; we narrow with
7
+ * `Array.isArray` and `typeof item === 'object'`, then assert each element to `T` once.
8
+ */
9
+ export function readObjectArrayProperty(obj, key) {
10
+ if (!(key in obj))
11
+ return undefined;
12
+ const raw = obj[key];
13
+ if (!Array.isArray(raw))
14
+ return undefined;
15
+ const out = [];
16
+ for (const item of raw) {
17
+ if (typeof item === 'object' && item !== null) {
18
+ out.push(item);
19
+ }
20
+ }
21
+ return out;
22
+ }
23
+ export function iterateObjectArrayProperty(obj, key, visit) {
24
+ const items = readObjectArrayProperty(obj, key);
25
+ if (!items)
26
+ return;
27
+ for (const item of items) {
28
+ visit(item);
29
+ }
30
+ }
@@ -1,7 +1,7 @@
1
1
  export type FileCategoryOptions = {
2
2
  importedFiles?: Set<string>;
3
3
  };
4
- export type PotentialFileCategory = 'page' | 'snippet' | 'mintConfig' | 'potentialYamlOpenApiSpec' | 'potentialJsonOpenApiSpec' | 'staticFile' | 'snippet-v2' | 'css' | 'js' | 'docsConfig' | 'generatedStaticFile' | 'mintIgnore' | null;
4
+ export type PotentialFileCategory = 'page' | 'snippet' | 'mintConfig' | 'potentialYamlOpenApiSpec' | 'potentialJsonOpenApiSpec' | 'staticFile' | 'snippet-v2' | 'css' | 'js' | 'docsConfig' | 'generatedStaticFile' | 'skillFile' | 'mintIgnore' | null;
5
5
  export type FileCategory = Omit<PotentialFileCategory, 'potentialYamlOpenApiSpec' | 'potentialJsonOpenApiSpec'> | 'openApi' | null;
6
6
  export declare const generatedStaticFiles: readonly ["llms.txt", "robots.txt", "sitemap.xml", "llms-full.txt"];
7
7
  export type GeneratedStaticFile = (typeof generatedStaticFiles)[number];
@@ -92,6 +92,10 @@ export const getFileCategory = (filePath, options) => {
92
92
  if (generatedStaticFiles.includes(parsed.base)) {
93
93
  return 'generatedStaticFile';
94
94
  }
95
+ if (normalizedFilePath === 'skill.md' ||
96
+ (normalizedFilePath.startsWith('.mintlify/skills/') && parsed.base === 'skill.md')) {
97
+ return 'skillFile';
98
+ }
95
99
  if ((normalizedFilePath.startsWith('_snippets/') || normalizedFilePath.startsWith('snippets/')) &&
96
100
  SNIPPET_EXTENSIONS.some((ext) => extension === ext)) {
97
101
  if (normalizedFilePath.startsWith('_snippets/')) {
@@ -1,4 +1,5 @@
1
1
  import { divisions } from '@mintlify/validation';
2
+ import { readObjectArrayProperty } from '../divisions/iterateObjectArrayProperty.js';
2
3
  export function getAllPathsInDocsNav(nav, paths = []) {
3
4
  if ('pages' in nav) {
4
5
  if ('root' in nav && typeof nav.root === 'string') {
@@ -8,10 +9,10 @@ export function getAllPathsInDocsNav(nav, paths = []) {
8
9
  return paths;
9
10
  }
10
11
  for (const division of ['groups', ...divisions]) {
11
- if (division in nav) {
12
- const items = nav[division];
13
- items.forEach((item) => getAllPathsInDocsNav(item, paths));
14
- }
12
+ const items = readObjectArrayProperty(nav, division);
13
+ if (!items)
14
+ continue;
15
+ items.forEach((item) => getAllPathsInDocsNav(item, paths));
15
16
  }
16
17
  return paths;
17
18
  }
@@ -1,4 +1,5 @@
1
1
  import { divisions, } from '@mintlify/validation';
2
+ import { readObjectArrayProperty } from '../divisions/iterateObjectArrayProperty.js';
2
3
  import { replaceSlashIndex } from '../slug/replaceSlashIndex.js';
3
4
  function getFirstFromPageOrGroup(entry) {
4
5
  if (typeof entry === 'string') {
@@ -31,17 +32,15 @@ export function getFirstPageFromNavConfig(nav) {
31
32
  }
32
33
  }
33
34
  for (const key of divisions) {
34
- if (key in nav) {
35
- const items = nav[key];
36
- if (Array.isArray(items)) {
37
- for (const item of items) {
38
- if (typeof item === 'object' && 'hidden' in item && item.hidden)
39
- continue;
40
- const result = getFirstPageFromNavConfig(item);
41
- if (result !== undefined)
42
- return result;
43
- }
44
- }
35
+ const items = readObjectArrayProperty(nav, key);
36
+ if (!items)
37
+ continue;
38
+ for (const item of items) {
39
+ if (typeof item === 'object' && 'hidden' in item && item.hidden)
40
+ continue;
41
+ const result = getFirstPageFromNavConfig(item);
42
+ if (result !== undefined)
43
+ return result;
45
44
  }
46
45
  }
47
46
  return undefined;
@@ -1,4 +1,5 @@
1
1
  import { divisions, } from '@mintlify/validation';
2
+ import { readObjectArrayProperty } from '../divisions/iterateObjectArrayProperty.js';
2
3
  import { replaceSlashIndex } from '../slug/replaceSlashIndex.js';
3
4
  import { checkNavAccess, isPage } from './index.js';
4
5
  import { prioritizeDefaultDivisionItem } from './prioritize-default-division-item.js';
@@ -42,19 +43,17 @@ export function getFirstPageFromNavigation(node, userGroups, shouldCheckNavAcces
42
43
  }
43
44
  }
44
45
  for (const key of divisions) {
45
- if (key in node) {
46
- const items = node[key];
47
- if (Array.isArray(items)) {
48
- const orderedItems = prioritizeDefaultDivisionItem(items, key);
49
- for (const item of orderedItems) {
50
- if (typeof item === 'object' && 'hidden' in item && item.hidden)
51
- continue;
52
- const page = getFirstPageFromNavigation(item, userGroups, shouldCheckNavAccess, isPreview);
53
- if (page) {
54
- page.href = replaceSlashIndex(page.href);
55
- return page;
56
- }
57
- }
46
+ const items = readObjectArrayProperty(node, key);
47
+ if (!items)
48
+ continue;
49
+ const orderedItems = prioritizeDefaultDivisionItem(items, key);
50
+ for (const item of orderedItems) {
51
+ if (typeof item === 'object' && 'hidden' in item && item.hidden)
52
+ continue;
53
+ const page = getFirstPageFromNavigation(item, userGroups, shouldCheckNavAccess, isPreview);
54
+ if (page) {
55
+ page.href = replaceSlashIndex(page.href);
56
+ return page;
58
57
  }
59
58
  }
60
59
  }