UNPKG

@mintlify/cli

Version:

The Mintlify CLI

131 lines (130 loc) 5.8 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { validate, getOpenApiDocumentFromUrl } from '@mintlify/common'; import { getBrokenInternalLinks, renameFilesAndUpdateLinksInContent } from '@mintlify/link-rot'; import { dev } from '@mintlify/previewing'; import Chalk from 'chalk'; import fs from 'fs/promises'; import yaml from 'js-yaml'; import path from 'path'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; import { checkPort, checkForMintJson, checkNodeVersion, upgradeConfig, checkForDocsJson, } from './helpers.js'; export const cli = () => yargs(hideBin(process.argv)) .middleware(checkNodeVersion) .command('dev', 'Runs Mintlify project locally.', (yargs) => yargs .option('open', { type: 'boolean', default: true, description: 'Open Mintlify in the browser', }) .usage('Usage: mintlify dev [options]') .example('mintlify dev', 'Run with default settings (opens in browser)') .example('mintlify dev --no-open', 'Run without opening in browser'), (argv) => __awaiter(void 0, void 0, void 0, function* () { const port = yield checkPort(argv); if (port != undefined) { yield dev(Object.assign(Object.assign({}, argv), { port })); } else { console.error(`No available port found.`); } })) .command('openapi-check <openapiFilenameOrUrl>', 'Validate an OpenAPI spec', (yargs) => yargs.positional('openapiFilenameOrUrl', { describe: 'The filename of the OpenAPI spec (e.g. ./openapi.yaml) or the URL to the OpenAPI spec (e.g. https://petstore3.swagger.io/api/v3/openapi.json)', type: 'string', demandOption: true, }), (_a) => __awaiter(void 0, [_a], void 0, function* ({ openapiFilenameOrUrl }) { try { if (openapiFilenameOrUrl.startsWith('https://')) { yield getOpenApiDocumentFromUrl(openapiFilenameOrUrl); console.log('✅ Your OpenAPI definition is valid.'); process.exit(0); } const pathname = path.resolve(process.cwd(), openapiFilenameOrUrl); const file = yield fs.readFile(pathname, 'utf-8'); const document = yaml.load(file); if (!document) { throw new Error('Failed to parse OpenAPI spec: could not parse file correctly, please check for any syntax errors.'); } yield validate(document); console.log('✅ Your OpenAPI definition is valid.'); } catch (err) { console.error(Chalk.red(err)); process.exit(1); } })) .command('broken-links', 'Check for broken links in your Mintlify project.', () => undefined, () => __awaiter(void 0, void 0, void 0, function* () { const hasMintJson = yield checkForMintJson(); if (!hasMintJson) { yield checkForDocsJson(); } console.log(Chalk.bold('Checking for broken links...\n')); try { const brokenLinks = yield getBrokenInternalLinks(); if (brokenLinks.length === 0) { console.log(Chalk.green('No broken links found.')); return; } const brokenLinksByFile = {}; brokenLinks.forEach((mdxPath) => { const filename = path.join(mdxPath.relativeDir, mdxPath.filename); const brokenLinksForFile = brokenLinksByFile[filename]; if (brokenLinksForFile) { brokenLinksForFile.push(mdxPath.originalPath); } else { brokenLinksByFile[filename] = [mdxPath.originalPath]; } }); Object.entries(brokenLinksByFile).forEach(([fileName, brokenLinks]) => { console.group(`${Chalk.underline(fileName)}`); console.log(brokenLinks.join('\n'), '\n'); console.groupEnd(); }); console.error(Chalk.yellow(`${brokenLinks.length} broken links found.`)); process.exit(1); } catch (err) { console.error(Chalk.red(err)); process.exit(1); } })) .command('rename <from> <to>', 'Rename file in a Mintlify project and update the internal link references.', (yargs) => yargs .positional('from', { describe: 'The file to rename', type: 'string', }) .positional('to', { describe: 'The new name for the file', type: 'string', }) .demandOption(['from', 'to']) .epilog('Example: `mintlify rename introduction.mdx overview.mdx`'), (_a) => __awaiter(void 0, [_a], void 0, function* ({ from, to }) { const hasMintJson = yield checkForMintJson(); if (!hasMintJson) { yield checkForDocsJson(); } yield renameFilesAndUpdateLinksInContent(from, to); })) .command('upgrade', 'Upgrade the mint.json file to v2 (docs.json)', () => undefined, () => __awaiter(void 0, void 0, void 0, function* () { const hasMintJson = yield checkForMintJson(); if (!hasMintJson) { yield checkForDocsJson(); } yield upgradeConfig(); })) // Print the help menu when the user enters an invalid command. .strictCommands() .demandCommand(1, 'Unknown command. See above for the list of supported commands.') // Alias option flags --help = -h, --version = -v .alias('h', 'help') .alias('v', 'version') .parse();