@mintlify/cli 4.0.604 → 4.0.606
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/CONTRIBUTING.md +4 -0
- package/__test__/brokenLinks.test.ts +106 -0
- package/__test__/{cli.test.ts → checkPort.test.ts} +31 -15
- package/__test__/minVersion.test.ts +24 -10
- package/__test__/openApiCheck.test.ts +127 -0
- package/__test__/update.test.ts +148 -47
- package/__test__/utils.ts +9 -0
- package/bin/cli.js +154 -148
- package/bin/helpers.js +29 -21
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/bin/update.js +22 -22
- package/package.json +9 -8
- package/src/cli.tsx +255 -0
- package/src/{helpers.ts → helpers.tsx} +44 -23
- package/src/update.tsx +79 -0
- package/tsconfig.json +3 -2
- package/src/cli.ts +0 -222
- package/src/update.ts +0 -71
package/src/cli.ts
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { validate, getOpenApiDocumentFromUrl, isAllowedLocalSchemaUrl } from '@mintlify/common';
|
|
2
|
-
import { getBrokenInternalLinks, renameFilesAndUpdateLinksInContent } from '@mintlify/link-rot';
|
|
3
|
-
import { dev } from '@mintlify/previewing';
|
|
4
|
-
import Chalk from 'chalk';
|
|
5
|
-
import fs from 'fs/promises';
|
|
6
|
-
import yaml from 'js-yaml';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
import semver from 'semver';
|
|
9
|
-
import yargs from 'yargs';
|
|
10
|
-
import { hideBin } from 'yargs/helpers';
|
|
11
|
-
|
|
12
|
-
import { LOCAL_LINKED_VERSION, MINIMUM_CLI_VERSION } from './constants.js';
|
|
13
|
-
import {
|
|
14
|
-
checkPort,
|
|
15
|
-
checkForMintJson,
|
|
16
|
-
checkNodeVersion,
|
|
17
|
-
upgradeConfig,
|
|
18
|
-
checkForDocsJson,
|
|
19
|
-
getCliVersion,
|
|
20
|
-
getVersions,
|
|
21
|
-
suppressConsoleWarnings,
|
|
22
|
-
} from './helpers.js';
|
|
23
|
-
import { update } from './update.js';
|
|
24
|
-
|
|
25
|
-
export const cli = () =>
|
|
26
|
-
yargs(hideBin(process.argv))
|
|
27
|
-
.middleware(checkNodeVersion)
|
|
28
|
-
.middleware(suppressConsoleWarnings)
|
|
29
|
-
.command(
|
|
30
|
-
'dev',
|
|
31
|
-
'Runs Mintlify project locally.',
|
|
32
|
-
(yargs) =>
|
|
33
|
-
yargs
|
|
34
|
-
.option('open', {
|
|
35
|
-
type: 'boolean',
|
|
36
|
-
default: true,
|
|
37
|
-
description: 'Open Mintlify in the browser',
|
|
38
|
-
})
|
|
39
|
-
.option('local-schema', {
|
|
40
|
-
type: 'boolean',
|
|
41
|
-
default: false,
|
|
42
|
-
hidden: true,
|
|
43
|
-
description:
|
|
44
|
-
'Use a locally hosted schema file (note: only https protocol is supported in production)',
|
|
45
|
-
})
|
|
46
|
-
.option('client-version', {
|
|
47
|
-
type: 'string',
|
|
48
|
-
hidden: true,
|
|
49
|
-
description: 'The version of the client to use for cli testing',
|
|
50
|
-
})
|
|
51
|
-
.usage('Usage: mintlify dev [options]')
|
|
52
|
-
.example('mintlify dev', 'Run with default settings (opens in browser)')
|
|
53
|
-
.example('mintlify dev --no-open', 'Run without opening in browser'),
|
|
54
|
-
async (argv) => {
|
|
55
|
-
const port = await checkPort(argv);
|
|
56
|
-
const packageName = process.argv[1]?.split('/').pop() ?? 'mintlify';
|
|
57
|
-
const cliVersion = getCliVersion();
|
|
58
|
-
if (
|
|
59
|
-
cliVersion &&
|
|
60
|
-
cliVersion !== LOCAL_LINKED_VERSION &&
|
|
61
|
-
semver.lt(cliVersion, MINIMUM_CLI_VERSION)
|
|
62
|
-
) {
|
|
63
|
-
await update({ packageName, silent: true });
|
|
64
|
-
}
|
|
65
|
-
if (port != undefined) {
|
|
66
|
-
await dev({
|
|
67
|
-
...argv,
|
|
68
|
-
port,
|
|
69
|
-
packageName,
|
|
70
|
-
cliVersion: cli,
|
|
71
|
-
});
|
|
72
|
-
} else {
|
|
73
|
-
console.error(`No available port found.`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
)
|
|
77
|
-
.command(
|
|
78
|
-
'openapi-check <openapiFilenameOrUrl>',
|
|
79
|
-
'Validate an OpenAPI spec',
|
|
80
|
-
(yargs) =>
|
|
81
|
-
yargs
|
|
82
|
-
.positional('openapiFilenameOrUrl', {
|
|
83
|
-
describe:
|
|
84
|
-
'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)',
|
|
85
|
-
type: 'string',
|
|
86
|
-
demandOption: true,
|
|
87
|
-
})
|
|
88
|
-
.option('local-schema', {
|
|
89
|
-
type: 'boolean',
|
|
90
|
-
default: false,
|
|
91
|
-
description:
|
|
92
|
-
'Use a locally hosted schema file (note: only https protocol is supported in production)',
|
|
93
|
-
}),
|
|
94
|
-
async ({ openapiFilenameOrUrl, 'local-schema': localSchema }) => {
|
|
95
|
-
try {
|
|
96
|
-
if (isAllowedLocalSchemaUrl(openapiFilenameOrUrl, localSchema)) {
|
|
97
|
-
await getOpenApiDocumentFromUrl(openapiFilenameOrUrl);
|
|
98
|
-
console.log('✅ Your OpenAPI definition is valid.');
|
|
99
|
-
process.exit(0);
|
|
100
|
-
}
|
|
101
|
-
const pathname = path.resolve(process.cwd(), openapiFilenameOrUrl);
|
|
102
|
-
const file = await fs.readFile(pathname, 'utf-8');
|
|
103
|
-
const document = yaml.load(file) as Record<string, unknown> | undefined;
|
|
104
|
-
|
|
105
|
-
if (!document) {
|
|
106
|
-
throw new Error(
|
|
107
|
-
'Failed to parse OpenAPI spec: could not parse file correctly, please check for any syntax errors.'
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
await validate(document);
|
|
111
|
-
console.log('✅ Your OpenAPI definition is valid.');
|
|
112
|
-
} catch (err) {
|
|
113
|
-
console.error(Chalk.red(err));
|
|
114
|
-
process.exit(1);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
)
|
|
118
|
-
.command(
|
|
119
|
-
'broken-links',
|
|
120
|
-
'Check for broken links in your Mintlify project.',
|
|
121
|
-
() => undefined,
|
|
122
|
-
async () => {
|
|
123
|
-
const hasMintJson = await checkForMintJson();
|
|
124
|
-
if (!hasMintJson) {
|
|
125
|
-
await checkForDocsJson();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
console.log(Chalk.bold('Checking for broken links...\n'));
|
|
129
|
-
try {
|
|
130
|
-
const brokenLinks = await getBrokenInternalLinks();
|
|
131
|
-
if (brokenLinks.length === 0) {
|
|
132
|
-
console.log(Chalk.green('No broken links found.'));
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const brokenLinksByFile: Record<string, string[]> = {};
|
|
137
|
-
brokenLinks.forEach((mdxPath) => {
|
|
138
|
-
const filename = path.join(mdxPath.relativeDir, mdxPath.filename);
|
|
139
|
-
const brokenLinksForFile = brokenLinksByFile[filename];
|
|
140
|
-
if (brokenLinksForFile) {
|
|
141
|
-
brokenLinksForFile.push(mdxPath.originalPath);
|
|
142
|
-
} else {
|
|
143
|
-
brokenLinksByFile[filename] = [mdxPath.originalPath];
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
Object.entries(brokenLinksByFile).forEach(([fileName, brokenLinks]) => {
|
|
147
|
-
console.group(`${Chalk.underline(fileName)}`);
|
|
148
|
-
console.log(brokenLinks.join('\n'), '\n');
|
|
149
|
-
console.groupEnd();
|
|
150
|
-
});
|
|
151
|
-
console.error(Chalk.yellow(`${brokenLinks.length} broken links found.`));
|
|
152
|
-
|
|
153
|
-
process.exit(1);
|
|
154
|
-
} catch (err) {
|
|
155
|
-
console.error(Chalk.red(err));
|
|
156
|
-
process.exit(1);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
)
|
|
160
|
-
.command(
|
|
161
|
-
'rename <from> <to>',
|
|
162
|
-
'Rename file in a Mintlify project and update the internal link references.',
|
|
163
|
-
(yargs) =>
|
|
164
|
-
yargs
|
|
165
|
-
.positional('from', {
|
|
166
|
-
describe: 'The file to rename',
|
|
167
|
-
type: 'string',
|
|
168
|
-
})
|
|
169
|
-
.positional('to', {
|
|
170
|
-
describe: 'The new name for the file',
|
|
171
|
-
type: 'string',
|
|
172
|
-
})
|
|
173
|
-
.demandOption(['from', 'to'])
|
|
174
|
-
.epilog('Example: `mintlify rename introduction.mdx overview.mdx`'),
|
|
175
|
-
async ({ from, to }) => {
|
|
176
|
-
const hasMintJson = await checkForMintJson();
|
|
177
|
-
if (!hasMintJson) {
|
|
178
|
-
await checkForDocsJson();
|
|
179
|
-
}
|
|
180
|
-
await renameFilesAndUpdateLinksInContent(from, to);
|
|
181
|
-
}
|
|
182
|
-
)
|
|
183
|
-
.command(
|
|
184
|
-
'update',
|
|
185
|
-
'Update the Mintlify client and cli to the latest version',
|
|
186
|
-
() => undefined,
|
|
187
|
-
async () => {
|
|
188
|
-
const packageName = process.argv[1]?.split('/').pop() ?? 'mintlify';
|
|
189
|
-
await update({ packageName });
|
|
190
|
-
}
|
|
191
|
-
)
|
|
192
|
-
.command(
|
|
193
|
-
'upgrade',
|
|
194
|
-
'Upgrade the mint.json file to v2 (docs.json)',
|
|
195
|
-
() => undefined,
|
|
196
|
-
async () => {
|
|
197
|
-
const hasMintJson = await checkForMintJson();
|
|
198
|
-
if (!hasMintJson) {
|
|
199
|
-
await checkForDocsJson();
|
|
200
|
-
}
|
|
201
|
-
await upgradeConfig();
|
|
202
|
-
}
|
|
203
|
-
)
|
|
204
|
-
.command(
|
|
205
|
-
['version', 'v'],
|
|
206
|
-
'Print the current version of the Mintlify CLI and client',
|
|
207
|
-
() => undefined,
|
|
208
|
-
() => {
|
|
209
|
-
const { cli, client } = getVersions();
|
|
210
|
-
console.log(`Mintlify CLI version: ${cli}`);
|
|
211
|
-
console.log(`Mintlify Client version: ${client}`);
|
|
212
|
-
}
|
|
213
|
-
)
|
|
214
|
-
// Print the help menu when the user enters an invalid command.
|
|
215
|
-
.strictCommands()
|
|
216
|
-
.demandCommand(1, 'Unknown command. See above for the list of supported commands.')
|
|
217
|
-
|
|
218
|
-
// Alias option flags --help = -h, default --version = -v
|
|
219
|
-
.alias('h', 'help')
|
|
220
|
-
.alias('v', 'version')
|
|
221
|
-
|
|
222
|
-
.parse();
|
package/src/update.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { getTargetMintVersion, downloadTargetMint } from '@mintlify/previewing';
|
|
2
|
-
import { execSync } from 'node:child_process';
|
|
3
|
-
import { Ora as OraType } from 'ora';
|
|
4
|
-
|
|
5
|
-
import { buildLogger, getLatestCliVersion, getVersions } from './helpers.js';
|
|
6
|
-
|
|
7
|
-
export const update = async ({
|
|
8
|
-
packageName,
|
|
9
|
-
silent,
|
|
10
|
-
}: {
|
|
11
|
-
packageName: string;
|
|
12
|
-
silent?: boolean;
|
|
13
|
-
}) => {
|
|
14
|
-
let logger: OraType | undefined = undefined;
|
|
15
|
-
if (!silent) {
|
|
16
|
-
logger = buildLogger(`Updating ${packageName} to the latest version...`);
|
|
17
|
-
}
|
|
18
|
-
const { cli: existingCliVersion, client: existingClientVersion } = getVersions();
|
|
19
|
-
const latestCliVersion = getLatestCliVersion(packageName);
|
|
20
|
-
const latestClientVersion = await getTargetMintVersion(logger);
|
|
21
|
-
const isUpToDate =
|
|
22
|
-
existingCliVersion &&
|
|
23
|
-
existingClientVersion &&
|
|
24
|
-
latestClientVersion &&
|
|
25
|
-
latestCliVersion &&
|
|
26
|
-
latestCliVersion.trim() === existingCliVersion.trim() &&
|
|
27
|
-
latestClientVersion.trim() === existingClientVersion.trim();
|
|
28
|
-
|
|
29
|
-
if (isUpToDate) {
|
|
30
|
-
if (!silent && logger) {
|
|
31
|
-
logger.succeed('Already up to date.');
|
|
32
|
-
}
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (existingCliVersion && latestCliVersion.trim() !== existingCliVersion.trim()) {
|
|
37
|
-
try {
|
|
38
|
-
if (logger) {
|
|
39
|
-
logger.text = `Updating ${packageName} package...`;
|
|
40
|
-
}
|
|
41
|
-
execSync(`npm install -g ${packageName}@latest --silent`);
|
|
42
|
-
} catch (err) {
|
|
43
|
-
if (logger) {
|
|
44
|
-
logger.fail(`Failed to update ${packageName}@latest`);
|
|
45
|
-
}
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (latestClientVersion && latestClientVersion !== existingClientVersion) {
|
|
51
|
-
try {
|
|
52
|
-
if (logger) {
|
|
53
|
-
logger.text = `Updating Mintlify client to ${latestClientVersion}...`;
|
|
54
|
-
}
|
|
55
|
-
await downloadTargetMint({
|
|
56
|
-
logger,
|
|
57
|
-
targetVersion: latestClientVersion,
|
|
58
|
-
existingVersion: existingClientVersion ?? null,
|
|
59
|
-
});
|
|
60
|
-
} catch (err) {
|
|
61
|
-
if (logger) {
|
|
62
|
-
logger.fail(`Failed to update Mintlify client to ${latestClientVersion}`);
|
|
63
|
-
}
|
|
64
|
-
process.exit(1);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (logger) {
|
|
69
|
-
logger.succeed(`Updated ${packageName} to the latest version: ${latestCliVersion}`);
|
|
70
|
-
}
|
|
71
|
-
};
|