chore: export an util function from openapi-core and move update-registry rule to decorators (#268)

This commit is contained in:
Roman Hotsiy
2021-03-20 16:48:15 +02:00
committed by GitHub
parent d4d2925eac
commit 9afd200fa8
13 changed files with 96 additions and 82 deletions

View File

@@ -14,3 +14,4 @@ export const __redoclyClient = {
export const RedoclyClient = jest.fn(() => __redoclyClient); export const RedoclyClient = jest.fn(() => __redoclyClient);
export const loadConfig = jest.fn(() => ({ configFile: null })); export const loadConfig = jest.fn(() => ({ configFile: null }));
export const bundle = jest.fn(() => ({ bundle: { parsed: null }, problems: null })); export const bundle = jest.fn(() => ({ bundle: { parsed: null }, problems: null }));
export const getTotals = jest.fn(() => ({ errors: 0 }));

View File

@@ -1,30 +1,32 @@
import { bundle, formatProblems, loadConfig, OutputFormat } from '@redocly/openapi-core'; import { bundle, formatProblems, getTotals, loadConfig, OutputFormat } from '@redocly/openapi-core';
import { import {
dumpBundle, dumpBundle,
getExecutionTime, getExecutionTime,
getFallbackEntryPointsOrExit, getFallbackEntryPointsOrExit,
getOutputFileName, getOutputFileName,
getTotals, handleError, printUnusedWarnings, handleError,
printUnusedWarnings,
saveBundle, saveBundle,
} from '../utils'; } from '../utils';
import { OutputExtensions, Totals } from '../types'; import { OutputExtensions, Totals } from '../types';
import { performance } from "perf_hooks"; import { performance } from 'perf_hooks';
import { blue, gray, green, yellow } from 'colorette'; import { blue, gray, green, yellow } from 'colorette';
export async function handleBundle (argv: { export async function handleBundle(
entrypoints: string[]; argv: {
output?: string; entrypoints: string[];
ext: OutputExtensions; output?: string;
'max-problems'?: number; ext: OutputExtensions;
'skip-rule'?: string[]; 'max-problems'?: number;
'skip-preprocessor'?: string[]; 'skip-rule'?: string[];
'skip-decorator'?: string[]; 'skip-preprocessor'?: string[];
dereferenced?: boolean; 'skip-decorator'?: string[];
force?: boolean; dereferenced?: boolean;
config?: string; force?: boolean;
format: OutputFormat; config?: string;
}, format: OutputFormat;
version: string },
version: string,
) { ) {
const config = await loadConfig(argv.config); const config = await loadConfig(argv.config);
config.lint.skipRules(argv['skip-rule']); config.lint.skipRules(argv['skip-rule']);
@@ -76,11 +78,9 @@ version: string
if (fileTotals.errors > 0) { if (fileTotals.errors > 0) {
if (argv.force) { if (argv.force) {
process.stderr.write( process.stderr.write(
`❓ Created a bundle for ${blue(entrypoint)} at ${blue( `❓ Created a bundle for ${blue(entrypoint)} at ${blue(outputFile)} with errors ${green(
outputFile, elapsed,
)} with errors ${green(elapsed)}.\n${yellow( )}.\n${yellow('Errors ignored because of --force')}.\n`,
'Errors ignored because of --force',
)}.\n`,
); );
} else { } else {
process.stderr.write( process.stderr.write(
@@ -91,9 +91,7 @@ version: string
} }
} else { } else {
process.stderr.write( process.stderr.write(
`📦 Created a bundle for ${blue(entrypoint)} at ${blue(outputFile)} ${green( `📦 Created a bundle for ${blue(entrypoint)} at ${blue(outputFile)} ${green(elapsed)}.\n`,
elapsed,
)}.\n`,
); );
} }
} catch (e) { } catch (e) {

View File

@@ -12,13 +12,13 @@ import {
Oas3Tag, Oas3Tag,
loadConfig, loadConfig,
formatProblems, formatProblems,
getTotals,
lintDocument, lintDocument,
detectOpenAPI, detectOpenAPI,
} from '@redocly/openapi-core'; } from '@redocly/openapi-core';
import { import {
getFallbackEntryPointsOrExit, getFallbackEntryPointsOrExit,
getTotals,
printExecutionTime, printExecutionTime,
handleError, handleError,
printLintTotals, printLintTotals,

View File

@@ -1,28 +1,35 @@
import { Config, formatProblems, lint, loadConfig, OutputFormat } from '@redocly/openapi-core'; import {
Config,
formatProblems,
getTotals,
lint,
loadConfig,
OutputFormat,
} from '@redocly/openapi-core';
import { import {
getExecutionTime, getExecutionTime,
getFallbackEntryPointsOrExit, getFallbackEntryPointsOrExit,
getTotals,
handleError, handleError,
pluralize, pluralize,
printLintTotals, printLintTotals,
printUnusedWarnings printUnusedWarnings,
} from '../utils'; } from '../utils';
import { Totals } from '../types'; import { Totals } from '../types';
import { blue, gray } from 'colorette'; import { blue, gray } from 'colorette';
import { performance } from "perf_hooks"; import { performance } from 'perf_hooks';
export async function handleLint (argv: { export async function handleLint(
entrypoints: string[]; argv: {
'max-problems'?: number; entrypoints: string[];
'generate-ignore-file'?: boolean; 'max-problems'?: number;
'skip-rule'?: string[]; 'generate-ignore-file'?: boolean;
'skip-preprocessor'?: string[]; 'skip-rule'?: string[];
extends?: string[]; 'skip-preprocessor'?: string[];
config?: string; extends?: string[];
format: OutputFormat; config?: string;
}, format: OutputFormat;
version: string },
version: string,
) { ) {
const config: Config = await loadConfig(argv.config, argv.extends); const config: Config = await loadConfig(argv.config, argv.extends);
config.lint.skipRules(argv['skip-rule']); config.lint.skipRules(argv['skip-rule']);
@@ -35,7 +42,9 @@ export async function handleLint (argv: {
let totalIgnored = 0; let totalIgnored = 0;
if (config.lint.recommendedFallback) { if (config.lint.recommendedFallback) {
process.stderr.write( process.stderr.write(
`No configurations were defined in extends -- using built in ${blue('recommended')} configuration by default.\n\n`, `No configurations were defined in extends -- using built in ${blue(
'recommended',
)} configuration by default.\n\n`,
); );
} }
@@ -64,7 +73,7 @@ export async function handleLint (argv: {
format: argv.format, format: argv.format,
maxProblems: argv['max-problems'], maxProblems: argv['max-problems'],
totals: fileTotals, totals: fileTotals,
version version,
}); });
} }

View File

@@ -1,7 +1,7 @@
import * as colorette from 'colorette'; import * as colorette from 'colorette';
import * as chockidar from 'chokidar'; import * as chockidar from 'chokidar';
import { bundle, loadConfig, ResolveError, YamlParseError, RedoclyClient } from "@redocly/openapi-core"; import { bundle, loadConfig, ResolveError, YamlParseError, RedoclyClient, getTotals } from "@redocly/openapi-core";
import { getFallbackEntryPointsOrExit, getTotals } from '../../utils'; import { getFallbackEntryPointsOrExit } from '../../utils';
import startPreviewServer from './preview-server/preview-server'; import startPreviewServer from './preview-server/preview-server';
export async function previewDocs(argv: { export async function previewDocs(argv: {

View File

@@ -5,13 +5,12 @@ import { performance } from 'perf_hooks';
import { yellow, green, blue } from 'colorette'; import { yellow, green, blue } from 'colorette';
import { createHash } from 'crypto'; import { createHash } from 'crypto';
import { bundle, Config, loadConfig, RedoclyClient, IGNORE_FILE, BundleOutputFormat } from '@redocly/openapi-core'; import { bundle, Config, loadConfig, RedoclyClient, IGNORE_FILE, BundleOutputFormat, getTotals } from '@redocly/openapi-core';
import { import {
promptUser, promptUser,
exitWithError, exitWithError,
printExecutionTime, printExecutionTime,
getFallbackEntryPointsOrExit, getFallbackEntryPointsOrExit,
getTotals,
pluralize, pluralize,
dumpBundle, dumpBundle,
slash slash

View File

@@ -11,7 +11,6 @@ import {
BundleOutputFormat, BundleOutputFormat,
Config, Config,
LintConfig, LintConfig,
NormalizedProblem,
ResolveError, ResolveError,
YamlParseError, YamlParseError,
} from '@redocly/openapi-core'; } from '@redocly/openapi-core';
@@ -50,27 +49,6 @@ async function expandGlobsInEntrypoints(args: string[], config: Config) {
}))).flat(); }))).flat();
} }
export function getTotals(problems: (NormalizedProblem & { ignored?: boolean })[]): Totals {
let errors = 0;
let warnings = 0;
let ignored = 0;
for (const m of problems) {
if (m.ignored) {
ignored++;
continue;
}
if (m.severity === 'error') errors++;
if (m.severity === 'warn') warnings++;
}
return {
errors,
warnings,
ignored,
};
}
export function getExecutionTime(startedAt: number) { export function getExecutionTime(startedAt: number) {
return process.env.NODE_ENV === 'test' return process.env.NODE_ENV === 'test'
? '<test>ms' ? '<test>ms'

View File

@@ -7,4 +7,7 @@ export const builtInConfigs: Record<string, LintRawConfig> = {
recommended, recommended,
minimal, minimal,
all, all,
'redocly-registry': {
decorators: { 'registry-dependencies': 'on' }
}
}; };

View File

@@ -10,16 +10,17 @@ import {
red, red,
} from 'colorette'; } from 'colorette';
const coreVersion = require('../../package.json').version;
import { NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject } from '../walk'; import { NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject } from '../walk';
import { getCodeframe, getLineColLocation } from './codeframes'; import { getCodeframe, getLineColLocation } from './codeframes';
type Totals = { export type Totals = {
errors: number; errors: number;
warnings: number; warnings: number;
ignored: number; ignored: number;
} }
const ERROR_MESSAGE = { const ERROR_MESSAGE = {
INVALID_SEVERITY_LEVEL: 'Invalid severity level; accepted values: error or warn', INVALID_SEVERITY_LEVEL: 'Invalid severity level; accepted values: error or warn',
}; };
@@ -47,6 +48,27 @@ function severityToNumber(severity: ProblemSeverity) {
export type OutputFormat = 'codeframe' | 'stylish' | 'json'; export type OutputFormat = 'codeframe' | 'stylish' | 'json';
export function getTotals(problems: (NormalizedProblem & { ignored?: boolean })[]): Totals {
let errors = 0;
let warnings = 0;
let ignored = 0;
for (const m of problems) {
if (m.ignored) {
ignored++;
continue;
}
if (m.severity === 'error') errors++;
if (m.severity === 'warn') warnings++;
}
return {
errors,
warnings,
ignored,
};
}
export function formatProblems( export function formatProblems(
problems: (NormalizedProblem & { ignored?: boolean })[], problems: (NormalizedProblem & { ignored?: boolean })[],
opts: { opts: {
@@ -54,7 +76,7 @@ export function formatProblems(
cwd?: string; cwd?: string;
format?: OutputFormat; format?: OutputFormat;
color?: boolean; color?: boolean;
totals: Totals; totals: Totals
version: string; version: string;
}, },
) { ) {
@@ -63,8 +85,8 @@ export function formatProblems(
cwd = process.cwd(), cwd = process.cwd(),
format = 'codeframe', format = 'codeframe',
color = colorOptions.enabled, color = colorOptions.enabled,
totals, totals = getTotals(problems),
version version = coreVersion,
} = opts; } = opts;
colorOptions.enabled = color; // force colors if specified colorOptions.enabled = color; // force colors if specified

View File

@@ -15,6 +15,6 @@ export { detectOpenAPI, OasMajorVersion, openAPIMajor } from './lint';
export { normalizeVisitors } from './visitors'; export { normalizeVisitors } from './visitors';
export { WalkContext, walkDocument, NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject, Loc } from './walk'; export { WalkContext, walkDocument, NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject, Loc } from './walk';
export { formatProblems, OutputFormat } from './format/format'; export { formatProblems, OutputFormat, getTotals, Totals } from './format/format';
export { OasVersion, lint, lint as validate, lintDocument } from './lint'; export { OasVersion, lint, lint as validate, lintDocument } from './lint';
export { bundle } from './bundle'; export { bundle } from './bundle';

View File

@@ -1,8 +1,8 @@
import { RedoclyClient } from '../../redocly'; import { RedoclyClient } from '../../redocly';
import { Oas3Rule, Oas2Rule } from '../../visitors'; import { Oas3Decorator, Oas2Decorator } from '../../visitors';
export const RegistryDependencies: Oas3Rule | Oas2Rule = () => { export const RegistryDependencies: Oas3Decorator | Oas2Decorator = () => {
let redoclyClient: RedoclyClient; let redoclyClient: RedoclyClient;
let registryDependencies = new Set<string>(); let registryDependencies = new Set<string>();

View File

@@ -24,7 +24,7 @@ import { OperationSingularTag } from '../common/operation-singular-tag';
import { OperationSecurityDefined } from '../common/operation-security-defined'; import { OperationSecurityDefined } from '../common/operation-security-defined';
import { NoUnresolvedRefs } from '../no-unresolved-refs'; import { NoUnresolvedRefs } from '../no-unresolved-refs';
import { PathHttpVerbsOrder } from '../common/path-http-verbs-order'; import { PathHttpVerbsOrder } from '../common/path-http-verbs-order';
import { Oas2Rule } from '../../visitors'; import { Oas2Decorator, Oas2Rule } from '../../visitors';
import { RegistryDependencies } from '../common/registry-dependencies'; import { RegistryDependencies } from '../common/registry-dependencies';
import { NoIdenticalPaths } from '../common/no-identical-paths'; import { NoIdenticalPaths } from '../common/no-identical-paths';
import { OperationOperationId } from '../common/operation-operationId'; import { OperationOperationId } from '../common/operation-operationId';
@@ -69,9 +69,10 @@ export const rules = {
'path-http-verbs-order': PathHttpVerbsOrder as Oas2Rule, 'path-http-verbs-order': PathHttpVerbsOrder as Oas2Rule,
'registry-dependencies': RegistryDependencies as Oas2Rule,
spec: OasSpec as Oas2Rule, spec: OasSpec as Oas2Rule,
}; };
export const preprocessors = {}; export const preprocessors = {};
export const decorators = {}; export const decorators = {
'registry-dependencies': RegistryDependencies as Oas2Decorator,
};

View File

@@ -38,6 +38,8 @@ import { OperationOperationId } from '../common/operation-operationId';
import { OperationSummary } from '../common/operation-summary'; import { OperationSummary } from '../common/operation-summary';
import { NoAmbiguousPaths } from '../common/no-ambiguous-paths'; import { NoAmbiguousPaths } from '../common/no-ambiguous-paths';
import { Oas3Decorator } from '../../visitors';
export const rules = { export const rules = {
'info-description': InfoDescription, 'info-description': InfoDescription,
'info-contact': InfoContact, 'info-contact': InfoContact,
@@ -72,7 +74,6 @@ export const rules = {
'boolean-parameter-prefixes': BooleanParameterPrefixes, 'boolean-parameter-prefixes': BooleanParameterPrefixes,
'path-http-verbs-order': PathHttpVerbsOrder, 'path-http-verbs-order': PathHttpVerbsOrder,
'no-invalid-media-type-examples': ValidContentExamples, 'no-invalid-media-type-examples': ValidContentExamples,
'registry-dependencies': RegistryDependencies,
'no-identical-paths': NoIdenticalPaths, 'no-identical-paths': NoIdenticalPaths,
'no-ambiguous-paths': NoAmbiguousPaths, 'no-ambiguous-paths': NoAmbiguousPaths,
'no-undefined-server-variable': NoUndefinedServerVariable, 'no-undefined-server-variable': NoUndefinedServerVariable,
@@ -81,4 +82,6 @@ export const rules = {
export const preprocessors = {}; export const preprocessors = {};
export const decorators = {}; export const decorators = {
'registry-dependencies': RegistryDependencies as Oas3Decorator,
};