@redocly/openapi-core 1.1.0 → 1.2.1

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 (77) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +250 -7
  3. package/lib/bundle.d.ts +12 -6
  4. package/lib/bundle.js +34 -24
  5. package/lib/config/builtIn.js +4 -0
  6. package/lib/config/config-resolvers.js +19 -6
  7. package/lib/config/config.d.ts +9 -9
  8. package/lib/config/config.js +32 -17
  9. package/lib/config/load.d.ts +3 -2
  10. package/lib/config/load.js +2 -2
  11. package/lib/config/rules.d.ts +2 -2
  12. package/lib/config/types.d.ts +10 -3
  13. package/lib/index.d.ts +4 -3
  14. package/lib/index.js +10 -6
  15. package/lib/lint.js +10 -16
  16. package/lib/oas-types.d.ts +16 -10
  17. package/lib/oas-types.js +52 -26
  18. package/lib/rules/async2/channels-kebab-case.d.ts +2 -0
  19. package/lib/rules/async2/channels-kebab-case.js +19 -0
  20. package/lib/rules/async2/index.d.ts +12 -0
  21. package/lib/rules/async2/index.js +22 -0
  22. package/lib/rules/async2/no-channel-trailing-slash.d.ts +2 -0
  23. package/lib/rules/async2/no-channel-trailing-slash.js +16 -0
  24. package/lib/rules/common/assertions/asserts.js +12 -4
  25. package/lib/rules/common/scalar-property-missing-example.js +1 -1
  26. package/lib/rules/common/spec.d.ts +2 -2
  27. package/lib/rules/common/spec.js +3 -3
  28. package/lib/rules/oas2/index.js +1 -1
  29. package/lib/rules/oas3/index.js +1 -1
  30. package/lib/rules/oas3/no-server-example.com.js +3 -2
  31. package/lib/types/asyncapi.d.ts +2 -0
  32. package/lib/types/asyncapi.js +1034 -0
  33. package/lib/types/oas3_1.js +8 -1
  34. package/lib/types/redocly-yaml.js +3 -0
  35. package/lib/typings/asyncapi.d.ts +21 -0
  36. package/lib/typings/asyncapi.js +2 -0
  37. package/lib/visitors.d.ts +12 -0
  38. package/lib/walk.d.ts +3 -3
  39. package/package.json +4 -2
  40. package/src/__tests__/__snapshots__/bundle.test.ts.snap +1 -1
  41. package/src/__tests__/bundle.test.ts +65 -25
  42. package/src/__tests__/fixtures/lint/openapi.yaml +10 -0
  43. package/src/__tests__/fixtures/redocly.yaml +2 -0
  44. package/src/__tests__/lint.test.ts +67 -8
  45. package/src/bundle.ts +62 -35
  46. package/src/config/__tests__/__snapshots__/config.test.ts.snap +24 -0
  47. package/src/config/__tests__/config.test.ts +15 -4
  48. package/src/config/__tests__/load.test.ts +35 -2
  49. package/src/config/builtIn.ts +4 -0
  50. package/src/config/config-resolvers.ts +25 -6
  51. package/src/config/config.ts +51 -27
  52. package/src/config/load.ts +11 -4
  53. package/src/config/rules.ts +2 -2
  54. package/src/config/types.ts +17 -4
  55. package/src/index.ts +10 -2
  56. package/src/lint.ts +13 -22
  57. package/src/oas-types.ts +59 -21
  58. package/src/rules/async2/__tests__/channels-kebab-case.test.ts +141 -0
  59. package/src/rules/async2/__tests__/no-channel-trailing-slash.test.ts +97 -0
  60. package/src/rules/async2/channels-kebab-case.ts +18 -0
  61. package/src/rules/async2/index.ts +22 -0
  62. package/src/rules/async2/no-channel-trailing-slash.ts +15 -0
  63. package/src/rules/common/assertions/asserts.ts +16 -4
  64. package/src/rules/common/scalar-property-missing-example.ts +2 -2
  65. package/src/rules/common/spec.ts +2 -2
  66. package/src/rules/oas2/index.ts +2 -2
  67. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +36 -1
  68. package/src/rules/oas3/__tests__/spec/spec.test.ts +1 -1
  69. package/src/rules/oas3/index.ts +2 -2
  70. package/src/rules/oas3/no-server-example.com.ts +3 -2
  71. package/src/types/asyncapi.ts +1142 -0
  72. package/src/types/oas3_1.ts +7 -1
  73. package/src/types/redocly-yaml.ts +3 -0
  74. package/src/typings/asyncapi.ts +26 -0
  75. package/src/visitors.ts +22 -0
  76. package/src/walk.ts +3 -3
  77. package/tsconfig.tsbuildinfo +1 -1
@@ -51,19 +51,22 @@ class StyleguideConfig {
51
51
  this.doNotResolveExamples = !!rawConfig.doNotResolveExamples;
52
52
  this.recommendedFallback = rawConfig.recommendedFallback || false;
53
53
  this.rules = {
54
- [oas_types_1.OasVersion.Version2]: Object.assign(Object.assign({}, rawConfig.rules), rawConfig.oas2Rules),
55
- [oas_types_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, rawConfig.rules), rawConfig.oas3_0Rules),
56
- [oas_types_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, rawConfig.rules), rawConfig.oas3_1Rules),
54
+ [oas_types_1.SpecVersion.OAS2]: Object.assign(Object.assign({}, rawConfig.rules), rawConfig.oas2Rules),
55
+ [oas_types_1.SpecVersion.OAS3_0]: Object.assign(Object.assign({}, rawConfig.rules), rawConfig.oas3_0Rules),
56
+ [oas_types_1.SpecVersion.OAS3_1]: Object.assign(Object.assign({}, rawConfig.rules), rawConfig.oas3_1Rules),
57
+ [oas_types_1.SpecVersion.Async2]: Object.assign(Object.assign({}, rawConfig.rules), rawConfig.async2Rules),
57
58
  };
