@redocly/openapi-core 1.26.0 → 1.27.0

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 (45) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/lib/config/all.js +2 -4
  3. package/lib/config/config-resolvers.d.ts +3 -1
  4. package/lib/config/config-resolvers.js +7 -5
  5. package/lib/config/minimal.js +1 -3
  6. package/lib/config/recommended-strict.js +2 -4
  7. package/lib/config/recommended.js +2 -4
  8. package/lib/config/rules.js +3 -0
  9. package/lib/config/spec.js +2 -4
  10. package/lib/config/types.d.ts +2 -3
  11. package/lib/rules/arazzo/index.js +2 -6
  12. package/lib/rules/spot/spot-supported-versions.d.ts +2 -0
  13. package/lib/rules/spot/{version-enum.js → spot-supported-versions.js} +3 -3
  14. package/lib/types/redocly-yaml.d.ts +1 -1
  15. package/lib/types/redocly-yaml.js +1 -3
  16. package/lib/visitors.d.ts +3 -0
  17. package/lib/visitors.js +2 -2
  18. package/lib/walk.js +14 -11
  19. package/package.json +1 -3
  20. package/src/__tests__/walk.test.ts +51 -0
  21. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +4 -8
  22. package/src/config/all.ts +2 -4
  23. package/src/config/config-resolvers.ts +28 -36
  24. package/src/config/minimal.ts +1 -3
  25. package/src/config/recommended-strict.ts +2 -4
  26. package/src/config/recommended.ts +2 -4
  27. package/src/config/rules.ts +3 -1
  28. package/src/config/spec.ts +2 -4
  29. package/src/config/types.ts +2 -6
  30. package/src/rules/arazzo/__tests__/{version-enum.test.ts → spot-supported-versions.test.ts} +3 -3
  31. package/src/rules/arazzo/index.ts +2 -6
  32. package/src/rules/spot/{version-enum.ts → spot-supported-versions.ts} +1 -1
  33. package/src/types/redocly-yaml.ts +1 -3
  34. package/src/visitors.ts +5 -2
  35. package/src/walk.ts +20 -11
  36. package/tsconfig.tsbuildinfo +1 -1
  37. package/lib/rules/spot/no-actions-type-end.d.ts +0 -2
  38. package/lib/rules/spot/no-actions-type-end.js +0 -28
  39. package/lib/rules/spot/parameters-not-in-body.d.ts +0 -2
  40. package/lib/rules/spot/parameters-not-in-body.js +0 -18
  41. package/lib/rules/spot/version-enum.d.ts +0 -2
  42. package/src/rules/arazzo/__tests__/no-actions-type-end.test.ts +0 -121
  43. package/src/rules/arazzo/__tests__/parameters-not-in-body.test.ts +0 -73
  44. package/src/rules/spot/no-actions-type-end.ts +0 -27
  45. package/src/rules/spot/parameters-not-in-body.ts +0 -17
@@ -187,8 +187,6 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
187
187
  arazzo1Rules: {
188
188
  'criteria-unique': 'off',
189
189
  'no-criteria-xpath': 'off',
190
- 'no-actions-type-end': 'off',
191
- 'parameters-not-in-body': 'off',
192
190
  'parameters-unique': 'off',
193
191
  'requestBody-replacements-unique': 'off',
194
192
  'sourceDescription-type': 'off',
@@ -197,7 +195,7 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
197
195
  'step-onFailure-unique': 'off',
198
196
  'stepId-unique': 'error',
199
197
  'sourceDescription-name-unique': 'off',
200
- 'version-enum': 'off',
198
+ 'spot-supported-versions': 'off',
201
199
  'workflowId-unique': 'error',
202
200
  'workflow-dependsOn': 'off',
203
201
  },
@@ -186,9 +186,7 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
186
186
  },
187
187
  arazzo1Rules: {
188
188
  'criteria-unique': 'error',
189
- 'no-criteria-xpath': 'error',
190
- 'no-actions-type-end': 'error',
191
- 'parameters-not-in-body': 'error',
189
+ 'no-criteria-xpath': 'off',
192
190
  'parameters-unique': 'error',
193
191
  'requestBody-replacements-unique': 'error',
194
192
  'sourceDescription-type': 'error',
@@ -197,7 +195,7 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
197
195
  'stepId-unique': 'error',
198
196
  'sourceDescription-name-unique': 'error',
199
197
  'sourceDescriptions-not-empty': 'error',
200
- 'version-enum': 'error',
198
+ 'spot-supported-versions': 'off',
201
199
  'workflowId-unique': 'error',
202
200
  'workflow-dependsOn': 'error',
203
201
  },
@@ -186,9 +186,7 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
186
186
  },
187
187
  arazzo1Rules: {
188
188
  'criteria-unique': 'warn',
189
- 'no-criteria-xpath': 'warn',
190
- 'no-actions-type-end': 'warn',
191
- 'parameters-not-in-body': 'warn',
189
+ 'no-criteria-xpath': 'off',
192
190
  'parameters-unique': 'error',
193
191
  'requestBody-replacements-unique': 'warn',
194
192
  'sourceDescription-type': 'error',
@@ -197,7 +195,7 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
197
195
  'stepId-unique': 'error',
198
196
  'sourceDescription-name-unique': 'error',
199
197
  'sourceDescriptions-not-empty': 'error',
200
- 'version-enum': 'warn',
198
+ 'spot-supported-versions': 'off',
201
199
  'workflowId-unique': 'error',
202
200
  'workflow-dependsOn': 'error',
203
201
  },
@@ -39,19 +39,21 @@ export function initRules(
39
39
  return undefined;
40
40
  }
41
41
  const severity: ProblemSeverity = ruleSettings.severity;
42
-
42
+ const message = ruleSettings.message;
43
43
  const visitors = rule(ruleSettings);
44
44
 
45
45
  if (Array.isArray(visitors)) {
46
46
  return visitors.map((visitor: any) => ({
47
47
  severity,
48
48
  ruleId,
49
+ message,
49
50
  visitor: visitor,
50
51
  }));
51
52
  }
52
53
 
53
54
  return {
54
55
  severity,
56
+ message,
55
57
  ruleId,
56
58
  visitor: visitors, // note: actually it is only one visitor object
57
59
  };
@@ -11,9 +11,8 @@ const spec: PluginStyleguideConfig<'built-in'> = {
11
11
  async2Rules: {},
12
12
  async3Rules: {},
13
13
  arazzo1Rules: {
14
- 'parameters-not-in-body': 'error',
15
14
  'sourceDescription-type': 'error',
16
- 'version-enum': 'error',
15
+ 'spot-supported-versions': 'off',
17
16
  'workflowId-unique': 'error',
18
17
  'stepId-unique': 'error',
19
18
  'sourceDescription-name-unique': 'error',
@@ -23,8 +22,7 @@ const spec: PluginStyleguideConfig<'built-in'> = {
23
22
  'step-onSuccess-unique': 'error',
24
23
  'step-onFailure-unique': 'error',
25
24
  'requestBody-replacements-unique': 'error',
26
- 'no-criteria-xpath': 'error',
27
- 'no-actions-type-end': 'error',
25
+ 'no-criteria-xpath': 'off',
28
26
  'criteria-unique': 'error',
29
27
  },
30
28
  };
@@ -26,15 +26,11 @@ import type { JSONSchema } from 'json-schema-to-ts';
26
26
 
27
27
  export type RuleSeverity = ProblemSeverity | 'off';
28
28
 
29
- export type RuleSettings = { severity: RuleSeverity };
29
+ export type RuleSettings = { severity: RuleSeverity; message?: string };
30
30
 
31
31
  export type PreprocessorSeverity = RuleSeverity | 'on';
32
32
 
33
- export type RuleConfig =
34
- | RuleSeverity
35
- | ({
36
- severity?: ProblemSeverity;
37
- } & Record<string, any>);
33
+ export type RuleConfig = RuleSeverity | (Partial<RuleSettings> & Record<string, any>);
38
34
 
39
35
  export type PreprocessorConfig =
40
36
  | PreprocessorSeverity
@@ -3,7 +3,7 @@ import { lintDocument } from '../../../lint';
3
3
  import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
4
4
  import { BaseResolver } from '../../../resolve';
5
5
 
6
- describe('Arazzo version-enum', () => {
6
+ describe('Arazzo spot-supported-versions', () => {
7
7
  const document = parseYamlToDocument(
8
8
  outdent`
9
9
  arazzo: '1.0.1'
@@ -38,7 +38,7 @@ describe('Arazzo version-enum', () => {
38
38
  externalRefResolver: new BaseResolver(),
39
39
  document,
40
40
  config: await makeConfig({
41
- rules: { 'version-enum': 'error' },
41
+ rules: { 'spot-supported-versions': 'error' },
42
42
  }),
43
43
  });
44
44
 
@@ -53,7 +53,7 @@ describe('Arazzo version-enum', () => {
53
53
  },
54
54
  ],
55
55
  "message": "Only 1.0.0 Arazzo version is supported by Spot.",
56
- "ruleId": "version-enum",
56
+ "ruleId": "spot-supported-versions",
57
57
  "severity": "error",
58
58
  "suggest": [],
59
59
  },
@@ -1,9 +1,8 @@
1
1
  import { Struct } from '../common/struct';
2
2
  import { Assertions } from '../common/assertions';
3
- import { ParametersNotInBody } from '../spot/parameters-not-in-body';
4
3
  import { SourceDescriptionType } from '../arazzo/sourceDescription-type';
5
4
  import { SourceDescriptionsNotEmpty } from './sourceDescriptions-not-empty';
6
- import { VersionEnum } from '../spot/version-enum';
5
+ import { SpotSupportedVersions } from '../spot/spot-supported-versions';
7
6
  import { WorkflowIdUnique } from './workflowId-unique';
8
7
  import { StepIdUnique } from './stepId-unique';
9
8
  import { SourceDescriptionsNameUnique } from './sourceDescriptions-name-unique';
@@ -13,7 +12,6 @@ import { StepOnSuccessUnique } from './step-onSuccess-unique';
13
12
  import { StepOnFailureUnique } from './step-onFailure-unique';
14
13
  import { RequestBodyReplacementsUnique } from './requestBody-replacements-unique';
15
14
  import { NoCriteriaXpath } from '../spot/no-criteria-xpath';
16
- import { NoActionsTypeEnd } from '../spot/no-actions-type-end';
17
15
  import { CriteriaUnique } from './criteria-unique';
18
16
 
19
17
  import type { Arazzo1Rule } from '../../visitors';
@@ -22,9 +20,8 @@ import type { Arazzo1RuleSet } from '../../oas-types';
22
20
  export const rules: Arazzo1RuleSet<'built-in'> = {
23
21
  struct: Struct as Arazzo1Rule,
24
22
  assertions: Assertions as Arazzo1Rule,
25
- 'parameters-not-in-body': ParametersNotInBody,
26
23
  'sourceDescription-type': SourceDescriptionType,
27
- 'version-enum': VersionEnum,
24
+ 'spot-supported-versions': SpotSupportedVersions,
28
25
  'workflowId-unique': WorkflowIdUnique,
29
26
  'stepId-unique': StepIdUnique,
30
27
  'sourceDescription-name-unique': SourceDescriptionsNameUnique,
@@ -35,7 +32,6 @@ export const rules: Arazzo1RuleSet<'built-in'> = {
35
32
  'step-onFailure-unique': StepOnFailureUnique,
36
33
  'requestBody-replacements-unique': RequestBodyReplacementsUnique,
37
34
  'no-criteria-xpath': NoCriteriaXpath,
38
- 'no-actions-type-end': NoActionsTypeEnd,
39
35
  'criteria-unique': CriteriaUnique,
40
36
  };
41
37
 
@@ -4,7 +4,7 @@ import { pluralize } from '../../utils';
4
4
  import type { Arazzo1Rule } from '../../visitors';
5
5
  import type { UserContext } from '../../walk';
6
6
 
7
- export const VersionEnum: Arazzo1Rule = () => {
7
+ export const SpotSupportedVersions: Arazzo1Rule = () => {
8
8
  const supportedVersions = ARAZZO_VERSIONS_SUPPORTED_BY_SPOT.join(', ');
9
9
  return {
10
10
  Root: {
@@ -141,9 +141,7 @@ export type BuiltInAsync2RuleId = typeof builtInAsync2Rules[number];
141
141
  export type BuiltInAsync3RuleId = typeof builtInAsync3Rules[number];
142
142
 
143
143
  const builtInArazzo1Rules = [
144
- 'parameters-not-in-body',
145
144
  'sourceDescription-type',
146
- 'version-enum',
147
145
  'workflowId-unique',
148
146
  'stepId-unique',
149
147
  'sourceDescription-name-unique',
@@ -152,9 +150,9 @@ const builtInArazzo1Rules = [
152
150
  'parameters-unique',
153
151
  'step-onSuccess-unique',
154
152
  'step-onFailure-unique',
153
+ 'spot-supported-versions',
155
154
  'requestBody-replacements-unique',
156
155
  'no-criteria-xpath',
157
- 'no-actions-type-end',
158
156
  'criteria-unique',
159
157
  ] as const;
160
158
 
package/src/visitors.ts CHANGED
@@ -97,6 +97,7 @@ type VisitFunctionOrObject<T> = VisitFunction<T> | VisitObject<T>;
97
97
  export type VisitorNode<T> = {
98
98
  ruleId: string;
99
99
  severity: ProblemSeverity;
100
+ message?: string;
100
101
  context: VisitorLevelContext | VisitorSkippedLevelContext;
101
102
  depth: number;
102
103
  visit: VisitFunction<T>;
@@ -106,6 +107,7 @@ export type VisitorNode<T> = {
106
107
  type VisitorRefNode = {
107
108
  ruleId: string;
108
109
  severity: ProblemSeverity;
110
+ message?: string;
109
111
  context: VisitorLevelContext;
110
112
  depth: number;
111
113
  visit: VisitRefFunction;
@@ -365,6 +367,7 @@ export type OasDecorator = Oas3Decorator;
365
367
  export type RuleInstanceConfig = {
366
368
  ruleId: string;
367
369
  severity: ProblemSeverity;
370
+ message?: string;
368
371
  };
369
372
 
370
373
  export function normalizeVisitors<T extends BaseVisitor>(
@@ -390,8 +393,8 @@ export function normalizeVisitors<T extends BaseVisitor>(
390
393
  leave: [],
391
394
  };
392
395
 
393
- for (const { ruleId, severity, visitor } of visitorsConfig) {
394
- normalizeVisitorLevel({ ruleId, severity }, visitor, null);
396
+ for (const { ruleId, severity, message, visitor } of visitorsConfig) {
397
+ normalizeVisitorLevel({ ruleId, severity, message }, visitor, null);
395
398
  }
396
399
 
397
400
  for (const v of Object.keys(normalizedVisitors)) {
package/src/walk.ts CHANGED
@@ -165,9 +165,9 @@ export function walkDocument<T extends BaseVisitor>(opts: {
165
165
 
166
166
  if (isRef(node)) {
167
167
  const refEnterVisitors = normalizedVisitors.ref.enter;
168
- for (const { visit: visitor, ruleId, severity, context } of refEnterVisitors) {
168
+ for (const { visit: visitor, ruleId, severity, message, context } of refEnterVisitors) {
169
169
  enteredContexts.add(context);
170
- const report = reportFn.bind(undefined, ruleId, severity);
170
+ const report = reportFn.bind(undefined, ruleId, severity, message);
171
171
  visitor(
172
172
  node,
173
173
  {
@@ -203,7 +203,7 @@ export function walkDocument<T extends BaseVisitor>(opts: {
203
203
 
204
204
  const activatedContexts: Array<VisitorSkippedLevelContext | VisitorLevelContext> = [];
205
205
 
206
- for (const { context, visit, skip, ruleId, severity } of currentEnterVisitors) {
206
+ for (const { context, visit, skip, ruleId, severity, message } of currentEnterVisitors) {
207
207
  if (ignoredNodes.has(`${currentLocation.absolutePointer}${currentLocation.pointer}`)) break;
208
208
 
209
209
  if (context.isSkippedLevel) {
@@ -258,7 +258,7 @@ export function walkDocument<T extends BaseVisitor>(opts: {
258
258
  if (!activatedOn.skipped) {
259
259
  visitedBySome = true;
260
260
  enteredContexts.add(context);
261
- visitWithContext(visit, resolvedNode, node, context, ruleId, severity);
261
+ visitWithContext(visit, resolvedNode, node, context, ruleId, severity, message);
262
262
  }
263
263
  }
264
264
  }
@@ -360,9 +360,9 @@ export function walkDocument<T extends BaseVisitor>(opts: {
360
360
  }
361
361
  }
362
362
 
363
- for (const { context, visit, ruleId, severity } of currentLeaveVisitors) {
363
+ for (const { context, visit, ruleId, severity, message } of currentLeaveVisitors) {
364
364
  if (!context.isSkippedLevel && enteredContexts.has(context)) {
365
- visitWithContext(visit, resolvedNode, node, context, ruleId, severity);
365
+ visitWithContext(visit, resolvedNode, node, context, ruleId, severity, message);
366
366
  }
367
367
  }
368
368
  }
@@ -371,9 +371,9 @@ export function walkDocument<T extends BaseVisitor>(opts: {
371
371
 
372
372
  if (isRef(node)) {
373
373
  const refLeaveVisitors = normalizedVisitors.ref.leave;
374
- for (const { visit: visitor, ruleId, severity, context } of refLeaveVisitors) {
374
+ for (const { visit: visitor, ruleId, severity, context, message } of refLeaveVisitors) {
375
375
  if (enteredContexts.has(context)) {
376
- const report = reportFn.bind(undefined, ruleId, severity);
376
+ const report = reportFn.bind(undefined, ruleId, severity, message);
377
377
  visitor(
378
378
  node,
379
379
  {
@@ -402,9 +402,10 @@ export function walkDocument<T extends BaseVisitor>(opts: {
402
402
  node: unknown,
403
403
  context: VisitorLevelContext,
404
404
  ruleId: string,
405
- severity: ProblemSeverity
405
+ severity: ProblemSeverity,
406
+ customMessage: string | undefined
406
407
  ) {
407
- const report = reportFn.bind(undefined, ruleId, severity);
408
+ const report = reportFn.bind(undefined, ruleId, severity, customMessage);
408
409
  visit(
409
410
  resolvedNode,
410
411
  {
@@ -428,7 +429,12 @@ export function walkDocument<T extends BaseVisitor>(opts: {
428
429
  );
429
430
  }
430
431
 
431
- function reportFn(ruleId: string, severity: ProblemSeverity, opts: Problem) {
432
+ function reportFn(
433
+ ruleId: string,
434
+ severity: ProblemSeverity,
435
+ customMessage: string,
436
+ opts: Problem
437
+ ) {
432
438
  const normalizedLocation = opts.location
433
439
  ? Array.isArray(opts.location)
434
440
  ? opts.location
@@ -445,6 +451,9 @@ export function walkDocument<T extends BaseVisitor>(opts: {
445
451
  ruleId: opts.ruleId || ruleId,
446
452
  severity: ruleSeverity,
447
453
  ...opts,
454
+ message: customMessage
455
+ ? customMessage.replace('{{message}}', opts.message)
456
+ : opts.message,
448
457
  suggest: opts.suggest || [],
449
458
  location,
450
459
  });