Skip to content

Commit

Permalink
perf: improve ruleset loading
Browse files Browse the repository at this point in the history
  • Loading branch information
P0lip committed May 29, 2020
1 parent 3ab53cd commit f7b0331
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/rulesets/mergers/formats.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RuleCollection } from '../../types';

export function mergeFormats(rules: RuleCollection, formats: string[]) {
export function mergeFormats(rules: RuleCollection, formats: string[]): void {
if (formats.length > 0) {
for (const rule of Object.values(rules)) {
if (typeof rule === 'object' && rule.formats === void 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/rulesets/mergers/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export function mergeFunctions(
target: RulesetFunctionCollection,
source: RulesetFunctionCollection,
rules: RuleCollection,
) {
): void {
const map: Dictionary<string, string> = {};

for (const [name, def] of Object.entries(source)) {
Expand Down
27 changes: 19 additions & 8 deletions src/rulesets/mergers/rules.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { DiagnosticSeverity } from '@stoplight/types';
import { cloneDeep } from 'lodash';
import { HumanReadableDiagnosticSeverity, IRule } from '../../types';
import { HumanReadableDiagnosticSeverity, IRule, IThen } from '../../types';
import { FileRule, FileRuleCollection, FileRulesetSeverity } from '../../types/ruleset';
import { DEFAULT_SEVERITY_LEVEL, getDiagnosticSeverity, getSeverityLevel } from '../severity';
import { isValidRule } from '../validation';
Expand Down Expand Up @@ -37,7 +36,7 @@ export function mergeRules(

const ROOT_DESCRIPTOR = Symbol('root-descriptor');

function markRule(rule: IRule) {
function markRule(rule: IRule): void {
if (!(ROOT_DESCRIPTOR in rule)) {
Object.defineProperty(rule, ROOT_DESCRIPTOR, {
configurable: false,
Expand All @@ -48,7 +47,7 @@ function markRule(rule: IRule) {
}
}

function updateRootRule(root: IRule, newRule: IRule | null) {
function updateRootRule(root: IRule, newRule: IRule | null): void {
markRule(root);
Object.assign(root[ROOT_DESCRIPTOR], copyRule(newRule === null ? root : Object.assign(root, newRule)));
}
Expand All @@ -57,11 +56,23 @@ function getRootRule(rule: IRule): IRule | null {
return rule[ROOT_DESCRIPTOR] !== undefined ? rule[ROOT_DESCRIPTOR] : null;
}

function copyRule(rule: IRule) {
return cloneDeep(rule);
function copyRuleThen(then: IThen): IThen {
return {
...then,
...('functionOptions' in then ? { ...then.functionOptions } : null),
};
}

function processRule(rules: FileRuleCollection, name: string, rule: FileRule | FileRulesetSeverity) {
function copyRule(rule: IRule): IRule {
return {
...rule,
...('then' in rule
? { then: Array.isArray(rule.then) ? rule.then.map(copyRuleThen) : copyRuleThen(rule.then) }
: null),
};
}

function processRule(rules: FileRuleCollection, name: string, rule: FileRule | FileRulesetSeverity): void {
const existingRule = rules[name];

switch (typeof rule) {
Expand Down Expand Up @@ -116,7 +127,7 @@ function processRule(rules: FileRuleCollection, name: string, rule: FileRule | F
}
}

function normalizeRule(rule: IRule, severity: DiagnosticSeverity | HumanReadableDiagnosticSeverity | undefined) {
function normalizeRule(rule: IRule, severity: DiagnosticSeverity | HumanReadableDiagnosticSeverity | undefined): void {
if (rule.recommended === void 0) {
rule.recommended = true;
}
Expand Down
15 changes: 12 additions & 3 deletions src/rulesets/reader.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Cache } from '@stoplight/json-ref-resolver';
import { ICache } from '@stoplight/json-ref-resolver/types';
import { join } from '@stoplight/path';
import { extname, join } from '@stoplight/path';
import { Optional } from '@stoplight/types';
import { parse } from '@stoplight/yaml';
import { readFile, readParsable } from '../fs/reader';
Expand All @@ -15,6 +15,14 @@ export interface IRulesetReadOptions {
timeout?: number;
}

function parseContent(content: string, source: string): unknown {
if (extname(source) === '.json') {
return JSON.parse(content);
}

return parse(content);
}

export async function readRuleset(uris: string | string[], opts?: IRulesetReadOptions): Promise<IRuleset> {
const base: IRuleset = {
rules: {},
Expand Down Expand Up @@ -54,18 +62,19 @@ const createRulesetProcessor = (

processedRulesets.add(rulesetUri);
const { result } = await httpAndFileResolver.resolve(
parse(
parseContent(
await readParsable(rulesetUri, {
timeout: readOpts?.timeout,
encoding: 'utf8',
}),
rulesetUri,
),
{
baseUri: rulesetUri,
dereferenceInline: false,
uriCache,
async parseResolveResult(opts) {
opts.result = parse(opts.result);
opts.result = parseContent(opts.result, opts.targetAuthority.pathname());
return opts;
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/rulesets/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { IFunction, IFunctionPaths, IFunctionValues, IRule, JSONSchema } from '.
const ajv = new AJV({ allErrors: true, jsonPointers: true });
const validate = ajv.addSchema(ruleSchema).compile(rulesetSchema);

const serializeAJVErrors = (errors: AJV.ErrorObject[]) =>
const serializeAJVErrors = (errors: AJV.ErrorObject[]): string =>
errors.map(({ message, dataPath }) => `${dataPath} ${message}`).join('\n');

export class ValidationError extends AJV.ValidationError {
Expand Down

0 comments on commit f7b0331

Please sign in to comment.