@mintlify/previewing 4.0.683 → 4.0.685

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.
@@ -0,0 +1,39 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { shouldRegenerateNavForPage } from '../local-preview/listener/utils.js';
3
+ describe('shouldRegenerateNavForPage', () => {
4
+ let frontmatterHashes;
5
+ beforeEach(() => {
6
+ frontmatterHashes = new Map();
7
+ });
8
+ it('should return true for first-time file processing', async () => {
9
+ const content = `---\ntitle: "Test Page"\ndescription: "A test page"\n---\n# Test Content`;
10
+ const result = await shouldRegenerateNavForPage('test.mdx', content, frontmatterHashes);
11
+ expect(result).toBe(true);
12
+ });
13
+ it('should return false when frontmatter has not changed', async () => {
14
+ const content = `---\ntitle: "Test Page"\ndescription: "A test page"\n---\n# Test Content`;
15
+ await shouldRegenerateNavForPage('test.mdx', content, frontmatterHashes);
16
+ const result = await shouldRegenerateNavForPage('test.mdx', content, frontmatterHashes);
17
+ expect(result).toBe(false);
18
+ });
19
+ it('should return true when frontmatter changes', async () => {
20
+ const originalContent = `---\ntitle: "Test Page"\ndescription: "A test page"\n---\n# Test Content`;
21
+ const updatedContent = `---\ntitle: "Updated Test Page"\ndescription: "A test page"\n---\n# Test Content`;
22
+ await shouldRegenerateNavForPage('test.mdx', originalContent, frontmatterHashes);
23
+ const result = await shouldRegenerateNavForPage('test.mdx', updatedContent, frontmatterHashes);
24
+ expect(result).toBe(true);
25
+ });
26
+ it('should return false when only content changes but frontmatter stays same', async () => {
27
+ const originalContent = `---\ntitle: "Test Page"\ndescription: "A test page"\n---\n# Original Content`;
28
+ const updatedContent = `---\ntitle: "Test Page"\ndescription: "A test page"\n---\n# Updated Content`;
29
+ await shouldRegenerateNavForPage('test.mdx', originalContent, frontmatterHashes);
30
+ const result = await shouldRegenerateNavForPage('test.mdx', updatedContent, frontmatterHashes);
31
+ expect(result).toBe(false);
32
+ });
33
+ it('should handle files with no frontmatter', async () => {
34
+ const contentNoFrontmatter = '# Just a heading\n\nSome content';
35
+ await shouldRegenerateNavForPage('test.mdx', contentNoFrontmatter, frontmatterHashes);
36
+ const result = await shouldRegenerateNavForPage('test.mdx', contentNoFrontmatter, frontmatterHashes);
37
+ expect(result).toBe(false);
38
+ });
39
+ });
@@ -16,8 +16,9 @@ import { generatePagesWithImports } from './generatePagesWithImports.js';
16
16
  import { getDocsState } from './getDocsState.js';
17
17
  import { resolveAllImports } from './resolveAllImports.js';
18
18
  import { updateGeneratedNav, updateOpenApiFiles, upsertOpenApiFile } from './update.js';
19
- import { isFileSizeValid } from './utils.js';
19
+ import { isFileSizeValid, shouldRegenerateNavForPage } from './utils.js';
20
20
  const { readFile } = _promises;
21
+ const frontmatterHashes = new Map();
21
22
  const listener = (callback) => {
22
23
  chokidar
23
24
  .watch(CMD_EXEC_PATH, {
@@ -132,8 +133,8 @@ const onUpdateEvent = async (filename, callback) => {
132
133
  : potentialCategory;
133
134
  switch (potentialCategory) {
134
135
  case 'page': {
135
- regenerateNav = true;
136
136
  let contentStr = (await readFile(filePath)).toString();
137
+ regenerateNav = await shouldRegenerateNavForPage(filename, contentStr, frontmatterHashes);
137
138
  const tree = await preparseMdxTree(contentStr, CMD_EXEC_PATH, filePath);
138
139
  const importsResponse = await findAndRemoveImports(tree);
139
140
  if (hasImports(importsResponse)) {
@@ -2,3 +2,4 @@ export declare const getFileExtension: (filename: string) => string;
2
2
  export declare const isFileSizeValid: (path: string, maxFileSizeInMb: number) => Promise<boolean>;
3
3
  export declare function isError(obj: unknown): boolean;
4
4
  export declare const readJsonFile: (path: string) => Promise<any>;
5
+ export declare const shouldRegenerateNavForPage: (filename: string, contentStr: string, frontmatterHashes: Map<string, string>) => Promise<boolean>;
@@ -1,5 +1,7 @@
1
+ import crypto from 'crypto';
1
2
  import { promises as _promises } from 'fs';
2
3
  import fse from 'fs-extra';
4
+ import matter from 'gray-matter';
3
5
  const { stat } = _promises;
4
6
  export const getFileExtension = (filename) => {
5
7
  return filename.substring(filename.lastIndexOf('.') + 1, filename.length) || filename;
@@ -16,3 +18,27 @@ export const readJsonFile = async (path) => {
16
18
  const file = await fse.readFile(path, 'utf-8');
17
19
  return JSON.parse(file);
18
20
  };
21
+ export const shouldRegenerateNavForPage = async (filename, contentStr, frontmatterHashes) => {
22
+ try {
23
+ const { data: currentFrontmatter } = matter(contentStr);
24
+ const prevFrontmatterHash = frontmatterHashes.get(filename);
25
+ const currentFrontmatterHash = crypto
26
+ .createHash('md5')
27
+ .update(JSON.stringify(currentFrontmatter))
28
+ .digest('hex');
29
+ if (!prevFrontmatterHash) {
30
+ frontmatterHashes.set(filename, currentFrontmatterHash);
31
+ return true;
32
+ }
33
+ if (currentFrontmatterHash !== prevFrontmatterHash) {
34
+ frontmatterHashes.set(filename, currentFrontmatterHash);
35
+ return true;
36
+ }
37
+ frontmatterHashes.set(filename, currentFrontmatterHash);
38
+ return false;
39
+ }
40
+ catch (error) {
41
+ console.warn(`Error parsing frontmatter for ${filename}, regenerating nav:`, error);
42
+ return true;
43
+ }
44
+ };