@redocly/openapi-core 1.0.0-beta.120 → 1.0.0-beta.121

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 (36) hide show
  1. package/lib/config/config.d.ts +2 -3
  2. package/lib/config/config.js +1 -2
  3. package/lib/config/types.d.ts +13 -6
  4. package/lib/config/utils.d.ts +1 -0
  5. package/lib/config/utils.js +21 -12
  6. package/lib/decorators/common/info-override.d.ts +2 -0
  7. package/lib/decorators/common/info-override.js +28 -0
  8. package/lib/decorators/oas2/index.d.ts +1 -0
  9. package/lib/decorators/oas2/index.js +2 -0
  10. package/lib/decorators/oas3/index.d.ts +1 -0
  11. package/lib/decorators/oas3/index.js +2 -0
  12. package/lib/rules/common/operation-2xx-response.js +15 -9
  13. package/lib/rules/common/operation-4xx-response.js +15 -9
  14. package/lib/rules/utils.d.ts +1 -0
  15. package/lib/rules/utils.js +14 -2
  16. package/lib/types/redocly-yaml.js +9 -2
  17. package/lib/utils.d.ts +2 -2
  18. package/lib/utils.js +9 -4
  19. package/package.json +1 -1
  20. package/src/__tests__/lint.test.ts +19 -73
  21. package/src/config/__tests__/config.test.ts +8 -10
  22. package/src/config/__tests__/utils.test.ts +67 -6
  23. package/src/config/config.ts +3 -4
  24. package/src/config/types.ts +15 -6
  25. package/src/config/utils.ts +32 -18
  26. package/src/decorators/common/info-override.ts +15 -0
  27. package/src/decorators/oas2/index.ts +2 -0
  28. package/src/decorators/oas3/index.ts +2 -0
  29. package/src/rules/common/__tests__/operation-2xx-response.test.ts +64 -0
  30. package/src/rules/common/__tests__/operation-4xx-response.test.ts +64 -0
  31. package/src/rules/common/operation-2xx-response.ts +17 -9
  32. package/src/rules/common/operation-4xx-response.ts +16 -9
  33. package/src/rules/utils.ts +26 -1
  34. package/src/types/redocly-yaml.ts +14 -4
  35. package/src/utils.ts +18 -4
  36. package/tsconfig.tsbuildinfo +1 -1
@@ -1,7 +1,7 @@
1
1
  import { NormalizedProblem } from '../walk';
2
2
  import { OasVersion, OasMajorVersion, Oas2RuleSet, Oas3RuleSet } from '../oas-types';
3
3
  import type { NodeType } from '../types';
4
- import type { DecoratorConfig, Plugin, PreprocessorConfig, Region, ResolveConfig, ResolvedApi, ResolvedConfig, ResolvedStyleguideConfig, RuleConfig, RuleSettings } from './types';
4
+ import type { DecoratorConfig, Plugin, PreprocessorConfig, Region, ResolveConfig, ResolvedApi, ResolvedConfig, ResolvedStyleguideConfig, RuleConfig, RuleSettings, ThemeRawConfig } from './types';
5
5
  export declare const IGNORE_FILE = ".redocly.lint-ignore.yaml";
6
6
  export declare const DEFAULT_REGION = "us";
