refactor: split in two packages: core and cli (#223)

This commit is contained in:
Andriy Leliv
2020-11-13 21:13:47 +02:00
committed by GitHub
parent 8f2dc079d7
commit 9ec79d21ea
180 changed files with 11778 additions and 3204 deletions

View File

@@ -18,7 +18,8 @@ jobs:
restore-keys: |
npm-${{ hashFiles('package-lock.json') }}
npm-
- run: npm ci
- run: npm i -g npm@7
- run: npm install
- run: npm test
deploy:
needs: test
@@ -34,8 +35,10 @@ jobs:
npm-${{ hashFiles('package-lock.json') }}
npm-
- name: Install npm@7
run: npm i -g npm@7
- name: Install dependencies
run: npm ci
run: npm install
- name: Build package
run: npm run build
@@ -68,8 +71,11 @@ jobs:
npm-${{ hashFiles('package-lock.json') }}
npm-
- name: Install npm@7
run: npm i -g npm@7
- name: Install dependencies
run: npm ci
run: npm install
- name: Build package
run: npm run build

View File

@@ -5,8 +5,16 @@ on: [push]
jobs:
build-and-unit:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: cache node modules
uses: actions/cache@v1
with:
@@ -15,5 +23,8 @@ jobs:
restore-keys: |
npm-${{ hashFiles('package-lock.json') }}
npm-
- run: npm ci
- run: npm i -g npm@7
- run: npm install
- run: npm test
env:
CI: true

4
.gitignore vendored
View File

@@ -2,12 +2,10 @@
.idea
node_modules/
nodejs/
coverage/
.vscode/
yarn.lock
dist/
lib/
*.tar.gz
*.tsbuildinfo

View File

@@ -1,6 +1,7 @@
import { readdirSync, statSync, existsSync } from 'fs';
import { spawnSync } from 'child_process';
import { join } from 'path';
//@ts-ignore
import { toMatchSpecificSnapshot, addSerializer } from './specific-snapshot';
expect.extend({
@@ -10,19 +11,18 @@ expect.extend({
});
addSerializer({
test: (val) => typeof val === 'string',
print: (v) => v as string,
test: (val: any) => typeof val === 'string',
print: (v: any) => v as string,
});
describe('E2E', () => {
const contents = readdirSync(__dirname);
for (const file of contents) {
const testPath = join(__dirname, file);
if (statSync(testPath).isFile()) continue;
if (!existsSync(join(testPath, '.redocly.yaml'))) continue;
const r = spawnSync('npx', ['ts-node', '--transpile-only', '../../src/cli.ts', 'lint'], {
const r = spawnSync('npx', ['ts-node', '--transpile-only', '../../packages/cli/src/index.ts', 'lint'], {
cwd: testPath,
env: {
...process.env,

View File

@@ -6,7 +6,6 @@ let commonSnapshotState;
function toMatchSpecificSnapshot(received, snapshotFile, ...rest) {
const absoluteSnapshotFile = getAbsolutePathToSnapshot(this.testPath, snapshotFile);
// store the common state to re-use it in "afterAll" hook.
commonSnapshotState = this.snapshotState;
let snapshotState = snapshotsStateMap.get(absoluteSnapshotFile);

13786
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,34 @@
{
"name": "@redocly/openapi-cli",
"name": "@redocly/openapi",
"version": "1.0.0-beta.18",
"description": "",
"main": "lib/index.js",
"private": true,
"engines": {
"node": ">=12.0.0"
"node": ">=15.0.0"
},
"engineStrict": true,
"scripts": {
"test": "npm run typecheck && npm run unit",
"unit": "jest ./src --coverage --coverageReporters lcov text-summary",
"e2e": "jest ./__tests__",
"cli": "ts-node src/cli.ts",
"build": "tsc -p tsconfig.build.json && cp ./src/cli/preview-server/default.hbs ./lib/cli/preview-server",
"benchmark": "node --expose-gc --noconcurrent_sweeping --predictable ./benchmark/benchmark.js",
"prettier": "npx prettier --write \"**/*.{ts,js}\"",
"unit": "jest ./packages --coverage --coverageReporters lcov text-summary",
"typecheck": "tsc --noEmit --skipLibCheck",
"prepublishOnly": "npm run build",
"bundle": "webpack --config webpack.config.ts",
"e2e": "jest ./__tests__",
"prettier": "npx prettier --write \"**/*.{ts,js}\"",
"clean": "rm -rf packages/**/lib packages/**/node_modules packages/**/*.tsbuildinfo package-lock.json node_modules",
"compile": "tsc -b tsconfig.build.json",
"prepare": "npm run compile",
"cli": "ts-node packages/cli/src/index.ts",
"lint": "npm run cli lint nodejs/resources/pets.yaml -- --format stylish",
"bundle": "npm run cli bundle nodejs/resources/pets.yaml nodejs/resources/p.yaml",
"stats": "npm run cli stats nodejs/resources/pets.yaml",
"split": "npm run cli split nodejs/resources/pets.yaml -- --outDir output",
"preview": "npm run cli preview-docs nodejs/resources/pets.yaml",
"benchmark": "node --expose-gc --noconcurrent_sweeping --predictable packages/core/src/benchmark/benchmark.js",
"webpack-bundle": "webpack --config webpack.config.ts",
"upload": "node scripts/archive-and-upload-bundle.js"
},
"bin": {
"openapi": "lib/cli.js"
},
"workspaces": [
"packages/*"
],
"repository": {
"type": "git",
"url": "https://github.com/Redocly/openapi-cli.git"
@@ -37,61 +43,37 @@
],
"contributors": [
"Sergey Dubovyk <serhii@redoc.ly> (https://redoc.ly/)",
"Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)"
"Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)",
"Andriy Leliv <andriy@redoc.ly> (https://redoc.ly/)"
],
"license": "MIT",
"devDependencies": {
"@types/jest": "^26.0.0",
"@types/js-levenshtein": "^1.1.0",
"@types/js-yaml": "^3.12.4",
"@types/lodash.isequal": "^4.5.5",
"@types/minimatch": "^3.0.3",
"@types/node-fetch": "^2.5.7",
"@types/yargs": "^15.0.5",
"jest": "^26.0.1",
"null-loader": "^4.0.0",
"outdent": "^0.7.1",
"prettier": "^2.0.5",
"shebang-loader": "0.0.1",
"ts-jest": "^26.1.0",
"ts-loader": "^8.0.2",
"ts-node": "^8.10.2",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
},
"dependencies": {
"@redocly/ajv": "^6.12.3",
"@types/node": "^14.0.13",
"chokidar": "^3.4.0",
"colorette": "^1.2.0",
"glob": "^7.1.6",
"glob-promise": "^3.4.0",
"handlebars": "^4.7.6",
"js-levenshtein": "^1.1.6",
"js-yaml": "^3.14.0",
"lodash.isequal": "^4.5.0",
"minimatch": "^3.0.4",
"node-fetch": "^2.6.1",
"portfinder": "^1.0.26",
"readline": "^1.3.0",
"simple-websocket": "^9.0.0",
"typescript": "^3.9.5",
"yaml-ast-parser": "0.0.43",
"yargs": "^15.3.1"
},
"prettier": {
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100
},
"devDependencies": {
"@types/jest": "^26.0.15",
"jest": "^26.6.3",
"null-loader": "^4.0.0",
"outdent": "^0.7.1",
"prettier": "^2.1.2",
"shebang-loader": "0.0.1",
"ts-jest": "^26.4.4",
"ts-loader": "^8.0.2",
"ts-node": "^9.0.0",
"typescript": "4.0.5",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
},
"jest": {
"preset": "ts-jest",
"collectCoverageFrom": [
"src/**/*.ts",
"!src/**/__tests__/**/*",
"!src/cli.ts",
"!src/cli/**/*.ts",
"!src/format/format.ts"
"packages/**/*.ts",
"!packages/**/__tests__/**/*",
"!packages/cli/src/index.ts",
"!packages/cli/**/*.ts",
"!packages/cli/src/format/format.ts"
],
"testMatch": [
"**/__tests__/**/*.test.ts",

3
packages/cli/bin/cli.js Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env node
require("../lib/index");

29
packages/cli/package.json Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "@redocly/openapi-cli",
"version": "1.0.0-beta.18",
"description": "",
"license": "MIT",
"bin": {
"openapi-cli": "bin/cli.js"
},
"scripts": {
"compile": "tsc"
},
"dependencies": {
"@redocly/openapi-core": "^1.0.0-beta.18",
"@types/node": "^14.11.8",
"yargs": "^15.3.1",
"colorette": "^1.2.0",
"chokidar": "^3.4.0",
"handlebars": "^4.7.6",
"portfinder": "^1.0.26",
"readline": "^1.3.0",
"simple-websocket": "^9.0.0",
"glob": "^7.1.6",
"glob-promise": "^3.4.0"
},
"devDependencies": {
"@types/yargs": "^15.0.5",
"typescript": "^4.0.3"
}
}

View File

@@ -1,12 +1,8 @@
import * as colorette from 'colorette';
import * as chockidar from 'chokidar';
import { loadConfig } from '../config/config';
import { bundle } from '../bundle';
import { getFallbackEntryPointsOrExit, getTotals } from '../cli';
import { bundle, loadConfig, ResolveError, YamlParseError, RedoclyClient } from "@redocly/openapi-core";
import { getFallbackEntryPointsOrExit, getTotals } from '../../utils';
import startPreviewServer from './preview-server/preview-server';
import { RedoclyClient } from '../redocly';
import { ResolveError, YamlParseError } from '../resolve';
export async function previewDocs(argv: {
port: number;
@@ -39,7 +35,6 @@ export async function previewDocs(argv: {
ref: entrypoint,
config,
});
const removed = [...deps].filter((x) => !fileDependencies.has(x));
watcher.unwatch(removed);
watcher.add([...fileDependencies]);

View File

@@ -1,8 +1,6 @@
// import { watch } from 'chokidar';
import { compile } from 'handlebars';
import * as colorette from 'colorette';
import * as portfinder from 'portfinder';
import { readFileSync, promises as fsPromises } from 'fs';
import * as path from 'path';

View File

@@ -1,14 +1,15 @@
import { printExecutionTime, readYaml, writeYaml } from '../../utils';
import { red, blue, yellow, green } from 'colorette';
import * as fs from 'fs';
import * as yaml from 'js-yaml';
import * as path from 'path';
import { performance } from 'perf_hooks';
const isEqual = require('lodash.isequal');
import { pathToFilename } from '../../ref-utils';
import { printExecutionTime, pathToFilename, readYaml, writeYaml } from '../../utils';
import { isString, isObject, isEmptyObject } from '../../js-utils';
import {
Definition,
Oas2Definition,
Oas3Schema,
Oas3Definition,
Oas3Components,
Oas3ComponentName,
@@ -22,8 +23,6 @@ import {
OPENAPI3_METHOD_NAMES,
OPENAPI3_COMPONENT_NAMES
} from './types'
import { performance } from 'perf_hooks';
import { Oas3Schema } from '../../typings/openapi';
export async function handleSplit (argv: {
entrypoint?: string;

View File

@@ -1,12 +1,13 @@
import {
Oas3Schema,
Oas3Definition,
Oas3Components,
Oas3PathItem,
Oas3Paths,
Oas3ComponentName,
} from '../../typings/openapi';
import { Oas2Definition } from '../../typings/swagger';
export { Oas3Definition, Oas2Definition, Oas3Components, Oas3Paths, Oas3PathItem, Oas3ComponentName }
Oas2Definition
} from "@redocly/openapi-core";
export { Oas3Definition, Oas2Definition, Oas3Components, Oas3Paths, Oas3PathItem, Oas3ComponentName, Oas3Schema }
export type Definition = Oas3Definition | Oas2Definition;
export interface ComponentsFiles {
[schemas: string]: any;

View File

@@ -1,17 +1,28 @@
import { performance } from 'perf_hooks';
import * as colors from 'colorette';
import { Config, LintConfig, loadConfig } from '..';
import { normalizeTypes } from '../types';
import { Oas3Types } from '../types/oas3';
import { Oas2Types } from '../types/oas2';
import { StatsAccumulator, StatsName } from '../typings/common';
import { BaseResolver, Document, resolveDocument } from '../resolve';
import { detectOpenAPI, OasMajorVersion, openAPIMajor } from '../validate';
import { normalizeVisitors } from '../visitors';
import { WalkContext, walkDocument } from '../walk';
import { getFallbackEntryPointsOrExit } from '../cli';
import {
Config,
LintConfig,
loadConfig,
normalizeTypes,
Oas3Types,
Oas2Types,
StatsAccumulator,
StatsName,
BaseResolver,
Document,
resolveDocument,
detectOpenAPI,
OasMajorVersion,
openAPIMajor,
normalizeVisitors,
WalkContext,
walkDocument,
Stats
} from "@redocly/openapi-core";
import { getFallbackEntryPointsOrExit } from '../utils'
import { printExecutionTime } from '../utils';
import { Stats } from '../rules/other/stats';
const statsAccumulator: StatsAccumulator = {
refs: { metric: '🚗 References', total: 0, color: 'red', items: new Set() },

View File

@@ -1,32 +1,39 @@
#!/usr/bin/env node
import * as yargs from 'yargs';
import { extname, basename, dirname, join, resolve } from 'path';
import { extname, basename, dirname, join } from 'path';
import { red, green, yellow, blue, gray } from 'colorette';
import { performance } from 'perf_hooks';
import * as glob from 'glob-promise';
import { validate } from './validate';
import { bundle } from './bundle';
import { Totals } from './types';
import {
BundleOutputFormat,
validate,
bundle,
loadConfig,
LintConfig,
ResolveError,
YamlParseError,
RedoclyClient,
formatProblems,
OutputFormat,
} from "@redocly/openapi-core";
import {
CircularJSONNotSupportedError,
getFallbackEntryPointsOrExit,
getExecutionTime,
getTotals,
dumpBundle,
saveBundle,
BundleOutputFormat,
promptUser,
CircularJSONNotSupportedError,
getExecutionTime,
} from './utils';
import { formatProblems, OutputFormat } from './format/format';
import { ResolveError, YamlParseError } from './resolve';
import { loadConfig, Config, LintConfig } from './config/config';
import { NormalizedProblem } from './walk';
import { previewDocs } from './cli/preview-docs';
import { handleStats } from './cli/stats';
import { handleSplit } from './cli/split';
import { RedoclyClient } from './redocly';
import { previewDocs } from './commands/preview-docs';
import { handleStats } from './commands/stats';
import { handleSplit } from './commands/split';
const version = require('../package.json').version;
const outputExtensions = ['json', 'yaml', 'yml'] as ReadonlyArray<BundleOutputFormat>;
const ERROR_MESSAGE = {
MISSING_ARGUMENT: 'error: missing required argument `entrypoints`.\n'
}
yargs
.version('version', 'Show version number.', version)
@@ -410,7 +417,8 @@ function handleError(e: Error, ref: string) {
`Failed to parse entrypoint definition at ${ref}:\n\n - ${e.message}.\n\n`,
);
// TODO: codeframe
} else if (e instanceof CircularJSONNotSupportedError) {
} else { // @ts-ignore
if (e instanceof CircularJSONNotSupportedError) {
process.stderr.write(
red(`Detected circular reference which can't be converted to JSON.\n`) +
`Try to use ${blue('yaml')} output or remove ${blue('--dereferenced')}.\n\n`,
@@ -420,6 +428,7 @@ function handleError(e: Error, ref: string) {
throw e;
}
}
}
function printLintTotals(totals: Totals, definitionsCount: number) {
const ignored = totals.ignored
@@ -463,33 +472,6 @@ function printLintTotals(totals: Totals, definitionsCount: number) {
process.stderr.write('\n');
}
export type Totals = {
errors: number;
warnings: number;
ignored: number;
};
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,
};
}
function pluralize(label: string, num: number) {
if (label.endsWith('is')) {
[label] = label.split(' ');
@@ -498,40 +480,6 @@ function pluralize(label: string, num: number) {
return num === 1 ? `${label}` : `${label}s`;
}
function getConfigDirectory(config: Config) {
return config.configFile ? dirname(config.configFile) : process.cwd();
}
function getAliasOrPath(config: Config, aliasOrPath: string) {
return config.apiDefinitions[aliasOrPath] || aliasOrPath;
}
function isNotEmptyArray(args?: string[]): boolean {
return Array.isArray(args) && !!args.length;
}
async function expandGlobsInEntrypoints(args: string[], config: Config) {
return (await Promise.all((args as string[]).map(async aliasOrPath => {
return glob.hasMagic(aliasOrPath)
? (await glob(aliasOrPath)).map((g: string) => getAliasOrPath(config, g))
: getAliasOrPath(config, aliasOrPath);
}))).flat();
}
export async function getFallbackEntryPointsOrExit(argsEntrypoints: string[] | undefined, config: Config) {
const { apiDefinitions } = config;
const shouldFallbackToAllDefinitions = !isNotEmptyArray(argsEntrypoints) && apiDefinitions && Object.keys(apiDefinitions).length > 0;
const res = shouldFallbackToAllDefinitions
? Object.values(apiDefinitions).map((fileName) => resolve(getConfigDirectory(config), fileName))
: await expandGlobsInEntrypoints(argsEntrypoints!, config);
if (!isNotEmptyArray(res)) {
process.stderr.write(ERROR_MESSAGE.MISSING_ARGUMENT);
process.exit(1);
}
return res;
}
function printUnusedWarnings(config: LintConfig) {
const { preprocessors, rules, decorators } = config.getUnusedRules();
if (rules.length) {

View File

@@ -0,0 +1,5 @@
export type Totals = {
errors: number;
warnings: number;
ignored: number;
}

135
packages/cli/src/utils.ts Normal file
View File

@@ -0,0 +1,135 @@
import { performance } from "perf_hooks";
import * as colors from 'colorette';
import * as glob from 'glob-promise';
import * as yaml from 'js-yaml';
import * as fs from 'fs';
import * as path from 'path';
import * as readline from 'readline';
import { BundleOutputFormat, Config, NormalizedProblem } from "@redocly/openapi-core";
import { dirname, resolve } from 'path';
import { Totals } from './types';
export async function getFallbackEntryPointsOrExit(argsEntrypoints: string[] | undefined, config: Config) {
const { apiDefinitions } = config;
const shouldFallbackToAllDefinitions = !isNotEmptyArray(argsEntrypoints) && apiDefinitions && Object.keys(apiDefinitions).length > 0;
const res = shouldFallbackToAllDefinitions
? Object.values(apiDefinitions).map((fileName) => resolve(getConfigDirectory(config), fileName))
: await expandGlobsInEntrypoints(argsEntrypoints!, config);
if (!isNotEmptyArray(res)) {
process.stderr.write('error: missing required argument `entrypoints`.\n');
process.exit(1);
}
return res;
}
function getConfigDirectory(config: Config) {
return config.configFile ? dirname(config.configFile) : process.cwd();
}
function isNotEmptyArray(args?: string[]): boolean {
return Array.isArray(args) && !!args.length;
}
function getAliasOrPath(config: Config, aliasOrPath: string) {
return config.apiDefinitions[aliasOrPath] || aliasOrPath;
}
async function expandGlobsInEntrypoints(args: string[], config: Config) {
return (await Promise.all((args as string[]).map(async aliasOrPath => {
return glob.hasMagic(aliasOrPath)
? (await glob(aliasOrPath)).map((g: string) => getAliasOrPath(config, g))
: getAliasOrPath(config, aliasOrPath);
}))).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) {
return process.env.NODE_ENV === 'test'
? '<test>ms'
: `${Math.ceil(performance.now() - startedAt)}ms`;
}
export function printExecutionTime(commandName: string, startedAt: number, entrypoint: string) {
const elapsed = getExecutionTime(startedAt);
process.stderr.write(colors.gray(`\n${entrypoint}: ${commandName} processed in ${elapsed}\n\n`));
}
export function pathToFilename(path: string) {
return path
.replace(/~1/g, '/')
.replace(/~0/g, '~')
.substring(1)
.replace(/\//g, '@');
}
export class CircularJSONNotSupportedError extends Error {
constructor(public originalError: Error) {
super(originalError.message);
// Set the prototype explicitly.
Object.setPrototypeOf(this, CircularJSONNotSupportedError.prototype);
}
}
export function dumpBundle(obj: any, format: BundleOutputFormat, dereference?: boolean) {
if (format === 'json') {
try {
return JSON.stringify(obj, null, 2);
} catch (e) {
if (e.message.indexOf('circular') > -1) {
throw new CircularJSONNotSupportedError(e);
}
throw e;
}
} else {
return yaml.safeDump(obj, {
noRefs: !dereference,
});
}
}
export function saveBundle(filename: string, output: string) {
fs.mkdirSync(path.dirname(filename), { recursive: true });
fs.writeFileSync(filename, output);
}
export async function promptUser(query: string): Promise<string> {
return new Promise((resolve) => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question(`${query}:\n\n `, (answer) => {
rl.close();
resolve(answer);
});
});
}
export function readYaml(filename: string) {
return yaml.safeLoad(fs.readFileSync(filename, 'utf-8'), { filename });
}
export function writeYaml(data: any, filename: string) {
return fs.writeFileSync(filename, yaml.safeDump(data));
}

View File

@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "lib"
},
"references": [{ "path": "../core" }],
"exclude": ["lib"]
}

View File

@@ -1,11 +1,11 @@
import outdent from 'outdent';
import * as path from 'path';
import { bundleDocument, bundle } from '../bundle';
import { bundleDocument, bundle } from '../src/bundle';
import { parseYamlToDocument, yamlSerializer } from './utils';
import { LintConfig, Config } from '../config/config';
import { BaseResolver } from '../resolve';
import { LintConfig, Config } from '../src/config/config';
import { BaseResolver } from '../src/resolve';
describe('bundle', () => {
expect.addSnapshotSerializer(yamlSerializer);

View File

@@ -1,8 +1,8 @@
import { outdent } from 'outdent';
import { getLineColLocation, getCodeframe } from '../format/codeframes';
import { LocationObject } from '../walk';
import { Source } from '../resolve';
import { getLineColLocation, getCodeframe } from '../src/format/codeframes';
import { LocationObject } from '../src/walk';
import { Source } from '../src/resolve';
describe('Location', () => {
it('should correctly calculate location for key', () => {
@@ -20,7 +20,6 @@ describe('Location', () => {
`,
),
};
const preciseLocation = getLineColLocation(loc);
expect(preciseLocation.start).toEqual({ line: 3, col: 3 });
expect(preciseLocation.end).toEqual({ line: 3, col: 10 });
@@ -41,7 +40,6 @@ describe('Location', () => {
`,
),
};
const preciseLocation = getLineColLocation(loc);
expect(preciseLocation.start).toEqual({ line: 2, col: 1 });
expect(preciseLocation.end).toEqual({ line: 2, col: 5 });
@@ -62,7 +60,6 @@ describe('Location', () => {
`,
),
};
const preciseLocation = getLineColLocation(loc);
expect(preciseLocation.start).toEqual({ line: 4, col: 11 });
expect(preciseLocation.end).toEqual({ line: 4, col: 14 });
@@ -83,7 +80,6 @@ describe('Location', () => {
`,
),
};
const preciseLocation = getLineColLocation(loc);
expect(preciseLocation.start).toEqual({ line: 3, col: 3 });
expect(preciseLocation.end).toEqual({ line: 5, col: 28 });
@@ -95,7 +91,6 @@ describe('Location', () => {
pointer: '#/info/missing',
source: new Source('foobar.yaml', ''),
};
const preciseLocation = getLineColLocation(loc);
expect(preciseLocation.start).toEqual({ line: 1, col: 1 });
expect(preciseLocation.end).toEqual({ line: 1, col: 1 });
@@ -107,7 +102,6 @@ describe('Location', () => {
pointer: '#/info/missing',
source: new Source('foobar.yaml', '\n\n\n'),
};
const preciseLocation = getLineColLocation(loc);
expect(preciseLocation.start).toEqual({ line: 1, col: 1 });
expect(preciseLocation.end).toEqual({ line: 1, col: 1 });

View File

@@ -1,7 +1,7 @@
import { normalizeVisitors, VisitorLevelContext } from '../visitors';
import { Oas3RuleSet } from '../validate';
import { Oas3Types } from '../types/oas3';
import { normalizeTypes } from '../types';
import { normalizeVisitors, VisitorLevelContext } from '../src/visitors';
import { Oas3RuleSet } from '../src/validate';
import { Oas3Types } from '../src/types/oas3';
import { normalizeTypes } from '../src/types';
describe('Normalize visitors', () => {
it('should work correctly for single rule', () => {

View File

@@ -1,10 +1,10 @@
import outdent from 'outdent';
import { parseYamlToDocument } from './utils';
import { parseRef } from '../ref-utils';
import { validateDocument } from '../validate';
import { LintConfig } from '../config/config';
import { BaseResolver } from '../resolve';
import { parseRef } from '../src/ref-utils';
import { validateDocument } from '../src/validate';
import { LintConfig } from '../src/config/config';
import { BaseResolver } from '../src/resolve';
describe('ref-utils', () => {
it(`should unescape refs with '/'`, () => {

View File

@@ -1,9 +1,9 @@
import { outdent } from 'outdent';
import { resolveDocument, BaseResolver } from '../resolve';
import { resolveDocument, BaseResolver } from '../src/resolve';
import { parseYamlToDocument } from './utils';
import { Oas3Types } from '../types/oas3';
import { normalizeTypes } from '../types';
import { Oas3Types } from '../src/types/oas3';
import { normalizeTypes } from '../src/types';
describe('Resolve http-headers', () => {
it('should use matching http-headers', async () => {

View File

@@ -1,10 +1,10 @@
import { outdent } from 'outdent';
import * as path from 'path';
import { resolveDocument, BaseResolver, Document } from '../resolve';
import { resolveDocument, BaseResolver, Document } from '../src/resolve';
import { parseYamlToDocument } from './utils';
import { Oas3Types } from '../types/oas3';
import { normalizeTypes } from '../types';
import { Oas3Types } from '../src/types/oas3';
import { normalizeTypes } from '../src/types';
describe('collect refs', () => {
it('should resolve local refs', async () => {
@@ -32,9 +32,9 @@ describe('collect refs', () => {
expect(Array.from(resolvedRefs.keys())).toMatchInlineSnapshot(
[`foobar.yaml::#/defs/info`],
`
Object {
"0": "foobar.yaml::#/defs/info",
}
Array [
"foobar.yaml::#/defs/info",
]
`,
);
expect(Array.from(resolvedRefs.values()).map((info) => info.node)).toEqual([

View File

@@ -1,10 +1,10 @@
import * as yaml from 'js-yaml';
import * as path from 'path';
import { Document, Source } from '../resolve';
import { NormalizedProblem } from '../walk';
import { RuleConfig, LintConfig, Plugin } from '../config/config';
import { Oas3RuleSet } from '../validate';
import { Document, Source } from '../src/resolve';
import { NormalizedProblem } from '../src/walk';
import { RuleConfig, LintConfig, Plugin } from '../src/config/config';
import { Oas3RuleSet } from '../src/validate';
export function parseYamlToDocument(body: string, absoluteRef: string = ''): Document {
return {

View File

@@ -1,11 +1,11 @@
import outdent from 'outdent';
import * as path from 'path';
import { validateDocument, Oas3RuleSet } from '../validate';
import { validateDocument, Oas3RuleSet } from '../src/validate';
import { parseYamlToDocument, replaceSourceWithRef, makeConfigForRuleset } from './utils';
import { BaseResolver, Document } from '../resolve';
import { listOf } from '../types';
import { BaseResolver, Document } from '../src/resolve';
import { listOf } from '../src/types';
describe('walk order', () => {
it('should run visitors', async () => {

View File

@@ -0,0 +1,26 @@
{
"name": "@redocly/openapi-core",
"version": "1.0.0-beta.18",
"description": "",
"main": "lib/index.js",
"license": "MIT",
"dependencies": {
"@types/node": "^14.11.8",
"colorette": "^1.2.0",
"js-yaml": "^3.14.0",
"yaml-ast-parser": "0.0.43",
"minimatch": "^3.0.4",
"node-fetch": "^2.6.1",
"js-levenshtein": "^1.1.6",
"@redocly/ajv": "^6.12.3",
"lodash.isequal": "^4.5.0"
},
"devDependencies": {
"@types/js-yaml": "^3.12.4",
"@types/minimatch": "^3.0.3",
"@types/node-fetch": "^2.5.7",
"@types/js-levenshtein": "^1.1.0",
"@types/lodash.isequal": "^4.5.5",
"typescript": "^4.0.5"
}
}

View File

@@ -1,15 +1,12 @@
import { readFileSync } from 'fs';
import { join as pathJoin, resolve as pathResolve } from 'path';
import { validateDocument } from '../../src/validate';
import { parseYamlToDocument } from '../../src/__tests__/utils';
import { LintConfig } from '../../src/config/config';
import { BaseResolver } from '../../src/resolve';
import { validateDocument } from '../../validate';
import { LintConfig } from '../../config/config';
import { BaseResolver } from '../../resolve';
import { parseYamlToDocument } from '../utils';
export const name = 'Validate with recommended rules';
export const count = 10;
const rebillyDefinitionRef = pathResolve(pathJoin(__dirname, 'rebilly.yaml'));
const rebillyDocument = parseYamlToDocument(
readFileSync(rebillyDefinitionRef, 'utf-8'),

View File

@@ -1,14 +1,12 @@
import * as path from 'path';
import { readFileSync } from 'fs';
import { resolveDocument, BaseResolver } from '../../src/resolve';
import { parseYamlToDocument } from '../../src/__tests__/utils';
import { Oas3Types } from '../../src/types/oas3';
import { normalizeTypes } from '../../src/types';
import { resolveDocument, BaseResolver } from '../../resolve';
import { parseYamlToDocument } from '../utils';
import { Oas3Types } from '../../types/oas3';
import { normalizeTypes } from '../../types';
export const name = 'Resolve with no external refs';
export const count = 10;
const rebillyDefinitionRef = path.resolve(path.join(__dirname, 'rebilly.yaml'));
const rebillyDocument = parseYamlToDocument(
readFileSync(rebillyDefinitionRef, 'utf-8'),

View File

@@ -1,13 +1,11 @@
import { readFileSync } from 'fs';
import { join as pathJoin, resolve as pathResolve } from 'path';
import { validateDocument } from '../../src/validate';
import { parseYamlToDocument, makeConfigForRuleset } from '../../src/__tests__/utils';
import { BaseResolver } from '../../src/resolve';
import { validateDocument } from '../../validate';
import { BaseResolver } from '../../resolve';
import { parseYamlToDocument, makeConfigForRuleset } from '../utils';
export const name = 'Validate with 50 top-level rules';
export const count = 10;
const rebillyDefinitionRef = pathResolve(pathJoin(__dirname, 'rebilly.yaml'));
const rebillyDocument = parseYamlToDocument(
readFileSync(rebillyDefinitionRef, 'utf-8'),
@@ -28,7 +26,6 @@ for (let i = 0; i < 50; i++) {
}
const config = makeConfigForRuleset(ruleset);
export function measureAsync() {
return validateDocument({
externalRefResolver: new BaseResolver(),

View File

@@ -1,19 +1,16 @@
import { readFileSync } from 'fs';
import { join as pathJoin, resolve as pathResolve } from 'path';
import { validateDocument } from '../../src/validate';
import { parseYamlToDocument, makeConfigForRuleset } from '../../src/__tests__/utils';
import { BaseResolver } from '../../src/resolve';
import { validateDocument } from '../../validate';
import { BaseResolver } from '../../resolve';
import { parseYamlToDocument, makeConfigForRuleset } from '../utils';
export const name = 'Validate with single nested rule';
export const count = 10;
const rebillyDefinitionRef = pathResolve(pathJoin(__dirname, 'rebilly.yaml'));
const rebillyDocument = parseYamlToDocument(
readFileSync(rebillyDefinitionRef, 'utf-8'),
rebillyDefinitionRef,
);
const visitor = {
test: () => {
let count = 0;
@@ -32,9 +29,7 @@ const visitor = {
};
},
};
const config = makeConfigForRuleset(visitor);
export function measureAsync() {
return validateDocument({
externalRefResolver: new BaseResolver(),

View File

@@ -1,21 +1,16 @@
import { readFileSync } from 'fs';
import { join as pathJoin, resolve as pathResolve } from 'path';
import { validateDocument } from '../../src/validate';
import { parseYamlToDocument, makeConfigForRuleset } from '../../src/__tests__/utils';
import { BaseResolver } from '../../src/resolve';
import { validateDocument } from '../../validate';
import { BaseResolver } from '../../resolve';
import { parseYamlToDocument, makeConfigForRuleset } from '../utils';
export const name = 'Validate with no rules';
export const count = 10;
const rebillyDefinitionRef = pathResolve(pathJoin(__dirname, 'rebilly.yaml'));
const rebillyDocument = parseYamlToDocument(
readFileSync(rebillyDefinitionRef, 'utf-8'),
rebillyDefinitionRef,
);
const config = makeConfigForRuleset({});
export function measureAsync() {
return validateDocument({
externalRefResolver: new BaseResolver(),

View File

@@ -1,13 +1,11 @@
import { readFileSync } from 'fs';
import { join as pathJoin, resolve as pathResolve } from 'path';
import { validateDocument } from '../../src/validate';
import { parseYamlToDocument, makeConfigForRuleset } from '../../src/__tests__/utils';
import { BaseResolver } from '../../src/resolve';
import { validateDocument } from '../../validate';
import { BaseResolver } from '../../resolve';
import { parseYamlToDocument, makeConfigForRuleset } from '../utils';
export const name = 'Validate with single top-level rule and report';
export const count = 10;
const rebillyDefinitionRef = pathResolve(pathJoin(__dirname, 'rebilly.yaml'));
const rebillyDocument = parseYamlToDocument(
readFileSync(rebillyDefinitionRef, 'utf-8'),
@@ -17,6 +15,7 @@ const rebillyDocument = parseYamlToDocument(
const config = makeConfigForRuleset({
test: () => {
return {
// @ts-ignore
Schema(schema, ctx) {
if (schema.type === 'number') {
ctx.report({

View File

@@ -1,13 +1,10 @@
import { readFileSync } from 'fs';
import { join as pathJoin, resolve as pathResolve } from 'path';
import { validateDocument } from '../../src/validate';
import { parseYamlToDocument, makeConfigForRuleset } from '../../src/__tests__/utils';
import { BaseResolver } from '../../src/resolve';
import { validateDocument } from '../../validate';
import { BaseResolver } from '../../resolve';
import { parseYamlToDocument, makeConfigForRuleset } from '../utils';
export const name = 'Validate with single top-level rule';
export const count = 10;
const rebillyDefinitionRef = pathResolve(pathJoin(__dirname, 'rebilly.yaml'));
const rebillyDocument = parseYamlToDocument(
readFileSync(rebillyDefinitionRef, 'utf-8'),

View File

@@ -1,14 +1,11 @@
'use strict';
const os = require('os');
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const { execSync } = require('child_process');
const { red, green, yellow, cyan, grey } = require('./colors');
const { sampleModule } = require('./fork');
const NS_PER_SEC = 1e9;
const LOCAL = 'local';
@@ -27,37 +24,32 @@ function prepareRevision(revision) {
console.log(`🍳 Preparing ${revision}...`);
if (revision === LOCAL) {
return tscBuild(LOCAL_DIR());
return tscBuild(path.join(LOCAL_DIR(), '../../..'));
}
// Returns the complete git hash for a given git revision reference.
const hash = exec(`git rev-parse "${revision}"`);
const dir = path.join(os.tmpdir(), 'openapi-cli-benchmark', hash);
fs.rmdirSync(dir, { recursive: true });
fs.mkdirSync(dir, { recursive: true });
exec(`git archive "${hash}" | tar -xC "${dir}"`);
exec('npm ci', { cwd: dir });
const to = path.join(dir, 'benchmark/benches');
const to = path.join(dir, 'packages/core/src/benchmark/benches');
exec(`rm -rf ${to}`);
exec(`cp -R ${LOCAL_DIR('benchmark/benches')} ${to}`);
return tscBuild(dir);
}
function tscBuild(dir) {
const oldCwd = process.cwd();
process.chdir(dir);
execSync('rm -rf dist && npx tsc', { stdio: 'inherit' });
execSync('npm run compile', { stdio: 'inherit' });
exec(
`cp ${path.join(dir, 'benchmark/benches/*.yaml')} ${path.join(dir, 'lib/benchmark/benches/')}`,
`cp ${path.join(dir, 'packages/core/src/benchmark/benches/*.yaml')} ${path.join(dir, 'packages/core/lib/benchmark/benches/')}`,
);
process.chdir(oldCwd);
return path.join(dir, 'lib/benchmark/benches');
return path.join(dir, 'packages/core/lib/benchmark/benches');
}
async function collectSamples(modulePath) {
@@ -258,10 +250,10 @@ function exec(command, options) {
// Find all benchmark tests to be run.
function matchBenchmarks(patterns) {
let benchmarks = findFiles(LOCAL_DIR('lib/benchmark/benches'), '*.bench.js');
let benchmarks = findFiles(LOCAL_DIR('../lib/benchmark/benches'), '*.bench.js');
if (patterns.length > 0) {
benchmarks = benchmarks.filter((benchmark) =>
patterns.some((pattern) => path.join('benchmark/benches', benchmark).includes(pattern)),
patterns.some((pattern) => path.join('../lib/benchmark/benches', benchmark).includes(pattern)),
);
}

View File

@@ -0,0 +1,31 @@
import * as yaml from 'js-yaml';
import { Document, Source } from '../resolve';
import { Oas3RuleSet } from '../validate';
import { RuleConfig, LintConfig, Plugin } from '../config/config';
export function parseYamlToDocument(body: string, absoluteRef: string = ''): Document {
return {
source: new Source(absoluteRef, body),
parsed: yaml.safeLoad(body, { filename: absoluteRef }),
};
}
export function makeConfigForRuleset(rules: Oas3RuleSet, plugin?: Partial<Plugin>) {
const rulesConf: Record<string, RuleConfig> = {};
const ruleId = 'test';
Object.keys(rules).forEach((name) => {
rulesConf[`${ruleId}/${name}`] = 'error';
});
return new LintConfig({
plugins: [
{
...plugin,
id: ruleId,
rules: { oas3: rules },
},
],
extends: [],
rules: rulesConf,
});
}

View File

@@ -1,7 +1,5 @@
import isEqual = require('lodash.isequal');
import { BaseResolver, resolveDocument, Document } from './resolve';
import { Oas3Rule, normalizeVisitors, Oas3Visitor, Oas2Visitor } from './visitors';
import { Oas3Types } from './types/oas3';
import { Oas2Types } from './types/oas2';

View File

@@ -6,10 +6,8 @@ export default {
'info-contact': 'error',
'info-license': 'error',
'info-license-url': 'error',
'tag-description': 'error',
'tags-alphabetical': 'error',
'parameter-description': 'error',
'no-identical-paths': 'error',
'no-ambiguous-paths': 'error',
@@ -27,17 +25,14 @@ export default {
'operation-tag-defined': 'error',
'operation-security-defined': 'error',
'operation-singular-tag': 'error',
'no-unresolved-refs': 'error',
'no-enum-type-mismatch': 'error',
'boolean-parameter-prefixes': 'error',
'paths-kebab-case': 'error',
spec: 'error',
},
oas3_0Rules: {
'no-invalid-media-type-examples': 'error',
'no-server-example.com': 'error',
'no-server-trailing-slash': 'error',
'no-empty-servers': 'error',

View File

@@ -3,7 +3,6 @@ import * as path from 'path';
import * as yaml from 'js-yaml';
import { dirname } from 'path';
import { red, blue } from 'colorette';
import { builtInConfigs } from './builtIn';
import * as builtinRules from '../rules/builtin';
import { loadYaml, notUndefined } from '../utils';

View File

@@ -6,10 +6,8 @@ export default {
'info-contact': 'off',
'info-license': 'off',
'info-license-url': 'off',
'tag-description': 'warn',
'tags-alphabetical': 'off',
'parameter-description': 'off',
'no-path-trailing-slash': 'warn',
'no-identical-paths': 'warn',
@@ -27,10 +25,8 @@ export default {
'operation-security-defined': 'warn',
'operation-operationId-url-safe': 'warn',
'operation-singular-tag': 'off',
'no-unresolved-refs': 'error',
'no-enum-type-mismatch': 'warn',
'boolean-parameter-prefixes': 'off',
'paths-kebab-case': 'off',
spec: 'error',
@@ -40,7 +36,6 @@ export default {
severity: 'warn',
disallowAdditionalProperties: true,
},
'no-server-example.com': 'warn',
'no-server-trailing-slash': 'error',
'no-empty-servers': 'warn',

View File

@@ -6,10 +6,8 @@ export default {
'info-contact': 'off',
'info-license': 'warn',
'info-license-url': 'warn',
'tag-description': 'warn',
'tags-alphabetical': 'off',
'parameter-description': 'off',
'no-path-trailing-slash': 'error',
'no-identical-paths': 'error',
@@ -27,10 +25,8 @@ export default {
'operation-tag-defined': 'off',
'operation-security-defined': 'error',
'operation-singular-tag': 'off',
'no-unresolved-refs': 'error',
'no-enum-type-mismatch': 'error',
'boolean-parameter-prefixes': 'off',
'paths-kebab-case': 'off',
spec: 'error',
@@ -40,7 +36,6 @@ export default {
severity: 'warn',
disallowAdditionalProperties: true,
},
'no-server-example.com': 'warn',
'no-server-trailing-slash': 'error',
'no-empty-servers': 'error',

View File

@@ -1,8 +1,6 @@
import { gray, red, options as colorOptions } from 'colorette';
import * as yamlAst from 'yaml-ast-parser';
import { parsePointer } from '../ref-utils';
import { unescapePointer } from '../ref-utils';
import { LineColLocationObject, Loc, LocationObject } from '../walk';
type YAMLMapping = yamlAst.YAMLMapping & { kind: yamlAst.Kind.MAPPING };
@@ -10,22 +8,22 @@ type YAMLMap = yamlAst.YamlMap & { kind: yamlAst.Kind.MAP };
type YAMLAnchorReference = yamlAst.YAMLAnchorReference & { kind: yamlAst.Kind.ANCHOR_REF };
type YAMLSequence = yamlAst.YAMLSequence & { kind: yamlAst.Kind.SEQ };
type YAMLScalar = yamlAst.YAMLScalar & { kind: yamlAst.Kind.SCALAR };
type YAMLNode = YAMLMapping | YAMLMap | YAMLAnchorReference | YAMLSequence | YAMLScalar;
const MAX_LINE_LENGTH = 150;
const MAX_CODEFRAME_LINES = 3;
// TODO: temporary
function parsePointer(pointer: string) {
return pointer.substr(2).split('/').map(unescapePointer);
}
export function getCodeframe(location: LineColLocationObject, color: boolean) {
colorOptions.enabled = color;
const { start, end = { line: start.line, col: start.col + 1 }, source } = location;
const lines = source.getLines();
const startLineNum = start.line;
const endLineNum = Math.max(Math.min(end.line, lines.length), start.line);
let skipLines = Math.max(endLineNum - startLineNum - MAX_CODEFRAME_LINES + 1, 0);
if (skipLines < 2) skipLines = 0; // do not skip one line

View File

@@ -12,7 +12,13 @@ import {
import { NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject } from '../walk';
import { getCodeframe, getLineColLocation } from './codeframes';
import { Totals } from '../cli';
type Totals = {
errors: number;
warnings: number;
ignored: number;
}
const ERROR_MESSAGE = {
INVALID_SEVERITY_LEVEL: 'Invalid severity level; accepted values: error or warn',
@@ -115,7 +121,7 @@ export function formatProblems(
problems: problems.map((p) => {
let problem = {
...p,
location: p.location.map((location) => ({
location: p.location.map((location: any) => ({
...location,
source: {
ref: path.relative(cwd, location.source.absoluteRef),

View File

@@ -0,0 +1,21 @@
export type { BundleOutputFormat } from './utils';
export { Oas3Types } from './types/oas3';
export { Oas2Types } from './types/oas2';
export { Oas3Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3Schema } from './typings/openapi';
export { Oas2Definition } from './typings/swagger';
export { StatsAccumulator, StatsName } from './typings/common';
export { normalizeTypes } from './types';
export { Stats } from './rules/other/stats';
export { loadConfig, Config, LintConfig } from './config/config';
export { RedoclyClient } from './redocly';
export { BaseResolver, Document, resolveDocument, ResolveError, YamlParseError } from './resolve';
export { unescapePointer } from './ref-utils';
export { detectOpenAPI, OasMajorVersion, openAPIMajor } from './validate';
export { normalizeVisitors } from './visitors';
export { WalkContext, walkDocument, NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject, Loc } from './walk';
export { formatProblems, OutputFormat } from './format/format';
export { validate } from './validate';
export { bundle } from './bundle';

View File

@@ -2,7 +2,6 @@ import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
import { resolve } from 'path';
import { homedir } from 'os';
import { yellow, red, green, gray } from 'colorette';
import { query } from './query';
const TOKEN_FILENAME = '.redocly-config.json';

View File

@@ -79,11 +79,3 @@ export function isMappingRef(mapping: string) {
mapping.indexOf('/') > -1
);
}
export function pathToFilename(path: string) {
return path
.replace(/~1/g, '/')
.replace(/~0/g, '~')
.substring(1)
.replace(/\//g, '@');
}

View File

@@ -3,7 +3,6 @@ import * as path from 'path';
import * as url from 'url';
import * as yaml from 'js-yaml';
const { readFile } = fs.promises;
import { OasRef } from './typings/openapi';
import { isRef, joinPointer, escapePointer, parseRef, isAbsoluteUrl } from './ref-utils';
import { safeLoad as safeLoadToAst, YAMLNode, Kind } from 'yaml-ast-parser';

View File

@@ -5,7 +5,7 @@ import { validateDocument } from '../../validate';
import { LintConfig } from '../..';
import { BaseResolver } from '../../resolve';
import { parseYamlToDocument, replaceSourceWithRef } from '../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
describe('oas3 boolean-parameter-prefixes', () => {
it('should report on unresolved $ref', async () => {

View File

@@ -1,3 +1,4 @@
// @ts-ignore
import * as Ajv from '@redocly/ajv';
// import * as jsonSpecV4 from 'ajv/lib/refs/json-schema-draft-04.json';
// import { OasVersion } from '../validate';
@@ -71,7 +72,7 @@ export function validateJsonSchema(
let suggest =
error.keyword === 'enum' ? (error.params as Ajv.EnumParams).allowedValues : undefined;
if (suggest) {
message += ` ${suggest.map((e) => `"${e}"`).join(', ')}`;
message += ` ${suggest.map((e: any) => `"${e}"`).join(', ')}`;
}
if (error.keyword === 'type') {

View File

@@ -1,6 +1,6 @@
import * as oas3 from './oas3/index';
import * as oas2 from './oas2/index';
import { CustomRulesConfig } from '../index';
import { CustomRulesConfig } from '../config/config';
export const rules: CustomRulesConfig = {
oas3: oas3.rules,

View File

@@ -1,7 +1,7 @@
import { outdent } from 'outdent';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { LintConfig } from '../../../config/config';
import { BaseResolver } from '../../../resolve';

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 info-license', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 license-url', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('no-ambiguous-paths', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 typed enum', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('no-identical-paths', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('no-path-trailing-slash', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 operation-2xx-response', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 operation-operationId-unique', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 operation-operationId-url-safe', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 operation-parameters-unique', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 operation-security-defined', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 operation-singular-tag', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Common path-http-verbs-order', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 path-not-include-query', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 path-params-defined', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 paths-kebab-case', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 tag-description', () => {

View File

@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
import { LintConfig } from '../../../config/config';
import { validateDocument } from '../../../validate';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
import { BaseResolver } from '../../../resolve';
describe('Oas3 tags-alphabetical', () => {

Some files were not shown because too many files have changed in this diff Show More