@redocly/openapi-core 1.0.0-beta.103 → 1.0.0-beta.106

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 (201) hide show
  1. package/README.md +4 -4
  2. package/__tests__/utils.ts +8 -6
  3. package/lib/benchmark/benches/recommended-oas3.bench.js +1 -1
  4. package/lib/benchmark/utils.d.ts +2 -2
  5. package/lib/benchmark/utils.js +2 -2
  6. package/lib/bundle.d.ts +2 -2
  7. package/lib/bundle.js +2 -2
  8. package/lib/config/all.d.ts +2 -2
  9. package/lib/config/all.js +1 -1
  10. package/lib/config/builtIn.d.ts +2 -2
  11. package/lib/config/builtIn.js +2 -2
  12. package/lib/config/config-resolvers.d.ts +5 -5
  13. package/lib/config/config-resolvers.js +39 -36
  14. package/lib/config/config.d.ts +6 -5
  15. package/lib/config/config.js +27 -20
  16. package/lib/config/load.js +6 -7
  17. package/lib/config/minimal.d.ts +2 -2
  18. package/lib/config/minimal.js +1 -1
  19. package/lib/config/recommended.d.ts +2 -2
  20. package/lib/config/recommended.js +1 -1
  21. package/lib/config/rules.d.ts +2 -2
  22. package/lib/config/rules.js +1 -1
  23. package/lib/config/types.d.ts +23 -19
  24. package/lib/config/utils.d.ts +5 -5
  25. package/lib/config/utils.js +43 -26
  26. package/lib/decorators/common/filters/filter-helper.js +1 -1
  27. package/lib/decorators/common/remove-x-internal.js +2 -2
  28. package/lib/format/format.js +1 -1
  29. package/lib/index.d.ts +2 -2
  30. package/lib/index.js +3 -2
  31. package/lib/js-yaml/index.js +1 -6
  32. package/lib/lint.d.ts +2 -2
  33. package/lib/lint.js +16 -6
  34. package/lib/redocly/registry-api.d.ts +1 -1
  35. package/lib/redocly/registry-api.js +2 -2
  36. package/lib/rules/ajv.d.ts +1 -1
  37. package/lib/rules/ajv.js +1 -1
  38. package/lib/rules/common/info-license-url.d.ts +1 -1
  39. package/lib/rules/common/info-license-url.js +5 -10
  40. package/lib/rules/common/info-license.d.ts +2 -0
  41. package/lib/rules/common/info-license.js +17 -0
  42. package/lib/rules/common/no-enum-type-mismatch.js +1 -3
  43. package/lib/rules/common/operation-operationId.js +1 -1
  44. package/lib/rules/common/path-not-include-query.js +1 -1
  45. package/lib/rules/common/paths-kebab-case.js +4 -1
  46. package/lib/rules/common/spec.js +1 -1
  47. package/lib/rules/oas2/index.js +4 -4
  48. package/lib/rules/oas2/remove-unused-components.js +3 -3
  49. package/lib/rules/oas3/index.js +4 -4
  50. package/lib/rules/oas3/no-empty-servers.js +1 -1
  51. package/lib/rules/oas3/remove-unused-components.js +2 -2
  52. package/lib/rules/other/stats.js +43 -14
  53. package/lib/rules/utils.d.ts +1 -1
  54. package/lib/rules/utils.js +4 -1
  55. package/lib/types/index.d.ts +2 -2
  56. package/lib/types/redocly-yaml.js +9 -7
  57. package/lib/utils.d.ts +3 -2
  58. package/lib/utils.js +11 -2
  59. package/lib/walk.d.ts +2 -14
  60. package/lib/walk.js +19 -19
  61. package/package.json +3 -2
  62. package/src/__tests__/__snapshots__/bundle.test.ts.snap +141 -0
  63. package/src/__tests__/bundle.test.ts +68 -34
  64. package/src/__tests__/codeframes.test.ts +13 -14
  65. package/src/__tests__/fixtures/.redocly.lint-ignore.yaml +5 -0
  66. package/src/__tests__/js-yaml.test.ts +6 -4
  67. package/src/__tests__/lint.test.ts +127 -12
  68. package/src/__tests__/login.test.ts +2 -2
  69. package/src/__tests__/normalizeVisitors.test.ts +4 -4
  70. package/src/__tests__/ref-utils.test.ts +13 -13
  71. package/src/__tests__/resolve-http.test.ts +1 -1
  72. package/src/__tests__/resolve.test.ts +14 -11
  73. package/src/__tests__/utils.test.ts +42 -1
  74. package/src/__tests__/walk.test.ts +48 -56
  75. package/src/benchmark/benches/lint-with-many-rules.bench.ts +1 -1
  76. package/src/benchmark/benches/lint-with-nested-rule.bench.ts +1 -1
  77. package/src/benchmark/benches/lint-with-no-rules.bench.ts +1 -1
  78. package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +1 -1
  79. package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +1 -1
  80. package/src/benchmark/benches/recommended-oas3.bench.ts +3 -3
  81. package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
  82. package/src/benchmark/benchmark.js +9 -5
  83. package/src/benchmark/utils.ts +5 -5
  84. package/src/bundle.ts +18 -17
  85. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +1 -1
  86. package/src/config/__tests__/config-resolvers.test.ts +123 -121
  87. package/src/config/__tests__/config.test.ts +76 -76
  88. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +4 -2
  89. package/src/config/__tests__/fixtures/resolve-config/plugin.js +4 -1
  90. package/src/config/__tests__/load.test.ts +2 -2
  91. package/src/config/__tests__/resolve-plugins.test.ts +3 -3
  92. package/src/config/__tests__/utils.test.ts +83 -0
  93. package/src/config/all.ts +3 -4
  94. package/src/config/builtIn.ts +5 -5
  95. package/src/config/config-resolvers.ts +122 -83
  96. package/src/config/config.ts +36 -32
  97. package/src/config/load.ts +13 -16
  98. package/src/config/minimal.ts +3 -3
  99. package/src/config/recommended.ts +3 -3
  100. package/src/config/rules.ts +6 -6
  101. package/src/config/types.ts +28 -19
  102. package/src/config/utils.ts +70 -50
  103. package/src/decorators/__tests__/filter-out.test.ts +113 -5
  104. package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
  105. package/src/decorators/common/filters/filter-helper.ts +1 -1
  106. package/src/decorators/common/info-description-override.ts +1 -1
  107. package/src/decorators/common/operation-description-override.ts +1 -1
  108. package/src/decorators/common/remove-x-internal.ts +4 -4
  109. package/src/decorators/common/tag-description-override.ts +1 -1
  110. package/src/format/codeframes.ts +4 -4
  111. package/src/format/format.ts +10 -10
  112. package/src/index.ts +3 -4
  113. package/src/js-yaml/index.ts +3 -8
  114. package/src/lint.ts +22 -18
  115. package/src/oas-types.ts +1 -6
  116. package/src/redocly/__tests__/redocly-client.test.ts +25 -19
  117. package/src/redocly/index.ts +6 -4
  118. package/src/redocly/registry-api.ts +6 -6
  119. package/src/ref-utils.ts +2 -2
  120. package/src/resolve.ts +7 -4
  121. package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
  122. package/src/rules/__tests__/utils.test.ts +122 -0
  123. package/src/rules/ajv.ts +7 -8
  124. package/src/rules/common/__tests__/info-description.test.ts +3 -3
  125. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  126. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  127. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  128. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +8 -8
  129. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  130. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
  131. package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
  132. package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
  133. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  134. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  135. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  136. package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
  137. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  138. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  139. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  140. package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
  141. package/src/rules/common/__tests__/paths-kebab-case.test.ts +15 -15
  142. package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +8 -8
  143. package/src/rules/common/__tests__/spec.test.ts +2 -2
  144. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  145. package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
  146. package/src/rules/common/assertions/__tests__/asserts.test.ts +513 -130
  147. package/src/rules/common/assertions/index.ts +6 -6
  148. package/src/rules/common/info-license-url.ts +4 -9
  149. package/src/rules/common/info-license.ts +15 -0
  150. package/src/rules/common/no-ambiguous-paths.ts +1 -1
  151. package/src/rules/common/no-enum-type-mismatch.ts +12 -9
  152. package/src/rules/common/no-invalid-parameter-examples.ts +2 -2
  153. package/src/rules/common/no-invalid-schema-examples.ts +1 -1
  154. package/src/rules/common/operation-operationId.ts +1 -1
  155. package/src/rules/common/operation-parameters-unique.ts +2 -2
  156. package/src/rules/common/path-not-include-query.ts +1 -1
  157. package/src/rules/common/path-params-defined.ts +1 -1
  158. package/src/rules/common/paths-kebab-case.ts +4 -1
  159. package/src/rules/common/scalar-property-missing-example.ts +1 -1
  160. package/src/rules/common/spec.ts +10 -7
  161. package/src/rules/no-unresolved-refs.ts +1 -1
  162. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  163. package/src/rules/oas2/__tests__/spec/info.test.ts +12 -12
  164. package/src/rules/oas2/__tests__/spec/operation.test.ts +4 -4
  165. package/src/rules/oas2/__tests__/spec/paths.test.ts +10 -10
  166. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +6 -2
  167. package/src/rules/oas2/__tests__/spec/utils.ts +6 -6
  168. package/src/rules/oas2/index.ts +3 -3
  169. package/src/rules/oas2/remove-unused-components.ts +13 -8
  170. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  171. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  172. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +8 -8
  173. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
  174. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  175. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  176. package/src/rules/oas3/__tests__/spec/callbacks.test.ts +1 -1
  177. package/src/rules/oas3/__tests__/spec/info.test.ts +12 -12
  178. package/src/rules/oas3/__tests__/spec/operation.test.ts +8 -8
  179. package/src/rules/oas3/__tests__/spec/paths.test.ts +10 -10
  180. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +12 -12
  181. package/src/rules/oas3/__tests__/spec/servers.test.ts +15 -15
  182. package/src/rules/oas3/__tests__/spec/spec.test.ts +6 -6
  183. package/src/rules/oas3/__tests__/spec/utils.ts +6 -6
  184. package/src/rules/oas3/index.ts +3 -3
  185. package/src/rules/oas3/no-empty-servers.ts +1 -1
  186. package/src/rules/oas3/no-invalid-media-type-examples.ts +12 -4
  187. package/src/rules/oas3/no-servers-empty-enum.ts +9 -10
  188. package/src/rules/oas3/remove-unused-components.ts +18 -7
  189. package/src/rules/other/stats.ts +46 -17
  190. package/src/rules/utils.ts +5 -3
  191. package/src/types/index.ts +5 -5
  192. package/src/types/redocly-yaml.ts +9 -7
  193. package/src/typings/common.ts +9 -1
  194. package/src/typings/openapi.ts +1 -1
  195. package/src/utils.ts +18 -8
  196. package/src/visitors.ts +4 -4
  197. package/src/walk.ts +23 -31
  198. package/tsconfig.tsbuildinfo +1 -1
  199. package/lib/rules/common/license-url.d.ts +0 -2
  200. package/lib/rules/common/license-url.js +0 -12
  201. package/src/rules/common/license-url.ts +0 -10