7
7
  export declare const DOMAINS: {
@@ -50,8 +50,7 @@ export declare class Config {
50
50
  resolve: ResolveConfig;
51
51
  licenseKey?: string;
52
52
  region?: Region;
53
- 'features.openapi': Record<string, any>;
54
- 'features.mockServer'?: Record<string, any>;
53
+ theme: ThemeRawConfig;
55
54
  organization?: string;
56
55
  files: string[];
57
56
  constructor(rawConfig: ResolvedConfig, configFile?: string | undefined);
@@ -244,8 +244,7 @@ class Config {
244
244
  this.configFile = configFile;
245
245
  this.apis = rawConfig.apis || {};
246
246
  this.styleguide = new StyleguideConfig(rawConfig.styleguide || {}, configFile);
247
- this['features.openapi'] = rawConfig['features.openapi'] || {};
248
- this['features.mockServer'] = rawConfig['features.mockServer'] || {};
247
+ this.theme = rawConfig.theme || {};
249
248
  this.resolve = utils_2.getResolveConfig(rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.resolve);
250
249
  this.region = rawConfig.region;
251
250
  this.organization = rawConfig.organization;
@@ -102,14 +102,14 @@ export declare type DeprecatedInRawConfig = {
102
102
  styleguide?: StyleguideRawConfig;
103
103
  referenceDocs?: Record<string, any>;
104
104
  apis?: Record<string, Api & DeprecatedInApi>;
105
- };
105
+ } & DeprecatedFeaturesConfig;
106
106
  export declare type Api = {
107
107
  root: string;
108
108
  styleguide?: ApiStyleguideRawConfig;
109
- } & FeaturesConfig;
109
+ } & ThemeConfig;
110
110
  export declare type DeprecatedInApi = {
111
111
  lint?: ApiStyleguideRawConfig;
112
- };
112
+ } & DeprecatedFeaturesConfig;
113
113
  export declare type ResolvedApi = Omit<Api, 'styleguide'> & {
114
114
  styleguide: ResolvedStyleguideConfig;
115
115
  files?: string[];
@@ -121,19 +121,26 @@ export declare type RawConfig = {
121
121
  region?: Region;
122
122
  organization?: string;
123
123
  files?: string[];
124
- } & FeaturesConfig;
124
+ } & ThemeConfig;
125
125
  export declare type FlatApi = Omit<Api, 'styleguide'> & Omit<ApiStyleguideRawConfig, 'doNotResolveExamples'>;
126
126
  export declare type FlatRawConfig = Omit<RawConfig, 'styleguide' | 'resolve' | 'apis'> & Omit<StyleguideRawConfig, 'doNotResolveExamples'> & {
127
127
  resolve?: RawResolveConfig;
128
128
  apis?: Record<string, FlatApi>;
129
- };
129
+ } & ThemeRawConfig;
130
130
  export declare type ResolvedConfig = Omit<RawConfig, 'apis' | 'styleguide'> & {
131
131
  apis: Record<string, ResolvedApi>;
132
132
  styleguide: ResolvedStyleguideConfig;
133
133
  };
134
- declare type FeaturesConfig = {
134
+ declare type DeprecatedFeaturesConfig = {
135
135
  'features.openapi'?: Record<string, any>;
136
136
  'features.mockServer'?: Record<string, any>;
137
137
  };
138
+ export declare type ThemeConfig = {
139
+ theme?: ThemeRawConfig;
140
+ };
141
+ export declare type ThemeRawConfig = {
142
+ openapi?: Record<string, any>;
143
+ mockServer?: Record<string, any>;
144
+ };
138
145
  export declare type RulesFields = 'rules' | 'oas2Rules' | 'oas3_0Rules' | 'oas3_1Rules' | 'preprocessors' | 'oas2Preprocessors' | 'oas3_0Preprocessors' | 'oas3_1Preprocessors' | 'decorators' | 'oas2Decorators' | 'oas3_0Decorators' | 'oas3_1Decorators';
139
146
  export {};
@@ -8,6 +8,7 @@ export declare function transformApiDefinitionsToApis(apiDefinitions?: Deprecate
8
8
  export declare function prefixRules<T extends Record<string, any>>(rules: T, prefix: string): any;
9
9
  export declare function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]): Omit<ResolvedStyleguideConfig, RulesFields> & Required<Pick<ResolvedStyleguideConfig, RulesFields>>;
10
10
  export declare function getMergedConfig(config: Config, apiName?: string): Config;
11
+ export declare function checkForDeprecatedFields(deprecatedField: keyof (DeprecatedInRawConfig & RawConfig), updatedField: keyof FlatRawConfig | undefined, rawConfig: DeprecatedInRawConfig & RawConfig & FlatRawConfig, updatedObject: keyof FlatRawConfig | undefined): void;
11
12
  export declare function transformConfig(rawConfig: DeprecatedInRawConfig & RawConfig & FlatRawConfig): RawConfig;
12
13
  export declare function getResolveConfig(resolve?: RawResolveConfig): ResolveConfig;
13
14
  export declare function getUniquePlugins(plugins: Plugin[]): Plugin[];
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  return t;
12
12
  };
13
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;
14
+ exports.getUniquePlugins = exports.getResolveConfig = exports.transformConfig = exports.checkForDeprecatedFields = exports.getMergedConfig = exports.mergeExtends = exports.prefixRules = exports.transformApiDefinitionsToApis = exports.parsePresetName = void 0;
15
15
  const utils_1 = require("../utils");