58
59
  this.preprocessors = {
59
- [oas_types_1.OasVersion.Version2]: Object.assign(Object.assign({}, rawConfig.preprocessors), rawConfig.oas2Preprocessors),
60
- [oas_types_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, rawConfig.preprocessors), rawConfig.oas3_0Preprocessors),
61
- [oas_types_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, rawConfig.preprocessors), rawConfig.oas3_1Preprocessors),
60
+ [oas_types_1.SpecVersion.OAS2]: Object.assign(Object.assign({}, rawConfig.preprocessors), rawConfig.oas2Preprocessors),
61
+ [oas_types_1.SpecVersion.OAS3_0]: Object.assign(Object.assign({}, rawConfig.preprocessors), rawConfig.oas3_0Preprocessors),
62
+ [oas_types_1.SpecVersion.OAS3_1]: Object.assign(Object.assign({}, rawConfig.preprocessors), rawConfig.oas3_1Preprocessors),
63
+ [oas_types_1.SpecVersion.Async2]: Object.assign(Object.assign({}, rawConfig.preprocessors), rawConfig.async2Preprocessors),
62
64
  };
63
65
  this.decorators = {
64
- [oas_types_1.OasVersion.Version2]: Object.assign(Object.assign({}, rawConfig.decorators), rawConfig.oas2Decorators),
65
- [oas_types_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, rawConfig.decorators), rawConfig.oas3_0Decorators),
66
- [oas_types_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, rawConfig.decorators), rawConfig.oas3_1Decorators),
66
+ [oas_types_1.SpecVersion.OAS2]: Object.assign(Object.assign({}, rawConfig.decorators), rawConfig.oas2Decorators),
67
+ [oas_types_1.SpecVersion.OAS3_0]: Object.assign(Object.assign({}, rawConfig.decorators), rawConfig.oas3_0Decorators),
68
+ [oas_types_1.SpecVersion.OAS3_1]: Object.assign(Object.assign({}, rawConfig.decorators), rawConfig.oas3_1Decorators),
69
+ [oas_types_1.SpecVersion.Async2]: Object.assign(Object.assign({}, rawConfig.decorators), rawConfig.async2Decorators),
67
70
  };
68
71
  this.extendPaths = rawConfig.extendPaths || [];
69
72
  this.pluginPaths = rawConfig.pluginPaths || [];
