@redocly/openapi-core 1.0.0-beta.49 → 1.0.0-beta.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/__tests__/normalizeVisitors.test.ts +1 -1
  2. package/__tests__/utils.ts +1 -1
  3. package/__tests__/walk.test.ts +77 -4
  4. package/lib/benchmark/benches/recommended-oas3.bench.js +2 -1
  5. package/lib/benchmark/utils.d.ts +1 -1
  6. package/lib/bundle.d.ts +1 -1
  7. package/lib/bundle.js +10 -10
  8. package/lib/config/builtIn.d.ts +2 -1
  9. package/lib/config/builtIn.js +9 -1
  10. package/lib/config/config.d.ts +5 -7
  11. package/lib/config/config.js +40 -100
  12. package/lib/config/load.d.ts +2 -0
  13. package/lib/config/load.js +65 -0
  14. package/lib/config/rules.d.ts +1 -1
  15. package/lib/format/codeframes.js +1 -1
  16. package/lib/index.d.ts +4 -3
  17. package/lib/index.js +13 -11
  18. package/lib/lint.d.ts +6 -19
  19. package/lib/lint.js +13 -43
  20. package/lib/oas-types.d.ts +19 -0
  21. package/lib/oas-types.js +42 -0
  22. package/lib/resolve.d.ts +6 -2
  23. package/lib/resolve.js +18 -5
  24. package/lib/rules/ajv.d.ts +3 -3
  25. package/lib/rules/ajv.js +21 -18
  26. package/lib/rules/common/info-contact.js +2 -1
  27. package/lib/rules/common/info-description.js +2 -1
  28. package/lib/rules/common/info-license-url.js +2 -1
  29. package/lib/rules/common/license-url.js +2 -1
  30. package/lib/rules/common/no-ambiguous-paths.js +2 -1
  31. package/lib/rules/common/no-enum-type-mismatch.js +2 -1
  32. package/lib/rules/common/no-identical-paths.js +2 -1
  33. package/lib/rules/common/no-path-trailing-slash.js +2 -1
  34. package/lib/rules/common/operation-2xx-response.js +2 -1
  35. package/lib/rules/common/operation-description.js +2 -1
  36. package/lib/rules/common/operation-operationId-unique.js +2 -1
  37. package/lib/rules/common/operation-operationId-url-safe.js +2 -1
  38. package/lib/rules/common/operation-operationId.js +9 -4
  39. package/lib/rules/common/operation-parameters-unique.js +2 -1
  40. package/lib/rules/common/operation-security-defined.js +2 -1
  41. package/lib/rules/common/operation-singular-tag.js +2 -1
  42. package/lib/rules/common/operation-summary.js +2 -1
  43. package/lib/rules/common/operation-tag-defined.js +2 -1
  44. package/lib/rules/common/parameter-description.js +2 -1
  45. package/lib/rules/common/path-declaration-must-exist.js +2 -1
  46. package/lib/rules/common/path-http-verbs-order.js +2 -1
  47. package/lib/rules/common/path-not-include-query.js +2 -1
  48. package/lib/rules/common/path-params-defined.js +3 -2
  49. package/lib/rules/common/paths-kebab-case.js +2 -1
  50. package/lib/rules/common/registry-dependencies.js +2 -1
  51. package/lib/rules/common/spec.js +5 -2
  52. package/lib/rules/common/tag-description.js +2 -1
  53. package/lib/rules/common/tags-alphabetical.js +2 -1
  54. package/lib/rules/no-unresolved-refs.js +2 -1
  55. package/lib/rules/oas2/boolean-parameter-prefixes.js +2 -1
  56. package/lib/rules/oas2/index.d.ts +1 -1
  57. package/lib/rules/oas2/index.js +1 -1
  58. package/lib/rules/oas3/boolean-parameter-prefixes.js +2 -1
  59. package/lib/rules/oas3/index.d.ts +2 -1
  60. package/lib/rules/oas3/index.js +2 -2
  61. package/lib/rules/oas3/no-empty-servers.js +2 -1
  62. package/lib/rules/oas3/no-example-value-and-externalValue.js +2 -1
  63. package/lib/rules/oas3/no-invalid-media-type-examples.js +20 -10
  64. package/lib/rules/oas3/no-server-example.com.js +2 -1
  65. package/lib/rules/oas3/no-server-trailing-slash.js +2 -1
  66. package/lib/rules/oas3/no-servers-empty-enum.js +2 -1
  67. package/lib/rules/oas3/no-undefined-server-variable.js +2 -1
  68. package/lib/rules/oas3/no-unused-components.js +2 -1
  69. package/lib/rules/other/stats.js +2 -1
  70. package/lib/types/oas2.js +1 -1
  71. package/lib/types/oas3.js +1 -1
  72. package/lib/types/oas3_1.js +1 -1
  73. package/lib/utils.d.ts +1 -1
  74. package/lib/visitors.d.ts +3 -1
  75. package/lib/visitors.js +4 -4
  76. package/lib/walk.d.ts +1 -1
  77. package/lib/walk.js +11 -2
  78. package/package.json +7 -7
  79. package/src/__tests__/lint.test.ts +44 -0
  80. package/src/benchmark/benches/recommended-oas3.bench.ts +2 -1
  81. package/src/benchmark/benchmark.js +3 -1
  82. package/src/benchmark/utils.ts +1 -1
  83. package/src/bundle.ts +2 -2
  84. package/src/config/__tests__/resolve-plugins.test.ts +1 -1
  85. package/src/config/builtIn.ts +11 -1
  86. package/src/config/config.ts +30 -78
  87. package/src/config/load.ts +60 -0
  88. package/src/config/rules.ts +1 -1
  89. package/src/format/codeframes.ts +1 -1
  90. package/src/index.ts +4 -3
  91. package/src/lint.ts +19 -56
  92. package/src/oas-types.ts +58 -0
  93. package/src/resolve.ts +17 -4
  94. package/src/rules/__tests__/config.ts +10 -0
  95. package/src/rules/__tests__/no-unresolved-refs.test.ts +9 -21
  96. package/src/rules/ajv.ts +27 -23
  97. package/src/rules/common/__tests__/info-description.test.ts +8 -16
  98. package/src/rules/common/__tests__/info-license.test.ts +3 -3
  99. package/src/rules/common/__tests__/license-url.test.ts +3 -3
  100. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +2 -2
  101. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +50 -5
  102. package/src/rules/common/__tests__/no-identical-paths.test.ts +2 -2
  103. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +4 -4
  104. package/src/rules/common/__tests__/operation-2xx-response.test.ts +4 -4
  105. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +3 -3
  106. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +2 -5
  107. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +5 -17
  108. package/src/rules/common/__tests__/operation-security-defined.test.ts +3 -3
  109. package/src/rules/common/__tests__/operation-singular-tag.test.ts +3 -3
  110. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +3 -3
  111. package/src/rules/common/__tests__/path-not-include-query.test.ts +3 -3
  112. package/src/rules/common/__tests__/path-params-defined.test.ts +4 -4
  113. package/src/rules/common/__tests__/paths-kebab-case.test.ts +3 -3
  114. package/src/rules/common/__tests__/tag-description.test.ts +3 -3
  115. package/src/rules/common/__tests__/tags-alphabetical.test.ts +3 -3
  116. package/src/rules/common/operation-operationId.ts +7 -3
  117. package/src/rules/common/spec.ts +4 -1
  118. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +7 -10
  119. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +3 -6
  120. package/src/rules/oas2/__tests__/spec/utils.ts +2 -0
  121. package/src/rules/oas2/index.ts +1 -10
  122. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +7 -10
  123. package/src/rules/oas3/__tests__/fixtures/common.yaml +11 -0
  124. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +7 -7
  125. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +3 -9
  126. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +103 -29
  127. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +3 -3
  128. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  129. package/src/rules/oas3/__tests__/no-unused-components.test.ts +2 -2
  130. package/src/rules/oas3/__tests__/spec/spec.test.ts +3 -1
  131. package/src/rules/oas3/__tests__/spec/utils.ts +2 -0
  132. package/src/rules/oas3/index.ts +3 -4
  133. package/src/rules/oas3/no-invalid-media-type-examples.ts +27 -19
  134. package/src/visitors.ts +12 -8
  135. package/src/walk.ts +24 -8
  136. package/tsconfig.tsbuildinfo +1 -3084
