@mintlify/previewing 4.0.1494 → 4.0.1496
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.
- package/dist/__tests__/packages-collect.test.js +5 -95
- package/dist/__tests__/packages-dev-snippets.test.js +2 -37
- package/dist/__tests__/packages-dev.test.js +0 -14
- package/dist/packages/collect.d.ts +0 -1
- package/dist/packages/collect.js +1 -10
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -70,10 +70,6 @@ const BAR_SNIPPET = `import { BarChart, Bar } from "recharts";
|
|
|
70
70
|
<Bar dataKey="v" name="{{brand}} revenue" />
|
|
71
71
|
</BarChart>
|
|
72
72
|
`;
|
|
73
|
-
const LINE_SNIPPET = `<LineChart width={400} height={200} data={[{ v: 2 }]}>
|
|
74
|
-
<Line dataKey="v" isAnimationActive={false} />
|
|
75
|
-
</LineChart>
|
|
76
|
-
`;
|
|
77
73
|
const writeDocs = async (root) => {
|
|
78
74
|
await fse.outputJson(join(root, 'docs.json'), {
|
|
79
75
|
name: 'Docs',
|
|
@@ -235,106 +231,20 @@ describe('collectPackageIslands', () => {
|
|
|
235
231
|
expect(compiled.mdxExtracts.packageBaseUrl).toBe('/_mintlify/pkg/abc');
|
|
236
232
|
expect(compiled.mdxSource.compiledSource).not.toMatch(/LineChart|RevenueChart/);
|
|
237
233
|
});
|
|
238
|
-
it('
|
|
234
|
+
it('reports a <Snippet file> that uses package components instead of extracting it', async () => {
|
|
239
235
|
await fse.outputFile(join(testPaths.cmd, '_snippets/bar.mdx'), BAR_SNIPPET);
|
|
240
|
-
await fse.outputFile(join(testPaths.cmd, '_snippets/line.mdx'), LINE_SNIPPET);
|
|
241
236
|
await fse.outputFile(join(testPaths.cmd, 'revenue.mdx'), '# Revenue\n\n<Snippet file="bar.mdx" />\n');
|
|
242
|
-
await fse.outputFile(join(testPaths.cmd, 'trend.mdx'), 'import { LineChart, Line } from "recharts";\n\n<Snippet file="line.mdx" />\n');
|
|
243
|
-
const setup = await readPackagesSetup(testPaths.cmd);
|
|
244
|
-
const collector = new PackageIslandCollector({
|
|
245
|
-
docsRoot: testPaths.cmd,
|
|
246
|
-
packageNames: setup?.packageNames ?? new Set(),
|
|
247
|
-
variables: setup?.variables,
|
|
248
|
-
});
|
|
249
|
-
const collected = await collector.collectAll();
|
|
250
|
-
setPackageImportOptions({
|
|
251
|
-
packageNames: setup?.packageNames ?? new Set(),
|
|
252
|
-
packageSnippets: collected.packageSnippets,
|
|
253
|
-
});
|
|
254
|
-
const islands = Object.fromEntries(collected.islands.map((island) => [
|
|
255
|
-
island.id,
|
|
256
|
-
{ prefix: `mi-${island.id}-`, html: '<svg></svg>' },
|
|
257
|
-
]));
|
|
258
|
-
const packageBuild = {
|
|
259
|
-
buildId: 'abc',
|
|
260
|
-
islands,
|
|
261
|
-
packageNames: [...(setup?.packageNames ?? [])],
|
|
262
|
-
packageSnippets: [...collected.packageSnippets],
|
|
263
|
-
};
|
|
264
|
-
expect(collected.pages['revenue.mdx']).toEqual({ ids: [expect.any(String)], errors: [] });
|
|
265
|
-
expect(collected.pages['trend.mdx']).toEqual({ ids: [expect.any(String)], errors: [] });
|
|
266
|
-
const [barId] = collected.pages['revenue.mdx']?.ids ?? [];
|
|
267
|
-
expect(collected.islands.find((island) => island.id === barId)?.module).toContain('Acme revenue');
|
|
268
|
-
for (const page of ['revenue.mdx', 'trend.mdx']) {
|
|
269
|
-
const compiled = await compileLikeMintDev(page, packageBuild);
|
|
270
|
-
expect(compiled.parseFailed).toBeUndefined();
|
|
271
|
-
expect(Object.keys(compiled.mdxExtracts.islands ?? {})).toEqual(collected.pages[page]?.ids);
|
|
272
|
-
expect(compiled.mdxSource.compiledSource).not.toMatch(/BarChart|LineChart/);
|
|
273
|
-
}
|
|
274
|
-
expect((await collector.updatePage('revenue.mdx')).pages['revenue.mdx']?.ids).toEqual([barId]);
|
|
275
|
-
});
|
|
276
|
-
it('resolves <Snippet file> imports against the snippet file with the ids mint dev compiles', async () => {
|
|
277
|
-
const component = (name) => `import { BarChart, Bar } from "recharts";\n\nexport const ${name} = () => (\n <BarChart width={300} height={150} data={[{ v: 1 }]}>\n <Bar dataKey="v" name="${name}" />\n </BarChart>\n);\n`;
|
|
278
|
-
await fse.outputFile(join(testPaths.cmd, 'snippets/chart.jsx'), component('Chart'));
|
|
279
|
-
await fse.outputFile(join(testPaths.cmd, 'snippets/inner.jsx'), component('Inner'));
|
|
280
|
-
await fse.outputFile(join(testPaths.cmd, 'snippets/wrong.jsx'), component('Wrong'));
|
|
281
|
-
await fse.outputFile(join(testPaths.cmd, '_snippets/charts/x.mdx'), 'import { Chart } from "../../snippets/chart.jsx";\n\n<Chart />\n\n<Snippet file="charts/inner/y.mdx" />\n');
|
|
282
|
-
await fse.outputFile(join(testPaths.cmd, '_snippets/charts/inner/y.mdx'), 'import { Inner } from "../../../snippets/inner.jsx";\n\n<Inner />\n');
|
|
283
|
-
await fse.outputFile(join(testPaths.cmd, '_snippets/charts/w.mdx'), 'import { Wrong } from "../snippets/wrong.jsx";\n\n<Wrong />\n');
|
|
284
|
-
await fse.outputFile(join(testPaths.cmd, 'guides/deep/nested/page.mdx'), '# Nested\n\n<Snippet file="charts/x.mdx" />\n');
|
|
285
|
-
await fse.outputFile(join(testPaths.cmd, 'guides/wrong.mdx'), '# Wrong\n\n<Snippet file="charts/w.mdx" />\n');
|
|
286
|
-
const setup = await readPackagesSetup(testPaths.cmd);
|
|
287
|
-
const collected = await collectPackageIslands({
|
|
288
|
-
docsRoot: testPaths.cmd,
|
|
289
|
-
packageNames: setup?.packageNames ?? new Set(),
|
|
290
|
-
variables: setup?.variables,
|
|
291
|
-
});
|
|
292
|
-
setPackageImportOptions({
|
|
293
|
-
packageNames: setup?.packageNames ?? new Set(),
|
|
294
|
-
packageSnippets: collected.packageSnippets,
|
|
295
|
-
});
|
|
296
|
-
const packageBuild = {
|
|
297
|
-
buildId: 'abc',
|
|
298
|
-
islands: Object.fromEntries(collected.islands.map((island) => [
|
|
299
|
-
island.id,
|
|
300
|
-
{ prefix: `mi-${island.id}-`, html: '<svg></svg>' },
|
|
301
|
-
])),
|
|
302
|
-
packageNames: [...(setup?.packageNames ?? [])],
|
|
303
|
-
packageSnippets: [...collected.packageSnippets],
|
|
304
|
-
};
|
|
305
|
-
const modules = (page) => (collected.pages[page]?.ids ?? []).map((id) => collected.islands.find((island) => island.id === id)?.module);
|
|
306
|
-
expect(modules('guides/deep/nested/page.mdx')).toEqual([
|
|
307
|
-
expect.stringContaining('/snippets/chart.jsx'),
|
|
308
|
-
expect.stringContaining('/snippets/inner.jsx'),
|
|
309
|
-
]);
|
|
310
|
-
expect(collected.pages['guides/wrong.mdx']).toEqual({ ids: [], errors: [] });
|
|
311
|
-
for (const page of ['guides/deep/nested/page.mdx', 'guides/wrong.mdx']) {
|
|
312
|
-
const compiled = await compileLikeMintDev(page, packageBuild);
|
|
313
|
-
expect(compiled.parseFailed).toBeUndefined();
|
|
314
|
-
expect(Object.keys(compiled.mdxExtracts.islands ?? {})).toEqual(collected.pages[page]?.ids);
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
it('reports a <Snippet file> cycle on the page instead of expanding it forever', async () => {
|
|
318
|
-
await fse.outputFile(join(testPaths.cmd, '_snippets/note.mdx'), 'Note\n');
|
|
319
|
-
await fse.outputFile(join(testPaths.cmd, '_snippets/a.mdx'), 'A\n\n<Snippet file="b.mdx" />\n');
|
|
320
|
-
await fse.outputFile(join(testPaths.cmd, '_snippets/b.mdx'), 'B\n\n<Snippet file="a.mdx" />\n');
|
|
321
|
-
await fse.outputFile(join(testPaths.cmd, 'loop.mdx'), '# Loop\n\n<Snippet file="a.mdx" />\n');
|
|
322
237
|
const setup = await readPackagesSetup(testPaths.cmd);
|
|
323
238
|
const collected = await collectPackageIslands({
|
|
324
239
|
docsRoot: testPaths.cmd,
|
|
325
240
|
packageNames: setup?.packageNames ?? new Set(),
|
|
326
241
|
variables: setup?.variables,
|
|
327
242
|
});
|
|
328
|
-
expect(collected.pages['
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
file: 'loop.mdx',
|
|
333
|
-
message: '<Snippet file="a.mdx"> includes itself (a.mdx -> b.mdx -> a.mdx).',
|
|
334
|
-
},
|
|
335
|
-
],
|
|
243
|
+
expect(collected.pages['revenue.mdx']).toEqual({ ids: [], errors: [] });
|
|
244
|
+
expect(collected.errors).toContainEqual({
|
|
245
|
+
file: '_snippets/bar.mdx',
|
|
246
|
+
message: expect.stringContaining('<Snippet>'),
|
|
336
247
|
});
|
|
337
|
-
expect(collected.pages['charts.mdx']?.errors).toEqual([]);
|
|
338
248
|
});
|
|
339
249
|
it('falls back to the snippet trees of a collector for the same docs root only', async () => {
|
|
340
250
|
const setup = await readPackagesSetup(testPaths.cmd);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { findAndRemoveImports, getFileCategory, parseFrontmatter } from '@mintlify/common';
|
|
2
2
|
import { getMdx } from '@mintlify/common/server-mdx';
|
|
3
|
-
import {
|
|
3
|
+
import { preparseMdxTree } from '@mintlify/prebuild';
|
|
4
4
|
import fse from 'fs-extra';
|
|
5
5
|
import { mkdtemp, readdir, rm } from 'fs/promises';
|
|
6
6
|
import { tmpdir } from 'os';
|
|
@@ -152,10 +152,6 @@ describe('package snippet membership in the mint dev watcher', () => {
|
|
|
152
152
|
await saveSnippet(file, content);
|
|
153
153
|
await untilBuilt(settled);
|
|
154
154
|
};
|
|
155
|
-
const compilePage = async (file) => {
|
|
156
|
-
const { pageContent } = await createPage(file, await fse.readFile(docs(file), 'utf8'), testPaths.cmd, [], []);
|
|
157
|
-
await fse.outputFile(join(testPaths.props, file), pageContent);
|
|
158
|
-
};
|
|
159
155
|
const legacySnippets = async () => {
|
|
160
156
|
const dir = join(testPaths.public, '_snippets');
|
|
161
157
|
const names = (await fse.pathExists(dir)) ? await readdir(dir) : [];
|
|
@@ -389,48 +385,17 @@ describe('package snippet membership in the mint dev watcher', () => {
|
|
|
389
385
|
expect(island.html).toBe(`<svg data-id="${id}"></svg>`);
|
|
390
386
|
}
|
|
391
387
|
});
|
|
392
|
-
it('renders placeholders for the islands a <Snippet file> edit adds until the rebuild finishes', async () => {
|
|
393
|
-
await fse.outputFile(docs('_snippets/badge.mdx'), 'Plain badge\n');
|
|
394
|
-
await fse.outputFile(docs('badge-page.mdx'), '# Badge\n\n<Snippet file="badge.mdx" />\n');
|
|
395
|
-
await start({ toggle: PLAIN_TOGGLE, wrapper: PLAIN_WRAPPER });
|
|
396
|
-
await compilePage('badge-page.mdx');
|
|
397
|
-
await fse.copy(docs('_snippets/badge.mdx'), join(testPaths.public, '_snippets/badge.mdx'));
|
|
398
|
-
expect(await render('badge-page.mdx')).toEqual({});
|
|
399
|
-
holdBuilds();
|
|
400
|
-
const settled = builds + 1;
|
|
401
|
-
await fse.outputFile(docs('_snippets/badge.mdx'), 'import { Switch } from "@acme/ui";\n\n<Switch />\n');
|
|
402
|
-
await dev.onFileChange('_snippets/badge.mdx', 'snippet');
|
|
403
|
-
await fse.copy(docs('_snippets/badge.mdx'), join(testPaths.public, '_snippets/badge.mdx'));
|
|
404
|
-
const pending = await render('badge-page.mdx');
|
|
405
|
-
const [id] = Object.keys(pending);
|
|
406
|
-
expect(pending).toEqual({ [id ?? '']: { prefix: `mi-${id}-` } });
|
|
407
|
-
releaseBuild();
|
|
408
|
-
await untilBuilt(settled);
|
|
409
|
-
expect(await render('badge-page.mdx')).toEqual({
|
|
410
|
-
[id ?? '']: { prefix: `mi-${id}-`, html: `<svg data-id="${id}"></svg>` },
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
388
|
it('keeps rendering the islands a snippet edit removes until the watcher recompiles the pages', async () => {
|
|
414
389
|
await fse.outputFile(docs('snippets/switches.mdx'), 'import { Switch } from "@acme/ui";\n\n<Switch />\n');
|
|
415
390
|
await fse.outputFile(docs('switch-page.mdx'), 'import Switches from "/snippets/switches.mdx";\n\n<Switches />\n');
|
|
416
|
-
await fse.outputFile(docs('_snippets/badge.mdx'), 'import { Switch } from "@acme/ui";\n\n<Switch size="sm" />\n');
|
|
417
|
-
await fse.outputFile(docs('badge-page.mdx'), '<Snippet file="badge.mdx" />\n');
|
|
418
391
|
await start({ toggle: PLAIN_TOGGLE, wrapper: PLAIN_WRAPPER });
|
|
419
|
-
await compilePage('badge-page.mdx');
|
|
420
|
-
await fse.copy(docs('_snippets/badge.mdx'), join(testPaths.public, '_snippets/badge.mdx'));
|
|
421
392
|
const switches = await render('switch-page.mdx');
|
|
422
|
-
|
|
423
|
-
expect(Object.keys({ ...switches, ...badge })).toHaveLength(2);
|
|
393
|
+
expect(Object.keys(switches)).toHaveLength(1);
|
|
424
394
|
holdBuilds();
|
|
425
395
|
await changeSnippet('snippets/switches.mdx', 'No switch\n');
|
|
426
396
|
expect(await render('switch-page.mdx')).toEqual(switches);
|
|
427
397
|
await regenerate('snippets/switches.mdx');
|
|
428
398
|
expect(await render('switch-page.mdx')).toEqual({});
|
|
429
|
-
await fse.outputFile(docs('_snippets/badge.mdx'), 'Plain badge\n');
|
|
430
|
-
await dev.onFileChange('_snippets/badge.mdx', 'snippet');
|
|
431
|
-
expect(await render('badge-page.mdx')).toEqual(badge);
|
|
432
|
-
await fse.copy(docs('_snippets/badge.mdx'), join(testPaths.public, '_snippets/badge.mdx'));
|
|
433
|
-
expect(await render('badge-page.mdx')).toEqual({});
|
|
434
399
|
});
|
|
435
400
|
it('recompiles pages on request after a package snippet change, and keeps serving ones that failed to compile', async () => {
|
|
436
401
|
markOnDemandPagesReady();
|
|
@@ -283,20 +283,6 @@ describe('PackagesDev', () => {
|
|
|
283
283
|
await until(() => rebuilt === 2);
|
|
284
284
|
expect((await props()).islands).toEqual(before);
|
|
285
285
|
});
|
|
286
|
-
it('re-extracts the islands of a <Snippet file> when the snippet changes', async () => {
|
|
287
|
-
await fse.outputFile(join(docsRoot, 'charts.mdx'), '<Snippet file="chart.mdx" />\n');
|
|
288
|
-
await fse.outputFile(join(docsRoot, '_snippets/chart.mdx'), page(2));
|
|
289
|
-
await dev.init();
|
|
290
|
-
rebuilt = 0;
|
|
291
|
-
const before = Object.keys((await props()).islands);
|
|
292
|
-
expect(before).toHaveLength(1);
|
|
293
|
-
await fse.outputFile(join(docsRoot, '_snippets/chart.mdx'), page(3));
|
|
294
|
-
await dev.onFileChange('_snippets/chart.mdx', 'snippet');
|
|
295
|
-
await until(() => rebuilt === 1);
|
|
296
|
-
const after = Object.keys((await props()).islands);
|
|
297
|
-
expect(after).toHaveLength(1);
|
|
298
|
-
expect(after).not.toEqual(before);
|
|
299
|
-
});
|
|
300
286
|
it('retries replacing the props file while another process has it open', async () => {
|
|
301
287
|
const rename = fse.rename.bind(fse);
|
|
302
288
|
let thrown = 0;
|
package/dist/packages/collect.js
CHANGED
|
@@ -24,12 +24,6 @@ const readSources = async (docsRoot, mintIgnore) => {
|
|
|
24
24
|
}));
|
|
25
25
|
return sources.flat();
|
|
26
26
|
};
|
|
27
|
-
const createLegacySnippetTreeMap = async (snippets, variables) => {
|
|
28
|
-
if (snippets.length === 0)
|
|
29
|
-
return {};
|
|
30
|
-
const { createPackageSnippetTreeMap } = await import('@mintlify/common/server-mdx');
|
|
31
|
-
return createPackageSnippetTreeMap(snippets, variables);
|
|
32
|
-
};
|
|
33
27
|
const resolveSnippets = async (snippets, variables, packages, onWarning) => {
|
|
34
28
|
const parsed = [];
|
|
35
29
|
for (const { filename, content } of snippets) {
|
|
@@ -64,7 +58,6 @@ export class PackageIslandCollector {
|
|
|
64
58
|
this.input = input;
|
|
65
59
|
this.snippetSources = [];
|
|
66
60
|
this.snippets = [];
|
|
67
|
-
this.snippetTreeMap = {};
|
|
68
61
|
this.packageSnippets = new Set();
|
|
69
62
|
this.packageSnippetTrees = new Map();
|
|
70
63
|
this.pageEntries = new Map();
|
|
@@ -117,7 +110,6 @@ export class PackageIslandCollector {
|
|
|
117
110
|
this.snippetSources = files
|
|
118
111
|
.filter(({ path }) => snippetPaths.has(path))
|
|
119
112
|
.map(({ path, content }) => ({ filename: withSlash(path), content }));
|
|
120
|
-
this.snippetTreeMap = await createLegacySnippetTreeMap(classified.legacySnippets, variables);
|
|
121
113
|
const previousTrees = this.packageSnippetTrees;
|
|
122
114
|
const parsedTrees = new Map(classified.snippets.map(({ path, tree }) => [path, tree]));
|
|
123
115
|
this.packageSnippetTrees = new Map();
|
|
@@ -207,7 +199,7 @@ export class PackageIslandCollector {
|
|
|
207
199
|
const { path } = page;
|
|
208
200
|
const content = replaceVariables(page.content, this.input.variables);
|
|
209
201
|
const noIslands = { ids: [], islands: [], errors: sourceErrors };
|
|
210
|
-
if (!mayImport(content)
|
|
202
|
+
if (!mayImport(content)) {
|
|
211
203
|
this.pageEntries.set(path, noIslands);
|
|
212
204
|
return;
|
|
213
205
|
}
|
|
@@ -228,7 +220,6 @@ export class PackageIslandCollector {
|
|
|
228
220
|
packageNames: this.input.packageNames,
|
|
229
221
|
packageSnippets: this.packageSnippets,
|
|
230
222
|
variables: this.input.variables,
|
|
231
|
-
snippetTreeMap: this.snippetTreeMap,
|
|
232
223
|
});
|
|
233
224
|
this.pageEntries.set(path, {
|
|
234
225
|
ids: extraction.ids,
|