@redocly/openapi-core 1.0.0-beta.93 → 1.0.0-beta.96

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 (127) 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__/normalizeVisitors.test.ts +1 -1
  6. package/__tests__/ref-utils.test.ts +1 -1
  7. package/__tests__/utils.ts +30 -18
  8. package/__tests__/walk.test.ts +6 -6
  9. package/lib/benchmark/benches/recommended-oas3.bench.js +2 -3
  10. package/lib/benchmark/utils.d.ts +2 -1
  11. package/lib/benchmark/utils.js +10 -7
  12. package/lib/bundle.d.ts +2 -2
  13. package/lib/config/all.d.ts +2 -2
  14. package/lib/config/builtIn.d.ts +1 -1
  15. package/lib/config/config-resolvers.d.ts +16 -0
  16. package/lib/config/config-resolvers.js +213 -0
  17. package/lib/config/config.d.ts +14 -129
  18. package/lib/config/config.js +17 -234
  19. package/lib/config/index.d.ts +7 -0
  20. package/lib/config/index.js +19 -0
  21. package/lib/config/load.d.ts +2 -1
  22. package/lib/config/load.js +20 -13
  23. package/lib/config/minimal.d.ts +2 -2
  24. package/lib/config/recommended.d.ts +2 -2
  25. package/lib/config/types.d.ts +113 -0
  26. package/lib/config/types.js +2 -0
  27. package/lib/config/utils.d.ts +13 -0
  28. package/lib/config/utils.js +160 -0
  29. package/lib/format/format.d.ts +1 -1
  30. package/lib/format/format.js +28 -0
  31. package/lib/index.d.ts +1 -2
  32. package/lib/index.js +5 -6
  33. package/lib/lint.d.ts +1 -1
  34. package/lib/lint.js +5 -7
  35. package/lib/redocly/index.d.ts +1 -1
  36. package/lib/redocly/index.js +1 -1
  37. package/lib/redocly/redocly-client-types.d.ts +1 -1
  38. package/lib/redocly/registry-api.d.ts +1 -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/types/index.js +2 -2
  45. package/lib/types/oas3_1.js +31 -5
  46. package/lib/utils.d.ts +4 -1
  47. package/lib/utils.js +18 -1
  48. package/package.json +7 -4
  49. package/src/__tests__/lint.test.ts +1 -1
  50. package/src/benchmark/benches/recommended-oas3.bench.ts +2 -3
  51. package/src/benchmark/benchmark.js +1 -1
  52. package/src/benchmark/utils.ts +13 -8
  53. package/src/bundle.ts +2 -1
  54. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +140 -0
  55. package/src/config/__tests__/config-resolvers.test.ts +398 -0
  56. package/src/config/__tests__/config.test.ts +244 -0
  57. package/src/config/__tests__/fixtures/plugin.js +1 -1
  58. package/src/config/__tests__/fixtures/resolve-config/api/nested-config.yaml +7 -0
  59. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +67 -0
  60. package/src/config/__tests__/fixtures/resolve-config/local-config-with-circular.yaml +8 -0
  61. package/src/config/__tests__/fixtures/resolve-config/local-config-with-file.yaml +12 -0
  62. package/src/config/__tests__/fixtures/resolve-config/local-config.yaml +10 -0
  63. package/src/config/__tests__/fixtures/resolve-config/plugin.js +66 -0
  64. package/src/config/__tests__/fixtures/resolve-remote-configs/nested-remote-config.yaml +4 -0
  65. package/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml +5 -0
  66. package/src/config/__tests__/load.test.ts +8 -1
  67. package/src/config/all.ts +3 -2
  68. package/src/config/builtIn.ts +2 -1
  69. package/src/config/config-resolvers.ts +304 -0
  70. package/src/config/config.ts +40 -457
  71. package/src/config/index.ts +7 -0
  72. package/src/config/load.ts +37 -31
  73. package/src/config/minimal.ts +2 -2
  74. package/src/config/recommended.ts +2 -2
  75. package/src/config/types.ts +168 -0
  76. package/src/config/utils.ts +208 -0
  77. package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
  78. package/src/format/format.ts +36 -6
  79. package/src/index.ts +6 -2
  80. package/src/lint.ts +4 -5
  81. package/src/redocly/__tests__/redocly-client.test.ts +7 -0
  82. package/src/redocly/index.ts +4 -2
  83. package/src/redocly/redocly-client-types.ts +1 -1
  84. package/src/redocly/registry-api.ts +3 -1
  85. package/src/resolve.ts +2 -4
  86. package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
  87. package/src/rules/common/__tests__/info-description.test.ts +3 -3
  88. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  89. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  90. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  91. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +5 -5
  92. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  93. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
  94. package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
  95. package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
  96. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  97. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  98. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  99. package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
  100. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  101. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  102. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  103. package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
  104. package/src/rules/common/__tests__/paths-kebab-case.test.ts +3 -3
  105. package/src/rules/common/__tests__/spec.test.ts +1 -1
  106. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  107. package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
  108. package/src/rules/common/assertions/index.ts +1 -1
  109. package/src/rules/common/assertions/utils.ts +5 -2
  110. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  111. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +1 -1
  112. package/src/rules/oas2/__tests__/spec/utils.ts +10 -7
  113. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  114. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +6 -6
  115. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  116. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +8 -8
  117. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
  118. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  119. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  120. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +23 -14
  121. package/src/rules/oas3/__tests__/spec/servers.test.ts +1 -1
  122. package/src/rules/oas3/__tests__/spec/spec.test.ts +4 -4
  123. package/src/rules/oas3/__tests__/spec/utils.ts +10 -7
  124. package/src/types/index.ts +2 -2
  125. package/src/types/oas3_1.ts +32 -7
  126. package/src/utils.ts +18 -2
  127. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,113 @@
