@redocly/openapi-core 1.0.0-beta.94 → 1.0.0-beta.97

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 (123) hide show
  1. package/README.md +1 -1
  2. package/__tests__/bundle.test.ts +6 -6
  3. package/__tests__/fixtures/extension.js +1 -1
  4. package/__tests__/login.test.ts +2 -2
  5. package/__tests__/ref-utils.test.ts +1 -1
  6. package/__tests__/utils.ts +30 -18
  7. package/lib/benchmark/benches/recommended-oas3.bench.js +2 -3
  8. package/lib/benchmark/utils.d.ts +2 -1
  9. package/lib/benchmark/utils.js +10 -7
  10. package/lib/bundle.d.ts +2 -2
  11. package/lib/config/all.d.ts +2 -2
  12. package/lib/config/builtIn.d.ts +1 -1
  13. package/lib/config/config-resolvers.d.ts +16 -0
  14. package/lib/config/config-resolvers.js +242 -0
  15. package/lib/config/config.d.ts +18 -130
  16. package/lib/config/config.js +34 -245
  17. package/lib/config/index.d.ts +7 -0
  18. package/lib/config/index.js +19 -0
  19. package/lib/config/load.d.ts +2 -1
  20. package/lib/config/load.js +20 -13
  21. package/lib/config/minimal.d.ts +2 -2
  22. package/lib/config/recommended.d.ts +2 -2
  23. package/lib/config/types.d.ts +113 -0
  24. package/lib/config/types.js +2 -0
  25. package/lib/config/utils.d.ts +13 -0
  26. package/lib/config/utils.js +160 -0
  27. package/lib/format/format.d.ts +1 -1
  28. package/lib/format/format.js +30 -1
  29. package/lib/index.d.ts +1 -2
  30. package/lib/index.js +5 -6
  31. package/lib/lint.d.ts +1 -1
  32. package/lib/lint.js +5 -7
  33. package/lib/redocly/index.d.ts +1 -1
  34. package/lib/redocly/index.js +10 -26
  35. package/lib/redocly/redocly-client-types.d.ts +1 -1
  36. package/lib/redocly/registry-api-types.d.ts +1 -0
  37. package/lib/redocly/registry-api.d.ts +2 -2
  38. package/lib/redocly/registry-api.js +2 -1
  39. package/lib/resolve.d.ts +1 -1
  40. package/lib/resolve.js +1 -2
  41. package/lib/rules/common/assertions/index.js +1 -1
  42. package/lib/rules/common/assertions/utils.d.ts +1 -1
  43. package/lib/rules/common/assertions/utils.js +6 -2
  44. package/lib/utils.d.ts +4 -2
  45. package/lib/utils.js +20 -3
  46. package/package.json +9 -6
  47. package/src/__tests__/lint.test.ts +1 -1
  48. package/src/benchmark/benches/recommended-oas3.bench.ts +2 -3
  49. package/src/benchmark/benchmark.js +1 -1
  50. package/src/benchmark/utils.ts +13 -8
  51. package/src/bundle.ts +2 -1
  52. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +157 -0
  53. package/src/config/__tests__/config-resolvers.test.ts +429 -0
  54. package/src/config/__tests__/config.test.ts +17 -29
  55. package/src/config/__tests__/fixtures/plugin.js +1 -1
  56. package/src/config/__tests__/fixtures/resolve-config/api/nested-config.yaml +12 -0
  57. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +67 -0
  58. package/src/config/__tests__/fixtures/resolve-config/local-config-with-circular.yaml +8 -0
  59. package/src/config/__tests__/fixtures/resolve-config/local-config-with-file.yaml +19 -0
  60. package/src/config/__tests__/fixtures/resolve-config/local-config.yaml +10 -0
  61. package/src/config/__tests__/fixtures/resolve-config/plugin.js +66 -0
  62. package/src/config/__tests__/fixtures/resolve-remote-configs/nested-remote-config.yaml +4 -0
  63. package/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml +5 -0
  64. package/src/config/__tests__/load.test.ts +8 -1
  65. package/src/config/all.ts +3 -2
  66. package/src/config/builtIn.ts +2 -1
  67. package/src/config/config-resolvers.ts +359 -0
  68. package/src/config/config.ts +60 -468
  69. package/src/config/index.ts +7 -0
  70. package/src/config/load.ts +37 -31
  71. package/src/config/minimal.ts +2 -2
  72. package/src/config/recommended.ts +2 -2
  73. package/src/config/types.ts +168 -0
  74. package/src/config/utils.ts +208 -0
  75. package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
  76. package/src/format/format.ts +38 -7
  77. package/src/index.ts +6 -2
  78. package/src/lint.ts +4 -5
  79. package/src/redocly/__tests__/redocly-client.test.ts +7 -0
  80. package/src/redocly/index.ts +14 -41
  81. package/src/redocly/redocly-client-types.ts +1 -1
  82. package/src/redocly/registry-api-types.ts +1 -0
  83. package/src/redocly/registry-api.ts +5 -1
  84. package/src/resolve.ts +2 -4
  85. package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
  86. package/src/rules/common/__tests__/info-description.test.ts +3 -3
  87. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  88. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  89. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  90. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +5 -5
  91. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  92. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
  93. package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
  94. package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
  95. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  96. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  97. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  98. package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
  99. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  100. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  101. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  102. package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
  103. package/src/rules/common/__tests__/paths-kebab-case.test.ts +3 -3
  104. package/src/rules/common/__tests__/spec.test.ts +1 -1
  105. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  106. package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
  107. package/src/rules/common/assertions/index.ts +1 -1
  108. package/src/rules/common/assertions/utils.ts +5 -2
  109. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  110. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +1 -1
  111. package/src/rules/oas2/__tests__/spec/utils.ts +10 -7
  112. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  113. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +6 -6
  114. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  115. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +8 -8
  116. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
  117. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  118. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  119. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +23 -14
  120. package/src/rules/oas3/__tests__/spec/spec.test.ts +4 -4
  121. package/src/rules/oas3/__tests__/spec/utils.ts +10 -7
  122. package/src/utils.ts +21 -4
  123. package/tsconfig.tsbuildinfo +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # openapi-core
