@mintlify/cli 4.0.1478 → 4.0.1480
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/__test__/format.test.ts +66 -0
- package/__test__/openApiCheck.test.ts +18 -5
- package/bin/cli.js +21 -3
- package/bin/format.js +1 -1
- package/bin/openApiCheck.js +49 -13
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/bin/vendor/converter.js +5 -10
- package/package.json +8 -8
- package/src/cli.tsx +25 -3
- package/src/format.tsx +1 -1
- package/src/openApiCheck.tsx +66 -11
package/bin/vendor/converter.js
CHANGED
|
@@ -1331,11 +1331,7 @@ import remarkFrontmatter from "remark-frontmatter";
|
|
|
1331
1331
|
import remarkGfm from "remark-gfm";
|
|
1332
1332
|
import remarkMath from "remark-math";
|
|
1333
1333
|
import remarkMdx from "remark-mdx";
|
|
1334
|
-
|
|
1335
|
-
return remark().use(remarkMdx).use(remarkGfm).use(remarkFrontmatter, ["yaml", "toml"]).use(remarkMath, { singleDollarTextMath }).freeze();
|
|
1336
|
-
}
|
|
1337
|
-
var coreRemark = buildRemark(true);
|
|
1338
|
-
var noSingleDollarTextMathRemark = buildRemark(false);
|
|
1334
|
+
var coreRemark = remark().use(remarkMdx).use(remarkGfm).use(remarkFrontmatter, ["yaml", "toml"]).use(remarkMath).freeze();
|
|
1339
1335
|
function convertHtmlCommentsToJsx(mdx) {
|
|
1340
1336
|
const parts = mdx.split(/(```[\s\S]*?```|~~~[\s\S]*?~~~)/);
|
|
1341
1337
|
return parts.map((part, i) => i % 2 === 0 ? part.replace(/<!--([\s\S]*?)-->/g, (_m, c) => `{/* ${c} */}`) : part).join("");
|
|
@@ -1348,14 +1344,13 @@ function preprocessMdxSource(mdx, options = {}) {
|
|
|
1348
1344
|
preprocessed: preprocessCustomHeadingIds(sanitized, { preserveOriginal: true })
|
|
1349
1345
|
};
|
|
1350
1346
|
}
|
|
1351
|
-
function parsePreprocessedMdx(preprocessed
|
|
1352
|
-
|
|
1353
|
-
return parser().parse(preprocessed);
|
|
1347
|
+
function parsePreprocessedMdx(preprocessed) {
|
|
1348
|
+
return coreRemark().parse(preprocessed);
|
|
1354
1349
|
}
|
|
1355
1350
|
function mdxToMdast(mdx, options = {
|
|
1356
1351
|
omitHtmlComments: true
|
|
1357
1352
|
}) {
|
|
1358
|
-
return parsePreprocessedMdx(preprocessMdxSource(mdx, options).preprocessed
|
|
1353
|
+
return parsePreprocessedMdx(preprocessMdxSource(mdx, options).preprocessed);
|
|
1359
1354
|
}
|
|
1360
1355
|
|
|
1361
1356
|
// ../editor/dist/converter/parse/handlers/prompt.js
|
|
@@ -12266,7 +12261,7 @@ var Preserver = class _Preserver {
|
|
|
12266
12261
|
const coords = SourceCoords.create(source, sanitized, preprocessed);
|
|
12267
12262
|
if (!coords)
|
|
12268
12263
|
return null;
|
|
12269
|
-
const root = parsePreprocessedMdx(preprocessed
|
|
12264
|
+
const root = parsePreprocessedMdx(preprocessed);
|
|
12270
12265
|
const ser = Object.assign(Object.assign({}, serializerOptions), { removeTrailingNewline: true, hasReferenceDefinitions: hasReferenceDefinitions(doc) });
|
|
12271
12266
|
return new _Preserver(doc, coords, root, parseOptions, ser);
|
|
12272
12267
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintlify/cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1480",
|
|
4
4
|
"description": "The Mintlify CLI",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@inquirer/prompts": "7.9.0",
|
|
48
|
-
"@mintlify/common": "1.0.
|
|
49
|
-
"@mintlify/link-rot": "3.0.
|
|
48
|
+
"@mintlify/common": "1.0.1132",
|
|
49
|
+
"@mintlify/link-rot": "3.0.1334",
|
|
50
50
|
"@mintlify/models": "0.0.353",
|
|
51
|
-
"@mintlify/prebuild": "1.0.
|
|
52
|
-
"@mintlify/previewing": "4.0.
|
|
53
|
-
"@mintlify/validation": "0.1.
|
|
51
|
+
"@mintlify/prebuild": "1.0.1286",
|
|
52
|
+
"@mintlify/previewing": "4.0.1358",
|
|
53
|
+
"@mintlify/validation": "0.1.849",
|
|
54
54
|
"adm-zip": "0.6.0",
|
|
55
55
|
"chalk": "5.2.0",
|
|
56
56
|
"color": "4.2.3",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"keytar": "7.9.0"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@mintlify/editor": "0.0.
|
|
89
|
+
"@mintlify/editor": "0.0.364",
|
|
90
90
|
"@mintlify/ts-config": "2.0.2",
|
|
91
91
|
"@tsconfig/recommended": "1.0.2",
|
|
92
92
|
"@types/detect-port": "1.3.2",
|
|
@@ -105,5 +105,5 @@
|
|
|
105
105
|
"vitest": "2.1.9",
|
|
106
106
|
"vitest-mock-process": "1.0.4"
|
|
107
107
|
},
|
|
108
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "c1d033f6c135aa4e10b8ed049bde57698764563d"
|
|
109
109
|
}
|
package/src/cli.tsx
CHANGED
|
@@ -45,7 +45,11 @@ import { logout } from './logout.js';
|
|
|
45
45
|
import { mdxLinter } from './mdxLinter.js';
|
|
46
46
|
import { createTelemetryMiddleware } from './middlewares/telemetryMiddleware.js';
|
|
47
47
|
import { mintTestHandler } from './mintTest.js';
|
|
48
|
-
import {
|
|
48
|
+
import {
|
|
49
|
+
buildOverlayRegistryForCheck,
|
|
50
|
+
checkOpenApiFile,
|
|
51
|
+
getOpenApiFilenamesFromDocsConfig,
|
|
52
|
+
} from './openApiCheck.js';
|
|
49
53
|
import { resolveExplicitFiles } from './resolveFiles.js';
|
|
50
54
|
import { scoreHandler } from './score/index.js';
|
|
51
55
|
import { signup } from './signup.js';
|
|
@@ -225,8 +229,18 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
225
229
|
openApiFilenames = getOpenApiFilenamesFromDocsConfig(JSON.parse(docsJson));
|
|
226
230
|
} catch {}
|
|
227
231
|
|
|
232
|
+
let overlayRegistry;
|
|
233
|
+
try {
|
|
234
|
+
overlayRegistry = await buildOverlayRegistryForCheck(argv['local-schema']);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
addLog(<ErrorLog message={error instanceof Error ? error.message : String(error)} />);
|
|
237
|
+
await terminate(1);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
228
240
|
const results = await Promise.all(
|
|
229
|
-
openApiFilenames.map((file) =>
|
|
241
|
+
openApiFilenames.map((file) =>
|
|
242
|
+
checkOpenApiFile(file, argv['local-schema'], overlayRegistry)
|
|
243
|
+
)
|
|
230
244
|
);
|
|
231
245
|
|
|
232
246
|
if (results.some((valid) => !valid)) {
|
|
@@ -308,7 +322,15 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
308
322
|
addLog(
|
|
309
323
|
<WarningLog message="openapi-check is deprecated, use `mintlify validate` instead" />
|
|
310
324
|
);
|
|
311
|
-
|
|
325
|
+
let overlayRegistry;
|
|
326
|
+
try {
|
|
327
|
+
overlayRegistry = await buildOverlayRegistryForCheck(localSchema);
|
|
328
|
+
} catch (error) {
|
|
329
|
+
addLog(<ErrorLog message={error instanceof Error ? error.message : String(error)} />);
|
|
330
|
+
await terminate(1);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const valid = await checkOpenApiFile(filename, localSchema, overlayRegistry);
|
|
312
334
|
await terminate(valid ? 0 : 1);
|
|
313
335
|
}
|
|
314
336
|
)
|
package/src/format.tsx
CHANGED
|
@@ -45,7 +45,7 @@ export const formatHandler = async (): Promise<void> => {
|
|
|
45
45
|
let formatted = raw;
|
|
46
46
|
let originalFrontmatterKeys = 0;
|
|
47
47
|
for (let pass = 0; pass < 3; pass++) {
|
|
48
|
-
const { doc, frontmatter } = mdxToPm(formatted
|
|
48
|
+
const { doc, frontmatter } = mdxToPm(formatted);
|
|
49
49
|
if (pass === 0) originalFrontmatterKeys = Object.keys(frontmatter).length;
|
|
50
50
|
const next = `${pmToMdx(doc, { frontmatter, ...canonicalPmToMdxOptions })}\n`;
|
|
51
51
|
if (next === formatted) break;
|
package/src/openApiCheck.tsx
CHANGED
|
@@ -1,24 +1,75 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
applyOverlays,
|
|
3
|
+
createOverlayRegistry,
|
|
4
|
+
getOpenApiDocumentFromUrl,
|
|
5
|
+
isAllowedLocalSchemaUrl,
|
|
6
|
+
resolveOverlaysForSpec,
|
|
7
|
+
validate,
|
|
8
|
+
type OverlayRegistry,
|
|
9
|
+
} from '@mintlify/common';
|
|
10
|
+
import { discoverOverlayFiles, getMintIgnore, resolveFileRefs } from '@mintlify/prebuild';
|
|
2
11
|
import { addLog, ErrorLog, SuccessLog, WarningLog } from '@mintlify/previewing';
|
|
3
|
-
import
|
|
12
|
+
import {
|
|
13
|
+
collectOpenApiOverlayConfig,
|
|
14
|
+
extractOpenApiEntries,
|
|
15
|
+
type DocsConfig,
|
|
16
|
+
} from '@mintlify/validation';
|
|
17
|
+
import { promises as fs } from 'fs';
|
|
18
|
+
import path from 'path';
|
|
4
19
|
|
|
5
|
-
import { readLocalOpenApiFile } from './helpers.js';
|
|
20
|
+
import { CMD_EXEC_PATH, readLocalOpenApiFile } from './helpers.js';
|
|
6
21
|
|
|
7
22
|
export const getOpenApiFilenamesFromDocsConfig = (config: Pick<DocsConfig, 'api'>): string[] => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
23
|
+
return extractOpenApiEntries(config.api?.openapi).map((entry) => entry.source);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Builds the overlay registry so checks validate specs with overlays applied.
|
|
28
|
+
* Throws when docs.json configures conflicting overlay lists, matching the build.
|
|
29
|
+
*/
|
|
30
|
+
export const buildOverlayRegistryForCheck = async (
|
|
31
|
+
localSchema?: boolean
|
|
32
|
+
): Promise<OverlayRegistry | undefined> => {
|
|
33
|
+
// Discovery failures propagate and fail the check: silently skipping overlays would
|
|
34
|
+
// validate a different document than the one the build produces.
|
|
35
|
+
const mintIgnore = await getMintIgnore(CMD_EXEC_PATH);
|
|
36
|
+
const discovered = await discoverOverlayFiles(CMD_EXEC_PATH, mintIgnore);
|
|
37
|
+
|
|
38
|
+
let rawConfig: unknown;
|
|
39
|
+
try {
|
|
40
|
+
rawConfig = JSON.parse(await fs.readFile(path.join(CMD_EXEC_PATH, 'docs.json'), 'utf-8'));
|
|
41
|
+
} catch {
|
|
42
|
+
rawConfig = undefined;
|
|
43
|
+
}
|
|
44
|
+
if (rawConfig !== undefined) {
|
|
45
|
+
try {
|
|
46
|
+
rawConfig = (await resolveFileRefs(rawConfig, CMD_EXEC_PATH)).resolved;
|
|
47
|
+
} catch {
|
|
48
|
+
// Broken $refs are reported by regular config validation; collect from the root file.
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const explicit = rawConfig == undefined ? undefined : collectOpenApiOverlayConfig(rawConfig);
|
|
52
|
+
|
|
53
|
+
if (explicit == undefined && discovered.length === 0) return undefined;
|
|
54
|
+
|
|
55
|
+
return createOverlayRegistry({
|
|
56
|
+
explicit,
|
|
57
|
+
discovered,
|
|
58
|
+
localSchema,
|
|
59
|
+
loadLocalDocument: (normalizedPath) => readLocalOpenApiFile(normalizedPath),
|
|
60
|
+
});
|
|
13
61
|
};
|
|
14
62
|
|
|
15
63
|
export const checkOpenApiFile = async (
|
|
16
64
|
filename: string,
|
|
17
|
-
localSchema: boolean
|
|
65
|
+
localSchema: boolean,
|
|
66
|
+
overlayRegistry?: OverlayRegistry
|
|
18
67
|
): Promise<boolean> => {
|
|
19
68
|
try {
|
|
69
|
+
const overlays = overlayRegistry ? await resolveOverlaysForSpec(overlayRegistry, filename) : [];
|
|
70
|
+
|
|
20
71
|
if (isAllowedLocalSchemaUrl(filename, localSchema)) {
|
|
21
|
-
await getOpenApiDocumentFromUrl(filename);
|
|
72
|
+
await getOpenApiDocumentFromUrl(filename, { overlays });
|
|
22
73
|
addLog(<SuccessLog message="OpenAPI definition is valid." />);
|
|
23
74
|
return true;
|
|
24
75
|
}
|
|
@@ -37,7 +88,11 @@ export const checkOpenApiFile = async (
|
|
|
37
88
|
'failed to parse OpenAPI spec: could not parse file correctly, please check for any syntax errors.'
|
|
38
89
|
);
|
|
39
90
|
}
|
|
40
|
-
|
|
91
|
+
const overlaid: unknown = overlays.length > 0 ? applyOverlays(document, overlays) : document;
|
|
92
|
+
if (overlaid == undefined || typeof overlaid !== 'object') {
|
|
93
|
+
throw new Error('applying overlays produced an invalid OpenAPI document.');
|
|
94
|
+
}
|
|
95
|
+
await validate(overlaid);
|
|
41
96
|
addLog(<SuccessLog message="OpenAPI definition is valid." />);
|
|
42
97
|
return true;
|
|
43
98
|
} catch (err) {
|