1
+ import type { ProblemSeverity } from '../walk';
2
+ import type { Oas3PreprocessorsSet, OasMajorVersion, Oas3DecoratorsSet, Oas2RuleSet, Oas2PreprocessorsSet, Oas2DecoratorsSet, Oas3RuleSet, OasVersion } from '../oas-types';
3
+ import type { NodeType } from '../types';
4
+ export declare type RuleConfig = ProblemSeverity | 'off' | ({
5
+ severity?: ProblemSeverity;
6
+ } & Record<string, any>);
7
+ export declare type PreprocessorConfig = ProblemSeverity | 'off' | 'on' | ({
8
+ severity?: ProblemSeverity;
9
+ } & Record<string, any>);
10
+ export declare type DecoratorConfig = PreprocessorConfig;
11
+ export declare type LintRawConfig = {
12
+ plugins?: (string | Plugin)[];
13
+ extends?: string[];
14
+ doNotResolveExamples?: boolean;
15
+ recommendedFallback?: boolean;
16
+ rules?: Record<string, RuleConfig>;
17
+ oas2Rules?: Record<string, RuleConfig>;
18
+ oas3_0Rules?: Record<string, RuleConfig>;
19
+ oas3_1Rules?: Record<string, RuleConfig>;
20
+ preprocessors?: Record<string, PreprocessorConfig>;
21
+ oas2Preprocessors?: Record<string, PreprocessorConfig>;
22
+ oas3_0Preprocessors?: Record<string, PreprocessorConfig>;
23
+ oas3_1Preprocessors?: Record<string, PreprocessorConfig>;
24
+ decorators?: Record<string, DecoratorConfig>;
25
+ oas2Decorators?: Record<string, DecoratorConfig>;
26
+ oas3_0Decorators?: Record<string, DecoratorConfig>;
27
+ oas3_1Decorators?: Record<string, DecoratorConfig>;
28
+ };
29
+ export declare type ResolvedLintConfig = PluginLintConfig & {
30
+ plugins?: Plugin[];
31
+ recommendedFallback?: boolean;
32
+ extends?: void | never;
33
+ extendPaths?: string[];
34
+ pluginPaths?: string[];
35
+ };
36
+ export declare type PreprocessorsConfig = {
37
+ oas3?: Oas3PreprocessorsSet;
38
+ oas2?: Oas2PreprocessorsSet;
39
+ };
40
+ export declare type DecoratorsConfig = {
41
+ oas3?: Oas3DecoratorsSet;
42
+ oas2?: Oas2DecoratorsSet;
43
+ };
44
+ export declare type TypesExtensionFn = (types: Record<string, NodeType>, oasVersion: OasVersion) => Record<string, NodeType>;
45
+ export declare type TypeExtensionsConfig = Partial<Record<OasMajorVersion, TypesExtensionFn>>;
46
+ export declare type CustomRulesConfig = {
47
+ oas3?: Oas3RuleSet;
48
+ oas2?: Oas2RuleSet;
49
+ };
50
+ export declare type Plugin = {
51
+ id: string;
52
+ configs?: Record<string, PluginLintConfig>;
53
+ rules?: CustomRulesConfig;
54
+ preprocessors?: PreprocessorsConfig;
55
+ decorators?: DecoratorsConfig;
56
+ typeExtension?: TypeExtensionsConfig;
57
+ };
58
+ export declare type PluginLintConfig = Omit<LintRawConfig, 'plugins' | 'extends'>;
59
+ export declare type ResolveHeader = {
60
+ name: string;
61
+ envVariable?: undefined;
62
+ value: string;
63
+ matches: string;
64
+ } | {
65
+ name: string;
66
+ value?: undefined;
67
+ envVariable: string;
68
+ matches: string;
69
+ };
70
+ export declare type RawResolveConfig = {
71
+ http?: Partial<HttpResolveConfig>;
72
+ };
73
+ export declare type HttpResolveConfig = {
74
+ headers: ResolveHeader[];
75
+ customFetch?: Function;
76
+ };
77
+ export declare type ResolveConfig = {
78
+ http: HttpResolveConfig;
79
+ };
80
+ export declare type Region = 'us' | 'eu';
81
+ export declare type AccessTokens = {
82
+ [region in Region]?: string;
83
+ };
84
+ export declare type DeprecatedRawConfig = {
85
+ apiDefinitions?: Record<string, string>;
86
+ lint?: LintRawConfig;
87
+ resolve?: RawResolveConfig;
88
+ region?: Region;
89
+ referenceDocs?: Record<string, any>;
90
+ };
91
+ export declare type Api = {
92
+ root: string;
93
+ lint?: Omit<LintRawConfig, 'plugins'>;
94
+ 'features.openapi'?: Record<string, any>;
95
+ 'features.mockServer'?: Record<string, any>;
96
+ };
97
+ export declare type ResolvedApi = Omit<Api, 'lint'> & {
98
+ lint: Omit<ResolvedLintConfig, 'plugins'>;
99
+ };
100
+ export declare type RawConfig = {
101
+ apis?: Record<string, Api>;
102
+ lint?: LintRawConfig;
103
+ resolve?: RawResolveConfig;
104
+ region?: Region;
105
+ 'features.openapi'?: Record<string, any>;
106
+ 'features.mockServer'?: Record<string, any>;
107
+ organization?: string;
108
+ };
109
+ export declare type ResolvedConfig = Omit<RawConfig, 'lint' | 'apis'> & {
110
+ lint: ResolvedLintConfig;
111
+ apis: Record<string, ResolvedApi>;
112
+ };
113
+ export declare type RulesFields = 'rules' | 'oas2Rules' | 'oas3_0Rules' | 'oas3_1Rules' | 'preprocessors' | 'oas2Preprocessors' | 'oas3_0Preprocessors' | 'oas3_1Preprocessors' | 'decorators' | 'oas2Decorators' | 'oas3_0Decorators' | 'oas3_1Decorators';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ import { Config } from './config';
2
+ import type { Api, DeprecatedRawConfig, Plugin, RawConfig, RawResolveConfig, ResolveConfig, ResolvedLintConfig, RulesFields } from './types';
3
+ export declare function parsePresetName(presetName: string): {
4
+ pluginId: string;
5
+ configName: string;
6
+ };
7
+ export declare function transformApiDefinitionsToApis(apiDefinitions?: Record<string, string>): Record<string, Api>;
8
+ export declare function prefixRules<T extends Record<string, any>>(rules: T, prefix: string): any;
9
+ export declare function mergeExtends(rulesConfList: ResolvedLintConfig[]): Omit<ResolvedLintConfig, RulesFields> & Required<Pick<ResolvedLintConfig, RulesFields>>;
10
+ export declare function getMergedConfig(config: Config, entrypointAlias?: string): Config;
11
+ export declare function transformConfig(rawConfig: DeprecatedRawConfig | RawConfig): RawConfig;
12
+ export declare function getResolveConfig(resolve?: RawResolveConfig): ResolveConfig;
13
+ export declare function getUniquePlugins(plugins: Plugin[]): Plugin[];
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.getUniquePlugins = exports.getResolveConfig = exports.transformConfig = exports.getMergedConfig = exports.mergeExtends = exports.prefixRules = exports.transformApiDefinitionsToApis = exports.parsePresetName = void 0;
15
+ const colorette_1 = require("colorette");
16
+ const utils_1 = require("../utils");
17
+ const config_1 = require("./config");
18
+ function parsePresetName(presetName) {
19
+ if (presetName.indexOf('/') > -1) {
20
+ const [pluginId, configName] = presetName.split('/');
21
+ return { pluginId, configName };
22
+ }
23
+ else {
24
+ return { pluginId: '', configName: presetName };
25
+ }
26
+ }
27
+ exports.parsePresetName = parsePresetName;
28
+ function transformApiDefinitionsToApis(apiDefinitions = {}) {
29
+ let apis = {};
30
+ for (const [apiName, apiPath] of Object.entries(apiDefinitions)) {
31
+ apis[apiName] = { root: apiPath };
32
+ }
33
+ return apis;
34
+ }
35
+ exports.transformApiDefinitionsToApis = transformApiDefinitionsToApis;
36
+ function prefixRules(rules, prefix) {
37
+ if (!prefix)
38
+ return rules;
39
+ const res = {};
40
+ for (const name of Object.keys(rules)) {
41
+ res[`${prefix}/${name}`] = rules[name];
42
+ }
43
+ return res;
44
+ }
45
+ exports.prefixRules = prefixRules;
46
+ function mergeExtends(rulesConfList) {
47
+ const result = {
48
+ rules: {},
49
+ oas2Rules: {},
50
+ oas3_0Rules: {},
51
+ oas3_1Rules: {},
52
+ preprocessors: {},
53
+ oas2Preprocessors: {},
54
+ oas3_0Preprocessors: {},
55
+ oas3_1Preprocessors: {},
56
+ decorators: {},
57
+ oas2Decorators: {},
58
+ oas3_0Decorators: {},
59
+ oas3_1Decorators: {},
60
+ plugins: [],
61
+ pluginPaths: [],
62
+ extendPaths: [],
63
+ };
64
+ for (let rulesConf of rulesConfList) {
65
+ if (rulesConf.extends) {
66
+ throw new Error(`\`extends\` is not supported in shared configs yet: ${JSON.stringify(rulesConf, null, 2)}.`);
67
+ }
68
+ Object.assign(result.rules, rulesConf.rules);
69
+ Object.assign(result.oas2Rules, rulesConf.oas2Rules);
70
+ utils_1.assignExisting(result.oas2Rules, rulesConf.rules || {});
71
+ Object.assign(result.oas3_0Rules, rulesConf.oas3_0Rules);
72
+ utils_1.assignExisting(result.oas3_0Rules, rulesConf.rules || {});
73
+ Object.assign(result.oas3_1Rules, rulesConf.oas3_1Rules);
74
+ utils_1.assignExisting(result.oas3_1Rules, rulesConf.rules || {});
75
+ Object.assign(result.preprocessors, rulesConf.preprocessors);
76
+ Object.assign(result.oas2Preprocessors, rulesConf.oas2Preprocessors);
77
+ utils_1.assignExisting(result.oas2Preprocessors, rulesConf.preprocessors || {});
78
+ Object.assign(result.oas3_0Preprocessors, rulesConf.oas3_0Preprocessors);
79
+ utils_1.assignExisting(result.oas3_0Preprocessors, rulesConf.preprocessors || {});
80
+ Object.assign(result.oas3_1Preprocessors, rulesConf.oas3_1Preprocessors);
81
+ utils_1.assignExisting(result.oas3_1Preprocessors, rulesConf.preprocessors || {});
82
+ Object.assign(result.decorators, rulesConf.decorators);
83
+ Object.assign(result.oas2Decorators, rulesConf.oas2Decorators);
84
+ utils_1.assignExisting(result.oas2Decorators, rulesConf.decorators || {});
85
+ Object.assign(result.oas3_0Decorators, rulesConf.oas3_0Decorators);
86
+ utils_1.assignExisting(result.oas3_0Decorators, rulesConf.decorators || {});
87
+ Object.assign(result.oas3_1Decorators, rulesConf.oas3_1Decorators);
88
+ utils_1.assignExisting(result.oas3_1Decorators, rulesConf.decorators || {});
89
+ result.plugins.push(...(rulesConf.plugins || []));
90
+ result.pluginPaths.push(...(rulesConf.pluginPaths || []));
91
+ result.extendPaths.push(...new Set(rulesConf.extendPaths));
92
+ }
93
+ return result;
94
+ }
95
+ exports.mergeExtends = mergeExtends;
96
+ function getMergedConfig(config, entrypointAlias) {
97
+ var _a, _b, _c, _d, _e, _f;
98
+ const extendPaths = [
99
+ ...Object.values(config.apis).map((api) => { var _a; return (_a = api === null || api === void 0 ? void 0 : api.lint) === null || _a === void 0 ? void 0 : _a.extendPaths; }),
100
+ (_b = (_a = config.rawConfig) === null || _a === void 0 ? void 0 : _a.lint) === null || _b === void 0 ? void 0 : _b.extendPaths,
101
+ ]
102
+ .flat()
103
+ .filter(Boolean);
104
+ const pluginPaths = [
105
+ ...Object.values(config.apis).map((api) => { var _a; return (_a = api === null || api === void 0 ? void 0 : api.lint) === null || _a === void 0 ? void 0 : _a.pluginPaths; }),
106
+ (_d = (_c = config.rawConfig) === null || _c === void 0 ? void 0 : _c.lint) === null || _d === void 0 ? void 0 : _d.pluginPaths,
107
+ ]
108
+ .flat()
109
+ .filter(Boolean);
110
+ return entrypointAlias
111
+ ? new config_1.Config(Object.assign(Object.assign({}, config.rawConfig), { lint: Object.assign(Object.assign({}, (config.apis[entrypointAlias]
112
+ ? config.apis[entrypointAlias].lint
113
+ : config.rawConfig.lint)), { extendPaths,
114
+ pluginPaths }), 'features.openapi': Object.assign(Object.assign({}, config['features.openapi']), (_e = config.apis[entrypointAlias]) === null || _e === void 0 ? void 0 : _e['features.openapi']), 'features.mockServer': Object.assign(Object.assign({}, config['features.mockServer']), (_f = config.apis[entrypointAlias]) === null || _f === void 0 ? void 0 : _f['features.mockServer']) }), config.configFile)
115
+ : config;
116
+ }
117
+ exports.getMergedConfig = getMergedConfig;
118
+ function transformConfig(rawConfig) {
119
+ if (rawConfig.apis && rawConfig.apiDefinitions) {
120
+ throw new Error("Do not use 'apiDefinitions' field. Use 'apis' instead.\n");
121
+ }
122
+ if (rawConfig['features.openapi'] &&
123
+ rawConfig.referenceDocs) {
124
+ throw new Error("Do not use 'referenceDocs' field. Use 'features.openapi' instead.\n");
125
+ }
126
+ const _a = rawConfig, { apiDefinitions, referenceDocs } = _a, rest = __rest(_a, ["apiDefinitions", "referenceDocs"]);
127
+ if (apiDefinitions) {
128
+ process.stderr.write(`The ${colorette_1.yellow('apiDefinitions')} field is deprecated. Use ${colorette_1.green('apis')} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`);
129
+ }
130
+ if (referenceDocs) {
131
+ process.stderr.write(`The ${colorette_1.yellow('referenceDocs')} field is deprecated. Use ${colorette_1.green('features.openapi')} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`);
132
+ }
133
+ return Object.assign({ 'features.openapi': referenceDocs, apis: transformApiDefinitionsToApis(apiDefinitions) }, rest);
134
+ }
135
+ exports.transformConfig = transformConfig;
136
+ function getResolveConfig(resolve) {
137
+ var _a, _b;
138
+ return {
139
+ http: {
140
+ headers: (_b = (_a = resolve === null || resolve === void 0 ? void 0 : resolve.http) === null || _a === void 0 ? void 0 : _a.headers) !== null && _b !== void 0 ? _b : [],
141
+ customFetch: undefined,
142
+ },
143
+ };
144
+ }
145
+ exports.getResolveConfig = getResolveConfig;
146
+ function getUniquePlugins(plugins) {
147
+ const seen = new Set();
148
+ const results = [];
149
+ for (const p of plugins) {
150
+ if (!seen.has(p.id)) {
151
+ results.push(p);
152
+ seen.add(p.id);
153
+ }
154
+ else if (p.id) {
155
+ process.stderr.write(`Duplicate plugin id "${colorette_1.yellow(p.id)}".\n`);
156
+ }
157
+ }
158
+ return results;
159
+ }
160
+ exports.getUniquePlugins = getUniquePlugins;
@@ -4,7 +4,7 @@ export declare type Totals = {
4
4
  warnings: number;
5
5
  ignored: number;
6
6
  };
