@redocly/openapi-core 1.0.0-beta.117 → 1.0.0-beta.118

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 (49) hide show
  1. package/lib/bundle.d.ts +1 -1
  2. package/lib/config/config-resolvers.js +13 -8
  3. package/lib/decorators/common/media-type-examples-override.d.ts +2 -0
  4. package/lib/decorators/common/media-type-examples-override.js +53 -0
  5. package/lib/decorators/oas3/index.d.ts +1 -0
  6. package/lib/decorators/oas3/index.js +2 -0
  7. package/lib/index.d.ts +2 -2
  8. package/lib/index.js +3 -1
  9. package/lib/resolve.js +3 -0
  10. package/lib/rules/common/assertions/asserts.js +10 -2
  11. package/lib/rules/common/assertions/utils.js +12 -6
  12. package/lib/rules/common/spec.js +7 -4
  13. package/lib/rules/oas3/spec-components-invalid-map-name.js +26 -5
  14. package/lib/types/index.d.ts +1 -0
  15. package/lib/types/index.js +7 -1
  16. package/lib/types/oas2.js +16 -0
  17. package/lib/types/oas3.js +28 -0
  18. package/lib/types/oas3_1.js +6 -0
  19. package/lib/types/redocly-yaml.js +1 -0
  20. package/lib/utils.d.ts +1 -0
  21. package/lib/utils.js +6 -1
  22. package/lib/visitors.d.ts +3 -1
  23. package/lib/visitors.js +4 -0
  24. package/lib/walk.js +8 -0
  25. package/package.json +1 -1
  26. package/src/__tests__/__snapshots__/bundle.test.ts.snap +10 -0
  27. package/src/config/config-resolvers.ts +12 -8
  28. package/src/decorators/__tests__/media-type-examples-override.test.ts +665 -0
  29. package/src/decorators/__tests__/resources/request.yaml +3 -0
  30. package/src/decorators/__tests__/resources/response.yaml +3 -0
  31. package/src/decorators/common/media-type-examples-override.ts +79 -0
  32. package/src/decorators/oas3/index.ts +2 -0
  33. package/src/index.ts +2 -1
  34. package/src/resolve.ts +4 -1
  35. package/src/rules/common/assertions/__tests__/asserts.test.ts +89 -19
  36. package/src/rules/common/assertions/asserts.ts +10 -1
  37. package/src/rules/common/assertions/utils.ts +15 -6
  38. package/src/rules/common/spec.ts +8 -5
  39. package/src/rules/oas3/__tests__/spec-components-invalid-map-name.test.ts +88 -0
  40. package/src/rules/oas3/spec-components-invalid-map-name.ts +26 -5
  41. package/src/types/index.ts +9 -0
  42. package/src/types/oas2.ts +16 -0
  43. package/src/types/oas3.ts +28 -0
  44. package/src/types/oas3_1.ts +6 -0
  45. package/src/types/redocly-yaml.ts +1 -0
  46. package/src/utils.ts +5 -0
  47. package/src/visitors.ts +7 -1
  48. package/src/walk.ts +15 -1
  49. package/tsconfig.tsbuildinfo +1 -1
@@ -18,6 +18,7 @@ const Root = {
18
18
  },
19
19
  required: ['openapi', 'info'],
20
20
  requiredOneOf: ['paths', 'components', 'webhooks'],
21
+ extensionsPrefix: 'x-',
21
22
  };
