Skip to content

Commit

Permalink
chore: wip config validation, extend types before
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanHotsiy authored and DmitryAnansky committed Jun 21, 2024
1 parent 9456460 commit 43a7883
Show file tree
Hide file tree
Showing 21 changed files with 368 additions and 149 deletions.
6 changes: 6 additions & 0 deletions .changeset/tender-vans-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@redocly/openapi-core": minor
"@redocly/cli": minor
---

Changed resolution process to include extendedTypes and plugins before linting.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
openapi: 3.1.0
info:
title: Food Empire API
version: 0.5.1
x-metadata:
lifecycle: production
owner-team: Engineering/Integrations
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const XMetaData = {
properties: {
lifecycle: { type: 'string', enum: ['development', 'staging', 'production'] },
'owner-team': { type: 'string' },
},
required: ['lifecycle'],
};

module.exports = {
id: 'type-extension',
typeExtension: {
oas3(types) {
newTypes = {
...types,
XMetaData: XMetaData,
Info: {
...types.Info,
properties: {
...types.Info.properties,
'x-metadata': 'XMetaData',
},
},
};
return newTypes;
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
extends: []

plugins:
- plugins/type-extention.js

rules:
spec: warn
rule/metadata-lifecycle:
subject:
type: XMetaData
property: 'lifecycle'
assertions:
enum: ['alpha', 'beta', 'production', 'deprecated']
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`E2E check-config config type extension in assertions 1`] = `
✅ Your config is valid.
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
openapi: 3.1.0
info:
title: Food Empire API
version: 0.5.1
x-metadata:
lifecycle: production
owner-team: Engineering/Integrations
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const XMetaData = {
properties: {
lifecycle: { type: 'string', enum: ['development', 'staging', 'production'] },
'owner-team': { type: 'string' },
},
required: ['lifecycle'],
};

module.exports = {
id: 'type-extension',
typeExtension: {
oas3(types) {
newTypes = {
...types,
XMetaData: XMetaData,
Info: {
...types.Info,
properties: {
...types.Info.properties,
'x-metadata': 'XMetaData',
},
},
};
return newTypes;
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
extends: []

plugins:
- plugins/type-extention.js

rules:
spec: warn
rule/metadata-lifecycle:
subject:
type: WrongXMetaData
property: 'lifecycle'
assertions:
enum: ['alpha', 'beta', 'production', 'deprecated']

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions __tests__/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,30 @@ describe('E2E', () => {
const result = getCommandOutput(passedArgs, folderPath);
(expect(result) as any).toMatchSpecificSnapshot(join(folderPath, 'snapshot.js'));
});

test('config type extension in assertions', () => {
const dirName = 'config-type-extensions-in-assertions';
const folderPath = join(__dirname, `check-config/${dirName}`);

const passedArgs = getParams('../../../packages/cli/src/index.ts', 'check-config', [
'--config=redocly.yaml',
]);

const result = getCommandOutput(passedArgs, folderPath);
(expect(result) as any).toMatchSpecificSnapshot(join(folderPath, 'snapshot.js'));
});

test('wrong config type extension in assertions', () => {
const dirName = 'wrong-config-type-extensions-in-assertions';
const folderPath = join(__dirname, `check-config/${dirName}`);

const passedArgs = getParams('../../../packages/cli/src/index.ts', 'check-config', [
'--config=redocly.yaml',
]);

const result = getCommandOutput(passedArgs, folderPath);
(expect(result) as any).toMatchSpecificSnapshot(join(folderPath, 'snapshot.js'));
});
});

describe('lint-config', () => {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions __tests__/lint/deprecated-apiDefinitions/snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

exports[`E2E lint deprecated-apiDefinitions 1`] = `
The 'apiDefinitions' field is deprecated. Use apis instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties
The 'lint' field is deprecated. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties
[1] redocly.yaml:1:1 at #/apiDefinitions
Property \`apiDefinitions\` is not expected here.
Expand Down Expand Up @@ -31,8 +33,6 @@ Warning was generated by the configuration spec rule.
⚠️ Your config has 2 warnings.
The 'apiDefinitions' field is deprecated. Use apis instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties
The 'lint' field is deprecated. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties
validating /openapi.yaml...
[1] openapi.yaml:2:1 at #/info/contact
Expand Down
2 changes: 1 addition & 1 deletion __tests__/lint/deprecated-lint/snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

exports[`E2E lint deprecated-lint 1`] = `
The 'lint' field is deprecated. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties
[1] redocly.yaml:8:1 at #/lint
Property \`lint\` is not expected here.
Expand Down Expand Up @@ -35,7 +36,6 @@ Warning was generated by the configuration spec rule.
⚠️ Your config has 2 warnings.
The 'lint' field is deprecated. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties
validating /openapi.yaml...
[1] openapi.yaml:11:7 at #/paths/~1pet~1findByStatus/get/responses
Expand Down
2 changes: 1 addition & 1 deletion __tests__/lint/deprecated-styleguide/snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

exports[`E2E lint deprecated-styleguide 1`] = `
The 'styleguide' field is deprecated. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties
[1] redocly.yaml:8:1 at #/styleguide
Property \`styleguide\` is not expected here.
Expand Down Expand Up @@ -31,7 +32,6 @@ Warning was generated by the configuration spec rule.
⚠️ Your config has 2 warnings.
The 'styleguide' field is deprecated. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties
validating /openapi.yaml...
[1] openapi.yaml:11:7 at #/paths/~1pet~1findByStatus/get/responses
Expand Down
9 changes: 5 additions & 4 deletions packages/cli/src/commands/lint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import {
import { blue, gray } from 'colorette';
import { performance } from 'perf_hooks';

import type { OutputFormat, ProblemSeverity, Document, RuleSeverity } from '@redocly/openapi-core';
import type { ResolvedRefMap } from '@redocly/openapi-core/lib/resolve';
import type { OutputFormat, ProblemSeverity, RuleSeverity } from '@redocly/openapi-core';
import type { RawConfigProcessor } from '@redocly/openapi-core/lib/config';
import type { CommandOptions, Skips, Totals } from '../types';
import { getCommandNameFromArgs } from '../utils/getCommandNameFromArgs';
import { Arguments } from 'yargs';
Expand Down Expand Up @@ -120,7 +120,7 @@ export async function handleLint(argv: LintOptions, config: Config, version: str
export function lintConfigCallback(
argv: CommandOptions & Record<string, undefined>,
version: string
) {
): RawConfigProcessor | undefined {
if (argv['lint-config'] === 'off') {
return;
}
Expand All @@ -130,10 +130,11 @@ export function lintConfigCallback(
return;
}

return async (document: Document, resolvedRefMap: ResolvedRefMap) => {
return async ({ document, resolvedRefMap, config }) => {
const problems = await lintConfig({
document,
resolvedRefMap,
config,
severity: (argv['lint-config'] || 'warn') as ProblemSeverity,
});

Expand Down
34 changes: 22 additions & 12 deletions packages/core/src/__tests__/lint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { outdent } from 'outdent';

import { lintFromString, lintConfig, lintDocument, lint } from '../lint';
import { BaseResolver } from '../resolve';
import { loadConfig } from '../config/load';
import { createConfig, loadConfig } from '../config/load';
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../__tests__/utils';
import { detectSpec } from '../oas-types';
import { rootRedoclyConfigSchema } from '@redocly/config';
Expand Down Expand Up @@ -293,7 +293,7 @@ describe('lint', () => {
- url: http://redocly-example.com
paths: {}
`,
config: await loadConfig(),
config: await loadConfig({ configPath: path.join(__dirname, 'fixtures/redocly.yaml') }),
});

expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -374,7 +374,8 @@ describe('lint', () => {
`,
''
);
const results = await lintConfig({ document });
const config = await createConfig({});
const results = await lintConfig({ document, config });

expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
[
Expand Down Expand Up @@ -435,7 +436,8 @@ describe('lint', () => {
`,
''
);
const results = await lintConfig({ document });
const config = await createConfig({});
const results = await lintConfig({ document, config });

expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
[
Expand Down Expand Up @@ -475,7 +477,8 @@ describe('lint', () => {
`,
''
);
const results = await lintConfig({ document });
const config = await createConfig({});
const results = await lintConfig({ document, config });

expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
[
Expand Down Expand Up @@ -510,7 +513,8 @@ describe('lint', () => {
`,
''
);
const results = await lintConfig({ document });
const config = await createConfig({});
const results = await lintConfig({ document, config });

expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
[
Expand All @@ -534,7 +538,8 @@ describe('lint', () => {

it('lintConfig should detect wrong fields in the default configuration after merging with the portal config schema', async () => {
const document = testPortalConfig;
const results = await lintConfig({ document });
const config = await createConfig({});
const results = await lintConfig({ document, config });

expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
[
Expand Down Expand Up @@ -1165,13 +1170,18 @@ describe('lint', () => {

it('lintConfig should alternate its behavior when supplied externalConfigTypes', async () => {
const document = testPortalConfig;
const config = await createConfig({});
const results = await lintConfig({
document,
externalConfigTypes: createConfigTypes({
type: 'object',
properties: { theme: rootRedoclyConfigSchema.properties.theme },
additionalProperties: false,
}),
externalConfigTypes: createConfigTypes(
{
type: 'object',
properties: { theme: rootRedoclyConfigSchema.properties.theme },
additionalProperties: false,
},
config
),
config,
});

expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
Expand Down
Loading

0 comments on commit 43a7883

Please sign in to comment.