@mintlify/cli 4.0.1477 → 4.0.1479

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.
@@ -6,11 +6,24 @@ import { readLocalOpenApiFile } from '../src/helpers.js';
6
6
  import { getOpenApiFilenamesFromDocsConfig } from '../src/openApiCheck.js';
7
7
  import { mockValidOpenApiDocument, runCommand } from './utils.js';
8
8
 
9
- vi.mock('@mintlify/common', () => ({
10
- getOpenApiDocumentFromUrl: vi.fn(),
11
- isAllowedLocalSchemaUrl: vi.fn(),
12
- validate: vi.fn(),
13
- }));
9
+ vi.mock('@mintlify/common', async (importOriginal) => {
10
+ const mod = await importOriginal<typeof import('@mintlify/common')>();
11
+ return {
12
+ ...mod,
13
+ getOpenApiDocumentFromUrl: vi.fn(),
14
+ isAllowedLocalSchemaUrl: vi.fn(),
15
+ validate: vi.fn(),
16
+ };
17
+ });
18
+
19
+ vi.mock('@mintlify/prebuild', async (importOriginal) => {
20
+ const mod = await importOriginal<typeof import('@mintlify/prebuild')>();
21
+ return {
22
+ ...mod,
23
+ getMintIgnore: vi.fn(async () => []),
24
+ discoverOverlayFiles: vi.fn(async () => []),
25
+ };
26
+ });
14
27
 