22
23
  const License = {
23
24
  properties: {
@@ -26,6 +27,7 @@ const License = {
26
27
  identifier: { type: 'string' },
27
28
  },
28
29
  required: ['name'],
30
+ extensionsPrefix: 'x-',
29
31
  };
30
32
  const Info = {
31
33
  properties: {
@@ -38,6 +40,7 @@ const Info = {
38
40
  license: 'License',
39
41
  },
40
42
  required: ['title', 'version'],
43
+ extensionsPrefix: 'x-',
41
44
  };
42
45
  const Components = {
43
46
  properties: {
@@ -52,6 +55,7 @@ const Components = {
52
55
  callbacks: 'NamedCallbacks',
53
56
  pathItems: 'NamedPathItems',
54
57
  },
58
+ extensionsPrefix: 'x-',
55
59
  };
56
60
  const Operation = {
57
61
  properties: {
@@ -74,6 +78,7 @@ const Operation = {
74
78
  'x-code-samples': _1.listOf('XCodeSample'),
75
79
  'x-hideTryItPanel': { type: 'boolean' },
76
80
  },
81
+ extensionsPrefix: 'x-',
77
82
  };
78
83
  const Schema = {
79
84
  properties: {
@@ -167,6 +172,7 @@ const Schema = {
167
172
  $comment: { type: 'string' },
168
173
  'x-tags': { type: 'array', items: { type: 'string' } },
169
174
  },
175
+ extensionsPrefix: 'x-',
170
176
  };
171
177
  const SecurityScheme = {
172
178
  properties: {
@@ -115,6 +115,7 @@ const nodeTypesList = [
115
115
  'XCodeSample',
116
116
  'XCodeSampleList',
117
117
  'WebhooksMap',
118
+ 'SpecExtension',
118
119
  ];
119
120
  const ConfigStyleguide = {
120
121
  properties: {
package/lib/utils.d.ts CHANGED
@@ -29,6 +29,7 @@ export declare function validateMimeType({ type, value }: any, { report, locatio
29
29
  export declare function validateMimeTypeOAS3({ type, value }: any, { report, location }: UserContext, allowedValues: string[]): void;
30
30
  export declare function isSingular(path: string): boolean;
31
31
  export declare function readFileAsStringSync(filePath: string): string;
32
+ export declare function yamlAndJsonSyncReader<T>(filePath: string): T;
32
33
  export declare function isPathParameter(pathSegment: string): boolean;
33
34
  /**
34
35
  * Convert Windows backslash paths to slash paths: foo\\bar ➔ foo/bar
package/lib/utils.js CHANGED
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.nextTick = exports.pickDefined = exports.keysOf = exports.identity = exports.isTruthy = exports.showErrorForDeprecatedField = exports.showWarningForDeprecatedField = exports.doesYamlFileExist = exports.isCustomRuleId = exports.getMatchingStatusCodeRange = exports.assignExisting = exports.isNotString = exports.isString = exports.isNotEmptyObject = exports.slash = exports.isPathParameter = exports.readFileAsStringSync = exports.isSingular = exports.validateMimeTypeOAS3 = exports.validateMimeType = exports.splitCamelCaseIntoWords = exports.omitObjectProps = exports.pickObjectProps = exports.readFileFromUrl = exports.isEmptyArray = exports.isEmptyObject = exports.isPlainObject = exports.isDefined = exports.loadYaml = exports.popStack = exports.pushStack = exports.stringifyYaml = exports.parseYaml = void 0;
12
+ exports.nextTick = exports.pickDefined = exports.keysOf = exports.identity = exports.isTruthy = exports.showErrorForDeprecatedField = exports.showWarningForDeprecatedField = exports.doesYamlFileExist = exports.isCustomRuleId = exports.getMatchingStatusCodeRange = exports.assignExisting = exports.isNotString = exports.isString = exports.isNotEmptyObject = exports.slash = exports.isPathParameter = exports.yamlAndJsonSyncReader = exports.readFileAsStringSync = exports.isSingular = exports.validateMimeTypeOAS3 = exports.validateMimeType = exports.splitCamelCaseIntoWords = exports.omitObjectProps = exports.pickObjectProps = exports.readFileFromUrl = exports.isEmptyArray = exports.isEmptyObject = exports.isPlainObject = exports.isDefined = exports.loadYaml = exports.popStack = exports.pushStack = exports.stringifyYaml = exports.parseYaml = void 0;
13
13
  const fs = require("fs");
14
14
  const path_1 = require("path");
15
15
  const minimatch = require("minimatch");
@@ -139,6 +139,11 @@ function readFileAsStringSync(filePath) {
139
139
  return fs.readFileSync(filePath, 'utf-8');
140
140
  }
141
141
  exports.readFileAsStringSync = readFileAsStringSync;
142
+ function yamlAndJsonSyncReader(filePath) {
143
+ const content = fs.readFileSync(filePath, 'utf-8');
144
+ return js_yaml_1.parseYaml(content);
145
+ }
146
+ exports.yamlAndJsonSyncReader = yamlAndJsonSyncReader;
142
147
  function isPathParameter(pathSegment) {
143
148
  return pathSegment.startsWith('{') && pathSegment.endsWith('}');
144
149
  }
package/lib/visitors.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Oas3Definition, Oas3ExternalDocs, Oas3Info, Oas3Contact, Oas3Components, Oas3License, Oas3Schema, Oas3Header, Oas3Parameter, Oas3Operation, Oas3PathItem, Oas3ServerVariable, Oas3Server, Oas3MediaType, Oas3Response, Oas3Example, Oas3RequestBody, Oas3Tag, OasRef, Oas3SecurityScheme, Oas3SecurityRequirement, Oas3Encoding, Oas3Link, Oas3Xml, Oas3Discriminator, Oas3Callback } from './typings/openapi';
2
2
  import type { Oas2Definition, Oas2Tag, Oas2ExternalDocs, Oas2SecurityRequirement, Oas2Info, Oas2Contact, Oas2License, Oas2PathItem, Oas2Operation, Oas2Header, Oas2Response, Oas2Schema, Oas2Xml, Oas2Parameter, Oas2SecurityScheme } from './typings/swagger';
3
- import type { NormalizedNodeType } from './types';
3
+ import { NormalizedNodeType } from './types';
4
4
  import type { Stack } from './utils';
5
5
  import type { UserContext, ResolveResult, ProblemSeverity } from './walk';
6
6
  import type { Location } from './ref-utils';
@@ -107,6 +107,7 @@ declare type Oas3FlatVisitor = {
107
107
  AuthorizationCode?: VisitFunctionOrObject<Oas3SecurityScheme['flows']['authorizationCode']>;
108
108
  OAuth2Flows?: VisitFunctionOrObject<Oas3SecurityScheme['flows']>;
109
109
  SecurityScheme?: VisitFunctionOrObject<Oas3SecurityScheme>;
110
+ SpecExtension?: VisitFunctionOrObject<unknown>;
110
111
  };
111
112
  declare type Oas2FlatVisitor = {
112
113
  Root?: VisitFunctionOrObject<Oas2Definition>;
@@ -131,6 +132,7 @@ declare type Oas2FlatVisitor = {
131
132
  NamedResponses?: VisitFunctionOrObject<Record<string, Oas2Response>>;
132
133
  NamedParameters?: VisitFunctionOrObject<Record<string, Oas2Parameter>>;
133
134
  SecurityScheme?: VisitFunctionOrObject<Oas2SecurityScheme>;
135
+ SpecExtension?: VisitFunctionOrObject<unknown>;
134
136
  };
135
137
  declare type Oas3NestedVisitor = {
136
138
  [T in keyof Oas3FlatVisitor]: Oas3FlatVisitor[T] extends Function ? Oas3FlatVisitor[T] : Oas3FlatVisitor[T] & NestedVisitor<Oas3NestedVisitor>;
package/lib/visitors.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeVisitors = void 0;
4
+ const types_1 = require("./types");
4
5
  const legacyTypesMap = {
5
6
  Root: 'DefinitionRoot',
6
7
  ServerVariablesMap: 'ServerVariableMap',
@@ -68,6 +69,9 @@ function normalizeVisitors(visitorsConfig, types) {
68
69
  possibleChildren.add(from.items);
69
70
  }
70
71
  }
72
+ if (from.extensionsPrefix) {
73
+ possibleChildren.add(types_1.SpecExtension);
74
+ }
71
75
  for (const fromType of Array.from(possibleChildren.values())) {
72
76
  addWeakNodes(ruleConf, fromType, to, parentContext, stack);
73
77
  }
package/lib/walk.js CHANGED
@@ -153,6 +153,9 @@ function walkDocument(opts) {
153
153
  if (type.additionalProperties) {
154
154
  props.push(...Object.keys(resolvedNode).filter((k) => !props.includes(k)));
155
155
  }
156
+ else if (type.extensionsPrefix) {
157
+ props.push(...Object.keys(resolvedNode).filter((k) => k.startsWith(type.extensionsPrefix)));
158
+ }
156
159
  if (ref_utils_1.isRef(node)) {
157
160
  props.push(...Object.keys(node).filter((k) => k !== '$ref' && !props.includes(k))); // properties on the same level as $ref
158
161
  }
@@ -168,6 +171,11 @@ function walkDocument(opts) {
168
171
  propType = type.additionalProperties;
169
172
  if (typeof propType === 'function')
170
173
  propType = propType(value, propName);
174
+ if (propType === undefined &&
175
+ type.extensionsPrefix &&
176
+ propName.startsWith(type.extensionsPrefix)) {
177
+ propType = types_1.SpecExtension;
178
+ }
171
179
  if (!types_1.isNamedType(propType) && (propType === null || propType === void 0 ? void 0 : propType.directResolveAs)) {
172
180
  propType = propType.directResolveAs;
173
181
  value = { $ref: value };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/openapi-core",
3
- "version": "1.0.0-beta.117",
3
+ "version": "1.0.0-beta.118",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "engines": {
@@ -23,6 +23,7 @@ rootType:
23
23
  type: string
24
24
  email:
25
25
  type: string
26
+ extensionsPrefix: x-
26
27
  name: Contact
27
28
  license:
28
29
  properties:
@@ -32,6 +33,7 @@ rootType:
32
33
  type: string
33
34
  required:
34
35
  - name
36
+ extensionsPrefix: x-
35
37
  name: License
36
38
  x-logo:
37
39
  properties:
@@ -47,6 +49,7 @@ rootType:
47
49
  required:
48
50
  - title
49
51
  - version
52
+ extensionsPrefix: x-
50
53
  name: Info
51
54
  servers:
52
55
  name: ServerList
@@ -62,6 +65,7 @@ rootType:
62
65
  properties: {}
63
66
  required:
64
67
  - url
68
+ extensionsPrefix: x-
65
69
  name: Server
66
70
  security:
67
71
  name: SecurityRequirementList
@@ -90,6 +94,7 @@ rootType:
90
94
  type: string
91
95
  required:
92
96
  - url
97
+ extensionsPrefix: x-
93
98
  name: ExternalDocs
94
99
  x-traitTag:
95
100
  type: boolean
@@ -97,6 +102,7 @@ rootType:
97
102
  type: string
98
103
  required:
99
104
  - name
105
+ extensionsPrefix: x-
100
106
  name: Tag
101
107
  externalDocs:
102
108
  properties:
@@ -106,6 +112,7 @@ rootType:
106
112
  type: string
107
113
  required:
108
114
  - url
115
+ extensionsPrefix: x-
109
116
  name: ExternalDocs
110
117
  paths:
111
118
  properties: {}
@@ -139,6 +146,7 @@ rootType:
139
146
  callbacks:
140
147
  name: NamedCallbacks
141
148
  properties: {}
149
+ extensionsPrefix: x-
142
150
  name: Components
143
151
  x-webhooks:
144
152
  properties: {}
@@ -154,6 +162,7 @@ rootType:
154
162
  type: array
155
163
  items:
156
164
  type: string
165
+ extensionsPrefix: x-
157
166
  name: TagGroup
158
167
  x-ignoredHeaderParameters:
159
168
  type: array
@@ -163,6 +172,7 @@ rootType:
163
172
  - openapi
164
173
  - paths
165
174
  - info
175
+ extensionsPrefix: x-
166
176
  name: Root
167
177
  refTypes: {}
168
178
  visitorsData:
@@ -79,14 +79,18 @@ export function resolvePlugins(
79
79
  }
80
80
 
81
81
  if (isString(plugin)) {
82
- const absoltePluginPath = path.resolve(path.dirname(configPath), plugin);
83
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
84
- // @ts-ignore
85
- return typeof __webpack_require__ === 'function'
86
- ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
87
- // @ts-ignore
88
- __non_webpack_require__(absoltePluginPath)
89
- : require(absoltePluginPath);
82
+ try {
83
+ const absoltePluginPath = path.resolve(path.dirname(configPath), plugin);
84
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
85
+ // @ts-ignore
86
+ return typeof __webpack_require__ === 'function'
87
+ ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
88
+ // @ts-ignore
89
+ __non_webpack_require__(absoltePluginPath)
90
+ : require(absoltePluginPath);
91
+ } catch (e) {
92
+ throw new Error(`Failed to load plugin "${plugin}". Please provide a valid path`);
93
+ }
90
94
  }
91
95
 
92
96
  return plugin;