@mintlify/previewing 4.0.837 → 4.0.838

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 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ import fse from 'fs-extra';
2
+ import { initializeImportCache, updateImportCacheForFile, removeFromImportCache, getImportedFilesFromCache, } from '../local-preview/listener/importCache.js';
3
+ vi.mock('fs-extra', () => ({
4
+ default: { readFile: vi.fn() },
5
+ }));
6
+ vi.mock('@mintlify/prebuild', async () => {
7
+ const actual = await vi.importActual('@mintlify/prebuild');
8
+ return {
9
+ ...actual,
10
+ getFileListSync: vi.fn().mockReturnValue([]),
11
+ };
12
+ });
13
+ const mockReadFile = vi.mocked(fse.readFile);
14
+ describe('importCache', () => {
15
+ beforeEach(async () => {
16
+ vi.clearAllMocks();
17
+ await initializeImportCache('/base');
18
+ });
19
+ it('starts with empty cache', () => {
20
+ expect(getImportedFilesFromCache()).toEqual(new Set());
21
+ });
22
+ it('tracks imports when file is updated', async () => {
23
+ mockReadFile.mockResolvedValue(Buffer.from(`import Foo from './foo.mdx';\n\n<Foo />`));
24
+ await updateImportCacheForFile('/base', 'page.mdx');
25
+ expect(getImportedFilesFromCache()).toEqual(new Set(['/foo.mdx']));
26
+ });
27
+ it('returns newlyImported when import is added', async () => {
28
+ mockReadFile.mockResolvedValue(Buffer.from(`import Bar from '/bar.mdx';\n\n<Bar />`));
29
+ const result = await updateImportCacheForFile('/base', 'page.mdx');
30
+ expect(result.newlyImported).toEqual(['/bar.mdx']);
31
+ });
32
+ it('returns noLongerImported when file is removed', async () => {
33
+ mockReadFile.mockResolvedValue(Buffer.from(`import X from './x.mdx';\n\n<X />`));
34
+ await updateImportCacheForFile('/base', 'a.mdx');
35
+ const result = removeFromImportCache('a.mdx');
36
+ expect(result.noLongerImported).toEqual(['/x.mdx']);
37
+ });
38
+ it('ignores non-mdx files', async () => {
39
+ const result = await updateImportCacheForFile('/base', 'file.js');
40
+ expect(result).toEqual({ newlyImported: [], noLongerImported: [] });
41
+ });
42
+ it('keeps import in cache if still referenced by another file', async () => {
43
+ mockReadFile.mockResolvedValue(Buffer.from(`import S from './shared.mdx';\n\n<S />`));
44
+ await updateImportCacheForFile('/base', 'a.mdx');
45
+ await updateImportCacheForFile('/base', 'b.mdx');
46
+ const result = removeFromImportCache('a.mdx');
47
+ expect(result.noLongerImported).toEqual([]);
48
+ expect(getImportedFilesFromCache()).toEqual(new Set(['/shared.mdx']));
49
+ });
50
+ it('detects when imports change in a file', async () => {
51
+ mockReadFile.mockResolvedValue(Buffer.from(`import Old from './old.mdx';\n\n<Old />`));
52
+ await updateImportCacheForFile('/base', 'page.mdx');
53
+ mockReadFile.mockResolvedValue(Buffer.from(`import New from './new.mdx';\n\n<New />`));
54
+ const result = await updateImportCacheForFile('/base', 'page.mdx');
55
+ expect(result.newlyImported).toEqual(['/new.mdx']);
56
+ expect(result.noLongerImported).toEqual(['/old.mdx']);
57
+ });
58
+ });
@@ -5,8 +5,8 @@ import isOnline from 'is-online';
5
5
  import { CLIENT_PATH, DOT_MINTLIFY, CMD_EXEC_PATH, VERSION_PATH, NEXT_PUBLIC_PATH, NEXT_PROPS_PATH, } from '../constants.js';
6
6
  import { addLog, clearLogs } from '../logging-state.js';
7
7
  import { ErrorLog, SpinnerLog } from '../logs.js';
8
- import { silentUpdateClient } from './update.js';
9
8
  import { run } from './run.js';