7
- export declare type OutputFormat = 'codeframe' | 'stylish' | 'json' | 'checkstyle';
7
+ export declare type OutputFormat = 'codeframe' | 'stylish' | 'json' | 'checkstyle' | 'codeclimate';
8
8
  export declare function getTotals(problems: (NormalizedProblem & {
9
9
  ignored?: boolean;
10
10
  })[]): Totals;
@@ -20,6 +20,10 @@ const SEVERITY_NAMES = {
20
20
  warn: 'Warning',
21
21
  error: 'Error',
22
22
  };
23
+ const CODECLIMATE_SEVERITY_MAPPING = {
24
+ error: 'critical',
25
+ warn: 'minor',
26
+ };
23
27
  const MAX_SUGGEST = 5;
24
28
  function severityToNumber(severity) {
25
29
  return severity === 'error' ? 1 : 2;
@@ -90,10 +94,31 @@ function formatProblems(problems, opts) {
90
94
  process.stdout.write(`</checkstyle>\n`);
91
95
  break;
92
96
  }
97
+ case 'codeclimate':
98
+ outputForCodeClimate();
99
+ break;
93
100
  }
94
101
  if (totalProblems - ignoredProblems > maxProblems) {
95
102
  process.stderr.write(`< ... ${totalProblems - maxProblems} more problems hidden > ${colorette_1.gray('increase with `--max-problems N`')}\n`);
96
103
  }
