@mintlify/previewing 4.0.1009 → 4.0.1011

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.
@@ -7,7 +7,7 @@ export const getDocsState = async (onError) => {
7
7
  const mintIgnore = await getMintIgnore(CMD_EXEC_PATH);
8
8
  const { openApiFiles } = await categorizeFilePaths(CMD_EXEC_PATH, mintIgnore);
9
9
  try {
10
- const mintConfig = await MintConfigUpdater.getConfig(join(CMD_EXEC_PATH, 'mint.json'), false, onError);
10
+ const mintConfig = await MintConfigUpdater.getConfig(join(CMD_EXEC_PATH, 'mint.json'), false, CMD_EXEC_PATH, onError);
11
11
  const docsConfig = upgradeToDocsConfig(mintConfig);
12
12
  const { mintConfig: newMintConfig } = await generateOpenApiAnchorsOrTabs(mintConfig, openApiFiles, CLIENT_PATH);
13
13
  const { newDocsConfig, pagesAcc, openApiFiles: newOpenApiFiles, } = await generateOpenApiDivisions(docsConfig, openApiFiles, CLIENT_PATH);
@@ -22,7 +22,7 @@ export const getDocsState = async (onError) => {
22
22
  const docsJsonPath = join(CMD_EXEC_PATH, 'docs.json');
23
23
  if (!(await fse.pathExists(docsJsonPath)))
24
24
  throw new Error('No config found');
25
- const docsConfig = await DocsConfigUpdater.getConfig(docsJsonPath, false, onError);
25
+ const docsConfig = await DocsConfigUpdater.getConfig(docsJsonPath, false, CMD_EXEC_PATH, onError);
26
26
  const { newDocsConfig, pagesAcc, openApiFiles: newOpenApiFiles, } = await generateOpenApiDivisions(docsConfig, openApiFiles, CLIENT_PATH);
27
27
  return { pagesAcc, openApiFiles: newOpenApiFiles, docsConfig: newDocsConfig };
28
28
  }
@@ -1,5 +1,5 @@
1
1
  import { initializeImportCache } from './importCache.js';
2
- declare const listener: (callback: () => void, options?: {
2
+ declare const listener: (triggerRefresh: () => void, options?: {
3
3
  localSchema?: boolean;
4
4
  groups?: string[];
5
5
  }) => void;
@@ -15,13 +15,14 @@ import { generateDependentSnippets } from './generateDependentSnippets.js';
15
15
  import { generatePagesWithImports } from './generatePagesWithImports.js';
16
16
  import { getDocsState } from './getDocsState.js';
17
17
  import { initializeImportCache, updateImportCacheForFile, removeFromImportCache, getImportedFilesFromCache, syncImportedFileLocations, } from './importCache.js';
18
+ import { hasTrackedReferencedFile, refreshTrackedReferencedFiles } from './referencedFiles.js';
18
19
  import { regenerateAllSnippets } from './regenerateAllSnippets.js';
19
20
  import { resolveAllImports } from './resolveAllImports.js';
20
21
  import { updateCustomLanguages, updateGeneratedNav, updateOpenApiFiles, upsertOpenApiFile, } from './update.js';
21
22
  import { getCurrentVariables, getMintIgnoreGlobs, handleParseError, isFileSizeValid, isJsonValid, shouldRegenerateNavForPage, suppressParseError, } from './utils.js';
22
23
  const { readFile } = _promises;
23
24
  const frontmatterHashes = new Map();
24
- const listener = (callback, options = {}) => {
25
+ const listener = (triggerRefresh, options = {}) => {
25
26
  const mintIgnoreGlobs = getMintIgnoreGlobs();
26
27
  chokidar
27
28
  .watch(CMD_EXEC_PATH, {
@@ -37,17 +38,17 @@ const listener = (callback, options = {}) => {
37
38
  },
38
39
  cwd: CMD_EXEC_PATH,
39
40
  })
40
- .on('add', (filename) => onAddEvent(filename, callback, options))
41
- .on('change', (filename) => onChangeEvent(filename, callback, options))
42
- .on('unlink', (filename) => onUnlinkEvent(filename, options));
41
+ .on('add', (filename) => onAddEvent(filename, triggerRefresh, options))
42
+ .on('change', (filename) => onChangeEvent(filename, triggerRefresh, options))
43
+ .on('unlink', (filename) => onUnlinkEvent(filename, triggerRefresh, options));
43
44
  };
44
- const onAddEvent = async (filename, callback, options) => {
45
+ const onAddEvent = async (filename, triggerRefresh, options) => {
45
46
  if (isMintIgnored(filename, getMintIgnoreGlobs())) {
46
47
  return;
47
48
  }
48
49
  try {
49
- const category = await onUpdateEvent(filename, callback, options);
50
- if (category) {
50
+ const category = await onUpdateEvent(filename, triggerRefresh, options);
51
+ if (category !== undefined) {
51
52
  addChangeLog(_jsx(AddedLog, { filename: filename }));
52
53
  }
53
54
  }
@@ -55,13 +56,13 @@ const onAddEvent = async (filename, callback, options) => {
55
56
  console.error(error.message);
56
57
  }
57
58
  };
58
- const onChangeEvent = async (filename, callback, options) => {
59
+ const onChangeEvent = async (filename, triggerRefresh, options) => {
59
60
  if (isMintIgnored(filename, getMintIgnoreGlobs())) {
60
61
  return;
61
62
  }
62
63
  try {
63
- const category = await onUpdateEvent(filename, callback, options);
64
- if (category) {
64
+ const category = await onUpdateEvent(filename, triggerRefresh, options);
65
+ if (category !== undefined) {
65
66
  addChangeLog(_jsx(EditedLog, { filename: filename }));
66
67
  }
67
68
  }
@@ -69,13 +70,38 @@ const onChangeEvent = async (filename, callback, options) => {
69
70
  console.error(error.message);
70
71
  }
71
72
  };
72
- const onUnlinkEvent = async (filename, options) => {
73
+ const onUnlinkEvent = async (filename, triggerRefresh, options) => {
73
74
  if (isMintIgnored(filename, getMintIgnoreGlobs())) {
74
75
  return;
75
76
  }
76
77
  try {
77
78
  const importedFiles = getImportedFilesFromCache();
78
79
  const potentialCategory = getFileCategory(filename, { importedFiles });
80
+ if (hasTrackedReferencedFile(filename)) {
81
+ try {
82
+ const { mintConfig, openApiFiles, docsConfig } = await getDocsState(handleParseError);
83
+ await refreshTrackedReferencedFiles();
84
+ if (mintConfig) {
85
+ await MintConfigUpdater.writeConfigFile(mintConfig, CLIENT_PATH);
86
+ }
87
+ await DocsConfigUpdater.writeConfigFile(docsConfig, CLIENT_PATH);
88
+ await updateOpenApiFiles(openApiFiles, suppressParseError);
89
+ await updateCustomLanguages(docsConfig, suppressParseError);
90
+ await updateGeneratedNav(suppressParseError);
91
+ }
92
+ catch (err) {
93
+ if (getCurrentErrorLogs().length === 0) {
94
+ console.error(err);
95
+ }
96
+ }
97
+ const updatedSnippets = await regenerateAllSnippets();
98
+ await generatePagesWithImports(new Set(updatedSnippets));
99
+ const importChanges = removeFromImportCache(filename);
100
+ await syncImportedFileLocations(importChanges);
101
+ triggerRefresh();
102
+ addChangeLog(_jsx(DeletedLog, { filename: filename }));
103
+ return;
104
+ }
79
105
  if (potentialCategory == null) {
80
106
  const importChanges = removeFromImportCache(filename);
81
107
  await syncImportedFileLocations(importChanges);
@@ -109,6 +135,7 @@ const onUnlinkEvent = async (filename, options) => {
109
135
  await fse.emptyDir(NEXT_PROPS_PATH);
110
136
  const prebuildResult = await prebuild(CMD_EXEC_PATH, options);
111
137
  await initializeImportCache(CMD_EXEC_PATH, prebuildResult?.fileImportsMap);
138
+ await refreshTrackedReferencedFiles();
112
139
  }
113
140
  catch (err) {
114
141
  console.error('Error rebuilding after .mintignore deletion:', err);
@@ -168,17 +195,39 @@ const validateConfigFiles = async () => {
168
195
  * @param filename
169
196
  * @returns FileCategory
170
197
  */
171
- const onUpdateEvent = async (filename, callback, options = {}) => {
198
+ const onUpdateEvent = async (filename, triggerRefresh, options = {}) => {
172
199
  clearErrorLogs();
173
200
  const filePath = pathUtil.join(CMD_EXEC_PATH, filename);
174
201
  const importChanges = await updateImportCacheForFile(CMD_EXEC_PATH, filename);
175
202
  await syncImportedFileLocations(importChanges);
176
203
  const importedFiles = getImportedFilesFromCache();
177
204
  const potentialCategory = getFileCategory(filename, { importedFiles });
178
- if (potentialCategory == null) {
179
- callback();
205
+ if (hasTrackedReferencedFile(filename)) {
206
+ try {
207
+ const { mintConfig, openApiFiles, docsConfig } = await getDocsState(handleParseError);
208
+ await refreshTrackedReferencedFiles();
209
+ if (mintConfig) {
210
+ await MintConfigUpdater.writeConfigFile(mintConfig, CLIENT_PATH);
211
+ }
212
+ await DocsConfigUpdater.writeConfigFile(docsConfig, CLIENT_PATH);
213
+ await updateOpenApiFiles(openApiFiles, suppressParseError);
214
+ await updateCustomLanguages(docsConfig, suppressParseError);
215
+ await updateGeneratedNav(suppressParseError);
216
+ }
217
+ catch (err) {
218
+ if (getCurrentErrorLogs().length === 0) {
219
+ console.error(err);
220
+ }
221
+ }
222
+ const updatedSnippets = await regenerateAllSnippets();
223
+ await generatePagesWithImports(new Set(updatedSnippets));
224
+ triggerRefresh();
180
225
  return null;
181
226
  }
227
+ if (potentialCategory == null) {
228
+ triggerRefresh();
229
+ return undefined;
230
+ }
182
231
  let regenerateNav = false;
183
232
  let category = potentialCategory === 'potentialYamlOpenApiSpec' ||
184
233
  potentialCategory === 'potentialJsonOpenApiSpec'
@@ -224,11 +273,12 @@ const onUpdateEvent = async (filename, callback, options = {}) => {
224
273
  const { valid, error } = isJsonValid(filePath);
225
274
  if (!valid) {
226
275
  addErrorLog(_jsx(ErrorLog, { message: `Syntax error in ${filename}: ${error}` }));
227
- return null;
276
+ return undefined;
228
277
  }
229
278
  regenerateNav = true;
230
279
  try {
231
280
  const { mintConfig, openApiFiles, docsConfig } = await getDocsState(handleParseError);
281
+ await refreshTrackedReferencedFiles();
232
282
  if (mintConfig) {
233
283
  await MintConfigUpdater.writeConfigFile(mintConfig, CLIENT_PATH);
234
284
  }
@@ -239,7 +289,7 @@ const onUpdateEvent = async (filename, callback, options = {}) => {
239
289
  catch (err) {
240
290
  if (getCurrentErrorLogs().length > 0) {
241
291
  // no-op to suppress duplicate error logging
242
- return null;
292
+ return undefined;
243
293
  }
244
294
  else {
245
295
  console.error(err);
@@ -258,6 +308,7 @@ const onUpdateEvent = async (filename, callback, options = {}) => {
258
308
  await fse.emptyDir(NEXT_PROPS_PATH);
259
309
  const prebuildResult = await prebuild(CMD_EXEC_PATH, options);
260
310
  await initializeImportCache(CMD_EXEC_PATH, prebuildResult?.fileImportsMap);
311
+ await refreshTrackedReferencedFiles();
261
312
  }
262
313
  catch (err) {
263
314
  console.error(err.message);
@@ -319,7 +370,7 @@ const onUpdateEvent = async (filename, callback, options = {}) => {
319
370
  // TODO: Instead of re-generating the entire nav, optimize by just updating the specific page that changed.
320
371
  await updateGeneratedNav(suppressParseError);
321
372
  }
322
- callback();
373
+ triggerRefresh();
323
374
  return category;
324
375
  };
325
376
  export { initializeImportCache };
@@ -0,0 +1,2 @@
1
+ export declare const refreshTrackedReferencedFiles: () => Promise<void>;
2
+ export declare const hasTrackedReferencedFile: (filePath: string) => boolean;
@@ -0,0 +1,21 @@
1
+ import { getConfigPath, resolveFileRefs } from '@mintlify/prebuild';
2
+ import { readFile } from 'fs/promises';
3
+ import { CMD_EXEC_PATH } from '../../constants.js';
4
+ let trackedReferencedFiles = new Set();
5
+ export const refreshTrackedReferencedFiles = async () => {
6
+ try {
7
+ const configPath = (await getConfigPath(CMD_EXEC_PATH, 'docs')) ?? (await getConfigPath(CMD_EXEC_PATH, 'mint'));
8
+ if (!configPath) {
9
+ trackedReferencedFiles = new Set();
10
+ return;
11
+ }
12
+ const content = await readFile(configPath, 'utf-8');
13
+ const parsed = JSON.parse(content);
14
+ const { referencedFiles } = await resolveFileRefs(parsed, CMD_EXEC_PATH);
15
+ trackedReferencedFiles = new Set(referencedFiles);
16
+ }
17
+ catch {
18
+ trackedReferencedFiles = new Set();
19
+ }
20
+ };
21
+ export const hasTrackedReferencedFile = (filePath) => trackedReferencedFiles.has(filePath);
@@ -1,4 +1,5 @@
1
1
  import { parseFrontmatter, processMintIgnoreString, optionallyAddLeadingSlash, } from '@mintlify/common';
2
+ import { resolveFileRefs } from '@mintlify/prebuild';
2
3
  import crypto from 'crypto';
3
4
  import { promises as _promises, readFileSync, existsSync } from 'fs';
4
5
  import fse from 'fs-extra';
@@ -87,8 +88,9 @@ export const suppressParseError = () => {
87
88
  export const getCurrentVariables = async () => {
88
89
  try {
89
90
  const content = await readFile(pathUtil.join(CMD_EXEC_PATH, 'docs.json'), 'utf8');
90
- const parsed = JSON.parse(content);
91
- return parsed.variables;
91
+ const { resolved } = await resolveFileRefs(JSON.parse(content), CMD_EXEC_PATH);
92
+ const resolvedConfig = resolved;
93
+ return resolvedConfig.variables;
92
94
  }
93
95
  catch {
94
96
  return undefined;
@@ -8,6 +8,7 @@ import { addLog, removeLastLog } from '../logging-state.js';
8
8
  import { LaunchLog, UpdateLog } from '../logs.js';
9
9
  import { maybeFixMissingWindowsEnvVar } from '../util.js';
10
10
  import listener, { initializeImportCache } from './listener/index.js';
11
+ import { refreshTrackedReferencedFiles } from './listener/referencedFiles.js';
11
12
  import { getLocalNetworkIp } from './network.js';
12
13
  import { setupNext } from './setupNext.js';
13
14
  export const run = async (argv) => {
@@ -49,5 +50,6 @@ export const run = async (argv) => {
49
50
  process.on('SIGTERM', onExit);
50
51
  });
51
52
  await initializeImportCache(CMD_EXEC_PATH, argv.fileImportsMap);
53
+ await refreshTrackedReferencedFiles();
52
54
  listener(onChange);
53
55
  };