9
+ import { silentUpdateClient } from './update.js';
10
10
  const dev = async (argv) => {
11
11
  const hasInternet = await isOnline();
12
12
  const localSchema = argv['local-schema'];
@@ -26,7 +26,11 @@ const dev = async (argv) => {
26
26
  process.exit(1);
27
27
  }
28
28
  addLog(_jsx(SpinnerLog, { message: "preparing local preview..." }));
29
- const { needsUpdate, error } = await silentUpdateClient({ versionString, clientVersion, cliVersion });
29
+ const { needsUpdate, error } = await silentUpdateClient({
30
+ versionString,
31
+ clientVersion,
32
+ cliVersion,
33
+ });
30
34
  if (error) {
31
35
  clearLogs();
32
36
  addLog(_jsx(ErrorLog, { message: error }));
@@ -37,8 +41,10 @@ const dev = async (argv) => {
37
41
  fse.emptyDirSync(NEXT_PUBLIC_PATH);
38
42
  fse.emptyDirSync(NEXT_PROPS_PATH);
39
43
  process.chdir(CLIENT_PATH);
44
+ let fileImportsMap;
40
45
  try {
41
- await prebuild(CMD_EXEC_PATH, { localSchema, groups, disableOpenApi });
46
+ const result = await prebuild(CMD_EXEC_PATH, { localSchema, groups, disableOpenApi });
47
+ fileImportsMap = result?.fileImportsMap;
42
48
  }
43
49
  catch (err) {
44
50
  clearLogs();
@@ -47,6 +53,6 @@ const dev = async (argv) => {
47
53
  await new Promise((resolve) => setTimeout(resolve, 50));
48
54
  process.exit(1);
49
55
  }
50
- await run({ ...argv, needsUpdate });
56
+ await run({ ...argv, needsUpdate, fileImportsMap });
51
57
  };
52
58
  export default dev;
@@ -1,4 +1,4 @@
1
- import { findAndRemoveImports, stringifyTree, topologicalSort, hasImports, optionallyAddLeadingSlash, optionallyRemoveLeadingSlash, resolveSnippetImportPath, } from '@mintlify/common';
1
+ import { findAndRemoveImports, stringifyTree, topologicalSort, hasImports, optionallyAddLeadingSlash, optionallyRemoveLeadingSlash, resolveImportPath, } from '@mintlify/common';
2
2
  import { outputFile } from 'fs-extra';
3
3
  import { join } from 'path';
4
4
  import { NEXT_PUBLIC_PATH } from '../../constants.js';
@@ -20,7 +20,7 @@ const findAllDependents = async (initialFileWithSlash, allSnippets, processedDat
20
20
  processedDataCache.set(potentialDependentFile, processedData);
21
21
  }
22
22
  const importsCurrentFile = Object.keys(processedData.importMap).some((importPath) => {
23
- const resolvedPath = resolveSnippetImportPath(importPath, potentialDependentFile);
23
+ const resolvedPath = resolveImportPath(importPath, potentialDependentFile);
24
24
  return resolvedPath === currentSourceFile;
25
25
  });
26
26
  if (importsCurrentFile) {
@@ -66,7 +66,7 @@ export const generateDependentSnippets = async (changedFilename, newImportData)
66
66
  const graph = {};
67
67
  snippets.forEach((item) => {
68
68
  graph[item.filename] = Object.keys(item.importMap)
69
- .map((dep) => resolveSnippetImportPath(dep, item.filename))
69
+ .map((dep) => resolveImportPath(dep, item.filename))
70
70
  .filter((resolvedDep) => resolvedDep != null);
71
71
  });
72
72
  const sortedSnippets = topologicalSort(graph).reverse();
@@ -1,16 +1,22 @@
1
- import { findAndRemoveImports, optionallyRemoveLeadingSlash, resolveAllImports, resolveSnippetImportPath, stringifyTree, SNIPPET_EXTENSIONS, } from '@mintlify/common';
2
- import { preparseMdxTree, getFileListSync } from '@mintlify/prebuild';
1
+ import { findAndRemoveImports, optionallyRemoveLeadingSlash, resolveAllImports, resolveImportPath, stringifyTree, isSnippetExtension, getFileCategory, } from '@mintlify/common';
2
+ import { preparseMdxTree, getFileListSync, getFileExtension } from '@mintlify/prebuild';
3
3
  import { promises as _promises } from 'fs';
4
4
  import { outputFile } from 'fs-extra';
5
5
  import { join } from 'path';
6
6
  import { CMD_EXEC_PATH, NEXT_PROPS_PATH } from '../../constants.js';
7
7
  import { getProcessedSnippets } from './getSnippets.js';
8
+ import { getImportedFilesFromCache } from './importCache.js';
8
9
  const { readFile } = _promises;
9
10
  export const generatePagesWithImports = async (updatedSnippets) => {
10
11
  const snippets = await getProcessedSnippets();
11
- const pageFilenames = getFileListSync(CMD_EXEC_PATH).filter((file) => SNIPPET_EXTENSIONS.some((ext) => file.endsWith(ext)) &&
12
- !file.startsWith('_snippets/') &&
13
- !file.startsWith('snippets/'));
12
+ const importedFiles = getImportedFilesFromCache();
13
+ const pageFilenames = getFileListSync(CMD_EXEC_PATH).filter((file) => {
14
+ if (!isSnippetExtension(getFileExtension(file))) {
15
+ return false;
16
+ }
17
+ const category = getFileCategory(file, { importedFiles });
18
+ return category === 'page';
19
+ });
14
20
  await Promise.all(pageFilenames.map(async (pageFilename) => {
15
21
  const sourcePath = join(CMD_EXEC_PATH, pageFilename);
16
22
  const contentStr = (await readFile(sourcePath)).toString();
@@ -18,7 +24,7 @@ export const generatePagesWithImports = async (updatedSnippets) => {
18
24
  const tree = await preparseMdxTree(contentStr, CMD_EXEC_PATH, sourcePath);
19
25
  const importsResponse = await findAndRemoveImports(tree);
20
26
  if (Object.keys(importsResponse.importMap).some((importPath) => {
21
- const resolvedPath = resolveSnippetImportPath(importPath, pageFilename);
27
+ const resolvedPath = resolveImportPath(importPath, pageFilename);
22
28
  return (resolvedPath != null &&
23
29
  updatedSnippets.has(optionallyRemoveLeadingSlash(resolvedPath)));
24
30
  })) {
@@ -1,14 +1,27 @@
1
- import { optionallyAddLeadingSlash, SNIPPET_EXTENSIONS } from '@mintlify/common';
2
- import { getFileListSync, preparseMdxTree } from '@mintlify/prebuild';
1
+ import { optionallyAddLeadingSlash, isSnippetExtension, isImportedAsSnippet, } from '@mintlify/common';
2
+ import { getFileListSync, preparseMdxTree, getFileExtension } from '@mintlify/prebuild';
3
3
  import { promises as _promises } from 'fs';
4
4
  import { join } from 'path';
5
5
  import { CMD_EXEC_PATH, NEXT_PUBLIC_PATH } from '../../constants.js';
6
+ import { getImportedFilesFromCache } from './importCache.js';
6
7
  const { readFile } = _promises;
7
- const getSnippetBase = async (BASE_DIR) => {
8
- const snippetFilenames = getFileListSync(BASE_DIR).filter((file) => SNIPPET_EXTENSIONS.some((ext) => file.endsWith(ext)) && file.startsWith('snippets/'));
9
- const promises = snippetFilenames.map(async (snippetFilename) => {
8
+ const getSnippetBase = async (baseDir) => {
9
+ const importedFiles = getImportedFilesFromCache();
10
+ const allSnippetFilenames = getFileListSync(baseDir).filter((file) => {
11
+ if (!isSnippetExtension(getFileExtension(file))) {
12
+ return false;
13
+ }
14
+ if (file.startsWith('snippets/') || file.startsWith('_snippets/')) {
15
+ return true;
16
+ }
17
+ if (getFileExtension(file) === 'jsx') {
18
+ return true;
19
+ }
20
+ return isImportedAsSnippet(file, importedFiles);
21
+ });
22
+ const promises = allSnippetFilenames.map(async (snippetFilename) => {
10
23
  try {
11
- const tree = await preparseMdxTree((await readFile(join(BASE_DIR, snippetFilename))).toString(), BASE_DIR, join(BASE_DIR, snippetFilename));
24
+ const tree = await preparseMdxTree((await readFile(join(baseDir, snippetFilename))).toString(), baseDir, join(baseDir, snippetFilename));
12
25
  return {
13
26
  filename: optionallyAddLeadingSlash(snippetFilename),
14
27
  tree,
@@ -0,0 +1,9 @@
1
+ export interface ImportCacheChangeResult {
2
+ newlyImported: string[];
3
+ noLongerImported: string[];
4
+ }
5
+ export declare const initializeImportCache: (baseDir: string, prebuildImportMap?: Map<string, Set<string>>) => Promise<void>;
6
+ export declare const updateImportCacheForFile: (baseDir: string, filename: string) => Promise<ImportCacheChangeResult>;
7
+ export declare const removeFromImportCache: (filename: string) => ImportCacheChangeResult;
8
+ export declare const getImportedFilesFromCache: () => Set<string>;
9
+ export declare const syncImportedFileLocations: (changes: ImportCacheChangeResult) => Promise<void>;
@@ -0,0 +1,168 @@
1
+ import { optionallyAddLeadingSlash, optionallyRemoveLeadingSlash, isSnippetExtension, extractImportSources, resolveImportPath, findAndRemoveImports, hasImports, stringifyTree, getFileCategory, } from '@mintlify/common';
2
+ import { getFileExtension } from '@mintlify/prebuild';
3
+ import { getFileListSync, createPage, preparseMdxTree } from '@mintlify/prebuild';
4
+ import fse from 'fs-extra';
5
+ import { join } from 'path';
6
+ import { CMD_EXEC_PATH, NEXT_PROPS_PATH, NEXT_PUBLIC_PATH } from '../../constants.js';
7
+ import { resolveAllImports } from './resolveAllImports.js';
8
+ import { normalizePathForComparison } from './utils.js';
9
+ const fileImportsMap = new Map();
10
+ const importerCounts = new Map();
11
+ const addImporter = (path) => {
12
+ const count = importerCounts.get(path) ?? 0;
13
+ importerCounts.set(path, count + 1);
14
+ return count === 0;
15
+ };
16
+ const removeImporter = (path) => {
17
+ const count = importerCounts.get(path);
18
+ if (count == null)
19
+ return false;
20
+ if (count <= 1) {
21
+ importerCounts.delete(path);
22
+ return true;
23
+ }
24
+ importerCounts.set(path, count - 1);
25
+ return false;
26
+ };
27
+ const extractFileImports = async (baseDir, filename) => {
28
+ const filePath = join(baseDir, filename);
29
+ try {
30
+ const content = (await fse.readFile(filePath)).toString();
31
+ const tree = await preparseMdxTree(content, baseDir, filePath);
32
+ const importSources = extractImportSources(tree);
33
+ const imports = new Set();
34
+ for (const source of importSources) {
35
+ const resolvedPath = resolveImportPath(source, optionallyAddLeadingSlash(filename));
36
+ if (resolvedPath != null) {
37
+ imports.add(normalizePathForComparison(resolvedPath));
38
+ }
39
+ }
40
+ return imports;
41
+ }
42
+ catch (err) {
43
+ console.log('Error extracting imports from file');
44
+ console.log(filename);
45
+ console.log(err);
46
+ return new Set();
47
+ }
48
+ };
49
+ export const initializeImportCache = async (baseDir, prebuildImportMap) => {
50
+ fileImportsMap.clear();
51
+ importerCounts.clear();
52
+ if (prebuildImportMap) {
53
+ for (const [filePath, imports] of prebuildImportMap) {
54
+ const normalizedPath = normalizePathForComparison(filePath);
55
+ fileImportsMap.set(normalizedPath, imports);
56
+ for (const imp of imports) {
57
+ addImporter(imp);
58
+ }
59
+ }
60
+ return;
61
+ }
62
+ const allFiles = getFileListSync(baseDir).filter((file) => isSnippetExtension(getFileExtension(file)));
63
+ await Promise.all(allFiles.map(async (filename) => {
64
+ const normalizedPath = normalizePathForComparison(filename);
65
+ const imports = await extractFileImports(baseDir, filename);
66
+ fileImportsMap.set(normalizedPath, imports);
67
+ for (const imp of imports) {
68
+ addImporter(imp);
69
+ }
70
+ }));
71
+ };
72
+ export const updateImportCacheForFile = async (baseDir, filename) => {
73
+ if (!isSnippetExtension(getFileExtension(filename))) {
74
+ return { newlyImported: [], noLongerImported: [] };
75
+ }
76
+ const normalizedPath = normalizePathForComparison(filename);
77
+ const newImports = await extractFileImports(baseDir, filename);
78
+ const oldImports = fileImportsMap.get(normalizedPath) ?? new Set();
79
+ const newlyImported = [];
80
+ const noLongerImported = [];
81
+ for (const imp of newImports) {
82
+ if (!oldImports.has(imp) && addImporter(imp)) {
83
+ newlyImported.push(imp);
84
+ }
85
+ }
86
+ for (const imp of oldImports) {
87
+ if (!newImports.has(imp) && removeImporter(imp)) {
88
+ noLongerImported.push(imp);
89
+ }
90
+ }
91
+ fileImportsMap.set(normalizedPath, newImports);
92
+ return { newlyImported, noLongerImported };
93
+ };
94
+ export const removeFromImportCache = (filename) => {
95
+ const normalizedPath = normalizePathForComparison(filename);
96
+ const oldImports = fileImportsMap.get(normalizedPath);
97
+ if (oldImports == null) {
98
+ return { newlyImported: [], noLongerImported: [] };
99
+ }
100
+ const noLongerImported = [];
101
+ for (const imp of oldImports) {
102
+ if (removeImporter(imp)) {
103
+ noLongerImported.push(imp);
104
+ }
105
+ }
106
+ fileImportsMap.delete(normalizedPath);
107
+ return { newlyImported: [], noLongerImported };
108
+ };
109
+ export const getImportedFilesFromCache = () => {
110
+ return new Set(Array.from(importerCounts.keys(), (key) => key.toLowerCase()));
111
+ };
112
+ const isSnippetByFolder = (path) => {
113
+ const normalized = normalizePathForComparison(path).toLowerCase();
114
+ return normalized.startsWith('/snippets/') || normalized.startsWith('/_snippets/');
115
+ };
116
+ const resolveFileImports = async (sourcePath, relativePath) => {
117
+ let contentStr = (await fse.readFile(sourcePath)).toString();
118
+ const tree = await preparseMdxTree(contentStr, CMD_EXEC_PATH, sourcePath);
119
+ const importsResponse = await findAndRemoveImports(tree);
120
+ if (hasImports(importsResponse)) {
121
+ contentStr = stringifyTree(await resolveAllImports({ ...importsResponse, filename: relativePath }));
122
+ }
123
+ return contentStr;
124
+ };
125
+ export const syncImportedFileLocations = async (changes) => {
126
+ for (const importedPath of changes.newlyImported) {
127
+ if (isSnippetByFolder(importedPath))
128
+ continue;
129
+ if (!isSnippetExtension(getFileExtension(importedPath)))
130
+ continue;
131
+ const relativePath = optionallyRemoveLeadingSlash(importedPath);
132
+ const sourcePath = join(CMD_EXEC_PATH, relativePath);
133
+ const targetPath = join(NEXT_PUBLIC_PATH, relativePath);
134
+ try {
135
+ const contentStr = await resolveFileImports(sourcePath, relativePath);
136
+ await fse.outputFile(targetPath, contentStr, { flag: 'w' });
137
+ await fse.remove(join(NEXT_PROPS_PATH, relativePath));
138
+ }
139
+ catch (err) {
140
+ console.log('Error processing newly imported snippet');
141
+ console.log(relativePath);
142
+ console.log(err);
143
+ }
144
+ }
145
+ for (const importedPath of changes.noLongerImported) {
146
+ if (isSnippetByFolder(importedPath))
147
+ continue;
148
+ if (!isSnippetExtension(getFileExtension(importedPath)))
149
+ continue;
150
+ const relativePath = optionallyRemoveLeadingSlash(importedPath);
151
+ const sourcePath = join(CMD_EXEC_PATH, relativePath);
152
+ await fse.remove(join(NEXT_PUBLIC_PATH, relativePath));
153
+ if (getFileCategory(relativePath) !== 'page')
154
+ continue;
155
+ if (await fse.pathExists(sourcePath)) {
156
+ try {
157
+ const contentStr = await resolveFileImports(sourcePath, relativePath);
158
+ const { pageContent } = await createPage(relativePath, contentStr, CMD_EXEC_PATH, [], [], true);
159
+ await fse.outputFile(join(NEXT_PROPS_PATH, relativePath), pageContent, { flag: 'w' });
160
+ }
161
+ catch (err) {
162
+ console.log('Error regenerating page after import status change');
163
+ console.log(relativePath);
164
+ console.log(err);
165
+ }
166
+ }
167
+ }
168
+ };
@@ -1,5 +1,7 @@
1
+ import { initializeImportCache } from './importCache.js';
1
2
  declare const listener: (callback: () => void, options?: {
2
3
  localSchema?: boolean;
3
4
  groups?: string[];
4
5
  }) => void;
6
+ export { initializeImportCache };
5
7
  export default listener;
@@ -14,6 +14,7 @@ import { AddedLog, DeletedLog, EditedLog, WarningLog, InfoLog, ErrorLog } from '
14
14
  import { generateDependentSnippets } from './generateDependentSnippets.js';
15
15
  import { generatePagesWithImports } from './generatePagesWithImports.js';
16
16
  import { getDocsState } from './getDocsState.js';
17
+ import { initializeImportCache, updateImportCacheForFile, removeFromImportCache, getImportedFilesFromCache, syncImportedFileLocations, } from './importCache.js';
17
18
  import { resolveAllImports } from './resolveAllImports.js';
18
19
  import { updateCustomLanguages, updateGeneratedNav, updateOpenApiFiles, upsertOpenApiFile, } from './update.js';
19
20
  import { getMintIgnoreGlobs, isFileSizeValid, isJsonValid, shouldRegenerateNavForPage, } from './utils.js';
@@ -72,7 +73,13 @@ const onUnlinkEvent = async (filename, options) => {
72
73
  return;
73
74
  }
74
75
  try {
75
- const potentialCategory = getFileCategory(filename);
76
+ const importedFiles = getImportedFilesFromCache();
77
+ const potentialCategory = getFileCategory(filename, { importedFiles });
78
+ if (potentialCategory == null) {
79
+ const importChanges = removeFromImportCache(filename);
80
+ await syncImportedFileLocations(importChanges);
81
+ return;
82
+ }
76
83
  const targetPath = getTargetPath(potentialCategory, filename);
77
84
  if (potentialCategory === 'page' ||
78
85
  potentialCategory === 'snippet' ||
@@ -99,13 +106,18 @@ const onUnlinkEvent = async (filename, options) => {
99
106
  try {
100
107
  await fse.emptyDir(NEXT_PUBLIC_PATH);
101
108
  await fse.emptyDir(NEXT_PROPS_PATH);
102
- await prebuild(CMD_EXEC_PATH, options);
109
+ const prebuildResult = await prebuild(CMD_EXEC_PATH, options);
110
+ if (prebuildResult) {
111
+ await initializeImportCache(CMD_EXEC_PATH, prebuildResult.fileImportsMap);
112
+ }
103
113
  }
104
114
  catch (err) {
105
115
  console.error('Error rebuilding after .mintignore deletion:', err);
106
116
  }
107
117
  break;
108
118
  }
119
+ const importChanges = removeFromImportCache(filename);
120
+ await syncImportedFileLocations(importChanges);
109
121
  addChangeLog(_jsx(DeletedLog, { filename: filename }));
110
122
  }
111
123
  catch (error) {
@@ -159,13 +171,20 @@ const validateConfigFiles = async () => {
159
171
  */
160
172
  const onUpdateEvent = async (filename, callback, options = {}) => {
161
173
  const filePath = pathUtil.join(CMD_EXEC_PATH, filename);
162
- const potentialCategory = getFileCategory(filename);
163
- const targetPath = getTargetPath(potentialCategory, filename);
174
+ const importChanges = await updateImportCacheForFile(CMD_EXEC_PATH, filename);
175
+ await syncImportedFileLocations(importChanges);
176
+ const importedFiles = getImportedFilesFromCache();
177
+ const potentialCategory = getFileCategory(filename, { importedFiles });
178
+ if (potentialCategory == null) {
179
+ callback();
180
+ return null;
181
+ }
164
182
  let regenerateNav = false;
165
183
  let category = potentialCategory === 'potentialYamlOpenApiSpec' ||
166
184
  potentialCategory === 'potentialJsonOpenApiSpec'
167
185
  ? 'staticFile'
168
186
  : potentialCategory;
187
+ const targetPath = getTargetPath(potentialCategory, filename);
169
188
  switch (potentialCategory) {
170
189
  case 'page': {
171
190
  let contentStr = (await readFile(filePath)).toString();
@@ -227,7 +246,10 @@ const onUpdateEvent = async (filename, callback, options = {}) => {
227
246
  addChangeLog(_jsx(InfoLog, { message: ".mintignore has been updated. Rebuilding..." }));
228
247
  await fse.emptyDir(NEXT_PUBLIC_PATH);
229
248
  await fse.emptyDir(NEXT_PROPS_PATH);
230
- await prebuild(CMD_EXEC_PATH, options);
249
+ const prebuildResult = await prebuild(CMD_EXEC_PATH, options);
250
+ if (prebuildResult) {
251
+ await initializeImportCache(CMD_EXEC_PATH, prebuildResult.fileImportsMap);
252
+ }
231
253
  }
232
254
  catch (err) {
233
255
  console.error(err.message);
@@ -291,4 +313,5 @@ const onUpdateEvent = async (filename, callback, options = {}) => {
291
313
  callback();
292
314
  return category;
293
315
  };
316
+ export { initializeImportCache };
294
317
  export default listener;
@@ -8,3 +8,4 @@ export declare const isJsonValid: (filePath: string) => {
8
8
  error?: string;
9
9
  };
10
10
  export declare const shouldRegenerateNavForPage: (filename: string, contentStr: string, frontmatterHashes: Map<string, string>) => Promise<boolean>;
11
+ export declare function normalizePathForComparison(filePath: string): string;
@@ -1,4 +1,4 @@
1
- import { parseFrontmatter, processMintIgnoreString } from '@mintlify/common';
1
+ import { parseFrontmatter, processMintIgnoreString, optionallyAddLeadingSlash, } from '@mintlify/common';
2
2
  import crypto from 'crypto';
3
3
  import { promises as _promises, readFileSync, existsSync } from 'fs';
4
4
  import fse from 'fs-extra';
@@ -65,3 +65,6 @@ export const shouldRegenerateNavForPage = async (filename, contentStr, frontmatt
65
65
  return true;
66
66
  }
67
67
  };
68
+ export function normalizePathForComparison(filePath) {
69
+ return optionallyAddLeadingSlash(filePath).toLowerCase();
70
+ }
@@ -1,4 +1,5 @@
1
1
  import { ArgumentsCamelCase } from 'yargs';
2
2
  export declare const run: (argv: ArgumentsCamelCase & {
3
3
  needsUpdate: boolean;
4
+ fileImportsMap?: Map<string, Set<string>>;
4
5
  }) => Promise<void>;
@@ -3,11 +3,11 @@ import open from 'better-opn';
3
3
  import express from 'express';
4
4
  import { createServer } from 'http';
5
5
  import { Server as SocketServer } from 'socket.io';
6
- import { NEXT_PUBLIC_PATH } from '../constants.js';
6
+ import { CMD_EXEC_PATH, NEXT_PUBLIC_PATH } from '../constants.js';
7
7
  import { addLog, removeLastLog } from '../logging-state.js';
8
8
  import { LaunchLog, UpdateLog } from '../logs.js';
9
9
  import { maybeFixMissingWindowsEnvVar } from '../util.js';
10
- import listener from './listener/index.js';
10
+ import listener, { initializeImportCache } from './listener/index.js';
11
11
  import { getLocalNetworkIp } from './network.js';
12
12
  import { setupNext } from './setupNext.js';
13
13
  export const run = async (argv) => {
@@ -48,5 +48,6 @@ export const run = async (argv) => {
48
48
  process.on('SIGINT', onExit);
49
49
  process.on('SIGTERM', onExit);
50
50
  });
51
+ await initializeImportCache(CMD_EXEC_PATH, argv.fileImportsMap);
51
52
  listener(onChange);
52
53
  };