104
+ function outputForCodeClimate() {
105
+ const issues = problems.map((p) => {
106
+ const location = p.location[0]; // TODO: support multiple location
107
+ const lineCol = codeframes_1.getLineColLocation(location);
108
+ return {
109
+ description: p.message,
110
+ location: {
111
+ path: path.relative(cwd, location.source.absoluteRef),
112
+ lines: {
113
+ begin: lineCol.start.line,
114
+ },
115
+ },
116
+ severity: CODECLIMATE_SEVERITY_MAPPING[p.severity],
117
+ fingerprint: `${p.ruleId}${p.location.length > 0 ? '-' + p.location[0].pointer : ''}`,
118
+ };
119
+ });
120
+ process.stdout.write(JSON.stringify(issues, null, 2));
121
+ }
97
122
  function outputJSON() {
98
123
  const resultObject = {
99
124
  totals,
@@ -140,6 +165,9 @@ function formatProblems(problems, opts) {
140
165
  }
141
166
  function formatStylish(problem, locationPad, ruleIdPad) {
142
167
  const color = COLORS[problem.severity];
168
+ if (!SEVERITY_NAMES[problem.severity]) {
169
+ return 'Error not found severity. Please check your config file. Allowed values: \`warn,error,off\`';
170
+ }
143
171
  const severityName = color(SEVERITY_NAMES[problem.severity].toLowerCase().padEnd(7));
144
172
  const { start } = problem.location[0];
145
173
  return ` ${`${start.line}:${start.col}`.padEnd(locationPad)} ${severityName} ${problem.ruleId.padEnd(ruleIdPad)} ${problem.message}`;
package/lib/index.d.ts CHANGED
@@ -8,8 +8,7 @@ export { Oas2Definition } from './typings/swagger';
8
8
  export { StatsAccumulator, StatsName } from './typings/common';
9
9
  export { normalizeTypes } from './types';
10
10
  export { Stats } from './rules/other/stats';
11
- export { Config, LintConfig, RawConfig, IGNORE_FILE, Region, getMergedConfig, transformConfig, } from './config/config';
12
- export { loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES } from './config/load';
11
+ export { Config, LintConfig, RawConfig, IGNORE_FILE, Region, getMergedConfig, transformConfig, loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES, } from './config';
13
12
  export { RedoclyClient, isRedoclyRegistryURL } from './redocly';
14
13
  export { Source, BaseResolver, Document, resolveDocument, ResolveError, YamlParseError, makeDocumentFromString, } from './resolve';
15
14
  export { parseYaml, stringifyYaml } from './js-yaml';
package/lib/index.js CHANGED
@@ -16,17 +16,16 @@ var types_1 = require("./types");
16
16
  Object.defineProperty(exports, "normalizeTypes", { enumerable: true, get: function () { return types_1.normalizeTypes; } });
17
17
  var stats_1 = require("./rules/other/stats");
18
18
  Object.defineProperty(exports, "Stats", { enumerable: true, get: function () { return stats_1.Stats; } });
19
- var config_1 = require("./config/config");
19
+ var config_1 = require("./config");
20
20
  Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
21
21
  Object.defineProperty(exports, "LintConfig", { enumerable: true, get: function () { return config_1.LintConfig; } });
22
22
  Object.defineProperty(exports, "IGNORE_FILE", { enumerable: true, get: function () { return config_1.IGNORE_FILE; } });
23
23
  Object.defineProperty(exports, "getMergedConfig", { enumerable: true, get: function () { return config_1.getMergedConfig; } });
24
24
  Object.defineProperty(exports, "transformConfig", { enumerable: true, get: function () { return config_1.transformConfig; } });
25
- var load_1 = require("./config/load");
26
- Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return load_1.loadConfig; } });
27
- Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return load_1.getConfig; } });
28
- Object.defineProperty(exports, "findConfig", { enumerable: true, get: function () { return load_1.findConfig; } });
29
- Object.defineProperty(exports, "CONFIG_FILE_NAMES", { enumerable: true, get: function () { return load_1.CONFIG_FILE_NAMES; } });
25
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_1.loadConfig; } });
26
+ Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return config_1.getConfig; } });
27
+ Object.defineProperty(exports, "findConfig", { enumerable: true, get: function () { return config_1.findConfig; } });
28
+ Object.defineProperty(exports, "CONFIG_FILE_NAMES", { enumerable: true, get: function () { return config_1.CONFIG_FILE_NAMES; } });
30
29
  var redocly_1 = require("./redocly");