@@ -124,17 +127,22 @@ class StyleguideConfig {
124
127
  for (const plugin of this.plugins) {
125
128
  if (plugin.typeExtension !== undefined) {
126
129
  switch (version) {
127
- case oas_types_1.OasVersion.Version3_0:
128
- case oas_types_1.OasVersion.Version3_1:
130
+ case oas_types_1.SpecVersion.OAS3_0:
131
+ case oas_types_1.SpecVersion.OAS3_1:
129
132
  if (!plugin.typeExtension.oas3)
130
133
  continue;
131
134
  extendedTypes = plugin.typeExtension.oas3(extendedTypes, version);
132
135
  break;
133
- case oas_types_1.OasVersion.Version2:
136
+ case oas_types_1.SpecVersion.OAS2:
134
137
  if (!plugin.typeExtension.oas2)
135
138
  continue;
136
139
  extendedTypes = plugin.typeExtension.oas2(extendedTypes, version);
137
140
  break;
141
+ case oas_types_1.SpecVersion.Async2:
142
+ if (!plugin.typeExtension.async2)
143
+ continue;
144
+ extendedTypes = plugin.typeExtension.async2(extendedTypes, version);
145
+ break;
138
146
  default:
139
147
  throw new Error('Not implemented');
140
148
  }
@@ -198,25 +206,32 @@ class StyleguideConfig {
198
206
  }
199
207
  getRulesForOasVersion(version) {
200
208
  switch (version) {
201
- case oas_types_1.OasMajorVersion.Version3:
209
+ case oas_types_1.SpecMajorVersion.OAS3:
202
210
  // eslint-disable-next-line no-case-declarations
203
211
  const oas3Rules = []; // default ruleset
204
212
  this.plugins.forEach((p) => { var _a; return ((_a = p.preprocessors) === null || _a === void 0 ? void 0 : _a.oas3) && oas3Rules.push(p.preprocessors.oas3); });
205
213
  this.plugins.forEach((p) => { var _a; return ((_a = p.rules) === null || _a === void 0 ? void 0 : _a.oas3) && oas3Rules.push(p.rules.oas3); });
206
214
  this.plugins.forEach((p) => { var _a; return ((_a = p.decorators) === null || _a === void 0 ? void 0 : _a.oas3) && oas3Rules.push(p.decorators.oas3); });
207
215
  return oas3Rules;
208
- case oas_types_1.OasMajorVersion.Version2:
216
+ case oas_types_1.SpecMajorVersion.OAS2:
209
217
  // eslint-disable-next-line no-case-declarations
210
218
  const oas2Rules = []; // default ruleset
211
219
  this.plugins.forEach((p) => { var _a; return ((_a = p.preprocessors) === null || _a === void 0 ? void 0 : _a.oas2) && oas2Rules.push(p.preprocessors.oas2); });
212
220
  this.plugins.forEach((p) => { var _a; return ((_a = p.rules) === null || _a === void 0 ? void 0 : _a.oas2) && oas2Rules.push(p.rules.oas2); });
213
221
  this.plugins.forEach((p) => { var _a; return ((_a = p.decorators) === null || _a === void 0 ? void 0 : _a.oas2) && oas2Rules.push(p.decorators.oas2); });
214
222
  return oas2Rules;
223
+ case oas_types_1.SpecMajorVersion.Async2:
224
+ // eslint-disable-next-line no-case-declarations
225
+ const asyncApiRules = []; // default ruleset
226
+ this.plugins.forEach((p) => { var _a; return ((_a = p.preprocessors) === null || _a === void 0 ? void 0 : _a.async2) && asyncApiRules.push(p.preprocessors.async2); });
227
+ this.plugins.forEach((p) => { var _a; return ((_a = p.rules) === null || _a === void 0 ? void 0 : _a.async2) && asyncApiRules.push(p.rules.async2); });
228
+ this.plugins.forEach((p) => { var _a; return ((_a = p.decorators) === null || _a === void 0 ? void 0 : _a.async2) && asyncApiRules.push(p.decorators.async2); });
229
+ return asyncApiRules;
215
230
  }
216
231
  }
217
232
  skipRules(rules) {
218
233
  for (const ruleId of rules || []) {
219
- for (const version of Object.values(oas_types_1.OasVersion)) {
234
+ for (const version of Object.values(oas_types_1.SpecVersion)) {
220
235
  if (this.rules[version][ruleId]) {
221
236
  this.rules[version][ruleId] = 'off';
222
237
  }
@@ -225,7 +240,7 @@ class StyleguideConfig {
225
240
  }
226
241
  skipPreprocessors(preprocessors) {
227
242
  for (const preprocessorId of preprocessors || []) {
228
- for (const version of Object.values(oas_types_1.OasVersion)) {
243
+ for (const version of Object.values(oas_types_1.SpecVersion)) {
229
244
  if (this.preprocessors[version][preprocessorId]) {
230
245
  this.preprocessors[version][preprocessorId] = 'off';
231
246
  }
@@ -234,7 +249,7 @@ class StyleguideConfig {
234
249
  }
235
250
  skipDecorators(decorators) {
236
251
  for (const decoratorId of decorators || []) {
237
- for (const version of Object.values(oas_types_1.OasVersion)) {
252
+ for (const version of Object.values(oas_types_1.SpecVersion)) {
238
253
  if (this.decorators[version][decoratorId]) {
239
254
  this.decorators[version][decoratorId] = 'off';
240
255
  }
@@ -1,5 +1,5 @@
1
1
  import { Config } from './config';
2
- import type { RawConfig, Region } from './types';
2
+ import type { RawConfig, RawUniversalConfig, Region } from './types';
3
3
  import { RegionalTokenWithValidity } from '../redocly/redocly-client-types';
4
4
  export declare function loadConfig(options?: {
5
5
  configPath?: string;
@@ -14,6 +14,7 @@ export declare function getConfig(configPath?: string | undefined, processRawCon
14
14
  declare type CreateConfigOptions = {
15
15
  extends?: string[];
16
16
  tokens?: RegionalTokenWithValidity[];
17
+ configPath?: string;
17
18
  };
18
- export declare function createConfig(config: string | RawConfig, options?: CreateConfigOptions): Promise<Config>;
19
+ export declare function createConfig(config: string | RawUniversalConfig, options?: CreateConfigOptions): Promise<Config>;
19
20
  export {};
@@ -82,8 +82,8 @@ function findConfig(dir) {
82
82
  const existingConfigFiles = exports.CONFIG_FILE_NAMES.map((name) => dir ? path.resolve(dir, name) : name).filter(fs.existsSync);
83
83
  if (existingConfigFiles.length > 1) {
84
84
  throw new Error(`
85
- Multiple configuration files are not allowed.
86
- Found the following files: ${existingConfigFiles.join(', ')}.
85
+ Multiple configuration files are not allowed.
86
+ Found the following files: ${existingConfigFiles.join(', ')}.
87
87
  Please use 'redocly.yaml' instead.
88
88
  `);
89
89
  }
@@ -1,4 +1,4 @@
1
- import { RuleSet, OasVersion } from '../oas-types';
1
+ import { RuleSet, SpecVersion } from '../oas-types';
2
2
  import { StyleguideConfig } from './config';
3
3
  import type { ProblemSeverity } from '../walk';
4
4
  declare type InitializedRule = {
@@ -6,5 +6,5 @@ declare type InitializedRule = {
6
6
  ruleId: string;
7
7
  visitor: any;
8
8
  };
9
- export declare function initRules<T extends Function, P extends RuleSet<T>>(rules: P[], config: StyleguideConfig, type: 'rules' | 'preprocessors' | 'decorators', oasVersion: OasVersion): InitializedRule[];
9
+ export declare function initRules<T extends Function, P extends RuleSet<T>>(rules: P[], config: StyleguideConfig, type: 'rules' | 'preprocessors' | 'decorators', oasVersion: SpecVersion): InitializedRule[];
10
10
  export {};
@@ -1,5 +1,5 @@
1
1
  import type { ProblemSeverity, UserContext } from '../walk';
2
- import type { Oas3PreprocessorsSet, OasMajorVersion, Oas3DecoratorsSet, Oas2RuleSet, Oas2PreprocessorsSet, Oas2DecoratorsSet, Oas3RuleSet, OasVersion } from '../oas-types';
2
+ import type { Oas3PreprocessorsSet, SpecMajorVersion, Oas3DecoratorsSet, Oas2RuleSet, Oas2PreprocessorsSet, Oas2DecoratorsSet, Oas3RuleSet, SpecVersion, Async2PreprocessorsSet, Async2DecoratorsSet, Async2RuleSet } from '../oas-types';
3
3
  import type { NodeType } from '../types';
4
4
  import { Location } from '../ref-utils';
5
5
  import type { SkipFunctionContext } from '../visitors';
@@ -24,14 +24,17 @@ export declare type StyleguideRawConfig = {
24
24
  oas2Rules?: Record<string, RuleConfig>;
25
25
  oas3_0Rules?: Record<string, RuleConfig>;
26
26
  oas3_1Rules?: Record<string, RuleConfig>;
27
+ async2Rules?: Record<string, RuleConfig>;
27
28
  preprocessors?: Record<string, PreprocessorConfig>;
28
29
  oas2Preprocessors?: Record<string, PreprocessorConfig>;
29
30
  oas3_0Preprocessors?: Record<string, PreprocessorConfig>;
30
31
  oas3_1Preprocessors?: Record<string, PreprocessorConfig>;
32
+ async2Preprocessors?: Record<string, PreprocessorConfig>;
31
33
  decorators?: Record<string, DecoratorConfig>;
32
34
  oas2Decorators?: Record<string, DecoratorConfig>;
33
35
  oas3_0Decorators?: Record<string, DecoratorConfig>;
34
36
  oas3_1Decorators?: Record<string, DecoratorConfig>;
37
+ async2Decorators?: Record<string, DecoratorConfig>;
35
38
  };
36
39
  export declare type ApiStyleguideRawConfig = Omit<StyleguideRawConfig, 'plugins'>;
37
40
  export declare type ResolvedStyleguideConfig = PluginStyleguideConfig & {
@@ -44,16 +47,19 @@ export declare type ResolvedStyleguideConfig = PluginStyleguideConfig & {
44
47
  export declare type PreprocessorsConfig = {
45
48
  oas3?: Oas3PreprocessorsSet;
46
49
  oas2?: Oas2PreprocessorsSet;
50
+ async2?: Async2PreprocessorsSet;
47
51
  };
48
52
  export declare type DecoratorsConfig = {
49
53
  oas3?: Oas3DecoratorsSet;
50
54
  oas2?: Oas2DecoratorsSet;
55
+ async2?: Async2DecoratorsSet;
51
56
  };
52
- export declare type TypesExtensionFn = (types: Record<string, NodeType>, oasVersion: OasVersion) => Record<string, NodeType>;
53
- export declare type TypeExtensionsConfig = Partial<Record<OasMajorVersion, TypesExtensionFn>>;
57
+ export declare type TypesExtensionFn = (types: Record<string, NodeType>, oasVersion: SpecVersion) => Record<string, NodeType>;
58
+ export declare type TypeExtensionsConfig = Partial<Record<SpecMajorVersion, TypesExtensionFn>>;
54
59
  export declare type CustomRulesConfig = {
55
60
  oas3?: Oas3RuleSet;
56
61
  oas2?: Oas2RuleSet;
62
+ async2?: Async2RuleSet;
57
63
  };
58
64
  export declare type AssertionContext = Partial<UserContext> & SkipFunctionContext & {
59
65
  node: any;
@@ -128,6 +134,7 @@ export declare type RawConfig = {
128
134
  files?: string[];
129
135
  telemetry?: Telemetry;
130
136
  } & ThemeConfig;
137
+ export declare type RawUniversalConfig = Omit<RawConfig, 'styleguide'> & StyleguideRawConfig;
131
138
  export declare type FlatApi = Omit<Api, 'styleguide'> & Omit<ApiStyleguideRawConfig, 'doNotResolveExamples'>;
132
139
  export declare type FlatRawConfig = Omit<RawConfig, 'styleguide' | 'resolve' | 'apis'> & Omit<StyleguideRawConfig, 'doNotResolveExamples'> & {
133
140
  resolve?: RawResolveConfig;
package/lib/index.d.ts CHANGED
@@ -2,21 +2,22 @@ export { BundleOutputFormat, readFileFromUrl, slash, doesYamlFileExist, isTruthy
2
2
  export { Oas3_1Types } from './types/oas3_1';
3
3
  export { Oas3Types } from './types/oas3';
4
4
  export { Oas2Types } from './types/oas2';
5
+ export { AsyncApi2Types } from './types/asyncapi';
5
6
  export { ConfigTypes } from './types/redocly-yaml';
6
7
  export type { Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3Schema, Oas3_1Schema, Oas3Tag, Oas3_1Webhooks, Referenced, OasRef, } from './typings/openapi';
7
8
  export type { Oas2Definition } from './typings/swagger';
8
9
  export type { StatsAccumulator, StatsName } from './typings/common';
9
10
  export { normalizeTypes } from './types';
10
11
  export { Stats } from './rules/other/stats';
11
- export { Config, StyleguideConfig, RawConfig, IGNORE_FILE, Region, getMergedConfig, transformConfig, loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES, RuleSeverity, createConfig, ResolvedApi, } from './config';
12
+ export { Config, StyleguideConfig, RawConfig, RawUniversalConfig, IGNORE_FILE, Region, getMergedConfig, transformConfig, loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES, RuleSeverity, createConfig, ResolvedApi, } from './config';
12
13
  export { RedoclyClient, isRedoclyRegistryURL } from './redocly';
13
14
  export { Source, BaseResolver, Document, resolveDocument, ResolveError, YamlParseError, makeDocumentFromString, } from './resolve';
14
15
  export { parseYaml, stringifyYaml } from './js-yaml';
15
16
  export { unescapePointer, isRef, isAbsoluteUrl } from './ref-utils';
16
- export { detectOpenAPI, OasMajorVersion, openAPIMajor, OasVersion } from './oas-types';
17
+ export { SpecMajorVersion, getMajorSpecVersion, SpecVersion, detectSpec, getTypes, } from './oas-types';
17
18
  export { normalizeVisitors } from './visitors';
18
19
  export { WalkContext, walkDocument, NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject, Loc, } from './walk';
19
20
  export { getAstNodeByPointer, getLineColLocation } from './format/codeframes';
20
21
  export { formatProblems, OutputFormat, getTotals, Totals } from './format/format';
21
22
  export { lint, lint as validate, lintDocument, lintFromString, lintConfig } from './lint';
22
- export { bundle, bundleDocument, mapTypeToComponent } from './bundle';
23
+ export { bundle, bundleDocument, mapTypeToComponent, bundleFromString } from './bundle';
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.bundleDocument = exports.bundle = exports.lintConfig = exports.lintFromString = exports.lintDocument = exports.validate = exports.lint = exports.getTotals = exports.formatProblems = exports.getLineColLocation = exports.getAstNodeByPointer = exports.walkDocument = exports.normalizeVisitors = exports.OasVersion = exports.openAPIMajor = exports.OasMajorVersion = exports.detectOpenAPI = exports.isAbsoluteUrl = exports.isRef = exports.unescapePointer = exports.stringifyYaml = exports.parseYaml = exports.makeDocumentFromString = exports.YamlParseError = exports.ResolveError = exports.resolveDocument = exports.BaseResolver = exports.Source = exports.isRedoclyRegistryURL = exports.RedoclyClient = exports.createConfig = exports.CONFIG_FILE_NAMES = exports.findConfig = exports.getConfig = exports.loadConfig = exports.transformConfig = exports.getMergedConfig = exports.IGNORE_FILE = exports.StyleguideConfig = exports.Config = exports.Stats = exports.normalizeTypes = exports.ConfigTypes = exports.Oas2Types = exports.Oas3Types = exports.Oas3_1Types = exports.isTruthy = exports.doesYamlFileExist = exports.slash = exports.readFileFromUrl = void 0;
4
- exports.mapTypeToComponent = void 0;
3
+ exports.lintConfig = exports.lintFromString = exports.lintDocument = exports.validate = exports.lint = exports.getTotals = exports.formatProblems = exports.getLineColLocation = exports.getAstNodeByPointer = exports.walkDocument = exports.normalizeVisitors = exports.getTypes = exports.detectSpec = exports.SpecVersion = exports.getMajorSpecVersion = exports.SpecMajorVersion = exports.isAbsoluteUrl = exports.isRef = exports.unescapePointer = exports.stringifyYaml = exports.parseYaml = exports.makeDocumentFromString = exports.YamlParseError = exports.ResolveError = exports.resolveDocument = exports.BaseResolver = exports.Source = exports.isRedoclyRegistryURL = exports.RedoclyClient = exports.createConfig = exports.CONFIG_FILE_NAMES = exports.findConfig = exports.getConfig = exports.loadConfig = exports.transformConfig = exports.getMergedConfig = exports.IGNORE_FILE = exports.StyleguideConfig = exports.Config = exports.Stats = exports.normalizeTypes = exports.ConfigTypes = exports.AsyncApi2Types = exports.Oas2Types = exports.Oas3Types = exports.Oas3_1Types = exports.isTruthy = exports.doesYamlFileExist = exports.slash = exports.readFileFromUrl = void 0;
4
+ exports.bundleFromString = exports.mapTypeToComponent = exports.bundleDocument = exports.bundle = void 0;
5
5
  var utils_1 = require("./utils");
6
6
  Object.defineProperty(exports, "readFileFromUrl", { enumerable: true, get: function () { return utils_1.readFileFromUrl; } });
7
7
  Object.defineProperty(exports, "slash", { enumerable: true, get: function () { return utils_1.slash; } });
@@ -13,6 +13,8 @@ var oas3_1 = require("./types/oas3");
13
13
  Object.defineProperty(exports, "Oas3Types", { enumerable: true, get: function () { return oas3_1.Oas3Types; } });
14
14
  var oas2_1 = require("./types/oas2");
15
15
  Object.defineProperty(exports, "Oas2Types", { enumerable: true, get: function () { return oas2_1.Oas2Types; } });
16
+ var asyncapi_1 = require("./types/asyncapi");
17
+ Object.defineProperty(exports, "AsyncApi2Types", { enumerable: true, get: function () { return asyncapi_1.AsyncApi2Types; } });
16
18
  var redocly_yaml_1 = require("./types/redocly-yaml");
17
19
  Object.defineProperty(exports, "ConfigTypes", { enumerable: true, get: function () { return redocly_yaml_1.ConfigTypes; } });
18
20
  var types_1 = require("./types");
@@ -48,10 +50,11 @@ Object.defineProperty(exports, "unescapePointer", { enumerable: true, get: funct
48
50
  Object.defineProperty(exports, "isRef", { enumerable: true, get: function () { return ref_utils_1.isRef; } });
49
51
  Object.defineProperty(exports, "isAbsoluteUrl", { enumerable: true, get: function () { return ref_utils_1.isAbsoluteUrl; } });
50
52
  var oas_types_1 = require("./oas-types");
51
- Object.defineProperty(exports, "detectOpenAPI", { enumerable: true, get: function () { return oas_types_1.detectOpenAPI; } });
52
- Object.defineProperty(exports, "OasMajorVersion", { enumerable: true, get: function () { return oas_types_1.OasMajorVersion; } });
53
- Object.defineProperty(exports, "openAPIMajor", { enumerable: true, get: function () { return oas_types_1.openAPIMajor; } });
54
- Object.defineProperty(exports, "OasVersion", { enumerable: true, get: function () { return oas_types_1.OasVersion; } });
53
+ Object.defineProperty(exports, "SpecMajorVersion", { enumerable: true, get: function () { return oas_types_1.SpecMajorVersion; } });
54
+ Object.defineProperty(exports, "getMajorSpecVersion", { enumerable: true, get: function () { return oas_types_1.getMajorSpecVersion; } });
55
+ Object.defineProperty(exports, "SpecVersion", { enumerable: true, get: function () { return oas_types_1.SpecVersion; } });
56
+ Object.defineProperty(exports, "detectSpec", { enumerable: true, get: function () { return oas_types_1.detectSpec; } });
57
+ Object.defineProperty(exports, "getTypes", { enumerable: true, get: function () { return oas_types_1.getTypes; } });
55
58
  var visitors_1 = require("./visitors");
56
59
  Object.defineProperty(exports, "normalizeVisitors", { enumerable: true, get: function () { return visitors_1.normalizeVisitors; } });
57
60
  var walk_1 = require("./walk");
@@ -72,3 +75,4 @@ var bundle_1 = require("./bundle");
72
75
  Object.defineProperty(exports, "bundle", { enumerable: true, get: function () { return bundle_1.bundle; } });
73
76
  Object.defineProperty(exports, "bundleDocument", { enumerable: true, get: function () { return bundle_1.bundleDocument; } });
74
77
  Object.defineProperty(exports, "mapTypeToComponent", { enumerable: true, get: function () { return bundle_1.mapTypeToComponent; } });
78
+ Object.defineProperty(exports, "bundleFromString", { enumerable: true, get: function () { return bundle_1.bundleFromString; } });
package/lib/lint.js CHANGED
@@ -12,9 +12,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.lintConfig = exports.lintDocument = exports.lintFromString = exports.lint = void 0;
13
13
  const resolve_1 = require("./resolve");
14
14
  const visitors_1 = require("./visitors");
15
- const oas3_1_1 = require("./types/oas3_1");
16
- const oas3_1 = require("./types/oas3");
17
- const oas2_1 = require("./types/oas2");
18
15
  const walk_1 = require("./walk");
19
16
  const config_1 = require("./config");
20
17
  const types_1 = require("./types");
@@ -42,21 +39,17 @@ function lintDocument(opts) {
42
39
  return __awaiter(this, void 0, void 0, function* () {
43
40
  ajv_1.releaseAjvInstance(); // FIXME: preprocessors can modify nodes which are then cached to ajv-instance by absolute path
44
41
  const { document, customTypes, externalRefResolver, config } = opts;
45
- const oasVersion = oas_types_1.detectOpenAPI(document.parsed);
46
- const oasMajorVersion = oas_types_1.openAPIMajor(oasVersion);
47
- const rules = config.getRulesForOasVersion(oasMajorVersion);
48
- const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === oas_types_1.OasMajorVersion.Version3)
49
- ? oasVersion === oas_types_1.OasVersion.Version3_1
50
- ? oas3_1_1.Oas3_1Types
51
- : oas3_1.Oas3Types
52
- : oas2_1.Oas2Types, oasVersion), config);
42
+ const specVersion = oas_types_1.detectSpec(document.parsed);
43
+ const specMajorVersion = oas_types_1.getMajorSpecVersion(specVersion);
44
+ const rules = config.getRulesForOasVersion(specMajorVersion);
45
+ const types = types_1.normalizeTypes(config.extendTypes(customTypes !== null && customTypes !== void 0 ? customTypes : oas_types_1.getTypes(specVersion), specVersion), config);
53
46
  const ctx = {
54
47
  problems: [],
55
- oasVersion: oasVersion,
48
+ oasVersion: specVersion,
56
49
  visitorsData: {},
57
50
  };
58
- const preprocessors = config_1.initRules(rules, config, 'preprocessors', oasVersion);
59
- const regularRules = config_1.initRules(rules, config, 'rules', oasVersion);
51
+ const preprocessors = config_1.initRules(rules, config, 'preprocessors', specVersion);
52
+ const regularRules = config_1.initRules(rules, config, 'rules', specVersion);
60
53
  let resolvedRefMap = yield resolve_1.resolveDocument({
61
54
  rootDocument: document,
62
55
  rootType: types.Root,
@@ -94,7 +87,7 @@ function lintConfig(opts) {
94
87
  const { document, severity } = opts;
95
88
  const ctx = {
96
89
  problems: [],
97
- oasVersion: oas_types_1.OasVersion.Version3_0,
90
+ oasVersion: oas_types_1.SpecVersion.OAS3_0,
98
91
  visitorsData: {},
99
92
  };
100
93
  const plugins = config_1.resolvePlugins([config_1.defaultPlugin]);
@@ -107,9 +100,10 @@ function lintConfig(opts) {
107
100
  {
108
101
  severity: severity || 'error',
109
102
  ruleId: 'configuration spec',
110
- visitor: spec_1.OasSpec({ severity: 'error' }),
103
+ visitor: spec_1.Spec({ severity: 'error' }),
111
104
  },
112
105
  ];
106
+ // TODO: check why any is needed
113
107
  const normalizedVisitors = visitors_1.normalizeVisitors(rules, types);
114
108
  walk_1.walkDocument({
115
109
  document,
@@ -1,19 +1,25 @@
1
- import { Oas3Rule, Oas3Preprocessor, Oas2Rule, Oas2Preprocessor } from './visitors';
1
+ import { Oas3Rule, Oas3Preprocessor, Oas2Rule, Oas2Preprocessor, Async2Preprocessor, Async2Rule } from './visitors';
2
2
  export declare type RuleSet<T> = Record<string, T>;
3
- export declare enum OasVersion {
4
- Version2 = "oas2",
5
- Version3_0 = "oas3_0",
6
- Version3_1 = "oas3_1"
3
+ export declare enum SpecVersion {
4
+ OAS2 = "oas2",
5
+ OAS3_0 = "oas3_0",
6
+ OAS3_1 = "oas3_1",
7
+ Async2 = "async2"
7
8
  }
8
- export declare enum OasMajorVersion {
9
- Version2 = "oas2",
10
- Version3 = "oas3"
9
+ export declare enum SpecMajorVersion {
10
+ OAS2 = "oas2",
11
+ OAS3 = "oas3",
12
+ Async2 = "async2"
11
13
  }
12
14
  export declare type Oas3RuleSet = Record<string, Oas3Rule>;
13
15
  export declare type Oas2RuleSet = Record<string, Oas2Rule>;
16
+ export declare type Async2RuleSet = Record<string, Async2Rule>;
14
17
  export declare type Oas3PreprocessorsSet = Record<string, Oas3Preprocessor>;
15
18
  export declare type Oas2PreprocessorsSet = Record<string, Oas2Preprocessor>;
19
+ export declare type Async2PreprocessorsSet = Record<string, Async2Preprocessor>;
16
20
  export declare type Oas3DecoratorsSet = Record<string, Oas3Preprocessor>;
17
21
  export declare type Oas2DecoratorsSet = Record<string, Oas2Preprocessor>;
18
- export declare function detectOpenAPI(root: any): OasVersion;
19
- export declare function openAPIMajor(version: OasVersion): OasMajorVersion;
22
+ export declare type Async2DecoratorsSet = Record<string, Async2Preprocessor>;
23
+ export declare function detectSpec(root: any): SpecVersion;
24
+ export declare function getMajorSpecVersion(version: SpecVersion): SpecMajorVersion;
25
+ export declare function getTypes(spec: SpecVersion): Record<string, import("./types").NodeType>;
package/lib/oas-types.js CHANGED
@@ -1,45 +1,71 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.openAPIMajor = exports.detectOpenAPI = exports.OasMajorVersion = exports.OasVersion = void 0;
4
- var OasVersion;
5
- (function (OasVersion) {
6
- OasVersion["Version2"] = "oas2";
7
- OasVersion["Version3_0"] = "oas3_0";
8
- OasVersion["Version3_1"] = "oas3_1";
9
- })(OasVersion = exports.OasVersion || (exports.OasVersion = {}));
10
- var OasMajorVersion;
11
- (function (OasMajorVersion) {
12
- OasMajorVersion["Version2"] = "oas2";
13
- OasMajorVersion["Version3"] = "oas3";
14
- })(OasMajorVersion = exports.OasMajorVersion || (exports.OasMajorVersion = {}));
15
- function detectOpenAPI(root) {
3
+ exports.getTypes = exports.getMajorSpecVersion = exports.detectSpec = exports.SpecMajorVersion = exports.SpecVersion = void 0;
4
+ const oas2_1 = require("./types/oas2");
5
+ const oas3_1 = require("./types/oas3");
6
+ const oas3_1_1 = require("./types/oas3_1");
7
+ const asyncapi_1 = require("./types/asyncapi");
8
+ var SpecVersion;
9
+ (function (SpecVersion) {
10
+ SpecVersion["OAS2"] = "oas2";
11
+ SpecVersion["OAS3_0"] = "oas3_0";
12
+ SpecVersion["OAS3_1"] = "oas3_1";
13
+ SpecVersion["Async2"] = "async2";
14
+ })(SpecVersion = exports.SpecVersion || (exports.SpecVersion = {}));
15
+ var SpecMajorVersion;
16
+ (function (SpecMajorVersion) {
17
+ SpecMajorVersion["OAS2"] = "oas2";
18
+ SpecMajorVersion["OAS3"] = "oas3";
19
+ SpecMajorVersion["Async2"] = "async2";
20
+ })(SpecMajorVersion = exports.SpecMajorVersion || (exports.SpecMajorVersion = {}));
21
+ const typesMap = {
22
+ [SpecVersion.OAS2]: oas2_1.Oas2Types,
23
+ [SpecVersion.OAS3_0]: oas3_1.Oas3Types,
24
+ [SpecVersion.OAS3_1]: oas3_1_1.Oas3_1Types,
25
+ [SpecVersion.Async2]: asyncapi_1.AsyncApi2Types,
26
+ };
27
+ function detectSpec(root) {
16
28
  if (typeof root !== 'object') {
17
29
  throw new Error(`Document must be JSON object, got ${typeof root}`);
18
30
  }
19
- if (!(root.openapi || root.swagger)) {
20
- throw new Error('This doesn’t look like an OpenAPI document.\n');
21
- }
22
31
  if (root.openapi && typeof root.openapi !== 'string') {
23
32
  throw new Error(`Invalid OpenAPI version: should be a string but got "${typeof root.openapi}"`);
24
33
  }
25
34
  if (root.openapi && root.openapi.startsWith('3.0')) {
26
- return OasVersion.Version3_0;
35
+ return SpecVersion.OAS3_0;
27
36
  }
28
37
  if (root.openapi && root.openapi.startsWith('3.1')) {
29
- return OasVersion.Version3_1;
38
+ return SpecVersion.OAS3_1;
30
39
  }
31
40
  if (root.swagger && root.swagger === '2.0') {
32
- return OasVersion.Version2;
41
+ return SpecVersion.OAS2;
42
+ }
43
+ // if not detected yet
44
+ if (root.openapi || root.swagger) {
45
+ throw new Error(`Unsupported OpenAPI version: ${root.openapi || root.swagger}`);
46
+ }
47
+ if (root.asyncapi && root.asyncapi.startsWith('2.')) {
48
+ return SpecVersion.Async2;
33
49
  }
34
- throw new Error(`Unsupported OpenAPI Version: ${root.openapi || root.swagger}`);
50
+ if (root.asyncapi) {
51
+ throw new Error(`Unsupported AsyncAPI version: ${root.asyncapi}`);
52
+ }
53
+ throw new Error(`Unsupported specification`);
35
54
  }
36
- exports.detectOpenAPI = detectOpenAPI;
37
- function openAPIMajor(version) {
38
- if (version === OasVersion.Version2) {
39
- return OasMajorVersion.Version2;
55
+ exports.detectSpec = detectSpec;
56
+ function getMajorSpecVersion(version) {
57
+ if (version === SpecVersion.OAS2) {
58
+ return SpecMajorVersion.OAS2;
59
+ }
60
+ else if (version === SpecVersion.Async2) {
61
+ return SpecMajorVersion.Async2;
40
62
  }
41
63
  else {
42
- return OasMajorVersion.Version3;
64
+ return SpecMajorVersion.OAS3;
43
65
  }
44
66
  }
45
- exports.openAPIMajor = openAPIMajor;
67
+ exports.getMajorSpecVersion = getMajorSpecVersion;
68
+ function getTypes(spec) {
69
+ return typesMap[spec];
70
+ }
71
+ exports.getTypes = getTypes;
@@ -0,0 +1,2 @@
1
+ import { Async2Rule } from '../../visitors';
2
+ export declare const ChannelsKebabCase: Async2Rule;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChannelsKebabCase = void 0;
4
+ const ChannelsKebabCase = () => {
5
+ return {
6
+ Channel(_channel, { report, key }) {
7
+ const segments = key
8
+ .split(/[/.:]/) // split on / or : as likely channel namespacers
9
+ .filter((s) => s !== ''); // filter out empty segments
10
+ if (!segments.every((segment) => /^{.+}$/.test(segment) || /^[a-z0-9-.]+$/.test(segment))) {
11
+ report({
12
+ message: `\`${key}\` does not use kebab-case.`,
13
+ location: { reportOnKey: true },
14
+ });
15
+ }
16
+ },
17
+ };
18
+ };
19
+ exports.ChannelsKebabCase = ChannelsKebabCase;
@@ -0,0 +1,12 @@
1
+ import { Async2Rule } from '../../visitors';
2
+ export declare const rules: {
3
+ spec: Async2Rule;
4
+ assertions: (opts: Record<string, import("../common/assertions").Assertion>) => (import("../../visitors").Oas3Visitor | import("../../visitors").Oas2Visitor)[];
5
+ 'info-contact': import("../../visitors").Oas3Rule | import("../../visitors").Oas2Rule;
6
+ 'operation-operationId': import("../../visitors").Oas3Rule | import("../../visitors").Oas2Rule;
7
+ 'channels-kebab-case': Async2Rule;
8
+ 'no-channel-trailing-slash': Async2Rule;
9
+ 'tag-description': import("../../visitors").Oas3Rule | import("../../visitors").Oas2Rule;
10
+ 'tags-alphabetical': import("../../visitors").Oas3Rule | import("../../visitors").Oas2Rule;
11
+ };
12
+ export declare const preprocessors: {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preprocessors = exports.rules = void 0;
4
+ const assertions_1 = require("../common/assertions");
5
+ const spec_1 = require("../common/spec");
6
+ const info_contact_1 = require("../common/info-contact");
7
+ const operation_operationId_1 = require("../common/operation-operationId");
8
+ const tag_description_1 = require("../common/tag-description");
9
+ const tags_alphabetical_1 = require("../common/tags-alphabetical");
10
+ const channels_kebab_case_1 = require("./channels-kebab-case");
11
+ const no_channel_trailing_slash_1 = require("./no-channel-trailing-slash");
12
+ exports.rules = {
13
+ spec: spec_1.Spec,
14
+ assertions: assertions_1.Assertions,
15
+ 'info-contact': info_contact_1.InfoContact,
16
+ 'operation-operationId': operation_operationId_1.OperationOperationId,
17
+ 'channels-kebab-case': channels_kebab_case_1.ChannelsKebabCase,
18
+ 'no-channel-trailing-slash': no_channel_trailing_slash_1.NoChannelTrailingSlash,
19
+ 'tag-description': tag_description_1.TagDescription,
20
+ 'tags-alphabetical': tags_alphabetical_1.TagsAlphabetical,
21
+ };
22
+ exports.preprocessors = {};
@@ -0,0 +1,2 @@
1
+ import { Async2Rule } from '../../visitors';
2
+ export declare const NoChannelTrailingSlash: Async2Rule;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoChannelTrailingSlash = void 0;
4
+ const NoChannelTrailingSlash = () => {
5
+ return {
6
+ Channel(_channel, { report, key, location }) {
7
+ if (key.endsWith('/') && key !== '/') {
8
+ report({
9
+ message: `\`${key}\` should not have a trailing slash.`,
10
+ location: location.key(),
11
+ });
12
+ }
13
+ },
14
+ };
15
+ };
16
+ exports.NoChannelTrailingSlash = NoChannelTrailingSlash;
@@ -35,7 +35,7 @@ exports.runOnValuesSet = new Set([
35
35
  'const',
36
36
  ]);
37
37
  exports.asserts = {
38
- pattern: (value, condition, { baseLocation }) => {
38
+ pattern: (value, condition, { baseLocation, rawValue }) => {
39
39
  if (typeof value === 'undefined' || utils_1.isPlainObject(value))
40
40
  return []; // property doesn't exist or is an object, no need to lint it with this assert
41
41
  const values = Array.isArray(value) ? value : [value];
@@ -43,11 +43,15 @@ exports.asserts = {
43
43
  return values
44
44
  .map((_val) => !(regex === null || regex === void 0 ? void 0 : regex.test(_val)) && {
45
45
  message: `"${_val}" should match a regex ${condition}`,
46
- location: utils_1.isString(value) ? baseLocation : baseLocation.key(),
46
+ location: utils_1.isString(value)
47
+ ? baseLocation
48
+ : utils_1.isPlainObject(rawValue)
49
+ ? baseLocation.child(_val).key()
50
+ : baseLocation.key(),
47
51
  })
48
52
  .filter(utils_1.isTruthy);
49
53
  },
50
- notPattern: (value, condition, { baseLocation }) => {
54
+ notPattern: (value, condition, { baseLocation, rawValue }) => {
51
55
  if (typeof value === 'undefined' || utils_1.isPlainObject(value))
52
56
  return []; // property doesn't exist or is an object, no need to lint it with this assert
53
57
  const values = Array.isArray(value) ? value : [value];
@@ -55,7 +59,11 @@ exports.asserts = {
55
59
  return values
56
60
  .map((_val) => (regex === null || regex === void 0 ? void 0 : regex.test(_val)) && {
57
61
  message: `"${_val}" should not match a regex ${condition}`,
58
- location: utils_1.isString(value) ? baseLocation : baseLocation.key(),
62
+ location: utils_1.isString(value)
63
+ ? baseLocation
64
+ : utils_1.isPlainObject(rawValue)
65
+ ? baseLocation.child(_val).key()
66
+ : baseLocation.key(),
59
67
  })
60
68
  .filter(utils_1.isTruthy);
61
69
  },
@@ -14,7 +14,7 @@ const ScalarPropertyMissingExample = () => {
14
14
  if (propSchema.example === undefined &&
15
15
  propSchema.examples === undefined) {
16
16
  report({
17
- message: `Scalar property should have "example"${oasVersion === oas_types_1.OasVersion.Version3_1 ? ' or "examples"' : ''} defined.`,
17
+ message: `Scalar property should have "example"${oasVersion === oas_types_1.SpecVersion.OAS3_1 ? ' or "examples"' : ''} defined.`,
18
18
  location: location.child(propName).key(),
19
19
  });
20
20
  }
@@ -1,2 +1,2 @@
1
- import type { Oas3Rule, Oas2Rule } from '../../visitors';
2
- export declare const OasSpec: Oas3Rule | Oas2Rule;
1
+ import type { Oas3Rule, Oas2Rule, Async2Rule } from '../../visitors';
2
+ export declare const Spec: Oas3Rule | Oas2Rule | Async2Rule;