@@ -29,7 +29,7 @@ export type PreprocessorConfig =
29
29
 
30
30
  export type DecoratorConfig = PreprocessorConfig;
31
31
 
32
- export type LintRawConfig = {
32
+ export type StyleguideRawConfig = {
33
33
  plugins?: (string | Plugin)[];
34
34
  extends?: string[];
35
35
  doNotResolveExamples?: boolean;
@@ -51,7 +51,9 @@ export type LintRawConfig = {
51
51
  oas3_1Decorators?: Record<string, DecoratorConfig>;
52
52
  };
53
53
 
54
- export type ResolvedLintConfig = PluginLintConfig & {
54
+ export type ApiStyleguideRawConfig = Omit<StyleguideRawConfig, 'plugins'>;
55
+
56
+ export type ResolvedStyleguideConfig = PluginStyleguideConfig & {
55
57
  plugins?: Plugin[];
56
58
  recommendedFallback?: boolean;
57
59
  extends?: void | never;
@@ -71,7 +73,7 @@ export type DecoratorsConfig = {
71
73
 
72
74
  export type TypesExtensionFn = (
73
75
  types: Record<string, NodeType>,
74
- oasVersion: OasVersion,
76
+ oasVersion: OasVersion
75
77
  ) => Record<string, NodeType>;
76
78
 
77
79
  export type TypeExtensionsConfig = Partial<Record<OasMajorVersion, TypesExtensionFn>>;
@@ -83,14 +85,14 @@ export type CustomRulesConfig = {
83
85
 
84
86
  export type Plugin = {
85
87
  id: string;
86
- configs?: Record<string, PluginLintConfig>;
88
+ configs?: Record<string, PluginStyleguideConfig>;
87
89
  rules?: CustomRulesConfig;
88
90
  preprocessors?: PreprocessorsConfig;
89
91
  decorators?: DecoratorsConfig;
90
92
  typeExtension?: TypeExtensionsConfig;
91
93
  };
92
94
 
93
- export type PluginLintConfig = Omit<LintRawConfig, 'plugins' | 'extends'>;
95
+ export type PluginStyleguideConfig = Omit<StyleguideRawConfig, 'plugins' | 'extends'>;
94
96
 
95
97
  export type ResolveHeader =
96
98
  | {
@@ -123,35 +125,42 @@ export type Region = 'us' | 'eu';
123
125
 
124
126
  export type AccessTokens = { [region in Region]?: string };
125
127
 
126
- export type DeprecatedRawConfig = {
128
+ export type DeprecatedInRawConfig = {
127
129
  apiDefinitions?: Record<string, string>;
128
- lint?: LintRawConfig;
129
- resolve?: RawResolveConfig;
130
- region?: Region;
130
+ lint?: StyleguideRawConfig;
131
131
  referenceDocs?: Record<string, any>;
132
+ apis?: Record<string, Api & DeprecatedInApi>;
132
133
  };
133
134
 
134
135
  export type Api = {
135
136
  root: string;
136
- lint?: Omit<LintRawConfig, 'plugins'>;
137
- 'features.openapi'?: Record<string, any>;
138
- 'features.mockServer'?: Record<string, any>;
137
+ styleguide?: ApiStyleguideRawConfig;
138
+ } & FeaturesConfig;
139
+
140
+ export type DeprecatedInApi = {
141
+ lint?: ApiStyleguideRawConfig;
142
+ };
143
+
144
+ export type ResolvedApi = Omit<Api, 'styleguide'> & {
145
+ styleguide: ResolvedStyleguideConfig;
139
146
  };
140
- export type ResolvedApi = Omit<Api, 'lint'> & { lint: Omit<ResolvedLintConfig, 'plugins'>};
141
147
 
142
148
  export type RawConfig = {
143
149
  apis?: Record<string, Api>;
144
- lint?: LintRawConfig;
150
+ styleguide?: StyleguideRawConfig;
145
151
  resolve?: RawResolveConfig;
146
152
  region?: Region;
147
- 'features.openapi'?: Record<string, any>;
148
- 'features.mockServer'?: Record<string, any>;
149
153
  organization?: string;
154
+ } & FeaturesConfig;
155
+
156
+ export type ResolvedConfig = Omit<RawConfig, 'apis' | 'styleguide'> & {
157
+ apis: Record<string, ResolvedApi>;
158
+ styleguide: ResolvedStyleguideConfig;
150
159
  };
151
160
 
152
- export type ResolvedConfig = Omit<RawConfig, 'lint' | 'apis'> & {
153
- lint: ResolvedLintConfig;
154
- apis: Record<string,ResolvedApi>
161
+ type FeaturesConfig = {
162
+ 'features.openapi'?: Record<string, any>;
163
+ 'features.mockServer'?: Record<string, any>;
155
164
  };
156
165
 
157
166
  export type RulesFields =
@@ -4,12 +4,13 @@ import { Config } from './config';
4
4
 
5
5
  import type {
6
6
  Api,
7
- DeprecatedRawConfig,
7
+ DeprecatedInApi,
8
+ DeprecatedInRawConfig,
8
9
  Plugin,
9
10
  RawConfig,
10
11
  RawResolveConfig,
11
12
  ResolveConfig,
12
- ResolvedLintConfig,
13
+ ResolvedStyleguideConfig,
13
14
  RulesFields,
14
15
  } from './types';
15
16
 
@@ -23,15 +24,27 @@ export function parsePresetName(presetName: string): { pluginId: string; configN
23
24
  }
24
25
 
25
26
  export function transformApiDefinitionsToApis(
26
- apiDefinitions: Record<string, string> = {},
27
- ): Record<string, Api> {
28
- let apis: Record<string, Api> = {};
27
+ apiDefinitions?: DeprecatedInRawConfig['apiDefinitions']
28
+ ): Record<string, Api> | undefined {
29
+ if (!apiDefinitions) return undefined;
30
+ const apis: Record<string, Api> = {};
29
31
  for (const [apiName, apiPath] of Object.entries(apiDefinitions)) {
30
32
  apis[apiName] = { root: apiPath };
31
33
  }
32
34
  return apis;
33
35
  }
34
36
 
37
+ function transformApis(
38
+ legacyApis?: Record<string, Api & DeprecatedInApi>
39
+ ): Record<string, Api> | undefined {
40
+ if (!legacyApis) return undefined;
41
+ const apis: Record<string, Api> = {};
42
+ for (const [apiName, { lint, ...apiContent }] of Object.entries(legacyApis)) {
43
+ apis[apiName] = { styleguide: lint, ...apiContent };
44
+ }
45
+ return apis;
46
+ }
47
+
35
48
  export function prefixRules<T extends Record<string, any>>(rules: T, prefix: string) {
36
49
  if (!prefix) return rules;
37
50
 
@@ -43,9 +56,9 @@ export function prefixRules<T extends Record<string, any>>(rules: T, prefix: str
43
56
  return res;
44
57
  }
45
58
 
46
- export function mergeExtends(rulesConfList: ResolvedLintConfig[]) {
47
- const result: Omit<ResolvedLintConfig, RulesFields> &
48
- Required<Pick<ResolvedLintConfig, RulesFields>> = {
59
+ export function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]) {
60
+ const result: Omit<ResolvedStyleguideConfig, RulesFields> &
61
+ Required<Pick<ResolvedStyleguideConfig, RulesFields>> = {
49
62
  rules: {},
50
63
  oas2Rules: {},
51
64
  oas3_0Rules: {},
@@ -69,11 +82,7 @@ export function mergeExtends(rulesConfList: ResolvedLintConfig[]) {
69
82
  for (let rulesConf of rulesConfList) {
70
83
  if (rulesConf.extends) {
71
84
  throw new Error(
72
- `\`extends\` is not supported in shared configs yet: ${JSON.stringify(
73
- rulesConf,
74
- null,
75
- 2,
76
- )}.`,
85
+ `'extends' is not supported in shared configs yet: ${JSON.stringify(rulesConf, null, 2)}.`
77
86
  );
78
87
  }
79
88
 
@@ -109,75 +118,88 @@ export function mergeExtends(rulesConfList: ResolvedLintConfig[]) {
109
118
  return result;
110
119
  }
111
120
 
112
- export function getMergedConfig(config: Config, entrypointAlias?: string): Config {
121
+ export function getMergedConfig(config: Config, apiName?: string): Config {
113
122
  const extendPaths = [
114
- ...Object.values(config.apis).map((api) => api?.lint?.extendPaths),
115
- config.rawConfig?.lint?.extendPaths,
123
+ ...Object.values(config.apis).map((api) => api?.styleguide?.extendPaths),
124
+ config.rawConfig?.styleguide?.extendPaths,
116
125
  ]
117
126
  .flat()
118
127
  .filter(Boolean) as string[];
119
128
 
120
129
  const pluginPaths = [
121
- ...Object.values(config.apis).map((api) => api?.lint?.pluginPaths),
122
- config.rawConfig?.lint?.pluginPaths,
130
+ ...Object.values(config.apis).map((api) => api?.styleguide?.pluginPaths),
131
+ config.rawConfig?.styleguide?.pluginPaths,
123
132
  ]
124
133
  .flat()
125
134
  .filter(Boolean) as string[];
126
135
 
127
- return entrypointAlias
136
+ return apiName
128
137
  ? new Config(
129
138
  {
130
139
  ...config.rawConfig,
131
- lint: {
132
- ...(config.apis[entrypointAlias]
133
- ? config.apis[entrypointAlias].lint
134
- : config.rawConfig.lint),
140
+ styleguide: {
141
+ ...(config.apis[apiName]
142
+ ? config.apis[apiName].styleguide
143
+ : config.rawConfig.styleguide),
135
144
  extendPaths,
136
145
  pluginPaths,
137
146
  },
138
147
  'features.openapi': {
139
148
  ...config['features.openapi'],
140
- ...config.apis[entrypointAlias]?.['features.openapi'],
149
+ ...config.apis[apiName]?.['features.openapi'],
141
150
  },
142
151
  'features.mockServer': {
143
152
  ...config['features.mockServer'],
144
- ...config.apis[entrypointAlias]?.['features.mockServer'],
153
+ ...config.apis[apiName]?.['features.mockServer'],
145
154
  },
146
155
  // TODO: merge everything else here
147
156
  },
148
- config.configFile,
157
+ config.configFile
149
158
  )
150
159
  : config;
151
160
  }
152
161
 
153
- export function transformConfig(rawConfig: DeprecatedRawConfig | RawConfig): RawConfig {
154
- if ((rawConfig as RawConfig).apis && (rawConfig as DeprecatedRawConfig).apiDefinitions) {
155
- throw new Error("Do not use 'apiDefinitions' field. Use 'apis' instead.\n");
156
- }
157
- if (
158
- (rawConfig as RawConfig)['features.openapi'] &&
159
- (rawConfig as DeprecatedRawConfig).referenceDocs
160
- ) {
161
- throw new Error("Do not use 'referenceDocs' field. Use 'features.openapi' instead.\n");
162
- }
163
- const { apiDefinitions, referenceDocs, ...rest } = rawConfig as DeprecatedRawConfig & RawConfig;
164
- if (apiDefinitions) {
165
- process.stderr.write(
166
- `The ${yellow('apiDefinitions')} field is deprecated. Use ${green(
167
- 'apis',
168
- )} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`,
162
+ function checkForDeprecatedFields(
163
+ deprecatedField: keyof DeprecatedInRawConfig,
164
+ updatedField: keyof RawConfig,
165
+ rawConfig: DeprecatedInRawConfig & RawConfig
166
+ ): void {
167
+ const isDeprecatedFieldInApis =
168
+ rawConfig.apis &&
169
+ Object.values(rawConfig.apis).some(
170
+ (api: Api & DeprecatedInApi & DeprecatedInRawConfig) => api[deprecatedField]
169
171
  );
172
+
173
+ if (rawConfig[deprecatedField] && rawConfig[updatedField]) {
174
+ throw new Error(`Do not use '${deprecatedField}' field. Use '${updatedField}' instead.\n`);
170
175
  }
171
- if (referenceDocs) {
176
+
177
+ if (rawConfig[deprecatedField] || isDeprecatedFieldInApis) {
172
178
  process.stderr.write(
173
- `The ${yellow('referenceDocs')} field is deprecated. Use ${green(
174
- 'features.openapi',
175
- )} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`,
179
+ `The ${yellow(deprecatedField)} field is deprecated. Use ${green(
180
+ updatedField
181
+ )} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`
176
182
  );
177
183
  }
184
+ }
185
+
186
+ export function transformConfig(rawConfig: DeprecatedInRawConfig & RawConfig): RawConfig {
187
+ const migratedFields: [keyof DeprecatedInRawConfig, keyof RawConfig][] = [
188
+ ['apiDefinitions', 'apis'],
189
+ ['referenceDocs', 'features.openapi'],
190
+ ['lint', 'styleguide'], // TODO: update docs
191
+ ];
192
+
193
+ for (const [deprecatedField, updatedField] of migratedFields) {
194
+ checkForDeprecatedFields(deprecatedField, updatedField, rawConfig);
195
+ }
196
+
197
+ const { apis, apiDefinitions, referenceDocs, lint, ...rest } = rawConfig;
198
+
178
199
  return {
179
200
  'features.openapi': referenceDocs,
180
- apis: transformApiDefinitionsToApis(apiDefinitions),
201
+ apis: transformApis(apis) || transformApiDefinitionsToApis(apiDefinitions),
202
+ styleguide: lint,
181
203
  ...rest,
182
204
  };
183
205
  }
@@ -199,9 +221,7 @@ export function getUniquePlugins(plugins: Plugin[]): Plugin[] {
199
221
  results.push(p);
200
222
  seen.add(p.id);
201
223
  } else if (p.id) {
202
- process.stderr.write(
203
- `Duplicate plugin id "${yellow(p.id)}".\n`,
204
- );
224
+ process.stderr.write(`Duplicate plugin id "${yellow(p.id)}".\n`);
205
225
  }
206
226
  }
207
227
  return results;
@@ -27,8 +27,7 @@ describe('oas3 filter-out', () => {
27
27
  callbacks:
28
28
  x-access: protected
29
29
  orderInProgress:
30
- x-internal: true
31
- `
30
+ x-internal: true`
32
31
  );
33
32
 
34
33
  it('should remove /pet path and y parameter', async () => {
@@ -62,7 +61,7 @@ describe('oas3 filter-out', () => {
62
61
  x:
63
62
  name: x
64
63
 
65
- `);
64
+ `);
66
65
  });
67
66
 
68
67
  it('should remove only /order path', async () => {
@@ -92,8 +91,8 @@ describe('oas3 filter-out', () => {
92
91
  post:
93
92
  summary: test
94
93
  components: {}
95
-
96
- `);
94
+
95
+ `);
97
96
  });
98
97
 
99
98
  it('should remove all paths', async () => {
@@ -160,6 +159,115 @@ describe('oas3 filter-out', () => {
160
159
 
161
160
  `);
162
161
  });
162
+
163
+ it('should remove /pet path and /my/path/false path', async () => {
164
+ const testDocument = parseYamlToDocument(
165
+ outdent`
166
+ openapi: 3.0.0
167
+ paths:
168
+ /pet:
169
+ get:
170
+ x-prop: false
171
+ parameters:
172
+ - $ref: '#/components/parameters/x'
173
+ /my/path/false:
174
+ x-access: private
175
+ x-prop: false
176
+ get:
177
+ parameters:
178
+ - $ref: '#/components/parameters/x'
179
+ /my/path/null:
180
+ x-access: private
181
+ x-prop: null
182
+ get:
183
+ parameters:
184
+ - $ref: '#/components/parameters/x'
185
+ components:
186
+ parameters:
187
+ x:
188
+ name: x
189
+
190
+ `
191
+ );
192
+ const { bundle: res } = await bundleDocument({
193
+ document: testDocument,
194
+ externalRefResolver: new BaseResolver(),
195
+ config: await makeConfig({}, { 'filter-out': { property: 'x-prop', value: false } }),
196
+ });
197
+ expect(res.parsed).toMatchInlineSnapshot(`
198
+ openapi: 3.0.0
199
+ paths:
200
+ /my/path/null:
201
+ x-access: private
202
+ x-prop: null
203
+ get:
204
+ parameters:
205
+ - $ref: '#/components/parameters/x'
206
+ components:
207
+ parameters:
208
+ x:
209
+ name: x
210
+
211
+ `);
212
+ });
213
+
214
+ it('should remove /my/path/null path ', async () => {
215
+ const testDocument = parseYamlToDocument(
216
+ outdent`
217
+ openapi: 3.0.0
218
+ paths:
219
+ /pet:
220
+ x-access: private
221
+ get:
222
+ x-prop: false
223
+ parameters:
224
+ - $ref: '#/components/parameters/y'
225
+ /my/path/false:
226
+ x-access: private
227
+ x-prop: false
228
+ get:
229
+ parameters:
230
+ - $ref: '#/components/parameters/y'
231
+ /my/path/null:
232
+ x-access: private
233
+ x-prop: null
234
+ get:
235
+ parameters:
236
+ - $ref: '#/components/parameters/y'
237
+ components:
238
+ parameters:
239
+ x:
240
+ name: x
241
+
242
+ `
243
+ );
244
+ const { bundle: res } = await bundleDocument({
245
+ document: testDocument,
246
+ externalRefResolver: new BaseResolver(),
247
+ config: await makeConfig({}, { 'filter-out': { property: 'x-prop', value: null } }),
248
+ });
249
+ expect(res.parsed).toMatchInlineSnapshot(`
250
+ openapi: 3.0.0
251
+ paths:
252
+ /pet:
253
+ x-access: private
254
+ get:
255
+ x-prop: false
256
+ parameters:
257
+ - $ref: '#/components/parameters/y'
258
+ /my/path/false:
259
+ x-access: private
260
+ x-prop: false
261
+ get:
262
+ parameters:
263
+ - $ref: '#/components/parameters/y'
264
+ components:
265
+ parameters:
266
+ x:
267
+ name: x
268
+
269
+ `);
270
+ });
163
271
  });
164
272
 
165
273
  describe('oas2 filter-out', () => {
@@ -18,7 +18,7 @@ describe('oas3 remove-x-internal', () => {
18
18
  parameters:
19
19
  x:
20
20
  name: x
21
- `,
21
+ `
22
22
  );
23
23
 
24
24
  it('should use `internalFlagProperty` option to remove internal paths', async () => {
@@ -87,7 +87,7 @@ describe('oas3 remove-x-internal', () => {
87
87
  name: x
88
88
  y:
89
89
  name: y
90
- `,
90
+ `
91
91
  );
92
92
  const { bundle: res } = await bundleDocument({
93
93
  document: testDoc,
@@ -160,7 +160,7 @@ describe('oas3 remove-x-internal', () => {
160
160
  servers:
161
161
  - url: //callback-url.path-level/v1
162
162
  description: Path level server
163
- `,
163
+ `
164
164
  );
165
165
  const { bundle: res } = await bundleDocument({
166
166
  document: testDoc,
@@ -234,7 +234,7 @@ describe('oas3 remove-x-internal', () => {
234
234
  schema:
235
235
  type: string
236
236
  x-internal: true
237
- `,
237
+ `
238
238
  );
239
239
  const { bundle: res } = await bundleDocument({
240
240
  document: testDoc,
@@ -297,7 +297,7 @@ describe('oas2 remove-x-internal', () => {
297
297
  '200':
298
298
  x-internal: true
299
299
  description: List of recent media entries.
300
- `,
300
+ `
301
301
  );
302
302
  const { bundle: res } = await bundleDocument({
303
303
  document: testDoc,
@@ -47,7 +47,7 @@ export function checkIfMatchByStrategy(
47
47
  decoratorValue: any,
48
48
  strategy: 'all' | 'any'
49
49
  ): boolean {
50
- if (!nodeValue || !decoratorValue) {
50
+ if (nodeValue === undefined || decoratorValue === undefined) {
51
51
  return false;
52
52
  }
53
53
 
@@ -8,7 +8,7 @@ export const InfoDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ filePat
8
8
  leave(info, { report, location }: UserContext) {
9
9
  if (!filePath)
10
10
  throw new Error(
11
- `Parameter "filePath" is not provided for "info-description-override" rule`,
11
+ `Parameter "filePath" is not provided for "info-description-override" rule`
12
12
  );
13
13
  try {
14
14
  info.description = readFileAsStringSync(filePath);
@@ -11,7 +11,7 @@ export const OperationDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ op
11
11
  if (!operation.operationId) return;
12
12
  if (!operationIds)
13
13
  throw new Error(
14
- `Parameter "operationIds" is not provided for "operation-description-override" rule`,
14
+ `Parameter "operationIds" is not provided for "operation-description-override" rule`
15
15
  );
16
16
  const operationId = operation.operationId;
17
17
  if (operationIds[operationId]) {
@@ -53,7 +53,7 @@ export const RemoveXInternal: Oas3Decorator | Oas2Decorator = ({ internalFlagPro
53
53
  any: {
54
54
  enter: (node, ctx) => {
55
55
  removeInternal(node, ctx);
56
- }
57
- }
58
- }
59
- }
56
+ },
57
+ },
58
+ };
59
+ };
@@ -8,7 +8,7 @@ export const TagDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ tagNames
8
8
  leave(tag, { report }: UserContext) {
9
9
  if (!tagNames)
10
10
  throw new Error(
11
- `Parameter "tagNames" is not provided for "tag-description-override" rule`,
11
+ `Parameter "tagNames" is not provided for "tag-description-override" rule`
12
12
  );
13
13
  if (tagNames[tag.name]) {
14
14
  try {
@@ -63,7 +63,7 @@ export function getCodeframe(location: LineColLocationObject, color: boolean) {
63
63
  line: string,
64
64
  startIdx: number = -1,
65
65
  endIdx: number = +Infinity,
66
- variant = gray,
66
+ variant = gray
67
67
  ) {
68
68
  if (!color) return line;
69
69
  if (!line) return line;
@@ -84,14 +84,14 @@ function printPrefixedLines(lines: [string, string][]): string {
84
84
 
85
85
  const padLen = Math.max(...existingLines.map(([prefix]) => prefix.length));
86
86
  const dedentLen = Math.min(
87
- ...existingLines.map(([_, line]) => (line === '' ? Infinity : padSize(line))),
87
+ ...existingLines.map(([_, line]) => (line === '' ? Infinity : padSize(line)))
88
88
  );
89
89
 
90
90
  return existingLines
91
91
  .map(
92
92
  ([prefix, line]) =>
93
93
  gray(leftPad(padLen, prefix) + ' |') +
94
- (line ? ' ' + limitLineLength(line.substring(dedentLen)) : ''),
94
+ (line ? ' ' + limitLineLength(line.substring(dedentLen)) : '')
95
95
  )
96
96
  .join('\n');
97
97
  }
@@ -146,7 +146,7 @@ export function getLineColLocation(location: LocationObject): LineColLocationObj
146
146
  function positionsToLoc(
147
147
  source: string,
148
148
  startPos: number,
149
- endPos: number,
149
+ endPos: number
150
150
  ): { start: Loc; end: Loc } {
151
151
  let currentLine = 1;
152
152
  let currentCol = 1;
@@ -14,7 +14,7 @@ const coreVersion = require('../../package.json').version;
14
14
 
15
15
  import { NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject } from '../walk';
16
16
  import { getCodeframe, getLineColLocation } from './codeframes';
17
- import { env } from "../config";
17
+ import { env } from '../config';
18
18
 
19
19
  export type Totals = {
20
20
  errors: number;
@@ -84,7 +84,7 @@ export function formatProblems(
84
84
  color?: boolean;
85
85
  totals: Totals;
86
86
  version: string;
87
- },
87
+ }
88
88
  ) {
89
89
  const {
90
90
  maxProblems = 100,
@@ -120,7 +120,7 @@ export function formatProblems(
120
120
  case 'stylish': {
121
121
  const groupedByFile = groupByFiles(problems);
122
122
  for (const [file, { ruleIdPad, locationPad: positionPad, fileProblems }] of Object.entries(
123
- groupedByFile,
123
+ groupedByFile
124
124
  )) {
125
125
  process.stderr.write(`${blue(path.relative(cwd, file))}:\n`);
126
126
 
@@ -156,8 +156,8 @@ export function formatProblems(
156
156
  if (totalProblems - ignoredProblems > maxProblems) {
157
157
  process.stderr.write(
158
158
  `< ... ${totalProblems - maxProblems} more problems hidden > ${gray(
159
- 'increase with `--max-problems N`',
160
- )}\n`,
159
+ 'increase with `--max-problems N`'
160
+ )}\n`
161
161
  );
162
162
  }
163
163
 
@@ -243,12 +243,12 @@ export function formatProblems(
243
243
  function formatStylish(problem: OnlyLineColProblem, locationPad: number, ruleIdPad: number) {
244
244
  const color = COLORS[problem.severity];
245
245
  if (!SEVERITY_NAMES[problem.severity]) {
246
- return 'Error not found severity. Please check your config file. Allowed values: \`warn,error,off\`'
246
+ return 'Error not found severity. Please check your config file. Allowed values: `warn,error,off`';
247
247
  }
248
248
  const severityName = color(SEVERITY_NAMES[problem.severity].toLowerCase().padEnd(7));
249
249
  const { start } = problem.location[0];
250
250
  return ` ${`${start.line}:${start.col}`.padEnd(
251
- locationPad,
251
+ locationPad
252
252
  )} ${severityName} ${problem.ruleId.padEnd(ruleIdPad)} ${problem.message}`;
253
253
  }
254
254
 
@@ -258,7 +258,7 @@ export function formatProblems(
258
258
  const message = xmlEscape(problem.message);
259
259
  const source = xmlEscape(problem.ruleId);
260
260
  process.stdout.write(
261
- `<error line="${line}" column="${col}" severity="${severity}" message="${message}" source="${source}" />\n`,
261
+ `<error line="${line}" column="${col}" severity="${severity}" message="${message}" source="${source}" />\n`
262
262
  );
263
263
  }
264
264
  }
@@ -307,12 +307,12 @@ const groupByFiles = (problems: NormalizedProblem[]) => {
307
307
  fileGroups[absoluteRef].fileProblems.push(mappedProblem);
308
308
  fileGroups[absoluteRef].ruleIdPad = Math.max(
309
309
  problem.ruleId.length,
310
- fileGroups[absoluteRef].ruleIdPad,
310
+ fileGroups[absoluteRef].ruleIdPad
311
311
  );
312
312
 
313
313
  fileGroups[absoluteRef].locationPad = Math.max(
314
314
  Math.max(...mappedProblem.location.map((loc) => `${loc.start.line}:${loc.start.col}`.length)),
315
- fileGroups[absoluteRef].locationPad,
315
+ fileGroups[absoluteRef].locationPad
316
316
  );
317
317
  }
318
318