@redocly/cli 1.18.1 → 1.20.0
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/CHANGELOG.md +24 -0
- package/lib/__mocks__/@redocly/openapi-core.d.ts +2 -2
- package/lib/__mocks__/@redocly/openapi-core.js +1 -0
- package/lib/__mocks__/fs.d.ts +0 -1
- package/lib/__mocks__/perf_hooks.d.ts +0 -1
- package/lib/__mocks__/redoc.d.ts +0 -1
- package/lib/__tests__/commands/build-docs.test.js +21 -23
- package/lib/__tests__/commands/bundle.test.js +21 -30
- package/lib/__tests__/commands/join.test.js +101 -70
- package/lib/__tests__/commands/lint.test.js +54 -54
- package/lib/__tests__/commands/push-region.test.js +24 -25
- package/lib/__tests__/commands/push.test.js +269 -170
- package/lib/__tests__/fetch-with-timeout.test.js +3 -12
- package/lib/__tests__/fixtures/config.d.ts +0 -1
- package/lib/__tests__/utils.test.js +32 -37
- package/lib/__tests__/wrapper.test.js +31 -20
- package/lib/cms/api/__tests__/api.client.test.js +29 -38
- package/lib/cms/api/api-client.d.ts +0 -2
- package/lib/cms/api/api-client.js +107 -128
- package/lib/cms/api/api-keys.js +1 -2
- package/lib/cms/api/domains.js +1 -2
- package/lib/cms/commands/__tests__/push-status.test.js +251 -162
- package/lib/cms/commands/__tests__/push.test.js +120 -102
- package/lib/cms/commands/__tests__/utils.test.js +12 -21
- package/lib/cms/commands/push-status.d.ts +3 -2
- package/lib/cms/commands/push-status.js +94 -106
- package/lib/cms/commands/push.d.ts +3 -2
- package/lib/cms/commands/push.js +66 -74
- package/lib/cms/commands/utils.js +20 -34
- package/lib/commands/build-docs/index.d.ts +2 -2
- package/lib/commands/build-docs/index.js +8 -17
- package/lib/commands/build-docs/utils.d.ts +1 -1
- package/lib/commands/build-docs/utils.js +27 -39
- package/lib/commands/bundle.d.ts +2 -2
- package/lib/commands/bundle.js +70 -94
- package/lib/commands/join.d.ts +2 -2
- package/lib/commands/join.js +375 -388
- package/lib/commands/lint.d.ts +2 -2
- package/lib/commands/lint.js +64 -75
- package/lib/commands/login.d.ts +3 -2
- package/lib/commands/login.js +10 -22
- package/lib/commands/preview-docs/index.d.ts +2 -2
- package/lib/commands/preview-docs/index.js +93 -106
- package/lib/commands/preview-docs/preview-server/preview-server.js +64 -76
- package/lib/commands/preview-docs/preview-server/server.d.ts +1 -4
- package/lib/commands/preview-docs/preview-server/server.js +6 -6
- package/lib/commands/preview-project/constants.d.ts +1 -1
- package/lib/commands/preview-project/index.d.ts +2 -1
- package/lib/commands/preview-project/index.js +5 -14
- package/lib/commands/preview-project/types.d.ts +1 -1
- package/lib/commands/push.d.ts +9 -12
- package/lib/commands/push.js +180 -196
- package/lib/commands/split/__tests__/index.test.js +31 -25
- package/lib/commands/split/index.d.ts +2 -1
- package/lib/commands/split/index.js +20 -33
- package/lib/commands/stats.d.ts +2 -2
- package/lib/commands/stats.js +36 -47
- package/lib/index.js +34 -49
- package/lib/types.d.ts +4 -5
- package/lib/utils/__mocks__/miscellaneous.d.ts +0 -1
- package/lib/utils/fetch-with-timeout.js +7 -12
- package/lib/utils/getCommandNameFromArgs.d.ts +1 -1
- package/lib/utils/getCommandNameFromArgs.js +2 -4
- package/lib/utils/js-utils.js +6 -7
- package/lib/utils/miscellaneous.d.ts +4 -1
- package/lib/utils/miscellaneous.js +130 -152
- package/lib/utils/update-version-notifier.js +4 -13
- package/lib/wrapper.d.ts +9 -2
- package/lib/wrapper.js +27 -16
- package/package.json +3 -3
- package/src/__mocks__/@redocly/openapi-core.ts +1 -0
- package/src/__tests__/commands/build-docs.test.ts +5 -4
- package/src/__tests__/commands/join.test.ts +51 -51
- package/src/__tests__/commands/push-region.test.ts +10 -8
- package/src/__tests__/commands/push.test.ts +127 -102
- package/src/__tests__/utils.test.ts +1 -0
- package/src/__tests__/wrapper.test.ts +24 -2
- package/src/cms/api/api-client.ts +2 -1
- package/src/cms/commands/__tests__/push-status.test.ts +70 -56
- package/src/cms/commands/__tests__/push.test.ts +30 -24
- package/src/cms/commands/push-status.ts +8 -7
- package/src/cms/commands/push.ts +12 -9
- package/src/commands/build-docs/index.ts +10 -5
- package/src/commands/build-docs/utils.ts +4 -4
- package/src/commands/bundle.ts +14 -6
- package/src/commands/join.ts +6 -2
- package/src/commands/lint.ts +9 -3
- package/src/commands/login.ts +5 -2
- package/src/commands/preview-docs/index.ts +7 -1
- package/src/commands/preview-docs/preview-server/preview-server.ts +4 -3
- package/src/commands/preview-docs/preview-server/server.ts +2 -1
- package/src/commands/preview-project/constants.ts +1 -1
- package/src/commands/preview-project/index.ts +5 -4
- package/src/commands/preview-project/types.ts +1 -1
- package/src/commands/push.ts +15 -18
- package/src/commands/split/__tests__/index.test.ts +17 -6
- package/src/commands/split/index.ts +4 -2
- package/src/commands/stats.ts +13 -6
- package/src/index.ts +13 -7
- package/src/types.ts +2 -3
- package/src/utils/getCommandNameFromArgs.ts +1 -1
- package/src/utils/miscellaneous.ts +11 -1
- package/src/wrapper.ts +37 -11
- package/tsconfig.tsbuildinfo +1 -1
package/src/commands/bundle.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { performance } from 'perf_hooks';
|
|
2
|
+
import { blue, gray, green, yellow } from 'colorette';
|
|
3
|
+
import { writeFileSync } from 'fs';
|
|
4
|
+
import { formatProblems, getTotals, getMergedConfig, bundle } from '@redocly/openapi-core';
|
|
2
5
|
import {
|
|
3
6
|
dumpBundle,
|
|
4
7
|
getExecutionTime,
|
|
@@ -8,12 +11,11 @@ import {
|
|
|
8
11
|
printUnusedWarnings,
|
|
9
12
|
saveBundle,
|
|
10
13
|
sortTopLevelKeysForOas,
|
|
14
|
+
checkForDeprecatedOptions,
|
|
11
15
|
} from '../utils/miscellaneous';
|
|
16
|
+
|
|
12
17
|
import type { OutputExtensions, Skips, Totals } from '../types';
|
|
13
|
-
import {
|
|
14
|
-
import { blue, gray, green, yellow } from 'colorette';
|
|
15
|
-
import { writeFileSync } from 'fs';
|
|
16
|
-
import { checkForDeprecatedOptions } from '../utils/miscellaneous';
|
|
18
|
+
import type { CommandArgs } from '../wrapper';
|
|
17
19
|
|
|
18
20
|
export type BundleOptions = {
|
|
19
21
|
apis?: string[];
|
|
@@ -28,7 +30,12 @@ export type BundleOptions = {
|
|
|
28
30
|
'keep-url-references'?: boolean;
|
|
29
31
|
} & Skips;
|
|
30
32
|
|
|
31
|
-
export async function handleBundle(
|
|
33
|
+
export async function handleBundle({
|
|
34
|
+
argv,
|
|
35
|
+
config,
|
|
36
|
+
version,
|
|
37
|
+
collectSpecData,
|
|
38
|
+
}: CommandArgs<BundleOptions>) {
|
|
32
39
|
const removeUnusedComponents =
|
|
33
40
|
argv['remove-unused-components'] ||
|
|
34
41
|
config.rawConfig?.styleguide?.decorators?.hasOwnProperty('remove-unused-components');
|
|
@@ -59,6 +66,7 @@ export async function handleBundle(argv: BundleOptions, config: Config, version:
|
|
|
59
66
|
dereference: argv.dereferenced,
|
|
60
67
|
removeUnusedComponents,
|
|
61
68
|
keepUrlRefs: argv['keep-url-references'],
|
|
69
|
+
collectSpecData,
|
|
62
70
|
});
|
|
63
71
|
|
|
64
72
|
const fileTotals = getTotals(problems);
|
package/src/commands/join.ts
CHANGED
|
@@ -2,7 +2,6 @@ import * as path from 'path';
|
|
|
2
2
|
import { red, blue, yellow, green } from 'colorette';
|
|
3
3
|
import { performance } from 'perf_hooks';
|
|
4
4
|
import {
|
|
5
|
-
Config,
|
|
6
5
|
SpecVersion,
|
|
7
6
|
BaseResolver,
|
|
8
7
|
formatProblems,
|
|
@@ -38,6 +37,7 @@ import type {
|
|
|
38
37
|
Oas3Server,
|
|
39
38
|
Oas3_1Definition,
|
|
40
39
|
} from '@redocly/openapi-core/lib/typings/openapi';
|
|
40
|
+
import type { CommandArgs } from '../wrapper';
|
|
41
41
|
|
|
42
42
|
const Tags = 'tags';
|
|
43
43
|
const xTagGroups = 'x-tagGroups';
|
|
@@ -64,7 +64,11 @@ export type JoinOptions = {
|
|
|
64
64
|
'lint-config'?: RuleSeverity;
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
-
export async function handleJoin(
|
|
67
|
+
export async function handleJoin({
|
|
68
|
+
argv,
|
|
69
|
+
config,
|
|
70
|
+
version: packageVersion,
|
|
71
|
+
}: CommandArgs<JoinOptions>) {
|
|
68
72
|
const startedAt = performance.now();
|
|
69
73
|
|
|
70
74
|
if (argv.apis.length < 2) {
|
package/src/commands/lint.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { blue, gray } from 'colorette';
|
|
2
2
|
import { performance } from 'perf_hooks';
|
|
3
3
|
import {
|
|
4
|
-
Config,
|
|
5
4
|
formatProblems,
|
|
6
5
|
getMergedConfig,
|
|
7
6
|
getTotals,
|
|
@@ -23,10 +22,11 @@ import {
|
|
|
23
22
|
} from '../utils/miscellaneous';
|
|
24
23
|
import { getCommandNameFromArgs } from '../utils/getCommandNameFromArgs';
|
|
25
24
|
|
|
25
|
+
import type { Arguments } from 'yargs';
|
|
26
26
|
import type { OutputFormat, ProblemSeverity, RuleSeverity } from '@redocly/openapi-core';
|
|
27
27
|
import type { RawConfigProcessor } from '@redocly/openapi-core/lib/config';
|
|
28
28
|
import type { CommandOptions, Skips, Totals } from '../types';
|
|
29
|
-
import type {
|
|
29
|
+
import type { CommandArgs } from '../wrapper';
|
|
30
30
|
|
|
31
31
|
export type LintOptions = {
|
|
32
32
|
apis?: string[];
|
|
@@ -38,7 +38,12 @@ export type LintOptions = {
|
|
|
38
38
|
'lint-config'?: RuleSeverity;
|
|
39
39
|
} & Omit<Skips, 'skip-decorator'>;
|
|
40
40
|
|
|
41
|
-
export async function handleLint(
|
|
41
|
+
export async function handleLint({
|
|
42
|
+
argv,
|
|
43
|
+
config,
|
|
44
|
+
version,
|
|
45
|
+
collectSpecData,
|
|
46
|
+
}: CommandArgs<LintOptions>) {
|
|
42
47
|
const apis = await getFallbackApisOrExit(argv.apis, config);
|
|
43
48
|
|
|
44
49
|
if (!apis.length) {
|
|
@@ -74,6 +79,7 @@ export async function handleLint(argv: LintOptions, config: Config, version: str
|
|
|
74
79
|
const results = await lint({
|
|
75
80
|
ref: path,
|
|
76
81
|
config: resolvedConfig,
|
|
82
|
+
collectSpecData,
|
|
77
83
|
});
|
|
78
84
|
|
|
79
85
|
const fileTotals = getTotals(results);
|
package/src/commands/login.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { Region, RedoclyClient, Config } from '@redocly/openapi-core';
|
|
2
1
|
import { blue, green, gray } from 'colorette';
|
|
2
|
+
import { RedoclyClient } from '@redocly/openapi-core';
|
|
3
3
|
import { promptUser } from '../utils/miscellaneous';
|
|
4
4
|
|
|
5
|
+
import type { CommandArgs } from '../wrapper';
|
|
6
|
+
import type { Region } from '@redocly/openapi-core';
|
|
7
|
+
|
|
5
8
|
export function promptClientToken(domain: string) {
|
|
6
9
|
return promptUser(
|
|
7
10
|
green(
|
|
@@ -17,7 +20,7 @@ export type LoginOptions = {
|
|
|
17
20
|
config?: string;
|
|
18
21
|
};
|
|
19
22
|
|
|
20
|
-
export async function handleLogin(argv
|
|
23
|
+
export async function handleLogin({ argv, config }: CommandArgs<LoginOptions>) {
|
|
21
24
|
const region = argv.region || config.region;
|
|
22
25
|
const client = new RedoclyClient(region);
|
|
23
26
|
const clientToken = await promptClientToken(client.domain);
|
|
@@ -7,7 +7,9 @@ import {
|
|
|
7
7
|
loadConfigAndHandleErrors,
|
|
8
8
|
} from '../../utils/miscellaneous';
|
|
9
9
|
import startPreviewServer from './preview-server/preview-server';
|
|
10
|
+
|
|
10
11
|
import type { Skips } from '../../types';
|
|
12
|
+
import type { CommandArgs } from '../../wrapper';
|
|
11
13
|
|
|
12
14
|
export type PreviewDocsOptions = {
|
|
13
15
|
port: number;
|
|
@@ -18,7 +20,10 @@ export type PreviewDocsOptions = {
|
|
|
18
20
|
force?: boolean;
|
|
19
21
|
} & Omit<Skips, 'skip-rule'>;
|
|
20
22
|
|
|
21
|
-
export async function previewDocs(
|
|
23
|
+
export async function previewDocs({
|
|
24
|
+
argv,
|
|
25
|
+
config: configFromFile,
|
|
26
|
+
}: CommandArgs<PreviewDocsOptions>) {
|
|
22
27
|
let isAuthorizedWithRedocly = false;
|
|
23
28
|
let redocOptions: any = {};
|
|
24
29
|
let config = await reloadConfig(configFromFile);
|
|
@@ -151,6 +156,7 @@ export async function previewDocs(argv: PreviewDocsOptions, configFromFile: Conf
|
|
|
151
156
|
}
|
|
152
157
|
}
|
|
153
158
|
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
154
160
|
export function debounce(func: Function, wait: number, immediate?: boolean) {
|
|
155
161
|
let timeout: NodeJS.Timeout | null;
|
|
156
162
|
|
|
@@ -3,11 +3,11 @@ import * as colorette from 'colorette';
|
|
|
3
3
|
import { getPort } from 'get-port-please';
|
|
4
4
|
import { readFileSync, promises as fsPromises } from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
|
-
|
|
7
6
|
import { startHttpServer, startWsServer, respondWithGzip, mimeTypes } from './server';
|
|
8
|
-
import type { IncomingMessage } from 'http';
|
|
9
7
|
import { isSubdir } from '../../../utils/miscellaneous';
|
|
10
8
|
|
|
9
|
+
import type { IncomingMessage } from 'http';
|
|
10
|
+
|
|
11
11
|
function getPageHTML(
|
|
12
12
|
htmlTemplate: string,
|
|
13
13
|
redocOptions: object = {},
|
|
@@ -60,7 +60,8 @@ export default async function startPreviewServer(
|
|
|
60
60
|
getBundle,
|
|
61
61
|
getOptions,
|
|
62
62
|
useRedocPro,
|
|
63
|
-
}:
|
|
63
|
+
}: // eslint-disable-next-line @typescript-eslint/ban-types
|
|
64
|
+
{ getBundle: Function; getOptions: Function; useRedocPro: boolean }
|
|
64
65
|
) {
|
|
65
66
|
const defaultTemplate = path.join(__dirname, 'default.hbs');
|
|
66
67
|
const handler = async (request: IncomingMessage, response: any) => {
|
|
@@ -4,12 +4,13 @@ import { spawn } from 'child_process';
|
|
|
4
4
|
import { PRODUCT_NAMES, PRODUCT_PACKAGES } from './constants';
|
|
5
5
|
|
|
6
6
|
import type { PreviewProjectOptions, Product } from './types';
|
|
7
|
+
import type { CommandArgs } from '../../wrapper';
|
|
7
8
|
|
|
8
|
-
export const previewProject = async (
|
|
9
|
-
const { plan, port } =
|
|
10
|
-
const projectDir =
|
|
9
|
+
export const previewProject = async ({ argv }: CommandArgs<PreviewProjectOptions>) => {
|
|
10
|
+
const { plan, port } = argv;
|
|
11
|
+
const projectDir = argv['source-dir'];
|
|
11
12
|
|
|
12
|
-
const product =
|
|
13
|
+
const product = argv.product || tryGetProductFromPackageJson(projectDir);
|
|
13
14
|
|
|
14
15
|
if (!isValidProduct(product)) {
|
|
15
16
|
process.stderr.write(`Invalid product ${product}`);
|
package/src/commands/push.ts
CHANGED
|
@@ -6,13 +6,10 @@ import { yellow, green, blue, red } from 'colorette';
|
|
|
6
6
|
import { createHash } from 'crypto';
|
|
7
7
|
import {
|
|
8
8
|
bundle,
|
|
9
|
-
Config,
|
|
10
9
|
RedoclyClient,
|
|
11
10
|
IGNORE_FILE,
|
|
12
|
-
BundleOutputFormat,
|
|
13
11
|
getTotals,
|
|
14
12
|
slash,
|
|
15
|
-
Region,
|
|
16
13
|
getMergedConfig,
|
|
17
14
|
getProxyAgent,
|
|
18
15
|
} from '@redocly/openapi-core';
|
|
@@ -26,9 +23,13 @@ import {
|
|
|
26
23
|
import { promptClientToken } from './login';
|
|
27
24
|
import { handlePush as handleCMSPush } from '../cms/commands/push';
|
|
28
25
|
|
|
26
|
+
import type { Config, BundleOutputFormat, Region } from '@redocly/openapi-core';
|
|
27
|
+
import type { CommandArgs } from '../wrapper';
|
|
28
|
+
|
|
29
29
|
const DEFAULT_VERSION = 'latest';
|
|
30
30
|
|
|
31
31
|
export const DESTINATION_REGEX =
|
|
32
|
+
// eslint-disable-next-line no-useless-escape
|
|
32
33
|
/^(@(?<organizationId>[\w\-\s]+)\/)?(?<name>[^@]*)@(?<version>[\w\.\-]+)$/;
|
|
33
34
|
|
|
34
35
|
export type PushOptions = {
|
|
@@ -59,7 +60,7 @@ export function commonPushHandler({
|
|
|
59
60
|
return transformPush(handlePush);
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
export async function handlePush(argv
|
|
63
|
+
export async function handlePush({ argv, config }: CommandArgs<PushOptions>): Promise<void> {
|
|
63
64
|
const client = new RedoclyClient(config.region);
|
|
64
65
|
const isAuthorized = await client.isAuthorizedWithRedoclyByRegion();
|
|
65
66
|
if (!isAuthorized) {
|
|
@@ -366,16 +367,11 @@ type BarePushArgs = Omit<PushOptions, 'destination' | 'branchName'> & {
|
|
|
366
367
|
|
|
367
368
|
export const transformPush =
|
|
368
369
|
(callback: typeof handlePush) =>
|
|
369
|
-
(
|
|
370
|
-
{
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
'job-id': jobId,
|
|
375
|
-
...rest
|
|
376
|
-
}: BarePushArgs & { 'batch-id'?: string },
|
|
377
|
-
config: Config
|
|
378
|
-
) => {
|
|
370
|
+
({
|
|
371
|
+
argv: { apis, branch, 'batch-id': batchId, 'job-id': jobId, ...rest },
|
|
372
|
+
config,
|
|
373
|
+
version,
|
|
374
|
+
}: CommandArgs<BarePushArgs & { 'batch-id'?: string }>) => {
|
|
379
375
|
const [maybeApiOrDestination, maybeDestination, maybeBranchName] = apis || [];
|
|
380
376
|
|
|
381
377
|
if (batchId) {
|
|
@@ -414,16 +410,17 @@ export const transformPush =
|
|
|
414
410
|
apiFile = maybeApiOrDestination;
|
|
415
411
|
}
|
|
416
412
|
|
|
417
|
-
return callback(
|
|
418
|
-
{
|
|
413
|
+
return callback({
|
|
414
|
+
argv: {
|
|
419
415
|
...rest,
|
|
420
416
|
destination: rest.destination ?? destination,
|
|
421
417
|
api: apiFile,
|
|
422
418
|
branchName: branch ?? maybeBranchName,
|
|
423
419
|
'job-id': jobId || batchId,
|
|
424
420
|
},
|
|
425
|
-
config
|
|
426
|
-
|
|
421
|
+
config,
|
|
422
|
+
version,
|
|
423
|
+
});
|
|
427
424
|
};
|
|
428
425
|
|
|
429
426
|
export function getApiRoot({
|
|
@@ -3,6 +3,9 @@ import * as path from 'path';
|
|
|
3
3
|
import * as openapiCore from '@redocly/openapi-core';
|
|
4
4
|
import { ComponentsFiles } from '../types';
|
|
5
5
|
import { blue, green } from 'colorette';
|
|
6
|
+
import { loadConfigAndHandleErrors } from '../../../utils/__mocks__/miscellaneous';
|
|
7
|
+
|
|
8
|
+
import type { Config } from '@redocly/openapi-core';
|
|
6
9
|
|
|
7
10
|
const utils = require('../../../utils/miscellaneous');
|
|
8
11
|
|
|
@@ -25,9 +28,13 @@ describe('#split', () => {
|
|
|
25
28
|
jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
26
29
|
|
|
27
30
|
await handleSplit({
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
argv: {
|
|
32
|
+
api: filePath,
|
|
33
|
+
outDir: openapiDir,
|
|
34
|
+
separator: '_',
|
|
35
|
+
},
|
|
36
|
+
config: loadConfigAndHandleErrors() as any as Config,
|
|
37
|
+
version: 'cli-version',
|
|
31
38
|
});
|
|
32
39
|
|
|
33
40
|
expect(process.stderr.write).toBeCalledTimes(2);
|
|
@@ -46,9 +53,13 @@ describe('#split', () => {
|
|
|
46
53
|
jest.spyOn(utils, 'pathToFilename').mockImplementation(() => 'newFilePath');
|
|
47
54
|
|
|
48
55
|
await handleSplit({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
argv: {
|
|
57
|
+
api: filePath,
|
|
58
|
+
outDir: openapiDir,
|
|
59
|
+
separator: '_',
|
|
60
|
+
},
|
|
61
|
+
config: loadConfigAndHandleErrors() as any as Config,
|
|
62
|
+
version: 'cli-version',
|
|
52
63
|
});
|
|
53
64
|
|
|
54
65
|
expect(utils.pathToFilename).toBeCalledWith(expect.anything(), '_');
|
|
@@ -36,6 +36,7 @@ import type {
|
|
|
36
36
|
Oas3PathItem,
|
|
37
37
|
Referenced,
|
|
38
38
|
} from './types';
|
|
39
|
+
import type { CommandArgs } from '../../wrapper';
|
|
39
40
|
|
|
40
41
|
export type SplitOptions = {
|
|
41
42
|
api: string;
|
|
@@ -44,12 +45,13 @@ export type SplitOptions = {
|
|
|
44
45
|
config?: string;
|
|
45
46
|
};
|
|
46
47
|
|
|
47
|
-
export async function handleSplit(argv: SplitOptions) {
|
|
48
|
+
export async function handleSplit({ argv, collectSpecData }: CommandArgs<SplitOptions>) {
|
|
48
49
|
const startedAt = performance.now();
|
|
49
50
|
const { api, outDir, separator } = argv;
|
|
50
51
|
validateDefinitionFileName(api!);
|
|
51
52
|
const ext = getAndValidateFileExtension(api);
|
|
52
53
|
const openapi = readYaml(api!) as Oas3Definition | Oas3_1Definition;
|
|
54
|
+
collectSpecData?.(openapi);
|
|
53
55
|
splitDefinition(openapi, outDir, separator, ext);
|
|
54
56
|
process.stderr.write(
|
|
55
57
|
`🪓 Document: ${blue(api!)} ${green('is successfully split')}
|
|
@@ -292,7 +294,7 @@ function iteratePathItems(
|
|
|
292
294
|
|
|
293
295
|
for (const pathName of Object.keys(pathItems)) {
|
|
294
296
|
const pathFile = `${path.join(outDir, pathToFilename(pathName, pathSeparator))}.${ext}`;
|
|
295
|
-
const pathData = pathItems[pathName]
|
|
297
|
+
const pathData = pathItems[pathName];
|
|
296
298
|
|
|
297
299
|
if (isRef(pathData)) continue;
|
|
298
300
|
|
package/src/commands/stats.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { performance } from 'perf_hooks';
|
|
2
2
|
import * as colors from 'colorette';
|
|
3
3
|
import {
|
|
4
|
-
Config,
|
|
5
|
-
StyleguideConfig,
|
|
6
4
|
normalizeTypes,
|
|
7
5
|
BaseResolver,
|
|
8
6
|
resolveDocument,
|
|
@@ -13,9 +11,16 @@ import {
|
|
|
13
11
|
Stats,
|
|
14
12
|
bundle,
|
|
15
13
|
} from '@redocly/openapi-core';
|
|
16
|
-
import { getFallbackApisOrExit } from '../utils/miscellaneous';
|
|
17
|
-
|
|
18
|
-
import type {
|
|
14
|
+
import { getFallbackApisOrExit, printExecutionTime } from '../utils/miscellaneous';
|
|
15
|
+
|
|
16
|
+
import type { CommandArgs } from '../wrapper';
|
|
17
|
+
import type {
|
|
18
|
+
StatsAccumulator,
|
|
19
|
+
StatsName,
|
|
20
|
+
WalkContext,
|
|
21
|
+
OutputFormat,
|
|
22
|
+
StyleguideConfig,
|
|
23
|
+
} from '@redocly/openapi-core';
|
|
19
24
|
|
|
20
25
|
const statsAccumulator: StatsAccumulator = {
|
|
21
26
|
refs: { metric: '🚗 References', total: 0, color: 'red', items: new Set() },
|
|
@@ -24,6 +29,7 @@ const statsAccumulator: StatsAccumulator = {
|
|
|
24
29
|
parameters: { metric: '👉 Parameters', total: 0, color: 'yellow', items: new Set() },
|
|
25
30
|
links: { metric: '🔗 Links', total: 0, color: 'cyan', items: new Set() },
|
|
26
31
|
pathItems: { metric: '🔀 Path Items', total: 0, color: 'green' },
|
|
32
|
+
webhooks: { metric: '🎣 Webhooks', total: 0, color: 'green' },
|
|
27
33
|
operations: { metric: '👷 Operations', total: 0, color: 'yellow' },
|
|
28
34
|
tags: { metric: '🔖 Tags', total: 0, color: 'white', items: new Set() },
|
|
29
35
|
};
|
|
@@ -86,10 +92,11 @@ export type StatsOptions = {
|
|
|
86
92
|
config?: string;
|
|
87
93
|
};
|
|
88
94
|
|
|
89
|
-
export async function handleStats(argv
|
|
95
|
+
export async function handleStats({ argv, config, collectSpecData }: CommandArgs<StatsOptions>) {
|
|
90
96
|
const [{ path }] = await getFallbackApisOrExit(argv.api ? [argv.api] : [], config);
|
|
91
97
|
const externalRefResolver = new BaseResolver(config.resolve);
|
|
92
98
|
const { bundle: document } = await bundle({ config, ref: path });
|
|
99
|
+
collectSpecData?.(document.parsed);
|
|
93
100
|
const lintConfig: StyleguideConfig = config.styleguide;
|
|
94
101
|
const specVersion = detectSpec(document.parsed);
|
|
95
102
|
const types = normalizeTypes(
|
package/src/index.ts
CHANGED
|
@@ -3,27 +3,33 @@
|
|
|
3
3
|
import './utils/assert-node-version';
|
|
4
4
|
import * as yargs from 'yargs';
|
|
5
5
|
import * as colors from 'colorette';
|
|
6
|
-
import { outputExtensions, PushArguments, regionChoices } from './types';
|
|
7
6
|
import { RedoclyClient } from '@redocly/openapi-core';
|
|
7
|
+
import { outputExtensions, regionChoices } from './types';
|
|
8
8
|
import { previewDocs } from './commands/preview-docs';
|
|
9
9
|
import { handleStats } from './commands/stats';
|
|
10
10
|
import { handleSplit } from './commands/split';
|
|
11
11
|
import { handleJoin } from './commands/join';
|
|
12
|
-
import { handlePushStatus
|
|
12
|
+
import { handlePushStatus } from './cms/commands/push-status';
|
|
13
13
|
import { handleLint } from './commands/lint';
|
|
14
14
|
import { handleBundle } from './commands/bundle';
|
|
15
15
|
import { handleLogin } from './commands/login';
|
|
16
16
|
import { handlerBuildCommand } from './commands/build-docs';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
cacheLatestVersion,
|
|
19
|
+
notifyUpdateCliVersion,
|
|
20
|
+
version,
|
|
21
|
+
} from './utils/update-version-notifier';
|
|
18
22
|
import { commandWrapper } from './wrapper';
|
|
19
|
-
import { version } from './utils/update-version-notifier';
|
|
20
|
-
import type { Arguments } from 'yargs';
|
|
21
|
-
import type { OutputFormat, RuleSeverity } from '@redocly/openapi-core';
|
|
22
|
-
import type { BuildDocsArgv } from './commands/build-docs/types';
|
|
23
23
|
import { previewProject } from './commands/preview-project';
|
|
24
24
|
import { PRODUCT_PLANS } from './commands/preview-project/constants';
|
|
25
25
|
import { commonPushHandler } from './commands/push';
|
|
26
26
|
|
|
27
|
+
import type { Arguments } from 'yargs';
|
|
28
|
+
import type { OutputFormat, RuleSeverity } from '@redocly/openapi-core';
|
|
29
|
+
import type { BuildDocsArgv } from './commands/build-docs/types';
|
|
30
|
+
import type { PushStatusOptions } from './cms/commands/push-status';
|
|
31
|
+
import type { PushArguments } from './types';
|
|
32
|
+
|
|
27
33
|
if (!('replaceAll' in String.prototype)) {
|
|
28
34
|
require('core-js/actual/string/replace-all');
|
|
29
35
|
}
|
package/src/types.ts
CHANGED
|
@@ -9,9 +9,8 @@ import type { StatsOptions } from './commands/stats';
|
|
|
9
9
|
import type { SplitOptions } from './commands/split';
|
|
10
10
|
import type { PreviewDocsOptions } from './commands/preview-docs';
|
|
11
11
|
import type { BuildDocsArgv } from './commands/build-docs/types';
|
|
12
|
-
import type { PushOptions as PushBhOptions } from './cms/commands/push';
|
|
13
|
-
import type { PushStatusOptions } from './cms/commands/push-status';
|
|
14
12
|
import type { PushOptions as CMSPushOptions } from './cms/commands/push';
|
|
13
|
+
import type { PushStatusOptions } from './cms/commands/push-status';
|
|
15
14
|
import type { PreviewProjectOptions } from './commands/preview-project/types';
|
|
16
15
|
|
|
17
16
|
export type Totals = {
|
|
@@ -31,7 +30,7 @@ export type CommandOptions =
|
|
|
31
30
|
| SplitOptions
|
|
32
31
|
| JoinOptions
|
|
33
32
|
| PushOptions
|
|
34
|
-
|
|
|
33
|
+
| CMSPushOptions
|
|
35
34
|
| LintOptions
|
|
36
35
|
| BundleOptions
|
|
37
36
|
| LoginOptions
|
|
@@ -522,6 +522,7 @@ export function checkIfRulesetExist(rules: typeof StyleguideConfig.prototype.rul
|
|
|
522
522
|
...rules.oas3_0,
|
|
523
523
|
...rules.oas3_1,
|
|
524
524
|
...rules.async2,
|
|
525
|
+
...rules.async3,
|
|
525
526
|
...rules.arazzo,
|
|
526
527
|
};
|
|
527
528
|
|
|
@@ -540,7 +541,10 @@ export function cleanColors(input: string): string {
|
|
|
540
541
|
export async function sendTelemetry(
|
|
541
542
|
argv: Arguments | undefined,
|
|
542
543
|
exit_code: ExitCode,
|
|
543
|
-
has_config: boolean | undefined
|
|
544
|
+
has_config: boolean | undefined,
|
|
545
|
+
spec_version: string | undefined,
|
|
546
|
+
spec_keyword: string | undefined,
|
|
547
|
+
spec_full_version: string | undefined
|
|
544
548
|
): Promise<void> {
|
|
545
549
|
try {
|
|
546
550
|
if (!argv) {
|
|
@@ -568,6 +572,9 @@ export async function sendTelemetry(
|
|
|
568
572
|
environment_ci: process.env.CI,
|
|
569
573
|
raw_input: cleanRawInput(process.argv.slice(2)),
|
|
570
574
|
has_config,
|
|
575
|
+
spec_version,
|
|
576
|
+
spec_keyword,
|
|
577
|
+
spec_full_version,
|
|
571
578
|
};
|
|
572
579
|
await fetch(`https://api.redocly.com/registry/telemetry/cli`, {
|
|
573
580
|
method: 'POST',
|
|
@@ -597,6 +604,9 @@ export type Analytics = {
|
|
|
597
604
|
environment_ci?: string;
|
|
598
605
|
raw_input: string;
|
|
599
606
|
has_config?: boolean;
|
|
607
|
+
spec_version?: string;
|
|
608
|
+
spec_keyword?: string;
|
|
609
|
+
spec_full_version?: string;
|
|
600
610
|
};
|
|
601
611
|
|
|
602
612
|
function isFile(value: string) {
|
package/src/wrapper.ts
CHANGED
|
@@ -1,22 +1,48 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { detectSpec, doesYamlFileExist } from '@redocly/openapi-core';
|
|
2
|
+
import { isPlainObject } from '@redocly/openapi-core/lib/utils';
|
|
3
3
|
import { version } from './utils/update-version-notifier';
|
|
4
|
-
import {
|
|
5
|
-
ExitCode,
|
|
6
|
-
exitWithError,
|
|
7
|
-
loadConfigAndHandleErrors,
|
|
8
|
-
sendTelemetry,
|
|
9
|
-
} from './utils/miscellaneous';
|
|
4
|
+
import { exitWithError, loadConfigAndHandleErrors, sendTelemetry } from './utils/miscellaneous';
|
|
10
5
|
import { lintConfigCallback } from './commands/lint';
|
|
6
|
+
|
|
7
|
+
import type { Arguments } from 'yargs';
|
|
8
|
+
import type { Config, Region } from '@redocly/openapi-core';
|
|
9
|
+
import type { CollectFn } from '@redocly/openapi-core/lib/utils';
|
|
10
|
+
import type { ExitCode } from './utils/miscellaneous';
|
|
11
11
|
import type { CommandOptions } from './types';
|
|
12
12
|
|
|
13
|
+
export type CommandArgs<T extends CommandOptions> = {
|
|
14
|
+
argv: T;
|
|
15
|
+
config: Config;
|
|
16
|
+
version: string;
|
|
17
|
+
collectSpecData?: CollectFn;
|
|
18
|
+
};
|
|
19
|
+
|
|
13
20
|
export function commandWrapper<T extends CommandOptions>(
|
|
14
|
-
commandHandler?: (
|
|
21
|
+
commandHandler?: (wrapperArgs: CommandArgs<T>) => Promise<unknown>
|
|
15
22
|
) {
|
|
16
23
|
return async (argv: Arguments<T>) => {
|
|
17
24
|
let code: ExitCode = 2;
|
|
18
25
|
let hasConfig;
|
|
19
26
|
let telemetry;
|
|
27
|
+
let specVersion: string | undefined;
|
|
28
|
+
let specKeyword: string | undefined;
|
|
29
|
+
let specFullVersion: string | undefined;
|
|
30
|
+
const collectSpecData: CollectFn = (document) => {
|
|
31
|
+
specVersion = detectSpec(document);
|
|
32
|
+
if (!isPlainObject(document)) return;
|
|
33
|
+
specKeyword = document?.openapi
|
|
34
|
+
? 'openapi'
|
|
35
|
+
: document?.swagger
|
|
36
|
+
? 'swagger'
|
|
37
|
+
: document?.asyncapi
|
|
38
|
+
? 'asyncapi'
|
|
39
|
+
: document?.arazzo
|
|
40
|
+
? 'arazzo'
|
|
41
|
+
: undefined;
|
|
42
|
+
if (specKeyword) {
|
|
43
|
+
specFullVersion = document[specKeyword] as string;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
20
46
|
try {
|
|
21
47
|
if (argv.config && !doesYamlFileExist(argv.config)) {
|
|
22
48
|
exitWithError('Please provide a valid path to the configuration file.');
|
|
@@ -32,14 +58,14 @@ export function commandWrapper<T extends CommandOptions>(
|
|
|
32
58
|
hasConfig = !config.styleguide.recommendedFallback;
|
|
33
59
|
code = 1;
|
|
34
60
|
if (typeof commandHandler === 'function') {
|
|
35
|
-
await commandHandler(argv, config, version);
|
|
61
|
+
await commandHandler({ argv, config, version, collectSpecData });
|
|
36
62
|
}
|
|
37
63
|
code = 0;
|
|
38
64
|
} catch (err) {
|
|
39
65
|
// Do nothing
|
|
40
66
|
} finally {
|
|
41
67
|
if (process.env.REDOCLY_TELEMETRY !== 'off' && telemetry !== 'off') {
|
|
42
|
-
await sendTelemetry(argv, code, hasConfig);
|
|
68
|
+
await sendTelemetry(argv, code, hasConfig, specVersion, specKeyword, specFullVersion);
|
|
43
69
|
}
|
|
44
70
|
process.once('beforeExit', () => {
|
|
45
71
|
process.exit(code);
|