15
28
  vi.mock('@mintlify/previewing', async (importOriginal) => {
16
29
  const mod = await importOriginal<typeof import('@mintlify/previewing')>();
package/bin/cli.js CHANGED
@@ -32,7 +32,7 @@ import { logout } from './logout.js';
32
32
  import { mdxLinter } from './mdxLinter.js';
33
33
  import { createTelemetryMiddleware } from './middlewares/telemetryMiddleware.js';
34
34
  import { mintTestHandler } from './mintTest.js';
35
- import { checkOpenApiFile, getOpenApiFilenamesFromDocsConfig } from './openApiCheck.js';
35
+ import { buildOverlayRegistryForCheck, checkOpenApiFile, getOpenApiFilenamesFromDocsConfig, } from './openApiCheck.js';
36
36
  import { resolveExplicitFiles } from './resolveFiles.js';
37
37
  import { scoreHandler } from './score/index.js';
38
38
  import { signup } from './signup.js';
@@ -191,7 +191,16 @@ export const cli = ({ packageName = 'mint' }) => {
191
191
  openApiFilenames = getOpenApiFilenamesFromDocsConfig(JSON.parse(docsJson));
192
192
  }
193
193
  catch (_a) { }
194
- const results = yield Promise.all(openApiFilenames.map((file) => checkOpenApiFile(file, argv['local-schema'])));
194
+ let overlayRegistry;
195
+ try {
196
+ overlayRegistry = yield buildOverlayRegistryForCheck(argv['local-schema']);
197
+ }
198
+ catch (error) {
199
+ addLog(_jsx(ErrorLog, { message: error instanceof Error ? error.message : String(error) }));
200
+ yield terminate(1);
201
+ return;
202
+ }
203
+ const results = yield Promise.all(openApiFilenames.map((file) => checkOpenApiFile(file, argv['local-schema'], overlayRegistry)));
195
204
  if (results.some((valid) => !valid)) {
196
205
  yield terminate(1);
197
206
  return;
@@ -243,7 +252,16 @@ export const cli = ({ packageName = 'mint' }) => {
243
252
  description: 'use a locally hosted schema file (note: only https protocol is supported in production)',
244
253
  }), (_a) => __awaiter(void 0, [_a], void 0, function* ({ filename, 'local-schema': localSchema }) {
245
254
  addLog(_jsx(WarningLog, { message: "openapi-check is deprecated, use `mintlify validate` instead" }));
246
- const valid = yield checkOpenApiFile(filename, localSchema);
255
+ let overlayRegistry;
256
+ try {
257
+ overlayRegistry = yield buildOverlayRegistryForCheck(localSchema);
258
+ }
259
+ catch (error) {
260
+ addLog(_jsx(ErrorLog, { message: error instanceof Error ? error.message : String(error) }));
261
+ yield terminate(1);
262
+ return;
263
+ }
264
+ const valid = yield checkOpenApiFile(filename, localSchema, overlayRegistry);
247
265
  yield terminate(valid ? 0 : 1);
248
266
  }))
249
267
  .command('broken-links', 'Check for broken links', (yargs) => yargs
@@ -8,24 +8,56 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
11
- import { validate, getOpenApiDocumentFromUrl, isAllowedLocalSchemaUrl } from '@mintlify/common';
11
+ import { applyOverlays, createOverlayRegistry, getOpenApiDocumentFromUrl, isAllowedLocalSchemaUrl, resolveOverlaysForSpec, validate, } from '@mintlify/common';
12
+ import { discoverOverlayFiles, getMintIgnore, resolveFileRefs } from '@mintlify/prebuild';
12
13
  import { addLog, ErrorLog, SuccessLog, WarningLog } from '@mintlify/previewing';
13
- import { readLocalOpenApiFile } from './helpers.js';
14
+ import { collectOpenApiOverlayConfig, extractOpenApiEntries, } from '@mintlify/validation';
15
+ import { promises as fs } from 'fs';
16
+ import path from 'path';
17
+ import { CMD_EXEC_PATH, readLocalOpenApiFile } from './helpers.js';
14
18
  export const getOpenApiFilenamesFromDocsConfig = (config) => {
15
19
  var _a;
16
- const openapi = (_a = config.api) === null || _a === void 0 ? void 0 : _a.openapi;
17
- if (openapi === undefined)
18
- return [];
19
- if (typeof openapi === 'string')
20
- return [openapi];
21
- if (Array.isArray(openapi))
22
- return openapi;
23
- return [openapi.source];
20
+ return extractOpenApiEntries((_a = config.api) === null || _a === void 0 ? void 0 : _a.openapi).map((entry) => entry.source);
24
21
  };
25
- export const checkOpenApiFile = (filename, localSchema) => __awaiter(void 0, void 0, void 0, function* () {
22
+ /**
23
+ * Builds the overlay registry so checks validate specs with overlays applied.
24
+ * Throws when docs.json configures conflicting overlay lists, matching the build.
25
+ */
26
+ export const buildOverlayRegistryForCheck = (localSchema) => __awaiter(void 0, void 0, void 0, function* () {
27
+ // Discovery failures propagate and fail the check: silently skipping overlays would
28
+ // validate a different document than the one the build produces.
29
+ const mintIgnore = yield getMintIgnore(CMD_EXEC_PATH);
30
+ const discovered = yield discoverOverlayFiles(CMD_EXEC_PATH, mintIgnore);
31
+ let rawConfig;
26
32
  try {
33
+ rawConfig = JSON.parse(yield fs.readFile(path.join(CMD_EXEC_PATH, 'docs.json'), 'utf-8'));
34
+ }
35
+ catch (_a) {
36
+ rawConfig = undefined;
37
+ }
38
+ if (rawConfig !== undefined) {
39
+ try {
40
+ rawConfig = (yield resolveFileRefs(rawConfig, CMD_EXEC_PATH)).resolved;
41
+ }
42
+ catch (_b) {
43
+ // Broken $refs are reported by regular config validation; collect from the root file.
44
+ }
45
+ }
46
+ const explicit = rawConfig == undefined ? undefined : collectOpenApiOverlayConfig(rawConfig);
47
+ if (explicit == undefined && discovered.length === 0)
48
+ return undefined;
49
+ return createOverlayRegistry({
50
+ explicit,
51
+ discovered,
52
+ localSchema,
53
+ loadLocalDocument: (normalizedPath) => readLocalOpenApiFile(normalizedPath),
54
+ });
55
+ });
56
+ export const checkOpenApiFile = (filename, localSchema, overlayRegistry) => __awaiter(void 0, void 0, void 0, function* () {
57
+ try {
58
+ const overlays = overlayRegistry ? yield resolveOverlaysForSpec(overlayRegistry, filename) : [];
27
59
  if (isAllowedLocalSchemaUrl(filename, localSchema)) {
28
- yield getOpenApiDocumentFromUrl(filename);
60
+ yield getOpenApiDocumentFromUrl(filename, { overlays });
29
61
  addLog(_jsx(SuccessLog, { message: "OpenAPI definition is valid." }));
30
62
  return true;
31
63
  }
@@ -38,7 +70,11 @@ export const checkOpenApiFile = (filename, localSchema) => __awaiter(void 0, voi
38
70
  if (!document) {
39
71
  throw new Error('failed to parse OpenAPI spec: could not parse file correctly, please check for any syntax errors.');
40
72
  }
41
- yield validate(document);
73
+ const overlaid = overlays.length > 0 ? applyOverlays(document, overlays) : document;
74
+ if (overlaid == undefined || typeof overlaid !== 'object') {
75
+ throw new Error('applying overlays produced an invalid OpenAPI document.');
76
+ }
77
+ yield validate(overlaid);
42
78
  addLog(_jsx(SuccessLog, { message: "OpenAPI definition is valid." }));
43
79
  return true;
44
80
  }