@redocly/openapi-core 1.0.0-beta.128 → 1.0.0-beta.130

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.
package/lib/config/all.js CHANGED
@@ -49,6 +49,7 @@ exports.default = {
49
49
  'no-invalid-parameter-examples': 'error',
50
50
  'scalar-property-missing-example': 'error',
51
51
  'spec-strict-refs': 'error',
52
+ 'component-name-unique': 'error',
52
53
  },
53
54
  oas3_0Rules: {
54
55
  'no-invalid-media-type-examples': 'error',
@@ -268,7 +268,7 @@ function groupStyleguideAssertionRules({ rules, plugins, }) {
268
268
  registerCustomAssertions(plugins, context);
269
269
  }
270
270
  }
271
- assertions.push(Object.assign(Object.assign({}, assertion), { assertionId: ruleKey.replace(/rule\/|assert\//, '') }));
271
+ assertions.push(Object.assign(Object.assign({}, assertion), { assertionId: ruleKey }));
272
272
  }
273
273
  else {
274
274
  // If it's not an assertion, keep it as is
@@ -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, ThemeRawConfig } from './types';
4
+ import type { DecoratorConfig, Plugin, PreprocessorConfig, Region, ResolveConfig, ResolvedApi, ResolvedConfig, ResolvedStyleguideConfig, RuleConfig, RuleSettings, Telemetry, 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: {
@@ -53,5 +53,6 @@ export declare class Config {
53
53
  theme: ThemeRawConfig;
54
54
  organization?: string;
55
55
  files: string[];
56
+ telemetry?: Telemetry;
56
57
  constructor(rawConfig: ResolvedConfig, configFile?: string | undefined);
57
58
  }
@@ -254,6 +254,7 @@ class Config {
254
254
  this.region = rawConfig.region;
255
255
  this.organization = rawConfig.organization;
256
256
  this.files = rawConfig.files || [];
257
+ this.telemetry = rawConfig.telemetry;
257
258
  }
258
259
  }
259
260
  exports.Config = Config;
@@ -32,6 +32,7 @@ exports.default = {
32
32
  'paths-kebab-case': 'off',
33
33
  spec: 'error',
34
34
  'spec-strict-refs': 'off',
35
+ 'component-name-unique': 'off',
35
36
  },
36
37
  oas3_0Rules: {
37
38
  'no-invalid-media-type-examples': {
@@ -32,6 +32,7 @@ exports.default = {
32
32
  'paths-kebab-case': 'off',
33
33
  spec: 'error',
34
34
  'spec-strict-refs': 'off',
35
+ 'component-name-unique': 'off',
35
36
  },
36
37
  oas3_0Rules: {
37
38
  'no-invalid-media-type-examples': {
@@ -97,6 +97,7 @@ export declare type ResolveConfig = {
97
97
  http: HttpResolveConfig;
98
98
  };
99
99
  export declare type Region = 'us' | 'eu';
100
+ export declare type Telemetry = 'on' | 'off';
100
101
  export declare type AccessTokens = {
101
102
  [region in Region]?: string;
102
103
  };
@@ -125,6 +126,7 @@ export declare type RawConfig = {
125
126
  region?: Region;
126
127
  organization?: string;
127
128
  files?: string[];
129
+ telemetry?: Telemetry;
128
130
  } & ThemeConfig;
129
131
  export declare type FlatApi = Omit<Api, 'styleguide'> & Omit<ApiStyleguideRawConfig, 'doNotResolveExamples'>;
130
132
  export declare type FlatRawConfig = Omit<RawConfig, 'styleguide' | 'resolve' | 'apis'> & Omit<StyleguideRawConfig, 'doNotResolveExamples'> & {
@@ -147,4 +149,14 @@ export declare type ThemeRawConfig = {
147
149
  mockServer?: Record<string, any>;
148
150
  };
149
151
  export declare type RulesFields = 'rules' | 'oas2Rules' | 'oas3_0Rules' | 'oas3_1Rules' | 'preprocessors' | 'oas2Preprocessors' | 'oas3_0Preprocessors' | 'oas3_1Preprocessors' | 'decorators' | 'oas2Decorators' | 'oas3_0Decorators' | 'oas3_1Decorators';
152
+ export declare enum AuthProviderType {
153
+ OIDC = "OIDC",
154
+ SAML2 = "SAML2",
155
+ BASIC = "BASIC"
156
+ }
157
+ export declare enum ApigeeDevOnboardingIntegrationAuthType {
158
+ SERVICE_ACCOUNT = "SERVICE_ACCOUNT",
159
+ OAUTH2 = "OAUTH2"
160
+ }
161
+ export declare const DEFAULT_TEAM_CLAIM_NAME = "https://redocly.com/sso/teams";
150
162
  export {};
@@ -1,2 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_TEAM_CLAIM_NAME = exports.ApigeeDevOnboardingIntegrationAuthType = exports.AuthProviderType = void 0;
4
+ var AuthProviderType;
5
+ (function (AuthProviderType) {
6
+ AuthProviderType["OIDC"] = "OIDC";
7
+ AuthProviderType["SAML2"] = "SAML2";
8
+ AuthProviderType["BASIC"] = "BASIC";
9
+ })(AuthProviderType = exports.AuthProviderType || (exports.AuthProviderType = {}));
10
+ var ApigeeDevOnboardingIntegrationAuthType;
11
+ (function (ApigeeDevOnboardingIntegrationAuthType) {
12
+ ApigeeDevOnboardingIntegrationAuthType["SERVICE_ACCOUNT"] = "SERVICE_ACCOUNT";
13
+ ApigeeDevOnboardingIntegrationAuthType["OAUTH2"] = "OAUTH2";
14
+ })(ApigeeDevOnboardingIntegrationAuthType = exports.ApigeeDevOnboardingIntegrationAuthType || (exports.ApigeeDevOnboardingIntegrationAuthType = {}));
15
+ exports.DEFAULT_TEAM_CLAIM_NAME = 'https://redocly.com/sso/teams';
@@ -11,12 +11,11 @@ const Assertions = (opts) => {
11
11
  // that is why we need to iterate through 'opts' values;
12
12
  // before - filter only object 'opts' values
13
13
  const assertions = Object.values(opts).filter((opt) => typeof opt === 'object' && opt !== null);
14
- for (const [index, assertion] of assertions.entries()) {
15
- const assertId = (assertion.assertionId && `${assertion.assertionId} assertion`) || `assertion #${index + 1}`;
14
+ for (const [_, assertion] of assertions.entries()) {
16
15
  if (!utils_2.isString(assertion.subject.type)) {
17
- throw new Error(`${assertId}: 'type' (String) is required`);
16
+ throw new Error(`${assertion.assertionId}: 'type' (String) is required`);
18
17
  }
19
- const subjectVisitor = utils_1.buildSubjectVisitor(assertId, assertion);
18
+ const subjectVisitor = utils_1.buildSubjectVisitor(assertion.assertionId, assertion);
20
19
  const visitorObject = utils_1.buildVisitorObject(assertion, subjectVisitor);
21
20
  visitors.push(visitorObject);
22
21
  }
@@ -0,0 +1,2 @@
1
+ import { Oas2Rule, Oas3Rule } from '../../visitors';
2
+ export declare const ComponentNameUnique: Oas3Rule | Oas2Rule;
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ComponentNameUnique = void 0;
4
+ const TYPE_NAME_SCHEMA = 'Schema';
5
+ const TYPE_NAME_PARAMETER = 'Parameter';
6
+ const TYPE_NAME_RESPONSE = 'Response';
7
+ const TYPE_NAME_REQUEST_BODY = 'RequestBody';
8
+ const TYPE_NAME_TO_OPTION_COMPONENT_NAME = {
9
+ [TYPE_NAME_SCHEMA]: 'schemas',
10
+ [TYPE_NAME_PARAMETER]: 'parameters',
11
+ [TYPE_NAME_RESPONSE]: 'responses',
12
+ [TYPE_NAME_REQUEST_BODY]: 'requestBodies',
13
+ };
14
+ const ComponentNameUnique = (options) => {
15
+ const components = new Map();
16
+ const typeNames = [];
17
+ if (options.schemas !== 'off') {
18
+ typeNames.push(TYPE_NAME_SCHEMA);
19
+ }
20
+ if (options.parameters !== 'off') {
21
+ typeNames.push(TYPE_NAME_PARAMETER);
22
+ }
23
+ if (options.responses !== 'off') {
24
+ typeNames.push(TYPE_NAME_RESPONSE);
25
+ }
26
+ if (options.requestBodies !== 'off') {
27
+ typeNames.push(TYPE_NAME_REQUEST_BODY);
28
+ }
29
+ const rule = {
30
+ ref: {
31
+ leave(ref, { type, resolve }) {
32
+ const typeName = type.name;
33
+ if (typeNames.includes(typeName)) {
34
+ const resolvedRef = resolve(ref);
35
+ if (!resolvedRef.location)
36
+ return;
37
+ addComponentFromAbsoluteLocation(typeName, resolvedRef.location.absolutePointer.toString());
38
+ }
39
+ },
40
+ },
41
+ Root: {
42
+ leave(root, ctx) {
43
+ components.forEach((value, key, _) => {
44
+ if (value.size > 1) {
45
+ const component = getComponentFromKey(key);
46
+ const optionComponentName = getOptionComponentNameForTypeName(component.typeName);
47
+ const definitions = Array.from(value)
48
+ .map((v) => `- ${v}`)
49
+ .join('\n');
50
+ const problem = {
51
+ message: `Component '${optionComponentName}/${component.componentName}' is not unique. It is defined at:\n${definitions}`,
52
+ };
53
+ const componentSeverity = optionComponentName ? options[optionComponentName] : null;
54
+ if (componentSeverity) {
55
+ problem.forceSeverity = componentSeverity;
56
+ }
57
+ ctx.report(problem);
58
+ }
59
+ });
60
+ },
61
+ },
62
+ };
63
+ if (options.schemas != 'off') {
64
+ rule.NamedSchemas = {
65
+ Schema(_, { location }) {
66
+ addComponentFromAbsoluteLocation(TYPE_NAME_SCHEMA, location.absolutePointer.toString());
67
+ },
68
+ };
69
+ }
70
+ if (options.responses != 'off') {
71
+ rule.NamedResponses = {
72
+ Response(_, { location }) {
73
+ addComponentFromAbsoluteLocation(TYPE_NAME_RESPONSE, location.absolutePointer.toString());
74
+ },
75
+ };
76
+ }
77
+ if (options.parameters != 'off') {
78
+ rule.NamedParameters = {
79
+ Parameter(_, { location }) {
80
+ addComponentFromAbsoluteLocation(TYPE_NAME_PARAMETER, location.absolutePointer.toString());
81
+ },
82
+ };
83
+ }
84
+ if (options.requestBodies != 'off') {
85
+ rule.NamedRequestBodies = {
86
+ RequestBody(_, { location }) {
87
+ addComponentFromAbsoluteLocation(TYPE_NAME_REQUEST_BODY, location.absolutePointer.toString());
88
+ },
89
+ };
90
+ }
91
+ return rule;
92
+ function getComponentNameFromAbsoluteLocation(absoluteLocation) {
93
+ const componentName = absoluteLocation.split('/').slice(-1)[0];
94
+ if (componentName.endsWith('.yml') ||
95
+ componentName.endsWith('.yaml') ||
96
+ componentName.endsWith('.json')) {
97
+ return componentName.slice(0, componentName.lastIndexOf('.'));
98
+ }
99
+ return componentName;
100
+ }
101
+ function addFoundComponent(typeName, componentName, absoluteLocation) {
102
+ var _a;
103
+ const key = getKeyForComponent(typeName, componentName);
104
+ const locations = (_a = components.get(key)) !== null && _a !== void 0 ? _a : new Set();
105
+ locations.add(absoluteLocation);
106
+ components.set(key, locations);
107
+ }
108
+ function addComponentFromAbsoluteLocation(typeName, absoluteLocation) {
109
+ const componentName = getComponentNameFromAbsoluteLocation(absoluteLocation);
110
+ addFoundComponent(typeName, componentName, absoluteLocation);
111
+ }
112
+ };
113
+ exports.ComponentNameUnique = ComponentNameUnique;
114
+ function getOptionComponentNameForTypeName(typeName) {
115
+ var _a;
116
+ return (_a = TYPE_NAME_TO_OPTION_COMPONENT_NAME[typeName]) !== null && _a !== void 0 ? _a : null;
117
+ }
118
+ function getKeyForComponent(typeName, componentName) {
119
+ return `${typeName}/${componentName}`;
120
+ }
121
+ function getComponentFromKey(key) {
122
+ const [typeName, componentName] = key.split('/');
123
+ return { typeName, componentName };
124
+ }
@@ -53,6 +53,7 @@ const spec_components_invalid_map_name_1 = require("./spec-components-invalid-ma
53
53
  const operation_4xx_problem_details_rfc7807_1 = require("./operation-4xx-problem-details-rfc7807");
54
54
  const required_string_property_missing_min_length_1 = require("../common/required-string-property-missing-min-length");
55
55
  const spec_strict_refs_1 = require("../common/spec-strict-refs");
56
+ const component_name_unique_1 = require("./component-name-unique");
56
57
  exports.rules = {
57
58
  spec: spec_1.OasSpec,
58
59
  'info-contact': info_contact_1.InfoContact,
@@ -107,5 +108,6 @@ exports.rules = {
107
108
  'spec-components-invalid-map-name': spec_components_invalid_map_name_1.SpecComponentsInvalidMapName,
108
109
  'required-string-property-missing-min-length': required_string_property_missing_min_length_1.RequiredStringPropertyMissingMinLength,
109
110
  'spec-strict-refs': spec_strict_refs_1.SpecStrictRefs,
111
+ 'component-name-unique': component_name_unique_1.ComponentNameUnique,
110
112
  };
111
113
  exports.preprocessors = {};
@@ -72,6 +72,8 @@ function validateDefinedAndNonEmpty(fieldName, value, ctx) {
72
72
  }
73
73
  exports.validateDefinedAndNonEmpty = validateDefinedAndNonEmpty;
74
74
  function getSuggest(given, variants) {
75
+ if (given === null)
76
+ return variants;
75
77
  if (typeof given !== 'string' || !variants.length)
76
78
  return [];
77
79
  const distances = [];
@@ -127,7 +129,7 @@ function validateSchemaEnumType(schemaEnum, propertyValue, propName, refLocation
127
129
  if (!schemaEnum) {
128
130
  return;
129
131
  }
130
- if (!schemaEnum.includes(propertyValue === null ? 'null' : propertyValue)) {
132
+ if (!schemaEnum.includes(propertyValue)) {
131
133
  report({
132
134
  location,
133
135
  message: `\`${propName}\` can be one of the following only: ${schemaEnum