2
2
 
3
- See https://github.com/Redocly/openapi-cli
3
+ See https://github.com/Redocly/redocly-cli
4
4
 
5
5
  ## Basic usage
6
6
 
@@ -4,7 +4,7 @@ import * as path from 'path';
4
4
  import { bundleDocument, bundle } from '../src/bundle';
5
5
 
6
6
  import { parseYamlToDocument, yamlSerializer } from './utils';
7
- import { LintConfig, Config } from '../src/config/config';
7
+ import { LintConfig, Config, ResolvedConfig } from '../src/config';
8
8
  import { BaseResolver } from '../src/resolve';
9
9
 
10
10
  describe('bundle', () => {
@@ -47,7 +47,7 @@ describe('bundle', () => {
47
47
 
48
48
  it('should bundle external refs', async () => {
49
49
  const { bundle: res, problems } = await bundle({
50
- config: new Config({}),
50
+ config: new Config({} as ResolvedConfig),
51
51
  ref: path.join(__dirname, 'fixtures/refs/openapi-with-external-refs.yaml'),
52
52
  });
53
53
  expect(problems).toHaveLength(0);
@@ -56,7 +56,7 @@ describe('bundle', () => {
56
56
 
57
57
  it('should bundle external refs and warn for conflicting names', async () => {
58
58
  const { bundle: res, problems } = await bundle({
59
- config: new Config({}),
59
+ config: new Config({} as ResolvedConfig),
60
60
  ref: path.join(__dirname, 'fixtures/refs/openapi-with-external-refs-conflicting-names.yaml'),
61
61
  });
62
62
  expect(problems).toHaveLength(1);
@@ -80,7 +80,7 @@ describe('bundle', () => {
80
80
 
81
81
  it('should place referenced schema inline when referenced schema name resolves to original schema name', async () => {
82
82
  const { bundle: res, problems } = await bundle({
83
- config: new Config({}),
83
+ config: new Config({} as ResolvedConfig),
84
84
  ref: path.join(__dirname, 'fixtures/refs/externalref.yaml'),
85
85
  });
86
86
 
@@ -90,7 +90,7 @@ describe('bundle', () => {
90
90
 
91
91
  it('should not place referened schema inline when component in question is not of type "schemas"', async () => {
92
92
  const { bundle: res, problems } = await bundle({
93
- config: new Config({}),
93
+ config: new Config({} as ResolvedConfig),
94
94
  ref: path.join(__dirname, 'fixtures/refs/external-request-body.yaml'),
95
95
  });
96
96
 
@@ -110,7 +110,7 @@ describe('bundle', () => {
110
110
  );
111
111
 
112
112
  const { bundle: res, problems } = await bundle({
113
- config: new Config({}),
113
+ config: new Config({} as ResolvedConfig),
114
114
  externalRefResolver: new BaseResolver({
115
115
  http: {
116
116
  customFetch: fetchMock,
@@ -1,6 +1,6 @@
1
1
  const { listOf } = require('../../types');
2
2
 
3
- /** @type {import('../../config/config').TypesExtension} */
3
+ /** @type {import('../../config/types').TypesExtension} */
4
4
  function oas3_0(types) {
5
5
  return {
6
6
  ...types,
@@ -1,6 +1,6 @@
1
1
  import { RedoclyClient } from '../src/redocly';
2
2
 
3
- describe('login', () => {
3
+ describe.skip('login', () => {
4
4
  it('should call login with setAccessTokens function', async () => {
5
5
  const client = new RedoclyClient();
6
6
  Object.defineProperty(client, 'registryApi', {
@@ -11,7 +11,7 @@ describe('login', () => {
11
11
  writable: true,
12
12
  configurable: true
13
13
  });
14
- await client.login('token');
14
+ await client.login('token'); // TODO: bug with rewrite local config file
15
15
  expect(client.registryApi.setAccessTokens).toHaveBeenCalled();
16
16
  });
17
17
  });
@@ -2,7 +2,7 @@ import outdent from 'outdent';
2
2
  import { parseYamlToDocument } from './utils';
3
3
  import { parseRef, refBaseName } from '../src/ref-utils';
4
4
  import { lintDocument } from '../src/lint';
5
- import { LintConfig } from '../src/config/config';
5
+ import { LintConfig } from '../src/config';
6
6
  import { BaseResolver } from '../src/resolve';
7
7
 
8
8
  describe('ref-utils', () => {
@@ -1,9 +1,10 @@
1
1
  import * as path from 'path';
2
2
 
3
3
  import { Document, Source, NormalizedProblem, parseYaml, stringifyYaml } from '../src';
4
- import { RuleConfig, LintConfig, Plugin, DecoratorConfig } from '../src/config/config';
4
+ import { LintConfig, resolveLint, resolvePlugins } from '../src/config';
5
5
  import { Oas3RuleSet } from '../src/oas-types';
6
- import { defaultPlugin } from '../src/config/builtIn';
6
+
7
+ import type { RuleConfig, Plugin, DecoratorConfig } from '../src/config';
7
8
 
8
9
  export function parseYamlToDocument(body: string, absoluteRef: string = ''): Document {
9
10
  return {
@@ -44,31 +45,42 @@ export const yamlSerializer = {
44
45
  },
45
46
  };
46
47
 
47
- export function makeConfigForRuleset(rules: Oas3RuleSet, plugin?: Partial<Plugin>, version: string = 'oas3') {
48
+ export function makeConfigForRuleset(
49
+ rules: Oas3RuleSet,
50
+ plugin?: Partial<Plugin>,
51
+ version: string = 'oas3',
52
+ ) {
48
53
  const rulesConf: Record<string, RuleConfig> = {};
49
54
  const ruleId = 'test';
50
55
  Object.keys(rules).forEach((name) => {
51
56
  rulesConf[`${ruleId}/${name}`] = 'error';
52
57
  });
58
+ const plugins = resolvePlugins([
59
+ {
60
+ ...plugin,
61
+ id: ruleId,
62
+ rules: { [version]: rules },
63
+ },
64
+ ]);
53
65
 
54
66
  return new LintConfig({
55
- plugins: [
56
- {
57
- ...plugin,
58
- id: ruleId,
59
- rules: { [version]: rules },
60
- },
61
- ],
62
- extends: [],
67
+ plugins,
63
68
  rules: rulesConf,
64
69
  });
65
70
  }
66
71
 
67
- export function makeConfig(rules: Record<string, RuleConfig>, decorators?: Record<string, DecoratorConfig>) {
68
- return new LintConfig({
69
- plugins: [defaultPlugin],
70
- extends: [],
71
- rules,
72
- decorators,
73
- });
72
+ export async function makeConfig(
73
+ rules: Record<string, RuleConfig>,
74
+ decorators?: Record<string, DecoratorConfig>,
75
+ ) {
76
+ return new LintConfig(
77
+ await resolveLint({
78
+ lintConfig: {
79
+ plugins: [],
80
+ extends: [],
81
+ rules,
82
+ decorators,
83
+ },
84
+ }),
85
+ );
74
86
  }
@@ -4,10 +4,9 @@ exports.measureAsync = exports.count = exports.name = void 0;
4
4
  const fs_1 = require("fs");
5
5
  const path_1 = require("path");
6
6
  const lint_1 = require("../../lint");
7
- const config_1 = require("../../config/config");
7
+ const config_1 = require("../../config");
8
8
  const resolve_1 = require("../../resolve");
9
9
  const utils_1 = require("../utils");
10
- const builtIn_1 = require("../../config/builtIn");
11
10
  exports.name = 'Validate with recommended rules';
12
11
  exports.count = 10;
13
12
  const rebillyDefinitionRef = path_1.resolve(path_1.join(__dirname, 'rebilly.yaml'));
@@ -16,7 +15,7 @@ function measureAsync() {
16
15
  return lint_1.lintDocument({
17
16
  externalRefResolver: new resolve_1.BaseResolver(),
18
17
  document: rebillyDocument,
19
- config: new config_1.LintConfig({ plugins: [builtIn_1.defaultPlugin] }),
18
+ config: new config_1.LintConfig(config_1.resolvePreset('recommended', [config_1.defaultPlugin])),
20
19
  });
21
20
  }
22
21
  exports.measureAsync = measureAsync;
@@ -1,5 +1,6 @@
1
1
  import { Document } from '../resolve';
2
2
  import { Oas3RuleSet } from '../oas-types';
3
- import { LintConfig, Plugin } from '../config/config';
3
+ import { LintConfig } from '../config';
4
+ import type { Plugin } from '../config/types';
4
5
  export declare function parseYamlToDocument(body: string, absoluteRef?: string): Document;
5
6
  export declare function makeConfigForRuleset(rules: Oas3RuleSet, plugin?: Partial<Plugin>): LintConfig;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeConfigForRuleset = exports.parseYamlToDocument = void 0;
4
4
  const js_yaml_1 = require("../js-yaml");
5
5
  const resolve_1 = require("../resolve");
6
- const config_1 = require("../config/config");
6
+ const config_1 = require("../config");
7
7
  function parseYamlToDocument(body, absoluteRef = '') {
8
8
  return {
9
9
  source: new resolve_1.Source(absoluteRef, body),
@@ -17,12 +17,15 @@ function makeConfigForRuleset(rules, plugin) {
17
17
  Object.keys(rules).forEach((name) => {
18
18
  rulesConf[`${ruleId}/${name}`] = 'error';
19
19
  });
20
- return new config_1.LintConfig({
21
- plugins: [
20
+ const extendConfigs = [
21
+ config_1.resolvePlugins([
22
22
  Object.assign(Object.assign({}, plugin), { id: ruleId, rules: { oas3: rules } }),
23
- ],
24
- extends: [],
25
- rules: rulesConf,
26
- });
23
+ ]),
24
+ ];
25
+ if (rules) {
26
+ extendConfigs.push({ rules });
27
+ }
28
+ const lint = config_1.mergeExtends(extendConfigs);
29
+ return new config_1.LintConfig(lint);
27
30
  }
28
31
  exports.makeConfigForRuleset = makeConfigForRuleset;
package/lib/bundle.d.ts CHANGED
@@ -2,7 +2,7 @@ import { BaseResolver, Document } from './resolve';
2
2
  import { Oas3Rule } from './visitors';
3
3
  import { NormalizedNodeType, NodeType } from './types';
4
4
  import { OasMajorVersion } from './oas-types';
5
- import type { Config, LintConfig } from './config/config';
5
+ import type { Config, LintConfig } from './config';
6
6
  export declare type Oas3RuleSet = Record<string, Oas3Rule>;
7
7
  export declare enum OasVersion {
8
8
  Version2 = "oas2",
@@ -42,4 +42,4 @@ export declare function bundleDocument(opts: {
42
42
  refTypes: Map<string, NormalizedNodeType> | undefined;
43
43
  visitorsData: Record<string, Record<string, unknown>>;
44
44
  }>;
45
- export declare function mapTypeToComponent(typeName: string, version: OasMajorVersion): "headers" | "responses" | "definitions" | "parameters" | "schemas" | "examples" | "requestBodies" | "securitySchemes" | "links" | "callbacks" | null;
45
+ export declare function mapTypeToComponent(typeName: string, version: OasMajorVersion): "headers" | "definitions" | "parameters" | "examples" | "responses" | "schemas" | "requestBodies" | "securitySchemes" | "links" | "callbacks" | null;
@@ -1,3 +1,3 @@
1
- import { LintRawConfig } from './config';
2
- declare const _default: LintRawConfig;
1
+ import type { PluginLintConfig } from "./types";
2
+ declare const _default: PluginLintConfig;
3
3
  export default _default;
@@ -1,3 +1,3 @@
1
- import { LintRawConfig, Plugin } from './config';
1
+ import type { LintRawConfig, Plugin } from './types';
2
2
  export declare const builtInConfigs: Record<string, LintRawConfig>;
3
3
  export declare const defaultPlugin: Plugin;
@@ -0,0 +1,16 @@
1
+ import { BaseResolver } from '../resolve';
2
+ import type { LintRawConfig, Plugin, RawConfig, ResolvedApi, ResolvedLintConfig } from './types';
3
+ import { Config } from './config';
4
+ export declare function resolveConfig(rawConfig: RawConfig, configPath?: string): Promise<Config>;
5
+ export declare function resolvePlugins(plugins: (string | Plugin)[] | null, configPath?: string): Plugin[];
6
+ export declare function resolveApis({ rawConfig, configPath, resolver, }: {
7
+ rawConfig: RawConfig;
8
+ configPath?: string;
9
+ resolver?: BaseResolver;
10
+ }): Promise<Record<string, ResolvedApi>>;
11
+ export declare function resolveLint(lintOpts: {
12
+ lintConfig?: LintRawConfig;
13
+ configPath?: string;
14
+ resolver?: BaseResolver;
15
+ }, parentConfigPaths?: string[], extendPaths?: string[]): Promise<ResolvedLintConfig>;
16
+ export declare function resolvePreset(presetName: string, plugins: Plugin[]): ResolvedLintConfig;
@@ -0,0 +1,242 @@
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
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.resolvePreset = exports.resolveLint = exports.resolveApis = exports.resolvePlugins = exports.resolveConfig = void 0;
24
+ const path = require("path");
25
+ const colorette_1 = require("colorette");
26
+ const ref_utils_1 = require("../ref-utils");
27
+ const resolve_1 = require("../resolve");
28
+ const builtIn_1 = require("./builtIn");
29
+ const utils_1 = require("./utils");
30
+ const utils_2 = require("../utils");
31
+ const config_1 = require("./config");
32
+ function resolveConfig(rawConfig, configPath) {
33
+ var _a, _b, _c, _d, _e;
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ if ((_b = (_a = rawConfig.lint) === null || _a === void 0 ? void 0 : _a.extends) === null || _b === void 0 ? void 0 : _b.some(utils_2.isNotString)) {
36
+ throw new Error(`Error configuration format not detected in extends value must contain strings`);
37
+ }
38
+ const resolver = new resolve_1.BaseResolver(utils_1.getResolveConfig(rawConfig.resolve));
39
+ const configExtends = (_d = (_c = rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.lint) === null || _c === void 0 ? void 0 : _c.extends) !== null && _d !== void 0 ? _d : ['recommended'];
40
+ const recommendedFallback = !((_e = rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.lint) === null || _e === void 0 ? void 0 : _e.extends);
41
+ const lintConfig = Object.assign(Object.assign({}, rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.lint), { extends: configExtends, recommendedFallback });
42
+ const apis = yield resolveApis({
43
+ rawConfig: Object.assign(Object.assign({}, rawConfig), { lint: lintConfig }),
44
+ configPath,
45
+ resolver,
46
+ });
47
+ const lint = yield resolveLint({
48
+ lintConfig,
49
+ configPath,
50
+ resolver,
51
+ });
52
+ return new config_1.Config(Object.assign(Object.assign({}, rawConfig), { apis,
53
+ lint }), configPath);
54
+ });
55
+ }
56
+ exports.resolveConfig = resolveConfig;
57
+ function resolvePlugins(plugins, configPath = '') {
58
+ if (!plugins)
59
+ return [];
60
+ // @ts-ignore
61
+ const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require;
62
+ const seenPluginIds = new Map();
63
+ return plugins
64
+ .map((p) => {
65
+ if (utils_2.isString(p) && ref_utils_1.isAbsoluteUrl(p)) {
66
+ throw new Error(colorette_1.red(`We don't support remote plugins yet.`));
67
+ }
68
+ // TODO: resolve npm packages similar to eslint
69
+ const pluginModule = utils_2.isString(p)
70
+ ? requireFunc(path.resolve(path.dirname(configPath), p))
71
+ : p;
72
+ const id = pluginModule.id;
73
+ if (typeof id !== 'string') {
74
+ throw new Error(colorette_1.red(`Plugin must define \`id\` property in ${colorette_1.blue(p.toString())}.`));
75
+ }
76
+ if (seenPluginIds.has(id)) {
77
+ const pluginPath = seenPluginIds.get(id);
78
+ throw new Error(colorette_1.red(`Plugin "id" must be unique. Plugin ${colorette_1.blue(p.toString())} uses id "${colorette_1.blue(id)}" already seen in ${colorette_1.blue(pluginPath)}`));
79
+ }
80
+ seenPluginIds.set(id, p.toString());
81
+ const plugin = Object.assign(Object.assign({ id }, (pluginModule.configs ? { configs: pluginModule.configs } : {})), (pluginModule.typeExtension ? { typeExtension: pluginModule.typeExtension } : {}));
82
+ if (pluginModule.rules) {
83
+ if (!pluginModule.rules.oas3 && !pluginModule.rules.oas2) {
84
+ throw new Error(`Plugin rules must have \`oas3\` or \`oas2\` rules "${p}.`);
85
+ }
86
+ plugin.rules = {};
87
+ if (pluginModule.rules.oas3) {
88
+ plugin.rules.oas3 = utils_1.prefixRules(pluginModule.rules.oas3, id);
89
+ }
90
+ if (pluginModule.rules.oas2) {
91
+ plugin.rules.oas2 = utils_1.prefixRules(pluginModule.rules.oas2, id);
92
+ }
93
+ }
94
+ if (pluginModule.preprocessors) {
95
+ if (!pluginModule.preprocessors.oas3 && !pluginModule.preprocessors.oas2) {
96
+ throw new Error(`Plugin \`preprocessors\` must have \`oas3\` or \`oas2\` preprocessors "${p}.`);
97
+ }
98
+ plugin.preprocessors = {};
99
+ if (pluginModule.preprocessors.oas3) {
100
+ plugin.preprocessors.oas3 = utils_1.prefixRules(pluginModule.preprocessors.oas3, id);
101
+ }
102
+ if (pluginModule.preprocessors.oas2) {
103
+ plugin.preprocessors.oas2 = utils_1.prefixRules(pluginModule.preprocessors.oas2, id);
104
+ }
105
+ }
106
+ if (pluginModule.decorators) {
107
+ if (!pluginModule.decorators.oas3 && !pluginModule.decorators.oas2) {
108
+ throw new Error(`Plugin \`decorators\` must have \`oas3\` or \`oas2\` decorators "${p}.`);
109
+ }
110
+ plugin.decorators = {};
111
+ if (pluginModule.decorators.oas3) {
112
+ plugin.decorators.oas3 = utils_1.prefixRules(pluginModule.decorators.oas3, id);
113
+ }
114
+ if (pluginModule.decorators.oas2) {
115
+ plugin.decorators.oas2 = utils_1.prefixRules(pluginModule.decorators.oas2, id);
116
+ }
117
+ }
118
+ return plugin;
119
+ })
120
+ .filter(utils_2.notUndefined);
121
+ }
122
+ exports.resolvePlugins = resolvePlugins;
123
+ function resolveApis({ rawConfig, configPath = '', resolver, }) {
124
+ var _a, _b;
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ const { apis = {}, lint: lintConfig = {} } = rawConfig;
127
+ let resolvedApis = {};
128
+ for (const [apiName, apiContent] of Object.entries(apis || {})) {
129
+ if ((_b = (_a = apiContent.lint) === null || _a === void 0 ? void 0 : _a.extends) === null || _b === void 0 ? void 0 : _b.some(utils_2.isNotString)) {
130
+ throw new Error(`Error configuration format not detected in extends value must contain strings`);
131
+ }
132
+ const rawLintConfig = getMergedLintRawConfig(lintConfig, apiContent.lint);
133
+ const apiLint = yield resolveLint({
134
+ lintConfig: rawLintConfig,
135
+ configPath,
136
+ resolver,
137
+ });
138
+ resolvedApis[apiName] = Object.assign(Object.assign({}, apiContent), { lint: apiLint });
139
+ }
140
+ return resolvedApis;
141
+ });
142
+ }
143
+ exports.resolveApis = resolveApis;
144
+ function resolveAndMergeNestedLint({ lintConfig, configPath = '', resolver = new resolve_1.BaseResolver(), }, parentConfigPaths = [], extendPaths = []) {
145
+ var _a, _b, _c;
146
+ return __awaiter(this, void 0, void 0, function* () {
147
+ if (parentConfigPaths.includes(configPath)) {
148
+ throw new Error(`Circular dependency in config file: "${configPath}"`);
149
+ }
150
+ const plugins = utils_1.getUniquePlugins(resolvePlugins([...((lintConfig === null || lintConfig === void 0 ? void 0 : lintConfig.plugins) || []), builtIn_1.defaultPlugin], configPath));
151
+ const pluginPaths = (_a = lintConfig === null || lintConfig === void 0 ? void 0 : lintConfig.plugins) === null || _a === void 0 ? void 0 : _a.filter(utils_2.isString).map((p) => path.resolve(path.dirname(configPath), p));
152
+ const resolvedConfigPath = ref_utils_1.isAbsoluteUrl(configPath)
153
+ ? configPath
154
+ : configPath && path.resolve(configPath);
155
+ const extendConfigs = yield Promise.all(((_b = lintConfig === null || lintConfig === void 0 ? void 0 : lintConfig.extends) === null || _b === void 0 ? void 0 : _b.map((presetItem) => __awaiter(this, void 0, void 0, function* () {
156
+ if (!ref_utils_1.isAbsoluteUrl(presetItem) && !path.extname(presetItem)) {
157
+ return resolvePreset(presetItem, plugins);
158
+ }
159
+ const pathItem = ref_utils_1.isAbsoluteUrl(presetItem)
160
+ ? presetItem
161
+ : ref_utils_1.isAbsoluteUrl(configPath)
162
+ ? new URL(presetItem, configPath).href
163
+ : path.resolve(path.dirname(configPath), presetItem);
164
+ const extendedLintConfig = yield loadExtendLintConfig(pathItem, resolver);
165
+ return yield resolveAndMergeNestedLint({
166
+ lintConfig: extendedLintConfig,
167
+ configPath: pathItem,
168
+ resolver: resolver,
169
+ }, [...parentConfigPaths, resolvedConfigPath], extendPaths);
170
+ }))) || []);
171
+ const _d = utils_1.mergeExtends([
172
+ ...extendConfigs,
173
+ Object.assign(Object.assign({}, lintConfig), { plugins, extends: undefined, extendPaths: [...parentConfigPaths, resolvedConfigPath], pluginPaths }),
174
+ ]), { plugins: mergedPlugins = [] } = _d, lint = __rest(_d, ["plugins"]);
175
+ return Object.assign(Object.assign({}, lint), { extendPaths: (_c = lint.extendPaths) === null || _c === void 0 ? void 0 : _c.filter((path) => path && !ref_utils_1.isAbsoluteUrl(path)), plugins: utils_1.getUniquePlugins(mergedPlugins), recommendedFallback: lintConfig === null || lintConfig === void 0 ? void 0 : lintConfig.recommendedFallback, doNotResolveExamples: lintConfig === null || lintConfig === void 0 ? void 0 : lintConfig.doNotResolveExamples });
176
+ });
177
+ }
178
+ function resolveLint(lintOpts, parentConfigPaths = [], extendPaths = []) {
179
+ return __awaiter(this, void 0, void 0, function* () {
180
+ const resolvedLint = yield resolveAndMergeNestedLint(lintOpts, parentConfigPaths, extendPaths);
181
+ return Object.assign(Object.assign({}, resolvedLint), { rules: resolvedLint.rules && groupLintAssertionRules(resolvedLint.rules) });
182
+ });
183
+ }
184
+ exports.resolveLint = resolveLint;
185
+ function resolvePreset(presetName, plugins) {
186
+ var _a;
187
+ const { pluginId, configName } = utils_1.parsePresetName(presetName);
188
+ const plugin = plugins.find((p) => p.id === pluginId);
189
+ if (!plugin) {
190
+ throw new Error(`Invalid config ${colorette_1.red(presetName)}: plugin ${pluginId} is not included.`);
191
+ }
192
+ const preset = (_a = plugin.configs) === null || _a === void 0 ? void 0 : _a[configName];
193
+ if (!preset) {
194
+ throw new Error(pluginId
195
+ ? `Invalid config ${colorette_1.red(presetName)}: plugin ${pluginId} doesn't export config with name ${configName}.`
196
+ : `Invalid config ${colorette_1.red(presetName)}: there is no such built-in config.`);
197
+ }
198
+ return preset;
199
+ }
200
+ exports.resolvePreset = resolvePreset;
201
+ function loadExtendLintConfig(filePath, resolver) {
202
+ return __awaiter(this, void 0, void 0, function* () {
203
+ try {
204
+ const fileSource = yield resolver.loadExternalRef(filePath);
205
+ const rawConfig = utils_1.transformConfig(utils_2.parseYaml(fileSource.body));
206
+ if (!rawConfig.lint) {
207
+ throw new Error(`Lint configuration format not detected: "${filePath}"`);
208
+ }
209
+ return rawConfig.lint;
210
+ }
211
+ catch (error) {
212
+ throw new Error(`Failed to load "${filePath}": ${error.message}`);
213
+ }
214
+ });
215
+ }
216
+ function getMergedLintRawConfig(configLint, apiLint) {
217
+ const resultLint = Object.assign(Object.assign(Object.assign({}, configLint), apiLint), { rules: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.rules), apiLint === null || apiLint === void 0 ? void 0 : apiLint.rules), oas2Rules: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas2Rules), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas2Rules), oas3_0Rules: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas3_0Rules), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas3_0Rules), oas3_1Rules: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas3_1Rules), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas3_1Rules), preprocessors: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.preprocessors), apiLint === null || apiLint === void 0 ? void 0 : apiLint.preprocessors), oas2Preprocessors: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas2Preprocessors), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas2Preprocessors), oas3_0Preprocessors: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas3_0Preprocessors), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas3_0Preprocessors), oas3_1Preprocessors: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas3_1Preprocessors), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas3_1Preprocessors), decorators: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.decorators), apiLint === null || apiLint === void 0 ? void 0 : apiLint.decorators), oas2Decorators: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas2Decorators), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas2Decorators), oas3_0Decorators: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas3_0Decorators), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas3_0Decorators), oas3_1Decorators: Object.assign(Object.assign({}, configLint === null || configLint === void 0 ? void 0 : configLint.oas3_1Decorators), apiLint === null || apiLint === void 0 ? void 0 : apiLint.oas3_1Decorators), recommendedFallback: (apiLint === null || apiLint === void 0 ? void 0 : apiLint.extends) ? false : configLint.recommendedFallback });
218
+ return resultLint;
219
+ }
220
+ function groupLintAssertionRules(rules) {
221
+ if (!rules) {
222
+ return rules;
223
+ }
224
+ // Create a new record to avoid mutating original
225
+ const transformedRules = {};
226
+ // Collect assertion rules
227
+ const assertions = [];
228
+ for (const [ruleKey, rule] of Object.entries(rules)) {
229
+ if (ruleKey.startsWith('assert/') && typeof rule === 'object' && rule !== null) {
230
+ const assertion = rule;
231
+ assertions.push(Object.assign(Object.assign({}, assertion), { assertionId: ruleKey.replace('assert/', '') }));
232
+ }
233
+ else {
234
+ // If it's not an assertion, keep it as is
235
+ transformedRules[ruleKey] = rule;
236
+ }
237
+ }
238
+ if (assertions.length > 0) {
239
+ transformedRules.assertions = assertions;
240
+ }
241
+ return transformedRules;
242
+ }