16
16
  const config_1 = require("./config");
17
17
  const logger_1 = require("../logger");
@@ -139,7 +139,7 @@ function mergeExtends(rulesConfList) {
139
139
  }
140
140
  exports.mergeExtends = mergeExtends;
141
141
  function getMergedConfig(config, apiName) {
142
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
142
+ var _a, _b, _c, _d, _e, _f, _g, _h;
143
143
  const extendPaths = [
144
144
  ...Object.values(config.apis).map((api) => { var _a; return (_a = api === null || api === void 0 ? void 0 : api.styleguide) === null || _a === void 0 ? void 0 : _a.extendPaths; }),
145
145
  (_b = (_a = config.rawConfig) === null || _a === void 0 ? void 0 : _a.styleguide) === null || _b === void 0 ? void 0 : _b.extendPaths,
@@ -156,11 +156,11 @@ function getMergedConfig(config, apiName) {
156
156
  ? new config_1.Config(Object.assign(Object.assign({}, config.rawConfig), { styleguide: Object.assign(Object.assign({}, (config.apis[apiName]
157
157
  ? config.apis[apiName].styleguide
158
158
  : config.rawConfig.styleguide)), { extendPaths,
159
- pluginPaths }), 'features.openapi': Object.assign(Object.assign({}, config['features.openapi']), (_e = config.apis[apiName]) === null || _e === void 0 ? void 0 : _e['features.openapi']), 'features.mockServer': Object.assign(Object.assign({}, config['features.mockServer']), (_f = config.apis[apiName]) === null || _f === void 0 ? void 0 : _f['features.mockServer']), files: [...config.files, ...((_j = (_h = (_g = config.apis) === null || _g === void 0 ? void 0 : _g[apiName]) === null || _h === void 0 ? void 0 : _h.files) !== null && _j !== void 0 ? _j : [])] }), config.configFile)
159
+ pluginPaths }), theme: Object.assign(Object.assign({}, config.rawConfig.theme), (_e = config.apis[apiName]) === null || _e === void 0 ? void 0 : _e.theme), files: [...config.files, ...((_h = (_g = (_f = config.apis) === null || _f === void 0 ? void 0 : _f[apiName]) === null || _g === void 0 ? void 0 : _g.files) !== null && _h !== void 0 ? _h : [])] }), config.configFile)
160
160
  : config;
161
161
  }
162
162
  exports.getMergedConfig = getMergedConfig;