31
30
  Object.defineProperty(exports, "RedoclyClient", { enumerable: true, get: function () { return redocly_1.RedoclyClient; } });
32
31
  Object.defineProperty(exports, "isRedoclyRegistryURL", { enumerable: true, get: function () { return redocly_1.isRedoclyRegistryURL; } });
package/lib/lint.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BaseResolver, Document } from './resolve';
2
2
  import { NodeType } from './types';
3
- import { LintConfig, Config } from './config/config';
3
+ import { LintConfig, Config } from './config';
4
4
  export declare function lint(opts: {
5
5
  ref: string;
6
6
  config: Config;
package/lib/lint.js CHANGED
@@ -16,14 +16,12 @@ const oas3_1_1 = require("./types/oas3_1");
16
16
  const oas3_1 = require("./types/oas3");
17
17
  const oas2_1 = require("./types/oas2");
18
18
  const walk_1 = require("./walk");
19
- const config_1 = require("./config/config");
19
+ const config_1 = require("./config");
20
20
  const types_1 = require("./types");
21
- const rules_1 = require("./config/rules");
22
21
  const ajv_1 = require("./rules/ajv");
23
22
  const oas_types_1 = require("./oas-types");
24
23
  const redocly_yaml_1 = require("./types/redocly-yaml");
25
24
  const spec_1 = require("./rules/common/spec");
26
- const builtIn_1 = require("./config/builtIn");
27
25
  function lint(opts) {
28
26
  return __awaiter(this, void 0, void 0, function* () {
29
27
  const { ref, externalRefResolver = new resolve_1.BaseResolver(opts.config.resolve) } = opts;
@@ -53,8 +51,8 @@ function lintDocument(opts) {
53
51
  oasVersion: oasVersion,
54
52
  visitorsData: {},
55
53
  };
56
- const preprocessors = rules_1.initRules(rules, config, 'preprocessors', oasVersion);
57
- const regularRules = rules_1.initRules(rules, config, 'rules', oasVersion);
54
+ const preprocessors = config_1.initRules(rules, config, 'preprocessors', oasVersion);
55
+ const regularRules = config_1.initRules(rules, config, 'rules', oasVersion);
58
56
  const normalizedVisitors = visitors_1.normalizeVisitors([...preprocessors, ...regularRules], types);
59
57
  const resolvedRefMap = yield resolve_1.resolveDocument({
60
58
  rootDocument: document,
@@ -80,9 +78,9 @@ function lintConfig(opts) {
80
78
  oasVersion: oas_types_1.OasVersion.Version3_0,
81
79
  visitorsData: {},
82
80
  };
81
+ const plugins = config_1.resolvePlugins([config_1.defaultPlugin]);
83
82
  const config = new config_1.LintConfig({
84
- plugins: [builtIn_1.defaultPlugin],
85
- extends: [],
83
+ plugins,
86
84
  rules: { spec: 'error' },
87
85
  });
88
86
  const types = types_1.normalizeTypes(redocly_yaml_1.ConfigTypes, config);
@@ -1,6 +1,6 @@
1
1
  import { RegistryApi } from './registry-api';
2
- import { AccessTokens, Region } from '../config/config';
3
2
  import { RegionalToken, RegionalTokenWithValidity } from './redocly-client-types';
3
+ import type { AccessTokens, Region } from '../config/types';
4
4
  export declare class RedoclyClient {
5
5
  private accessTokens;
6
6
  private region;
@@ -57,7 +57,7 @@ class RedoclyClient {
57
57
  const token = this.accessTokens[this.region];
58
58
  // print this only if there is token but invalid
59
59
  if (token && !this.isAuthorizedWithRedoclyByRegion()) {
60
- process.stderr.write(`${colorette_1.yellow('Warning:')} invalid Redocly API key. Use "npx @redocly/openapi-cli login" to provide your API key\n`);
60
+ process.stderr.write(`${colorette_1.yellow('Warning:')} invalid Redocly API key. Use "npx @redocly/cli login" to provide your API key\n`);
61
61
  return undefined;
62
62
  }
63
63
  return token;
@@ -1,4 +1,4 @@
1
- import { Region } from '../config/config';
1
+ import type { Region } from '../config/types';
2
2
  export interface RegionalToken {
3
3
  region: Region;
4
4
  token: string;
@@ -1,5 +1,5 @@
1
1
  import { RegistryApiTypes } from './registry-api-types';
2
- import { AccessTokens, Region } from '../config/config';
2
+ import type { AccessTokens, Region } from '../config/types';
3
3
  export declare class RegistryApi {
4
4
  private accessTokens;
5
5
  private region;
package/lib/resolve.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { YAMLNode, LoadOptions } from 'yaml-ast-parser';
2
2
  import { NormalizedNodeType } from './types';
3
- import { ResolveConfig } from './config/config';
3
+ import { ResolveConfig } from './config/types';
4
4
  export declare type CollectedRefs = Map<string, Document>;
5
5
  export declare class Source {
6
6
  absoluteRef: string;
package/lib/resolve.js CHANGED
@@ -12,7 +12,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.resolveDocument = exports.BaseResolver = exports.makeDocumentFromString = exports.makeRefId = exports.YamlParseError = exports.ResolveError = exports.Source = void 0;
13
13
  const fs = require("fs");
14
14
  const path = require("path");
15
- const url = require("url");
16
15
  const ref_utils_1 = require("./ref-utils");
17
16
  const types_1 = require("./types");
18
17
  const utils_1 = require("./utils");
@@ -99,7 +98,7 @@ class BaseResolver {
99
98
  return ref;
100
99
  }
101
100
  if (base && ref_utils_1.isAbsoluteUrl(base)) {
102
- return url.resolve(base, ref);
101
+ return new URL(ref, base).href;
103
102
  }
104
103
  return path.resolve(base ? path.dirname(base) : process.cwd(), ref);
105
104
  }
@@ -7,7 +7,7 @@ const Assertions = (opts) => {
7
7
  let visitors = [];
8
8
  // As 'Assertions' has an array of asserts,
9
9
  // that array spreads into an 'opts' object on init rules phase here
10
- // https://github.com/Redocly/openapi-cli/blob/master/packages/core/src/config/config.ts#L311
10
+ // https://github.com/Redocly/redocly-cli/blob/master/packages/core/src/config/config.ts#L311
11
11
  // that is why we need to iterate through 'opts' values;
12
12
  // before - filter only object 'opts' values
13
13
  const assertions = Object.values(opts).filter((opt) => typeof opt === 'object' && opt !== null);
@@ -15,6 +15,6 @@ export declare type AssertToApply = {
15
15
  runsOnValues: boolean;
16
16
  };
17
17
  export declare function buildVisitorObject(subject: string, context: Record<string, any>[], subjectVisitor: any): Record<string, any>;
18
- export declare function buildSubjectVisitor(properties: string | string[], asserts: AssertToApply[], context?: Record<string, any>[]): (node: any, { report, location, key, type }: UserContext) => void;
18
+ export declare function buildSubjectVisitor(properties: string | string[], asserts: AssertToApply[], context?: Record<string, any>[]): (node: any, { report, location, key, type, resolve }: UserContext) => void;
19
19
  export declare function getIntersectionLength(keys: string[], properties: string[]): number;
20
20
  export declare function isOrdered(value: any[], options: OrderOptions | OrderDirection): boolean;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isOrdered = exports.getIntersectionLength = exports.buildSubjectVisitor = exports.buildVisitorObject = void 0;
4
+ const ref_utils_1 = require("../../../ref-utils");
4
5
  const asserts_1 = require("./asserts");
5
6
  function buildVisitorObject(subject, context, subjectVisitor) {
6
7
  if (!context) {
@@ -44,7 +45,8 @@ function buildVisitorObject(subject, context, subjectVisitor) {
44
45
  }
45
46
  exports.buildVisitorObject = buildVisitorObject;
46
47
  function buildSubjectVisitor(properties, asserts, context) {
47
- return function (node, { report, location, key, type }) {
48
+ return function (node, { report, location, key, type, resolve }) {
49
+ var _a;
48
50
  // We need to check context's last node if it has the same type as subject node;
49
51
  // if yes - that means we didn't create context's last node visitor,
50
52
  // so we need to handle 'matchParentKeys' and 'excludeParentKeys' conditions here;
@@ -67,7 +69,9 @@ function buildSubjectVisitor(properties, asserts, context) {
67
69
  for (const assert of asserts) {
68
70
  if (properties) {
69
71
  for (const property of properties) {
70
- runAssertion(node[property], assert, location.child(property), report);
72
+ // we can have resolvable scalar so need to resolve value here.
73
+ const value = ref_utils_1.isRef(node[property]) ? (_a = resolve(node[property])) === null || _a === void 0 ? void 0 : _a.node : node[property];
74
+ runAssertion(value, assert, location.child(property), report);
71
75
  }
72
76
  }
73
77
  else {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isNamedType = exports.normalizeTypes = exports.mapOf = exports.listOf = void 0;
4
4
  function listOf(typeName) {
5
5
  return {
6
- name: typeName + '_List',
6
+ name: `${typeName}List`,
7
7
  properties: {},
8
8
  items: typeName,
9
9
  };
@@ -11,7 +11,7 @@ function listOf(typeName) {
11
11
  exports.listOf = listOf;
12
12
  function mapOf(typeName) {
13
13
  return {
14
- name: typeName + '_Map',
14
+ name: `${typeName}Map`,
15
15
  properties: {},
16
16
  additionalProperties: () => typeName,
17
17
  };
@@ -17,7 +17,7 @@ const DefinitionRoot = {
17
17
  jsonSchemaDialect: { type: 'string' },
18
18
  },
19
19
  required: ['openapi', 'info'],
20
- requiredOneOf: ['paths', 'components', 'webhooks']
20
+ requiredOneOf: ['paths', 'components', 'webhooks'],
21
21
  };
22
22
  const License = {
23
23
  properties: {
@@ -103,7 +103,10 @@ const Schema = {
103
103
  enum: { type: 'array' },
104
104
  type: (value) => {
105
105
  if (Array.isArray(value)) {
106
- return { type: 'array', items: { enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'] } };
106
+ return {
107
+ type: 'array',
108
+ items: { enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'] },
109
+ };
107
110
  }
108
111
  else {
109
112
  return {
@@ -124,7 +127,14 @@ const Schema = {
124
127
  patternProperties: { type: 'object' },
125
128
  propertyNames: 'Schema',
126
129
  unevaluatedItems: 'Schema',
127
- unevaluatedProperties: 'Schema',
130
+ unevaluatedProperties: (value) => {
131
+ if (typeof value === 'boolean') {
132
+ return { type: 'boolean' };
133
+ }
134
+ else {
135
+ return 'Schema';
136
+ }
137
+ },
128
138
  summary: { type: 'string' },
129
139
  properties: 'SchemaProperties',
130
140
  items: (value) => {
@@ -195,9 +205,25 @@ const SecurityScheme = {
195
205
  case 'clientCredentials':
196
206
  return ['type', 'flows', 'tokenUrl', 'refreshUrl', 'description', 'scopes'];
197
207
  case 'authorizationCode':
198
- return ['type', 'flows', 'authorizationUrl', 'refreshUrl', 'tokenUrl', 'description', 'scopes'];
208
+ return [
209
+ 'type',
210
+ 'flows',
211
+ 'authorizationUrl',
212
+ 'refreshUrl',
213
+ 'tokenUrl',
214
+ 'description',
215
+ 'scopes',
216
+ ];
199
217
  default:
200
- return ['type', 'flows', 'authorizationUrl', 'refreshUrl', 'tokenUrl', 'description', 'scopes'];
218
+ return [
219
+ 'type',
220
+ 'flows',
221
+ 'authorizationUrl',
222
+ 'refreshUrl',
223
+ 'tokenUrl',
224
+ 'description',
225
+ 'scopes',
226
+ ];
201
227
  }
202
228
  case 'openIdConnect':
203
229
  return ['type', 'openIdConnectUrl', 'description'];
package/lib/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { HttpResolveConfig } from './config/config';
2
1
  import { UserContext } from './walk';
2
+ import type { HttpResolveConfig } from './config';
3
3
  export { parseYaml, stringifyYaml } from './js-yaml';
4
4
  export declare type StackFrame<T> = {
5
5
  prev: StackFrame<T> | null;
@@ -36,3 +36,6 @@ export declare function isPathParameter(pathSegment: string): boolean;
36
36
  */
37
37
  export declare function slash(path: string): string;
38
38
  export declare function isNotEmptyObject(obj: any): boolean;
39
+ export declare function isString(value: unknown): value is string;
40
+ export declare function isNotString<T>(value: string | T): value is T;
41
+ export declare function assignExisting<T>(target: Record<string, T>, obj: Record<string, T>): void;