@@ -1,5 +1,5 @@
1
1
  import { normalizeVisitors, VisitorLevelContext } from '../src/visitors';
2
- import { Oas3RuleSet } from '../src/lint';
2
+ import { Oas3RuleSet } from '../src/oas-types';
3
3
  import { Oas3Types } from '../src/types/oas3';
4
4
  import { normalizeTypes } from '../src/types';
5
5
 
@@ -4,7 +4,7 @@ import * as path from 'path';
4
4
  import { Document, Source } from '../src/resolve';
5
5
  import { NormalizedProblem } from '../src/walk';
6
6
  import { RuleConfig, LintConfig, Plugin } from '../src/config/config';
7
- import { Oas3RuleSet } from '../src/lint';
7
+ import { Oas3RuleSet } from '../src/oas-types';
8
8
 
9
9
  export function parseYamlToDocument(body: string, absoluteRef: string = ''): Document {
10
10
  return {
@@ -1,11 +1,13 @@
1
1
  import outdent from 'outdent';
2
+ import each from 'jest-each';
2
3
  import * as path from 'path';
3
4
 
4
- import { lintDocument, Oas3RuleSet } from '../src/lint';
5
+ import { lintDocument } from '../src/lint';
5
6
 
6
7
  import { parseYamlToDocument, replaceSourceWithRef, makeConfigForRuleset } from './utils';
7
8
  import { BaseResolver, Document } from '../src/resolve';
8
9
  import { listOf } from '../src/types';
10
+ import { Oas3RuleSet } from '../src/oas-types';
9
11
 
10
12
  describe('walk order', () => {
11
13
  it('should run visitors', async () => {
@@ -1245,7 +1247,10 @@ describe('context.resolve', () => {
1245
1247
  });
1246
1248
 
1247
1249
  describe('type extensions', () => {
1248
- it('should correctly visit extended types', async () => {
1250
+ each([
1251
+ ['3.0.0', 'oas3_0'],
1252
+ ['3.1.0', 'oas3_1'],
1253
+ ]).it('should correctly visit OpenAPI %s extended types', async (openapi, oas) => {
1249
1254
  const calls: string[] = [];
1250
1255
 
1251
1256
  const testRuleSet: Oas3RuleSet = {
@@ -1273,7 +1278,7 @@ describe('type extensions', () => {
1273
1278
 
1274
1279
  const document = parseYamlToDocument(
1275
1280
  outdent`
1276
- openapi: 3.0.0
1281
+ openapi: ${openapi}
1277
1282
  x-webhooks:
1278
1283
  name: test
1279
1284
  parameters:
@@ -1288,7 +1293,7 @@ describe('type extensions', () => {
1288
1293
  config: makeConfigForRuleset(testRuleSet, {
1289
1294
  typeExtension: {
1290
1295
  oas3(types, version) {
1291
- expect(version).toEqual('oas3_0');
1296
+ expect(version).toEqual(oas);
1292
1297
 
1293
1298
  return {
1294
1299
  ...types,
@@ -1326,3 +1331,71 @@ describe('type extensions', () => {
1326
1331
  `);
1327
1332
  });
1328
1333
  });
1334
+
1335
+ describe('ignoreNextRules', () => {
1336
+ it('should correctly skip top level', async () => {
1337
+ const calls: string[] = [];
1338
+
1339
+ const testRuleSet: Oas3RuleSet = {
1340
+ skip: jest.fn(() => {
1341
+ return {
1342
+ Operation: {
1343
+ enter: jest.fn((op, ctx) => {
1344
+ if (op.operationId === 'get') {
1345
+ ctx.ignoreNextVisitorsOnNode();
1346
+ calls.push(`enter and skip operation ${op.operationId}`);
1347
+ } else {
1348
+ calls.push(`enter and not skip operation ${op.operationId}`);
1349
+ }
1350
+ }),
1351
+ leave: jest.fn((op) => {
1352
+ if (op.operationId === 'get') {
1353
+ calls.push(`leave skipped operation ${op.operationId}`);
1354
+ } else {
1355
+ calls.push(`leave not skipped operation ${op.operationId}`);
1356
+ }
1357
+ }),
1358
+ },
1359
+ };
1360
+ }),
1361
+ test: jest.fn(() => {
1362
+ return {
1363
+ Operation: {
1364
+ enter: jest.fn((op) => calls.push(`enter operation ${op.operationId}`)),
1365
+ leave: jest.fn((op) => calls.push(`leave operation ${op.operationId}`)),
1366
+ },
1367
+ };
1368
+ }),
1369
+ };
1370
+
1371
+ const document = parseYamlToDocument(
1372
+ outdent`
1373
+ openapi: 3.0.0
1374
+ paths:
1375
+ /pet:
1376
+ get:
1377
+ operationId: get
1378
+ put:
1379
+ operationId: put
1380
+ `,
1381
+ '',
1382
+ );
1383
+
1384
+ await lintDocument({
1385
+ externalRefResolver: new BaseResolver(),
1386
+ document,
1387
+ config: makeConfigForRuleset(testRuleSet),
1388
+ });
1389
+
1390
+ expect(calls).toMatchInlineSnapshot(`
1391
+ Array [
1392
+ "enter and skip operation get",
1393
+ "leave skipped operation get",
1394
+ "enter and not skip operation put",
1395
+ "enter operation put",
1396
+ "leave not skipped operation put",
1397
+ "leave operation put",
1398
+ ]
1399
+ `);
1400
+ });
1401
+ });
@@ -7,6 +7,7 @@ const lint_1 = require("../../lint");
7
7
  const config_1 = require("../../config/config");
8
8
  const resolve_1 = require("../../resolve");
9
9
  const utils_1 = require("../utils");
10
+ const builtIn_1 = require("../../config/builtIn");
10
11
  exports.name = 'Validate with recommended rules';
11
12
  exports.count = 10;
12
13
  const rebillyDefinitionRef = path_1.resolve(path_1.join(__dirname, 'rebilly.yaml'));
@@ -15,7 +16,7 @@ function measureAsync() {
15
16
  return lint_1.lintDocument({
16
17
  externalRefResolver: new resolve_1.BaseResolver(),
17
18
  document: rebillyDocument,
18
- config: new config_1.LintConfig({}),
19
+ config: new config_1.LintConfig({ plugins: [builtIn_1.defaultPlugin] }),
19
20
  });
20
21
  }
21
22
  exports.measureAsync = measureAsync;
@@ -1,5 +1,5 @@
1
1
  import { Document } from '../resolve';
2
- import { Oas3RuleSet } from '../lint';
2
+ import { Oas3RuleSet } from '../oas-types';
3
3
  import { LintConfig, Plugin } from '../config/config';
4
4
  export declare function parseYamlToDocument(body: string, absoluteRef?: string): Document;
5
5
  export declare function makeConfigForRuleset(rules: Oas3RuleSet, plugin?: Partial<Plugin>): LintConfig;
package/lib/bundle.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BaseResolver, Document } from './resolve';
2
2
  import { Oas3Rule } from './visitors';
3
3
  import { NodeType } from './types';
4
- import { Config, LintConfig } from './config/config';
4
+ import type { Config, LintConfig } from './config/config';
5
5
  export declare type Oas3RuleSet = Record<string, Oas3Rule>;
6
6
  export declare enum OasVersion {
7
7
  Version2 = "oas2",
package/lib/bundle.js CHANGED
@@ -18,7 +18,7 @@ const oas2_1 = require("./types/oas2");
18
18
  const oas3_1_1 = require("./types/oas3_1");
19
19
  const types_1 = require("./types");
20
20
  const walk_1 = require("./walk");
21
- const lint_1 = require("./lint");
21
+ const oas_types_1 = require("./oas-types");
22
22
  const ref_utils_1 = require("./ref-utils");
23
23
  const rules_1 = require("./config/rules");
24
24
  const no_unresolved_refs_1 = require("./rules/no-unresolved-refs");
@@ -46,10 +46,10 @@ exports.bundle = bundle;
46
46
  function bundleDocument(opts) {
47
47
  return __awaiter(this, void 0, void 0, function* () {
48
48
  const { document, config, customTypes, externalRefResolver, dereference = false } = opts;
49
- const oasVersion = lint_1.detectOpenAPI(document.parsed);
50
- const oasMajorVersion = lint_1.openAPIMajor(oasVersion);
49
+ const oasVersion = oas_types_1.detectOpenAPI(document.parsed);
50
+ const oasMajorVersion = oas_types_1.openAPIMajor(oasVersion);
51
51
  const rules = config.getRulesForOasVersion(oasMajorVersion);
52
- const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === lint_1.OasMajorVersion.Version3) ? (oasVersion === OasVersion.Version3_1 ? oas3_1_1.Oas3_1Types : oas3_1.Oas3Types) : oas2_1.Oas2Types, oasVersion), config);
52
+ const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === oas_types_1.OasMajorVersion.Version3) ? (oasVersion === OasVersion.Version3_1 ? oas3_1_1.Oas3_1Types : oas3_1.Oas3Types) : oas2_1.Oas2Types, oasVersion), config);
53
53
  const preprocessors = rules_1.initRules(rules, config, 'preprocessors', oasVersion);
54
54
  const decorators = rules_1.initRules(rules, config, 'decorators', oasVersion);
55
55
  const ctx = {
@@ -87,7 +87,7 @@ function bundleDocument(opts) {
87
87
  exports.bundleDocument = bundleDocument;
88
88
  function mapTypeToComponent(typeName, version) {
89
89
  switch (version) {
90
- case lint_1.OasMajorVersion.Version3:
90
+ case oas_types_1.OasMajorVersion.Version3:
91
91
  switch (typeName) {
92
92
  case 'Schema':
93
93
  return 'schemas';
@@ -110,7 +110,7 @@ function mapTypeToComponent(typeName, version) {
110
110
  default:
111
111
  return null;
112
112
  }
113
- case lint_1.OasMajorVersion.Version2:
113
+ case oas_types_1.OasMajorVersion.Version2:
114
114
  switch (typeName) {
115
115
  case 'Schema':
116
116
  return 'definitions';
@@ -156,16 +156,16 @@ function makeBundleVisitor(version, dereference, rootDocument) {
156
156
  },
157
157
  DefinitionRoot: {
158
158
  enter(root) {
159
- if (version === lint_1.OasMajorVersion.Version3) {
159
+ if (version === oas_types_1.OasMajorVersion.Version3) {
160
160
  components = root.components = root.components || {};
161
161
  }
162
- else if (version === lint_1.OasMajorVersion.Version2) {
162
+ else if (version === oas_types_1.OasMajorVersion.Version2) {
163
163
  components = root;
164
164
  }
165
165
  },
166
166
  },
167
167
  };
168
- if (version === lint_1.OasMajorVersion.Version3) {
168
+ if (version === oas_types_1.OasMajorVersion.Version3) {
169
169
  visitor.DiscriminatorMapping = {
170
170
  leave(mapping, ctx) {
171
171
  for (const name of Object.keys(mapping)) {
@@ -200,7 +200,7 @@ function makeBundleVisitor(version, dereference, rootDocument) {
200
200
  components[componentType] = components[componentType] || {};
201
201
  const name = getComponentName(target, componentType, ctx);
202
202
  components[componentType][name] = target.node;
203
- if (version === lint_1.OasMajorVersion.Version3) {
203
+ if (version === oas_types_1.OasMajorVersion.Version3) {
204
204
  return `#/components/${componentType}/${name}`;
205
205
  }
206
206
  else {
@@ -1,2 +1,3 @@
1
- import { LintRawConfig } from './config';
1
+ import { LintRawConfig, Plugin } from './config';
2
2
  export declare const builtInConfigs: Record<string, LintRawConfig>;
3
+ export declare const defaultPlugin: Plugin;
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.builtInConfigs = void 0;
3
+ exports.defaultPlugin = exports.builtInConfigs = void 0;
4
4
  const recommended_1 = require("./recommended");
5
5
  const all_1 = require("./all");
6
6
  const minimal_1 = require("./minimal");
7
+ const builtinRules = require("../rules/builtin");
7
8
  exports.builtInConfigs = {
8
9
  recommended: recommended_1.default,
9
10
  minimal: minimal_1.default,
@@ -12,3 +13,10 @@ exports.builtInConfigs = {
12
13
  decorators: { 'registry-dependencies': 'on' }
13
14
  }
14
15
  };
16
+ exports.defaultPlugin = {
17
+ id: '',
18
+ rules: builtinRules.rules,
19
+ preprocessors: builtinRules.preprocessors,
20
+ decorators: builtinRules.decorators,
21
+ configs: exports.builtInConfigs,
22
+ };
@@ -1,6 +1,5 @@
1
- import { OasVersion, Oas3PreprocessorsSet, OasMajorVersion, Oas3DecoratorsSet, Oas2RuleSet, Oas2PreprocessorsSet, Oas2DecoratorsSet } from '../lint';
1
+ import { OasVersion, Oas3PreprocessorsSet, OasMajorVersion, Oas3DecoratorsSet, Oas2RuleSet, Oas2PreprocessorsSet, Oas2DecoratorsSet, Oas3RuleSet } from '../oas-types';
2
2
  import { ProblemSeverity, NormalizedProblem } from '../walk';
3
- import { Oas3RuleSet } from '../lint';
4
3
  import { NodeType } from '../types';
5
4
  export declare const IGNORE_FILE = ".redocly.lint-ignore.yaml";
6
5
  export declare type RuleConfig = ProblemSeverity | 'off' | ({
@@ -95,16 +94,16 @@ export declare class LintConfig {
95
94
  addProblemToIgnore(problem: NormalizedProblem): NormalizedProblem;
96
95
  extendTypes(types: Record<string, NodeType>, version: OasVersion): Record<string, NodeType>;
97
96
  getRuleSettings(ruleId: string, oasVersion: OasVersion): {
98
- severity: "error" | "warn" | "off";
97
+ severity: ProblemSeverity | "off";
99
98
  };
100
99
  getPreprocessorSettings(ruleId: string, oasVersion: OasVersion): {
101
- severity: "error" | "warn" | "off";
100
+ severity: ProblemSeverity | "off";
102
101
  } | {
103
102
  severity: ProblemSeverity;
104
103
  options?: Record<string, any> | undefined;
105
104
  };
106
105
  getDecoratorSettings(ruleId: string, oasVersion: OasVersion): {
107
- severity: "error" | "warn" | "off";
106
+ severity: ProblemSeverity | "off";
108
107
  } | {
109
108
  severity: ProblemSeverity;
110
109
  options?: Record<string, any> | undefined;
@@ -114,7 +113,7 @@ export declare class LintConfig {
114
113
  preprocessors: string[];
115
114
  decorators: string[];
116
115
  };
117
- getRulesForOasVersion(version: OasMajorVersion): Record<string, import("../visitors").Oas3Rule>[] | Record<string, import("../visitors").Oas2Rule>[];
116
+ getRulesForOasVersion(version: OasMajorVersion): Oas3RuleSet[] | Oas2RuleSet[];
118
117
  skipRules(rules?: string[]): void;
119
118
  skipPreprocessors(preprocessors?: string[]): void;
120
119
  skipDecorators(decorators?: string[]): void;
@@ -128,4 +127,3 @@ export declare class Config {
128
127
  resolve: ResolveConfig;
129
128
  constructor(rawConfig: RawConfig, configFile?: string | undefined);
130
129
  }
131
- export declare function loadConfig(configPath?: string, customExtends?: string[]): Promise<Config>;
@@ -1,26 +1,14 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.loadConfig = exports.Config = exports.LintConfig = exports.IGNORE_FILE = void 0;
3
+ exports.Config = exports.LintConfig = exports.IGNORE_FILE = void 0;
13
4
  const fs = require("fs");
14
5
  const path = require("path");
15
6
  const yaml = require("js-yaml");
16
7
  const path_1 = require("path");
17
8
  const colorette_1 = require("colorette");
18
- const builtIn_1 = require("./builtIn");
19
- const builtinRules = require("../rules/builtin");
20
9
  const utils_1 = require("../utils");
21
- const lint_1 = require("../lint");
10
+ const oas_types_1 = require("../oas-types");
22
11
  const recommended_1 = require("./recommended");
23
- const redocly_1 = require("../redocly");
24
12
  exports.IGNORE_FILE = '.redocly.lint-ignore.yaml';
25
13
  const IGNORE_BANNER = `# This file instructs Redocly's linter to ignore the rules contained for specific parts of your API.\n` +
26
14
  `# See https://redoc.ly/docs/cli/ for more information.\n`;
@@ -34,12 +22,6 @@ class LintConfig {
34
22
  this.recommendedFallback = false;
35
23
  this.plugins = rawConfig.plugins ? resolvePlugins(rawConfig.plugins, configFile) : [];
36
24
  this.doNotResolveExamples = !!rawConfig.doNotResolveExamples;
37
- this.plugins.push({
38
- id: '',
39
- rules: builtinRules.rules,
40
- preprocessors: builtinRules.preprocessors,
41
- decorators: builtinRules.decorators,
42
- });
43
25
  if (!rawConfig.extends) {
44
26
  this.recommendedFallback = true;
45
27
  }
@@ -55,21 +37,21 @@ class LintConfig {
55
37
  }
56
38
  const merged = mergeExtends(extendConfigs);
57
39
  this.rules = {
58
- [lint_1.OasVersion.Version2]: Object.assign(Object.assign({}, merged.rules), merged.oas2Rules),
59
- [lint_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, merged.rules), merged.oas3_0Rules),
60
- [lint_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, merged.rules), merged.oas3_1Rules),
40
+ [oas_types_1.OasVersion.Version2]: Object.assign(Object.assign({}, merged.rules), merged.oas2Rules),
41
+ [oas_types_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, merged.rules), merged.oas3_0Rules),
42
+ [oas_types_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, merged.rules), merged.oas3_1Rules),
61
43
  };
62
44
  this.preprocessors = {
63
- [lint_1.OasVersion.Version2]: Object.assign(Object.assign({}, merged.preprocessors), merged.oas2Preprocessors),
64
- [lint_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, merged.preprocessors), merged.oas3_0Preprocessors),
65
- [lint_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, merged.preprocessors), merged.oas3_1Preprocessors),
45
+ [oas_types_1.OasVersion.Version2]: Object.assign(Object.assign({}, merged.preprocessors), merged.oas2Preprocessors),
46
+ [oas_types_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, merged.preprocessors), merged.oas3_0Preprocessors),
47
+ [oas_types_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, merged.preprocessors), merged.oas3_1Preprocessors),
66
48
  };
67
49
  this.decorators = {
68
- [lint_1.OasVersion.Version2]: Object.assign(Object.assign({}, merged.decorators), merged.oas2Decorators),
69
- [lint_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, merged.decorators), merged.oas3_0Decorators),
70
- [lint_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, merged.decorators), merged.oas3_1Decorators),
50
+ [oas_types_1.OasVersion.Version2]: Object.assign(Object.assign({}, merged.decorators), merged.oas2Decorators),
51
+ [oas_types_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, merged.decorators), merged.oas3_0Decorators),
52
+ [oas_types_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, merged.decorators), merged.oas3_1Decorators),
71
53
  };
72
- const dir = this.configFile ? path.dirname(this.configFile) : process.cwd();
54
+ const dir = this.configFile ? path.dirname(this.configFile) : (typeof process !== 'undefined' && process.cwd() || '');
73
55
  const ignoreFile = path.join(dir, exports.IGNORE_FILE);
74
56
  /* no crash when using it on the client */
75
57
  if (fs.hasOwnProperty('existsSync') && fs.existsSync(ignoreFile)) {
@@ -122,11 +104,12 @@ class LintConfig {
122
104
  for (const plugin of this.plugins) {
123
105
  if (plugin.typeExtension !== undefined) {
124
106
  switch (version) {
125
- case lint_1.OasVersion.Version3_0:
107
+ case oas_types_1.OasVersion.Version3_0:
108
+ case oas_types_1.OasVersion.Version3_1:
126
109
  if (!plugin.typeExtension.oas3)
127
110
  continue;
128
111
  extendedTypes = plugin.typeExtension.oas3(extendedTypes, version);
129
- case lint_1.OasVersion.Version2:
112
+ case oas_types_1.OasVersion.Version2:
130
113
  if (!plugin.typeExtension.oas2)
131
114
  continue;
132
115
  extendedTypes = plugin.typeExtension.oas2(extendedTypes, version);
@@ -193,13 +176,13 @@ class LintConfig {
193
176
  }
194
177
  getRulesForOasVersion(version) {
195
178
  switch (version) {
196
- case lint_1.OasMajorVersion.Version3:
179
+ case oas_types_1.OasMajorVersion.Version3:
197
180
  const oas3Rules = []; // default ruleset
198
181
  this.plugins.forEach((p) => { var _a; return ((_a = p.preprocessors) === null || _a === void 0 ? void 0 : _a.oas3) && oas3Rules.push(p.preprocessors.oas3); });
199
182
  this.plugins.forEach((p) => { var _a; return ((_a = p.rules) === null || _a === void 0 ? void 0 : _a.oas3) && oas3Rules.push(p.rules.oas3); });
200
183
  this.plugins.forEach((p) => { var _a; return ((_a = p.decorators) === null || _a === void 0 ? void 0 : _a.oas3) && oas3Rules.push(p.decorators.oas3); });
201
184
  return oas3Rules;
202
- case lint_1.OasMajorVersion.Version2:
185
+ case oas_types_1.OasMajorVersion.Version2:
203
186
  const oas2Rules = []; // default ruleset
204
187
  this.plugins.forEach((p) => { var _a; return ((_a = p.preprocessors) === null || _a === void 0 ? void 0 : _a.oas2) && oas2Rules.push(p.preprocessors.oas2); });
205
188
  this.plugins.forEach((p) => { var _a; return ((_a = p.rules) === null || _a === void 0 ? void 0 : _a.oas2) && oas2Rules.push(p.rules.oas2); });
@@ -209,7 +192,7 @@ class LintConfig {
209
192
  }
210
193
  skipRules(rules) {
211
194
  for (const ruleId of rules || []) {
212
- for (const version of Object.values(lint_1.OasVersion)) {
195
+ for (const version of Object.values(oas_types_1.OasVersion)) {
213
196
  if (this.rules[version][ruleId]) {
214
197
  this.rules[version][ruleId] = 'off';
215
198
  }
@@ -218,7 +201,7 @@ class LintConfig {
218
201
  }
219
202
  skipPreprocessors(preprocessors) {
220
203
  for (const preprocessorId of preprocessors || []) {
221
- for (const version of Object.values(lint_1.OasVersion)) {
204
+ for (const version of Object.values(oas_types_1.OasVersion)) {
222
205
  if (this.preprocessors[version][preprocessorId]) {
223
206
  this.preprocessors[version][preprocessorId] = 'off';
224
207
  }
@@ -227,7 +210,7 @@ class LintConfig {
227
210
  }
228
211
  skipDecorators(decorators) {
229
212
  for (const decoratorId of decorators || []) {
230
- for (const version of Object.values(lint_1.OasVersion)) {
213
+ for (const version of Object.values(oas_types_1.OasVersion)) {
231
214
  if (this.decorators[version][decoratorId]) {
232
215
  this.decorators[version][decoratorId] = 'off';
233
216
  }
@@ -253,77 +236,32 @@ class Config {
253
236
  }
254
237
  }
255
238
  exports.Config = Config;
256
- function loadConfig(configPath, customExtends) {
257
- var _a;
258
- return __awaiter(this, void 0, void 0, function* () {
259
- if (configPath === undefined) {
260
- configPath = findConfig();
261
- }
262
- let rawConfig = {};
263
- // let resolvedPlugins: Plugin[] = [];
264
- if (configPath !== undefined) {
265
- try {
266
- rawConfig = (yield utils_1.loadYaml(configPath));
267
- }
268
- catch (e) {
269
- throw new Error(`Error parsing config file at \`${configPath}\`: ${e.message}`);
270
- }
271
- }
272
- if (customExtends !== undefined) {
273
- rawConfig.lint = rawConfig.lint || {};
274
- rawConfig.lint.extends = customExtends;
275
- }
276
- const redoclyClient = new redocly_1.RedoclyClient();
277
- if (redoclyClient.hasToken()) {
278
- if (!rawConfig.resolve)
279
- rawConfig.resolve = {};
280
- if (!rawConfig.resolve.http)
281
- rawConfig.resolve.http = {};
282
- rawConfig.resolve.http.headers = [
283
- {
284
- matches: `https://api.${process.env.REDOCLY_DOMAIN || 'redoc.ly'}/registry/**`,
285
- name: 'Authorization',
286
- envVariable: undefined,
287
- value: (redoclyClient && (yield redoclyClient.getAuthorizationHeader())) || '',
288
- },
289
- ...((_a = rawConfig.resolve.http.headers) !== null && _a !== void 0 ? _a : []),
290
- ];
291
- }
292
- return new Config(rawConfig, configPath);
293
- });
294
- }
295
- exports.loadConfig = loadConfig;
296
- function findConfig() {
297
- if (fs.existsSync('.redocly.yaml')) {
298
- return '.redocly.yaml';
299
- }
300
- else if (fs.existsSync('.redocly.yml')) {
301
- return '.redocly.yml';
302
- }
303
- return undefined;
304
- }
305
239
  function resolvePresets(presets, plugins) {
306
240
  return presets.map((presetName) => {
307
241
  var _a;
308
- let preset = builtIn_1.builtInConfigs[presetName];
309
- if (!preset && presetName.indexOf('/') > -1) {
310
- const [pluginName, configName] = presetName.split('/');
311
- const plugin = plugins.find((p) => p.id === pluginName);
312
- if (!plugin) {
313
- throw new Error(`Invalid config ${colorette_1.red(presetName)}: plugin ${pluginName} is not included.`);
314
- }
315
- preset = (_a = plugin.configs) === null || _a === void 0 ? void 0 : _a[configName];
316
- if (!preset) {
317
- throw new Error(`Invalid config ${colorette_1.red(presetName)}: plugin ${pluginName} doesn't export config with name ${configName}.`);
318
- }
319
- return preset;
242
+ const { pluginId, configName } = parsePresetName(presetName);
243
+ const plugin = plugins.find((p) => p.id === pluginId);
244
+ if (!plugin) {
245
+ throw new Error(`Invalid config ${colorette_1.red(presetName)}: plugin ${pluginId} is not included.`);
320
246
  }
247
+ const preset = (_a = plugin.configs) === null || _a === void 0 ? void 0 : _a[configName];
321
248
  if (!preset) {
322
- throw new Error(`Invalid config ${colorette_1.red(presetName)}: there is no such built-in config.`);
249
+ throw new Error(pluginId
250
+ ? `Invalid config ${colorette_1.red(presetName)}: plugin ${pluginId} doesn't export config with name ${configName}.`
251
+ : `Invalid config ${colorette_1.red(presetName)}: there is no such built-in config.`);
323
252
  }
324
253
  return preset;
325
254
  });
326
255
  }
256
+ function parsePresetName(presetName) {
257
+ if (presetName.indexOf('/') > -1) {
258
+ const [pluginId, configName] = presetName.split('/');
259
+ return { pluginId, configName };
260
+ }
261
+ else {
262
+ return { pluginId: '', configName: presetName };
263
+ }
264
+ }
327
265
  function resolvePlugins(plugins, configPath = '') {
328
266
  if (!plugins)
329
267
  return [];
@@ -337,7 +275,7 @@ function resolvePlugins(plugins, configPath = '') {
337
275
  ? requireFunc(path.resolve(path.dirname(configPath), p))
338
276
  : p;
339
277
  const id = pluginModule.id;
340
- if (!id) {
278
+ if (typeof id !== 'string') {
341
279
  throw new Error(colorette_1.red(`Plugin must define \`id\` property in ${colorette_1.blue(p.toString())}.`));
342
280
  }
343
281
  if (seenPluginIds.has(id)) {
@@ -387,6 +325,8 @@ function resolvePlugins(plugins, configPath = '') {
387
325
  .filter(utils_1.notUndefined);
388
326
  }
389
327
  function prefixRules(rules, prefix) {
328
+ if (!prefix)
329
+ return rules;
390
330
  const res = {};
391
331
  for (const name of Object.keys(rules)) {
392
332
  res[`${prefix}/${name}`] = rules[name];
@@ -0,0 +1,2 @@
1
+ import { Config } from './config';
2
+ export declare function loadConfig(configPath?: string, customExtends?: string[]): Promise<Config>;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.loadConfig = void 0;
13
+ const fs = require("fs");
14
+ const redocly_1 = require("../redocly");
15
+ const utils_1 = require("../utils");
16
+ const config_1 = require("./config");
17
+ const builtIn_1 = require("./builtIn");
18
+ function loadConfig(configPath, customExtends) {
19
+ var _a, _b;
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ if (configPath === undefined) {
22
+ configPath = findConfig();
23
+ }
24
+ let rawConfig = {};
25
+ if (configPath !== undefined) {
26
+ try {
27
+ rawConfig = (yield utils_1.loadYaml(configPath));
28
+ }
29
+ catch (e) {
30
+ throw new Error(`Error parsing config file at \`${configPath}\`: ${e.message}`);
31
+ }
32
+ }
33
+ if (customExtends !== undefined) {
34
+ rawConfig.lint = rawConfig.lint || {};
35
+ rawConfig.lint.extends = customExtends;
36
+ }
37
+ const redoclyClient = new redocly_1.RedoclyClient();
38
+ if (redoclyClient.hasToken()) {
39
+ if (!rawConfig.resolve)
40
+ rawConfig.resolve = {};
41
+ if (!rawConfig.resolve.http)
42
+ rawConfig.resolve.http = {};
43
+ rawConfig.resolve.http.headers = [
44
+ {
45
+ matches: `https://api.${process.env.REDOCLY_DOMAIN || 'redoc.ly'}/registry/**`,
46
+ name: 'Authorization',
47
+ envVariable: undefined,
48
+ value: (redoclyClient && (yield redoclyClient.getAuthorizationHeader())) || '',
49
+ },
50
+ ...((_a = rawConfig.resolve.http.headers) !== null && _a !== void 0 ? _a : []),
51
+ ];
52
+ }
53
+ return new config_1.Config(Object.assign(Object.assign({}, rawConfig), { lint: Object.assign(Object.assign({}, rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.lint), { plugins: [...(((_b = rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.lint) === null || _b === void 0 ? void 0 : _b.plugins) || []), builtIn_1.defaultPlugin] }) }), configPath);
54
+ });
55
+ }
56
+ exports.loadConfig = loadConfig;
57
+ function findConfig() {
58
+ if (fs.existsSync('.redocly.yaml')) {
59
+ return '.redocly.yaml';
60
+ }
61
+ else if (fs.existsSync('.redocly.yml')) {
62
+ return '.redocly.yml';
63
+ }
64
+ return undefined;
65
+ }
@@ -1,4 +1,4 @@
1
- import { RuleSet, OasVersion } from '../lint';
1
+ import { RuleSet, OasVersion } from '../oas-types';
2
2
  import { LintConfig } from './config';
3
3
  export declare function initRules<T extends Function, P extends RuleSet<T>>(rules: P[], config: LintConfig, type: 'rules' | 'preprocessors' | 'decorators', oasVersion: OasVersion): {
4
4
  severity: import("..").ProblemSeverity;
@@ -105,7 +105,7 @@ function getLineColLocation(location) {
105
105
  if (location.pointer === undefined)
106
106
  return location;
107
107
  const { source, pointer, reportOnKey } = location;
108
- const ast = source.getAst();
108
+ const ast = source.getAst(yamlAst.safeLoad);
109
109
  const astNode = getAstNodeByPointer(ast, pointer, !!reportOnKey);
110
110
  return Object.assign(Object.assign(Object.assign({}, location), { pointer: undefined }), positionsToLoc(source.body, (_a = astNode === null || astNode === void 0 ? void 0 : astNode.startPosition) !== null && _a !== void 0 ? _a : 1, (_b = astNode === null || astNode === void 0 ? void 0 : astNode.endPosition) !== null && _b !== void 0 ? _b : 1));
111
111
  }