Skip to content

Commit

Permalink
integrate schema rule with spectral ruleset
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu committed Aug 25, 2022
1 parent 32f7b44 commit 75472a0
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 13 deletions.
11 changes: 6 additions & 5 deletions src/parser.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Spectral } from "@stoplight/spectral-core";
import { asyncapi as aasRuleset } from "@stoplight/spectral-rulesets";

import { parse } from "./parse";
import { lint, validate } from "./lint";
import { registerSchemaParser } from './schema-parser';
import { configureSpectral } from "./spectral";

import type { IConstructorOpts } from "@stoplight/spectral-core";
import type { ParseInput, ParseOptions } from "./parse";
Expand All @@ -18,16 +18,17 @@ export class Parser {
public readonly parserRegistry = new Map<string, SchemaParser>();
public readonly spectral: Spectral;

constructor(options?: ParserOptions) {
const { spectral } = options || {};
constructor(
private readonly options?: ParserOptions
) {
const { spectral } = this.options || {};
if (spectral instanceof Spectral) {
this.spectral = spectral;
} else {
this.spectral = new Spectral(spectral);
}

// TODO: fix type
this.spectral.setRuleset(aasRuleset as any);
configureSpectral(this);
}

parse(asyncapi: ParseInput, options?: ParseOptions) {
Expand Down
9 changes: 3 additions & 6 deletions src/schema-parser/spectral-rule-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@ import { createDetailedAsyncAPI } from '../utils';
import type { RuleDefinition } from "@stoplight/spectral-core";
import type { Parser } from '../parser';
import type { ValidateSchemaInput } from './index';
import { SchemaValidateResult } from 'types';
import type { SchemaValidateResult } from '../types';

const aas2Formats = [aas2_0, aas2_1, aas2_2, aas2_3, aas2_4];

export const aas2schemaParserRuleName = 'asyncapi-custom-schema';
export function aas2schemaParserRule(parser: Parser): RuleDefinition {
return {
description: 'Custom schema must be correctly formatted from the point of view of the used format.',
formats: aas2Formats,
formats: [aas2_0, aas2_1, aas2_2, aas2_3, aas2_4],
message: '{{error}}',
severity: 'error',
type: 'validation',
Expand Down Expand Up @@ -59,7 +56,7 @@ function rulesetFunction(parser: Parser) {
const schemaFormat = getSchemaFormat(targetVal.schematFormat, spec.asyncapi);
const defaultSchemaFormat = getDefaultSchemaFormat(spec.asyncapi);
// we don't have a parsed specification yet because we are still executing code in the context of spectral
const asyncapi = createDetailedAsyncAPI(spec, undefined as any);
const asyncapi = createDetailedAsyncAPI(ctx.document.source as string, spec);

const input: ValidateSchemaInput = {
asyncapi,
Expand Down
29 changes: 29 additions & 0 deletions src/spectral.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { RulesetDefinition } from "@stoplight/spectral-core";
import { asyncapi as aasRuleset } from "@stoplight/spectral-rulesets";

import { aas2schemaParserRule } from './schema-parser/spectral-rule-v2';

import type { Parser } from "./parser";

export function configureSpectral(parser: Parser) {
const ruleset = configureRuleset(parser);
parser.spectral.setRuleset(ruleset);
}

function configureRuleset(parser: Parser): RulesetDefinition {
// We do not use these two given rules from the official ruleset due to the fact that the given rules validate only AsyncAPI Schemas and prevent defining schemas in other formats
const rules = {
...aasRuleset.rules,
'asyncapi-schemas-v2': aas2schemaParserRule(parser),
'asyncapi-payload-unsupported-schemaFormat': undefined,
'asyncapi-payload': undefined,
};
delete rules['asyncapi-payload-unsupported-schemaFormat'];
delete rules['asyncapi-payload'];

// official type for RulesetDefinition needs `extends` so we need to convert first to any and then to RulesetDefinition - bug on Spectral side
return {
...aasRuleset,
rules,
} as any as RulesetDefinition;
}
3 changes: 1 addition & 2 deletions test/parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ describe('Parser class', function() {

it('should register schema parser', async function() {
const parser = new Parser();
const schemaParser = AsyncAPISchemaParser();
parser.registerSchemaParser(schemaParser);
parser.registerSchemaParser(AsyncAPISchemaParser());
expect(parser.parserRegistry.size).toBeGreaterThan(1);
});
});
39 changes: 39 additions & 0 deletions test/schema-parser/spectral-rule-v2.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Parser } from '../../src/parser';
import { validate } from '../../src/lint';
import { AsyncAPISchemaParser } from '../../src/schema-parser/asyncapi-schema-parser';

describe('aas2schemaParserRule', function() {
const parser = new Parser();
parser.registerSchemaParser(AsyncAPISchemaParser());

it('should validate invalid AsyncAPI Schema with invalid schema', async function() {
const document = {
asyncapi: '2.0.0',
info: {
title: 'Valid AsyncApi document',
version: '1.0',
},
channels: {
channel1: {
publish: {
message: {
payload: {
oneOf: "this should be an array",
properties: {
name: {
if: "this should be an if"
}
}
}
}
}
}
}
}
const { diagnostics } = await validate(parser, document);

// expect(parsed).toBeInstanceOf(AsyncAPIDocumentV2);
// expect(diagnostics.length > 0).toEqual(true);
// console.log(diagnostics);
});
});

0 comments on commit 75472a0

Please sign in to comment.