163
- function checkForDeprecatedFields(deprecatedField, updatedField, rawConfig) {
163
+ function checkForDeprecatedFields(deprecatedField, updatedField, rawConfig, updatedObject) {
164
164
  const isDeprecatedFieldInApis = rawConfig.apis &&
165
165
  Object.values(rawConfig.apis).some((api) => api[deprecatedField]);
166
166
  if (rawConfig[deprecatedField] && updatedField === null) {
@@ -169,23 +169,32 @@ function checkForDeprecatedFields(deprecatedField, updatedField, rawConfig) {
169
169
  if (rawConfig[deprecatedField] && updatedField && rawConfig[updatedField]) {
170
170
  utils_1.showErrorForDeprecatedField(deprecatedField, updatedField);
171
171
  }
172
+ if (rawConfig[deprecatedField] && updatedObject && rawConfig[updatedObject]) {
173
+ utils_1.showErrorForDeprecatedField(deprecatedField, updatedField, updatedObject);
174
+ }
172
175
  if (rawConfig[deprecatedField] || isDeprecatedFieldInApis) {
173
- utils_1.showWarningForDeprecatedField(deprecatedField, updatedField);
176
+ utils_1.showWarningForDeprecatedField(deprecatedField, updatedField, updatedObject);
174
177
  }
175
178
  }
179
+ exports.checkForDeprecatedFields = checkForDeprecatedFields;
176
180
  function transformConfig(rawConfig) {
181
+ var _a, _b;
177
182
  const migratedFields = [
178
- ['apiDefinitions', 'apis'],
179
- ['referenceDocs', 'features.openapi'],
180
- ['lint', undefined],
181
- ['styleguide', undefined],
183
+ ['apiDefinitions', 'apis', undefined],
184
+ ['referenceDocs', 'openapi', 'theme'],
185
+ ['lint', undefined, undefined],
186
+ ['styleguide', undefined, undefined],
187
+ ['features.openapi', 'openapi', 'theme'],
182
188
  ];
183
- for (const [deprecatedField, updatedField] of migratedFields) {
184
- checkForDeprecatedFields(deprecatedField, updatedField, rawConfig);
189
+ for (const [deprecatedField, updatedField, updatedObject] of migratedFields) {
190
+ checkForDeprecatedFields(deprecatedField, updatedField, rawConfig, updatedObject);
185
191
  }
186
192
  const { apis, apiDefinitions, referenceDocs, lint } = rawConfig, rest = __rest(rawConfig, ["apis", "apiDefinitions", "referenceDocs", "lint"]);
187
193
  const { styleguideConfig, rawConfigRest } = extractFlatConfig(rest);
188
- return Object.assign({ 'features.openapi': referenceDocs, apis: transformApis(apis) || transformApiDefinitionsToApis(apiDefinitions), styleguide: styleguideConfig || lint }, rawConfigRest);
194
+ return Object.assign({ theme: {
195
+ openapi: Object.assign(Object.assign(Object.assign({}, referenceDocs), rawConfig['features.openapi']), (_a = rawConfig.theme) === null || _a === void 0 ? void 0 : _a.openapi),
196
+ mockServer: Object.assign(Object.assign({}, rawConfig['features.mockServer']), (_b = rawConfig.theme) === null || _b === void 0 ? void 0 : _b.mockServer),
197
+ }, apis: transformApis(apis) || transformApiDefinitionsToApis(apiDefinitions), styleguide: styleguideConfig || lint }, rawConfigRest);
189
198
  }
190
199
  exports.transformConfig = transformConfig;
191
200
  function getResolveConfig(resolve) {
@@ -0,0 +1,2 @@
1
+ import { Oas3Decorator, Oas2Decorator } from '../../visitors';
2
+ export declare const InfoOverride: Oas3Decorator | Oas2Decorator;
@@ -0,0 +1,28 @@
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.InfoOverride = void 0;
15
+ const InfoOverride = (newInfo) => {
16
+ return {
17
+ Info: {
18
+ leave(info) {
19
+ if (typeof newInfo !== 'object' || Array.isArray(newInfo) || newInfo === null) {
20
+ throw new Error(`"info-override" decorator should be called with an object`);
21
+ }
22
+ const { severity: _ } = newInfo, rest = __rest(newInfo, ["severity"]);
23
+ Object.assign(info, rest);
24
+ },
25
+ },
26
+ };
27
+ };
28
+ exports.InfoOverride = InfoOverride;
@@ -4,6 +4,7 @@ export declare const decorators: {
4
4
  'operation-description-override': Oas2Decorator;
5
5
  'tag-description-override': Oas2Decorator;
6
6
  'info-description-override': Oas2Decorator;
7
+ 'info-override': Oas2Decorator;
7
8
  'remove-x-internal': Oas2Decorator;
8
9
  'filter-in': Oas2Decorator;
9
10
  'filter-out': Oas2Decorator;
@@ -5,6 +5,7 @@ const registry_dependencies_1 = require("../common/registry-dependencies");
5
5
  const operation_description_override_1 = require("../common/operation-description-override");
6
6
  const tag_description_override_1 = require("../common/tag-description-override");
7
7
  const info_description_override_1 = require("../common/info-description-override");
8
+ const info_override_1 = require("../common/info-override");
8
9
  const remove_x_internal_1 = require("../common/remove-x-internal");
9
10
  const filter_in_1 = require("../common/filters/filter-in");
10
11
  const filter_out_1 = require("../common/filters/filter-out");
@@ -13,6 +14,7 @@ exports.decorators = {
13
14
  'operation-description-override': operation_description_override_1.OperationDescriptionOverride,
14
15
  'tag-description-override': tag_description_override_1.TagDescriptionOverride,
15
16
  'info-description-override': info_description_override_1.InfoDescriptionOverride,
17
+ 'info-override': info_override_1.InfoOverride,
16
18
  'remove-x-internal': remove_x_internal_1.RemoveXInternal,
17
19
  'filter-in': filter_in_1.FilterIn,
18
20
  'filter-out': filter_out_1.FilterOut,
@@ -4,6 +4,7 @@ export declare const decorators: {
4
4
  'operation-description-override': Oas3Decorator;
5
5
  'tag-description-override': Oas3Decorator;
6
6
  'info-description-override': Oas3Decorator;
7
+ 'info-override': Oas3Decorator;
7
8
  'remove-x-internal': Oas3Decorator;
8
9
  'filter-in': Oas3Decorator;
9
10
  'filter-out': Oas3Decorator;
@@ -5,6 +5,7 @@ const registry_dependencies_1 = require("../common/registry-dependencies");
5
5
  const operation_description_override_1 = require("../common/operation-description-override");
6
6
  const tag_description_override_1 = require("../common/tag-description-override");
7
7
  const info_description_override_1 = require("../common/info-description-override");
8
+ const info_override_1 = require("../common/info-override");
8
9
  const remove_x_internal_1 = require("../common/remove-x-internal");
9
10
  const filter_in_1 = require("../common/filters/filter-in");
10
11
  const filter_out_1 = require("../common/filters/filter-out");
@@ -14,6 +15,7 @@ exports.decorators = {
14
15
  'operation-description-override': operation_description_override_1.OperationDescriptionOverride,
15
16
  'tag-description-override': tag_description_override_1.TagDescriptionOverride,
16
17
  'info-description-override': info_description_override_1.InfoDescriptionOverride,
18
+ 'info-override': info_override_1.InfoOverride,
17
19
  'remove-x-internal': remove_x_internal_1.RemoveXInternal,
18
20
  'filter-in': filter_in_1.FilterIn,
19
21
  'filter-out': filter_out_1.FilterOut,
@@ -1,16 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Operation2xxResponse = void 0;
4
- const Operation2xxResponse = () => {
4
+ const utils_1 = require("../utils");
5
+ const Operation2xxResponse = ({ validateWebhooks }) => {
5
6
  return {
6
- Responses(responses, { report }) {
7
- const codes = Object.keys(responses || {});
8
- if (!codes.some((code) => code === 'default' || /2[Xx0-9]{2}/.test(code))) {
9
- report({
10
- message: 'Operation must have at least one `2XX` response.',
11
- location: { reportOnKey: true },
12
- });
13
- }
7
+ Paths: {
8
+ Responses(responses, { report }) {
9
+ const codes = Object.keys(responses || {});
10
+ utils_1.validateResponseCodes(codes, '2XX', { report });
11
+ },
12
+ },
13
+ WebhooksMap: {
14
+ Responses(responses, { report }) {
15
+ if (!validateWebhooks)
16
+ return;
17
+ const codes = Object.keys(responses || {});
18
+ utils_1.validateResponseCodes(codes, '2XX', { report });
19
+ },
14
20
  },
15
21
  };
16
22
  };
@@ -1,16 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Operation4xxResponse = void 0;
4
- const Operation4xxResponse = () => {
4
+ const utils_1 = require("../utils");
5
+ const Operation4xxResponse = ({ validateWebhooks }) => {
5
6
  return {
6
- Responses(responses, { report }) {
7
- const codes = Object.keys(responses || {});
8
- if (!codes.some((code) => /4[Xx0-9]{2}/.test(code))) {
9
- report({
10
- message: 'Operation must have at least one `4XX` response.',
11
- location: { reportOnKey: true },
12
- });
13
- }
7
+ Paths: {
8
+ Responses(responses, { report }) {
9
+ const codes = Object.keys(responses || {});
10
+ utils_1.validateResponseCodes(codes, '4XX', { report });
11
+ },
12
+ },
13
+ WebhooksMap: {
14
+ Responses(responses, { report }) {
15
+ if (!validateWebhooks)
16
+ return;
17
+ const codes = Object.keys(responses || {});
18
+ utils_1.validateResponseCodes(codes, '4XX', { report });
19
+ },
14
20
  },
15
21
  };
16
22
  };
@@ -17,3 +17,4 @@ export declare function getSuggest(given: string, variants: string[]): string[];
17
17
  export declare function validateExample(example: any, schema: Referenced<Oas3Schema>, dataLoc: Location, { resolve, location, report }: UserContext, allowAdditionalProperties: boolean): void;
18
18
  export declare function getAdditionalPropertiesOption(opts: Record<string, any>): boolean;
19
19
  export declare function validateSchemaEnumType(schemaEnum: string[], propertyValue: string, propName: string, refLocation: Location | undefined, { report, location }: UserContext): void;
20
+ export declare function validateResponseCodes(responseCodes: string[], codeRange: string, { report }: UserContext): void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateSchemaEnumType = exports.getAdditionalPropertiesOption = exports.validateExample = exports.getSuggest = exports.validateDefinedAndNonEmpty = exports.fieldNonEmpty = exports.missingRequiredField = exports.matchesJsonSchemaType = exports.oasTypeOf = void 0;
3
+ exports.validateResponseCodes = exports.validateSchemaEnumType = exports.getAdditionalPropertiesOption = exports.validateExample = exports.getSuggest = exports.validateDefinedAndNonEmpty = exports.fieldNonEmpty = exports.missingRequiredField = exports.matchesJsonSchemaType = exports.oasTypeOf = void 0;
4
4
  const levenshtein = require("js-levenshtein");
5
5
  const ref_utils_1 = require("../ref-utils");
6
6
  const ajv_1 = require("./ajv");
@@ -117,7 +117,7 @@ function getAdditionalPropertiesOption(opts) {
117
117
  return opts.allowAdditionalProperties;
118
118
  }
119
119
  if (opts.allowAdditionalProperties !== undefined) {
120
- utils_1.showErrorForDeprecatedField('disallowAdditionalProperties', 'allowAdditionalProperties');
120
+ utils_1.showErrorForDeprecatedField('disallowAdditionalProperties', 'allowAdditionalProperties', undefined);
121
121
  }
122
122
  utils_1.showWarningForDeprecatedField('disallowAdditionalProperties', 'allowAdditionalProperties');
123
123
  return !opts.disallowAdditionalProperties;
@@ -139,3 +139,15 @@ function validateSchemaEnumType(schemaEnum, propertyValue, propName, refLocation
139
139
  }
140
140
  }
141
141
  exports.validateSchemaEnumType = validateSchemaEnumType;
142
+ function validateResponseCodes(responseCodes, codeRange, { report }) {
143
+ const responseCodeRegexp = new RegExp(`^${codeRange[0]}[0-9Xx]{2}$`);
144
+ const containsNeededCode = responseCodes.some((code) => (codeRange === '2XX' && code === 'default') || // It's OK to replace 2xx codes with the default
145
+ responseCodeRegexp.test(code));
146
+ if (!containsNeededCode) {
147
+ report({
148
+ message: `Operation must have at least one \`${codeRange}\` response.`,
149
+ location: { reportOnKey: true },
150
+ });
151
+ }
152
+ }
153
+ exports.validateResponseCodes = validateResponseCodes;
@@ -146,7 +146,7 @@ const RootConfigStyleguide = {
146
146
  } }, ConfigStyleguide.properties),
147
147
  };
148
148
  const ConfigRoot = {
149
- properties: Object.assign(Object.assign({ organization: { type: 'string' }, apis: 'ConfigApis' }, RootConfigStyleguide.properties), { 'features.openapi': 'ConfigReferenceDocs', 'features.mockServer': 'ConfigMockServer', region: { enum: ['us', 'eu'] }, resolve: {
149
+ properties: Object.assign(Object.assign({ organization: { type: 'string' }, apis: 'ConfigApis' }, RootConfigStyleguide.properties), { theme: 'ConfigRootTheme', 'features.openapi': 'ConfigReferenceDocs', 'features.mockServer': 'ConfigMockServer', region: { enum: ['us', 'eu'] }, resolve: {
150
150
  properties: {
151
151
  http: 'ConfigHTTP',
152
152
  doNotResolveExamples: { type: 'boolean' },
@@ -168,7 +168,7 @@ const ConfigApisProperties = {
168
168
  items: {
169
169
  type: 'string',
170
170
  },
171
- }, lint: 'ConfigStyleguide', styleguide: 'ConfigStyleguide' }, ConfigStyleguide.properties), { 'features.openapi': 'ConfigReferenceDocs', 'features.mockServer': 'ConfigMockServer', files: {
171
+ }, lint: 'ConfigStyleguide', styleguide: 'ConfigStyleguide' }, ConfigStyleguide.properties), { 'features.openapi': 'ConfigReferenceDocs', 'features.mockServer': 'ConfigMockServer', theme: 'ConfigRootTheme', files: {
172
172
  type: 'array',
173
173
  items: {
174
174
  type: 'string',
@@ -186,6 +186,12 @@ const ConfigHTTP = {
186
186
  },
187
187
  },
188
188
  };
189
+ const ConfigRootTheme = {
190
+ properties: {
191
+ openapi: 'ConfigReferenceDocs',
192
+ mockServer: 'ConfigMockServer',
193
+ },
194
+ };
189
195
  const Rules = {
190
196
  properties: {},
191
197
  additionalProperties: (value, key) => {
@@ -815,6 +821,7 @@ exports.ConfigTypes = {
815
821
  ConfigSidebarLinks,
816
822
  CommonConfigSidebarLinks,
817
823
  ConfigTheme,
824
+ ConfigRootTheme,
818
825
  AssertDefinition,
819
826
  ThemeColors,
820
827
  CommonThemeColors,
package/lib/utils.d.ts CHANGED
@@ -42,8 +42,8 @@ export declare function assignExisting<T>(target: Record<string, T>, obj: Record
42
42
  export declare function getMatchingStatusCodeRange(code: number | string): string;
43
43
  export declare function isCustomRuleId(id: string): boolean;
44
44
  export declare function doesYamlFileExist(filePath: string): boolean;
45
- export declare function showWarningForDeprecatedField(deprecatedField: string, updatedField?: string): void;
46
- export declare function showErrorForDeprecatedField(deprecatedField: string, updatedField?: string): void;
45
+ export declare function showWarningForDeprecatedField(deprecatedField: string, updatedField?: string, updatedObject?: string): void;
46
+ export declare function showErrorForDeprecatedField(deprecatedField: string, updatedField?: string, updatedObject?: string): void;
47
47
  export declare type Falsy = undefined | null | false | '' | 0;
48
48
  export declare function isTruthy<Truthy>(value: Truthy | Falsy): value is Truthy;
49
49
  export declare function identity<T>(value: T): T;
package/lib/utils.js CHANGED
@@ -194,12 +194,14 @@ function doesYamlFileExist(filePath) {
194
194
  fs.existsSync(filePath));
195
195
  }
196
196
  exports.doesYamlFileExist = doesYamlFileExist;
197
- function showWarningForDeprecatedField(deprecatedField, updatedField) {
198
- logger_1.logger.warn(`The '${logger_1.colorize.red(deprecatedField)}' field is deprecated. ${updatedField ? `Use ${logger_1.colorize.green(updatedField)} instead. ` : ''}Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`);
197
+ function showWarningForDeprecatedField(deprecatedField, updatedField, updatedObject) {
198
+ logger_1.logger.warn(`The '${logger_1.colorize.red(deprecatedField)}' field is deprecated. ${updatedField
199
+ ? `Use ${logger_1.colorize.green(getUpdatedFieldName(updatedField, updatedObject))} instead. `
200
+ : ''}Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`);
199
201
  }
200
202
  exports.showWarningForDeprecatedField = showWarningForDeprecatedField;
201
- function showErrorForDeprecatedField(deprecatedField, updatedField) {
202
- throw new Error(`Do not use '${deprecatedField}' field. ${updatedField ? `Use '${updatedField}' instead. ` : ''}\n`);
203
+ function showErrorForDeprecatedField(deprecatedField, updatedField, updatedObject) {
204
+ throw new Error(`Do not use '${deprecatedField}' field. ${updatedField ? `Use '${getUpdatedFieldName(updatedField, updatedObject)}' instead. ` : ''}\n`);
203
205
  }
204
206
  exports.showErrorForDeprecatedField = showErrorForDeprecatedField;
205
207
  function isTruthy(value) {
@@ -234,3 +236,6 @@ function nextTick() {
234
236
  });
235
237
  }
236
238
  exports.nextTick = nextTick;
239
+ function getUpdatedFieldName(updatedField, updatedObject) {
240
+ return `${typeof updatedObject !== 'undefined' ? `${updatedObject}.` : ''}${updatedField}`;
241
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/openapi-core",
3
- "version": "1.0.0-beta.120",
3
+ "version": "1.0.0-beta.121",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "engines": {
@@ -68,17 +68,8 @@ describe('lint', () => {
68
68
  assertions:
69
69
  local/checkWordsCount:
70
70
  min: 3
71
- features.openapi:
72
- showConsole: true
73
- layout:
74
- scope: section
75
- routingStrategy: browser
76
- theme:
77
- rightPanel:
78
- backgroundColor: '#263238'
79
- links:
80
- color: '#6CC496'
81
- features.openapi:
71
+ theme:
72
+ openapi:
82
73
  showConsole: true
83
74
  layout:
84
75
  scope: section
@@ -88,6 +79,17 @@ describe('lint', () => {
88
79
  backgroundColor: '#263238'
89
80
  links:
90
81
  color: '#6CC496'
82
+ theme:
83
+ openapi:
84
+ showConsole: true
85
+ layout:
86
+ scope: section
87
+ routingStrategy: browser
88
+ theme:
89
+ rightPanel:
90
+ backgroundColor: '#263238'
91
+ links:
92
+ color: '#6CC496'
91
93
  `,
92
94
  ''
93
95
  );
@@ -99,70 +101,28 @@ describe('lint', () => {
99
101
  "from": undefined,
100
102
  "location": Array [
101
103
  Object {
102
- "pointer": "#/atures.openapi",
104
+ "pointer": "#/eme",
103
105
  "reportOnKey": true,
104
106
  "source": "",
105
107
  },
106
108
  ],
107
- "message": "Property \`atures.openapi\` is not expected here.",
109
+ "message": "Property \`eme\` is not expected here.",
108
110
  "ruleId": "configuration spec",
109
111
  "severity": "error",
110
112
  "suggest": Array [
111
- "features.openapi",
113
+ "theme",
112
114
  ],
113
115
  },
114
116
  Object {
115
117
  "from": undefined,
116
118
  "location": Array [
117
119
  Object {
118
- "pointer": "#/showConsole",
120
+ "pointer": "#/openapi",
119
121
  "reportOnKey": true,
120
122
  "source": "",
121
123
  },
122
124
  ],
123
- "message": "Property \`showConsole\` is not expected here.",
124
- "ruleId": "configuration spec",
125
- "severity": "error",
126
- "suggest": Array [],
127
- },
128
- Object {
129
- "from": undefined,
130
- "location": Array [
131
- Object {
132
- "pointer": "#/layout",
133
- "reportOnKey": true,
134
- "source": "",
135
- },
136
- ],
137
- "message": "Property \`layout\` is not expected here.",
138
- "ruleId": "configuration spec",
139
- "severity": "error",
140
- "suggest": Array [],
141
- },
142
- Object {
143
- "from": undefined,
144
- "location": Array [
145
- Object {
146
- "pointer": "#/routingStrategy",
147
- "reportOnKey": true,
148
- "source": "",
149
- },
150
- ],
151
- "message": "Property \`routingStrategy\` is not expected here.",
152
- "ruleId": "configuration spec",
153
- "severity": "error",
154
- "suggest": Array [],
155
- },
156
- Object {
157
- "from": undefined,
158
- "location": Array [
159
- Object {
160
- "pointer": "#/theme",
161
- "reportOnKey": true,
162
- "source": "",
163
- },
164
- ],
165
- "message": "Property \`theme\` is not expected here.",
125
+ "message": "Property \`openapi\` is not expected here.",
166
126
  "ruleId": "configuration spec",
167
127
  "severity": "error",
168
128
  "suggest": Array [],
@@ -181,20 +141,6 @@ describe('lint', () => {
181
141
  "severity": "error",
182
142
  "suggest": Array [],
183
143
  },
184
- Object {
185
- "from": undefined,
186
- "location": Array [
187
- Object {
188
- "pointer": "#/features.openapi/layout",
189
- "reportOnKey": false,
190
- "source": "",
191
- },
192
- ],
193
- "message": "\`layout\` can be one of the following only: \\"stacked\\", \\"three-panel\\".",
194
- "ruleId": "configuration spec",
195
- "severity": "error",
196
- "suggest": Array [],
197
- },
198
144
  ]
199
145
  `);
200
146
  });
@@ -234,7 +180,7 @@ describe('lint', () => {
234
180
  `);
235
181
  });
236
182
 
237
- it('lintConfig should work with legacy fields', async () => {
183
+ it('lintConfig should work with legacy fields - referenceDocs', async () => {
238
184
  const document = parseYamlToDocument(
239
185
  outdent`
240
186
  apis: