@redocly/openapi-core 1.23.1 → 1.24.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.
- package/CHANGELOG.md +11 -0
- package/lib/config/all.js +3 -0
- package/lib/config/config.js +4 -1
- package/lib/config/minimal.js +3 -0
- package/lib/config/recommended-strict.js +3 -0
- package/lib/config/recommended.js +3 -0
- package/lib/rules/arazzo/criteria-unique.d.ts +2 -0
- package/lib/rules/arazzo/criteria-unique.js +65 -0
- package/lib/rules/arazzo/index.js +6 -0
- package/lib/rules/spot/no-actions-type-end.d.ts +2 -0
- package/lib/rules/spot/no-actions-type-end.js +28 -0
- package/lib/rules/spot/no-criteria-xpath.d.ts +2 -0
- package/lib/rules/spot/no-criteria-xpath.js +21 -0
- package/lib/types/arazzo.js +1 -1
- package/lib/types/redocly-yaml.d.ts +1 -1
- package/lib/types/redocly-yaml.js +3 -0
- package/package.json +2 -2
- package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +6 -0
- package/src/config/all.ts +3 -0
- package/src/config/config.ts +4 -1
- package/src/config/minimal.ts +3 -0
- package/src/config/recommended-strict.ts +3 -0
- package/src/config/recommended.ts +3 -0
- package/src/rules/arazzo/__tests__/criteria-unique.test.ts +161 -0
- package/src/rules/arazzo/__tests__/no-actions-type-end.test.ts +122 -0
- package/src/rules/arazzo/__tests__/no-criteria-xpath.test.ts +127 -0
- package/src/rules/arazzo/criteria-unique.ts +63 -0
- package/src/rules/arazzo/index.ts +6 -0
- package/src/rules/spot/no-actions-type-end.ts +27 -0
- package/src/rules/spot/no-criteria-xpath.ts +20 -0
- package/src/types/arazzo.ts +1 -1
- package/src/types/redocly-yaml.ts +3 -0
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @redocly/openapi-core
|
|
2
2
|
|
|
3
|
+
## 1.24.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added Spot and Arazzo rules: `no-criteria-xpath`, `no-actions-type-end`, `criteria-unique`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated @redocly/ajv to v8.11.2.
|
|
12
|
+
- Fixed an issue where custom rules were not applied to Arazzo descriptions.
|
|
13
|
+
|
|
3
14
|
## 1.23.1
|
|
4
15
|
|
|
5
16
|
## 1.23.0
|
package/lib/config/all.js
CHANGED
|
@@ -139,6 +139,9 @@ const all = {
|
|
|
139
139
|
'step-onSuccess-unique': 'error',
|
|
140
140
|
'step-onFailure-unique': 'error',
|
|
141
141
|
'requestBody-replacements-unique': 'error',
|
|
142
|
+
'no-criteria-xpath': 'error',
|
|
143
|
+
'no-actions-type-end': 'error',
|
|
144
|
+
'criteria-unique': 'error',
|
|
142
145
|
},
|
|
143
146
|
};
|
|
144
147
|
exports.default = all;
|
package/lib/config/config.js
CHANGED
|
@@ -38,7 +38,10 @@ class StyleguideConfig {
|
|
|
38
38
|
[oas_types_1.SpecVersion.OAS3_1]: { ...rawConfig.rules, ...rawConfig.oas3_1Rules },
|
|
39
39
|
[oas_types_1.SpecVersion.Async2]: { ...rawConfig.rules, ...rawConfig.async2Rules },
|
|
40
40
|
[oas_types_1.SpecVersion.Async3]: { ...rawConfig.rules, ...rawConfig.async3Rules },
|
|
41
|
-
[oas_types_1.SpecVersion.Arazzo]: {
|
|
41
|
+
[oas_types_1.SpecVersion.Arazzo]: {
|
|
42
|
+
...rawConfig.arazzoRules,
|
|
43
|
+
...(rawConfig.rules?.assertions ? { assertions: rawConfig.rules.assertions } : {}),
|
|
44
|
+
},
|
|
42
45
|
};
|
|
43
46
|
this.preprocessors = {
|
|
44
47
|
[oas_types_1.SpecVersion.OAS2]: { ...rawConfig.preprocessors, ...rawConfig.oas2Preprocessors },
|
package/lib/config/minimal.js
CHANGED
|
@@ -121,6 +121,9 @@ const minimal = {
|
|
|
121
121
|
'step-onSuccess-unique': 'off',
|
|
122
122
|
'step-onFailure-unique': 'off',
|
|
123
123
|
'requestBody-replacements-unique': 'off',
|
|
124
|
+
'no-criteria-xpath': 'off',
|
|
125
|
+
'no-actions-type-end': 'off',
|
|
126
|
+
'criteria-unique': 'off',
|
|
124
127
|
},
|
|
125
128
|
};
|
|
126
129
|
exports.default = minimal;
|
|
@@ -121,6 +121,9 @@ const recommendedStrict = {
|
|
|
121
121
|
'step-onSuccess-unique': 'error',
|
|
122
122
|
'step-onFailure-unique': 'error',
|
|
123
123
|
'requestBody-replacements-unique': 'error',
|
|
124
|
+
'no-criteria-xpath': 'error',
|
|
125
|
+
'no-actions-type-end': 'error',
|
|
126
|
+
'criteria-unique': 'error',
|
|
124
127
|
},
|
|
125
128
|
};
|
|
126
129
|
exports.default = recommendedStrict;
|
|
@@ -121,6 +121,9 @@ const recommended = {
|
|
|
121
121
|
'step-onSuccess-unique': 'warn',
|
|
122
122
|
'step-onFailure-unique': 'warn',
|
|
123
123
|
'requestBody-replacements-unique': 'warn',
|
|
124
|
+
'no-criteria-xpath': 'warn',
|
|
125
|
+
'no-actions-type-end': 'warn',
|
|
126
|
+
'criteria-unique': 'warn',
|
|
124
127
|
},
|
|
125
128
|
};
|
|
126
129
|
exports.default = recommended;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CriteriaUnique = void 0;
|
|
4
|
+
const CriteriaUnique = () => {
|
|
5
|
+
return {
|
|
6
|
+
FailureActionObject: {
|
|
7
|
+
enter(action, { report, location }) {
|
|
8
|
+
const criterias = action.criteria;
|
|
9
|
+
const seen = new Set();
|
|
10
|
+
for (const criteria of criterias) {
|
|
11
|
+
const key = JSON.stringify(criteria);
|
|
12
|
+
if (seen.has(key)) {
|
|
13
|
+
report({
|
|
14
|
+
message: 'The FailureAction criteria items must be unique.',
|
|
15
|
+
location: location.child(['criteria', criterias.indexOf(criteria)]),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
seen.add(key);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
SuccessActionObject: {
|
|
25
|
+
enter(action, { report, location }) {
|
|
26
|
+
const criterias = action.criteria;
|
|
27
|
+
const seen = new Set();
|
|
28
|
+
for (const criteria of criterias) {
|
|
29
|
+
const key = JSON.stringify(criteria);
|
|
30
|
+
if (seen.has(key)) {
|
|
31
|
+
report({
|
|
32
|
+
message: 'The SuccessAction criteria items must be unique.',
|
|
33
|
+
location: location.child(['criteria', criterias.indexOf(criteria)]),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
seen.add(key);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
Step: {
|
|
43
|
+
enter(step, { report, location }) {
|
|
44
|
+
if (!step.successCriteria) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const successCriterias = step.successCriteria;
|
|
48
|
+
const seen = new Set();
|
|
49
|
+
for (const criteria of successCriterias) {
|
|
50
|
+
const key = JSON.stringify(criteria);
|
|
51
|
+
if (seen.has(key)) {
|
|
52
|
+
report({
|
|
53
|
+
message: 'The Step SuccessCriteria items must be unique.',
|
|
54
|
+
location: location.child(['successCriteria', successCriterias.indexOf(criteria)]),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
seen.add(key);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
exports.CriteriaUnique = CriteriaUnique;
|
|
@@ -14,6 +14,9 @@ const parameters_unique_1 = require("./parameters-unique");
|
|
|
14
14
|
const step_onSuccess_unique_1 = require("./step-onSuccess-unique");
|
|
15
15
|
const step_onFailure_unique_1 = require("./step-onFailure-unique");
|
|
16
16
|
const requestBody_replacements_unique_1 = require("./requestBody-replacements-unique");
|
|
17
|
+
const no_criteria_xpath_1 = require("../spot/no-criteria-xpath");
|
|
18
|
+
const no_actions_type_end_1 = require("../spot/no-actions-type-end");
|
|
19
|
+
const criteria_unique_1 = require("./criteria-unique");
|
|
17
20
|
exports.rules = {
|
|
18
21
|
spec: spec_1.Spec,
|
|
19
22
|
assertions: assertions_1.Assertions,
|
|
@@ -28,5 +31,8 @@ exports.rules = {
|
|
|
28
31
|
'step-onSuccess-unique': step_onSuccess_unique_1.StepOnSuccessUnique,
|
|
29
32
|
'step-onFailure-unique': step_onFailure_unique_1.StepOnFailureUnique,
|
|
30
33
|
'requestBody-replacements-unique': requestBody_replacements_unique_1.RequestBodyReplacementsUnique,
|
|
34
|
+
'no-criteria-xpath': no_criteria_xpath_1.NoCriteriaXpath,
|
|
35
|
+
'no-actions-type-end': no_actions_type_end_1.NoActionsTypeEnd,
|
|
36
|
+
'criteria-unique': criteria_unique_1.CriteriaUnique,
|
|
31
37
|
};
|
|
32
38
|
exports.preprocessors = {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoActionsTypeEnd = void 0;
|
|
4
|
+
const NoActionsTypeEnd = () => {
|
|
5
|
+
return {
|
|
6
|
+
FailureActionObject: {
|
|
7
|
+
enter(action, { report, location }) {
|
|
8
|
+
if (action.type === 'end') {
|
|
9
|
+
report({
|
|
10
|
+
message: 'The `end` type action is not supported by Spot.',
|
|
11
|
+
location: location.child(['type']),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
SuccessActionObject: {
|
|
17
|
+
enter(action, { report, location }) {
|
|
18
|
+
if (action.type === 'end') {
|
|
19
|
+
report({
|
|
20
|
+
message: 'The `end` type action is not supported by Spot.',
|
|
21
|
+
location: location.child(['type']),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
exports.NoActionsTypeEnd = NoActionsTypeEnd;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoCriteriaXpath = void 0;
|
|
4
|
+
const NoCriteriaXpath = () => {
|
|
5
|
+
return {
|
|
6
|
+
CriterionObject: {
|
|
7
|
+
enter(criteria, { report, location }) {
|
|
8
|
+
if (!criteria.type) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (criteria?.type?.type === 'xpath' || criteria?.type === 'xpath') {
|
|
12
|
+
report({
|
|
13
|
+
message: 'The `xpath` type criteria is not supported by Spot.',
|
|
14
|
+
location: location.child(['type']),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
exports.NoCriteriaXpath = NoCriteriaXpath;
|
package/lib/types/arazzo.js
CHANGED
|
@@ -212,7 +212,7 @@ const CriterionObject = {
|
|
|
212
212
|
else if (typeof value === 'string') {
|
|
213
213
|
return { enum: ['regex', 'jsonpath', 'simple', 'xpath'] };
|
|
214
214
|
}
|
|
215
|
-
else if (value
|
|
215
|
+
else if (value?.type === 'jsonpath') {
|
|
216
216
|
return 'JSONPathCriterion';
|
|
217
217
|
}
|
|
218
218
|
else {
|
|
@@ -11,7 +11,7 @@ declare const builtInAsync2Rules: readonly ["spec", "info-contact", "info-licens
|
|
|
11
11
|
declare const builtInAsync3Rules: readonly ["spec", "info-contact", "info-license-strict", "operation-operationId", "tag-description", "tags-alphabetical", "channels-kebab-case", "no-channel-trailing-slash"];
|
|
12
12
|
export type BuiltInAsync2RuleId = typeof builtInAsync2Rules[number];
|
|
13
13
|
export type BuiltInAsync3RuleId = typeof builtInAsync3Rules[number];
|
|
14
|
-
declare const builtInArazzoRules: readonly ["spec", "parameters-not-in-body", "sourceDescription-type", "version-enum", "workflowId-unique", "stepId-unique", "sourceDescription-name-unique", "workflow-dependsOn", "parameters-unique", "step-onSuccess-unique", "step-onFailure-unique", "requestBody-replacements-unique"];
|
|
14
|
+
declare const builtInArazzoRules: readonly ["spec", "parameters-not-in-body", "sourceDescription-type", "version-enum", "workflowId-unique", "stepId-unique", "sourceDescription-name-unique", "workflow-dependsOn", "parameters-unique", "step-onSuccess-unique", "step-onFailure-unique", "requestBody-replacements-unique", "no-criteria-xpath", "no-actions-type-end", "criteria-unique"];
|
|
15
15
|
export type BuiltInArazzoRuleId = typeof builtInArazzoRules[number];
|
|
16
16
|
declare const oas2NodeTypesList: readonly ["Root", "Tag", "TagList", "ExternalDocs", "SecurityRequirement", "SecurityRequirementList", "Info", "Contact", "License", "Paths", "PathItem", "Parameter", "ParameterList", "ParameterItems", "Operation", "Example", "ExamplesMap", "Examples", "Header", "Responses", "Response", "Schema", "Xml", "SchemaProperties", "NamedSchemas", "NamedResponses", "NamedParameters", "NamedSecuritySchemes", "SecurityScheme", "TagGroup", "TagGroups", "EnumDescriptions", "Logo", "XCodeSample", "XCodeSampleList", "XServer", "XServerList"];
|
|
17
17
|
export type Oas2NodeType = typeof oas2NodeTypesList[number];
|
|
@@ -106,6 +106,9 @@ const builtInArazzoRules = [
|
|
|
106
106
|
'step-onSuccess-unique',
|
|
107
107
|
'step-onFailure-unique',
|
|
108
108
|
'requestBody-replacements-unique',
|
|
109
|
+
'no-criteria-xpath',
|
|
110
|
+
'no-actions-type-end',
|
|
111
|
+
'criteria-unique',
|
|
109
112
|
];
|
|
110
113
|
const builtInRules = [
|
|
111
114
|
...builtInCommonOASRules,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/openapi-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"engines": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@redocly/ajv": "^8.11.
|
|
38
|
+
"@redocly/ajv": "^8.11.2",
|
|
39
39
|
"@redocly/config": "^0.10.1",
|
|
40
40
|
"colorette": "^1.2.0",
|
|
41
41
|
"https-proxy-agent": "^7.0.4",
|
|
@@ -5,6 +5,9 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1
|
|
|
5
5
|
"arazzoDecorators": {},
|
|
6
6
|
"arazzoPreprocessors": {},
|
|
7
7
|
"arazzoRules": {
|
|
8
|
+
"criteria-unique": "warn",
|
|
9
|
+
"no-actions-type-end": "warn",
|
|
10
|
+
"no-criteria-xpath": "warn",
|
|
8
11
|
"parameters-not-in-body": "warn",
|
|
9
12
|
"parameters-unique": "error",
|
|
10
13
|
"requestBody-replacements-unique": "warn",
|
|
@@ -147,6 +150,9 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w
|
|
|
147
150
|
"arazzoDecorators": {},
|
|
148
151
|
"arazzoPreprocessors": {},
|
|
149
152
|
"arazzoRules": {
|
|
153
|
+
"criteria-unique": "warn",
|
|
154
|
+
"no-actions-type-end": "warn",
|
|
155
|
+
"no-criteria-xpath": "warn",
|
|
150
156
|
"parameters-not-in-body": "warn",
|
|
151
157
|
"parameters-unique": "error",
|
|
152
158
|
"requestBody-replacements-unique": "warn",
|
package/src/config/all.ts
CHANGED
|
@@ -139,6 +139,9 @@ const all: PluginStyleguideConfig<'built-in'> = {
|
|
|
139
139
|
'step-onSuccess-unique': 'error',
|
|
140
140
|
'step-onFailure-unique': 'error',
|
|
141
141
|
'requestBody-replacements-unique': 'error',
|
|
142
|
+
'no-criteria-xpath': 'error',
|
|
143
|
+
'no-actions-type-end': 'error',
|
|
144
|
+
'criteria-unique': 'error',
|
|
142
145
|
},
|
|
143
146
|
};
|
|
144
147
|
|
package/src/config/config.ts
CHANGED
|
@@ -73,7 +73,10 @@ export class StyleguideConfig {
|
|
|
73
73
|
[SpecVersion.OAS3_1]: { ...rawConfig.rules, ...rawConfig.oas3_1Rules },
|
|
74
74
|
[SpecVersion.Async2]: { ...rawConfig.rules, ...rawConfig.async2Rules },
|
|
75
75
|
[SpecVersion.Async3]: { ...rawConfig.rules, ...rawConfig.async3Rules },
|
|
76
|
-
[SpecVersion.Arazzo]: {
|
|
76
|
+
[SpecVersion.Arazzo]: {
|
|
77
|
+
...rawConfig.arazzoRules,
|
|
78
|
+
...(rawConfig.rules?.assertions ? { assertions: rawConfig.rules.assertions } : {}),
|
|
79
|
+
},
|
|
77
80
|
};
|
|
78
81
|
|
|
79
82
|
this.preprocessors = {
|
package/src/config/minimal.ts
CHANGED
|
@@ -121,6 +121,9 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
|
|
|
121
121
|
'step-onSuccess-unique': 'off',
|
|
122
122
|
'step-onFailure-unique': 'off',
|
|
123
123
|
'requestBody-replacements-unique': 'off',
|
|
124
|
+
'no-criteria-xpath': 'off',
|
|
125
|
+
'no-actions-type-end': 'off',
|
|
126
|
+
'criteria-unique': 'off',
|
|
124
127
|
},
|
|
125
128
|
};
|
|
126
129
|
|
|
@@ -121,6 +121,9 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
|
|
|
121
121
|
'step-onSuccess-unique': 'error',
|
|
122
122
|
'step-onFailure-unique': 'error',
|
|
123
123
|
'requestBody-replacements-unique': 'error',
|
|
124
|
+
'no-criteria-xpath': 'error',
|
|
125
|
+
'no-actions-type-end': 'error',
|
|
126
|
+
'criteria-unique': 'error',
|
|
124
127
|
},
|
|
125
128
|
};
|
|
126
129
|
|
|
@@ -121,6 +121,9 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
|
|
|
121
121
|
'step-onSuccess-unique': 'warn',
|
|
122
122
|
'step-onFailure-unique': 'warn',
|
|
123
123
|
'requestBody-replacements-unique': 'warn',
|
|
124
|
+
'no-criteria-xpath': 'warn',
|
|
125
|
+
'no-actions-type-end': 'warn',
|
|
126
|
+
'criteria-unique': 'warn',
|
|
124
127
|
},
|
|
125
128
|
};
|
|
126
129
|
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { outdent } from 'outdent';
|
|
2
|
+
import { lintDocument } from '../../../lint';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
4
|
+
import { BaseResolver } from '../../../resolve';
|
|
5
|
+
|
|
6
|
+
describe('Arazzo criteria-unique', () => {
|
|
7
|
+
const document = parseYamlToDocument(
|
|
8
|
+
outdent`
|
|
9
|
+
arazzo: '1.0.0'
|
|
10
|
+
info:
|
|
11
|
+
title: Cool API
|
|
12
|
+
version: 1.0.0
|
|
13
|
+
description: A cool API
|
|
14
|
+
sourceDescriptions:
|
|
15
|
+
- name: museum-api
|
|
16
|
+
type: openapi
|
|
17
|
+
url: openapi.yaml
|
|
18
|
+
workflows:
|
|
19
|
+
- workflowId: get-museum-hours
|
|
20
|
+
description: This workflow demonstrates how to get the museum opening hours and buy tickets.
|
|
21
|
+
parameters:
|
|
22
|
+
- in: header
|
|
23
|
+
name: Authorization
|
|
24
|
+
value: Basic Og==
|
|
25
|
+
steps:
|
|
26
|
+
- stepId: create-event
|
|
27
|
+
description: >-
|
|
28
|
+
Create a new special event.
|
|
29
|
+
operationPath: $sourceDescriptions.museum-api#/paths/~1special-events/post
|
|
30
|
+
requestBody:
|
|
31
|
+
payload:
|
|
32
|
+
name: 'Mermaid Treasure Identification and Analysis'
|
|
33
|
+
location: 'Under the seaaa 🦀 🎶 🌊.'
|
|
34
|
+
eventDescription: 'Join us as we review and classify a rare collection of 20 thingamabobs, gadgets, gizmos, whoosits, and whatsits, kindly donated by Ariel.'
|
|
35
|
+
dates:
|
|
36
|
+
- '2023-09-05'
|
|
37
|
+
- '2023-09-08'
|
|
38
|
+
price: 0
|
|
39
|
+
successCriteria:
|
|
40
|
+
- condition: $statusCode == 200
|
|
41
|
+
- condition: $statusCode == 200
|
|
42
|
+
- context: $response.body
|
|
43
|
+
condition: $.name == 'Mermaid Treasure Identification and Analysis'
|
|
44
|
+
type: jsonpath
|
|
45
|
+
- context: $response.body
|
|
46
|
+
condition: $.name == 'Mermaid Treasure Identification and Analysis'
|
|
47
|
+
type: jsonpath
|
|
48
|
+
onSuccess:
|
|
49
|
+
- name: 'onSuccessActionName'
|
|
50
|
+
type: 'goto'
|
|
51
|
+
stepId: 'buy-ticket'
|
|
52
|
+
criteria:
|
|
53
|
+
- condition: $response.body.open == true
|
|
54
|
+
- condition: $response.body.open == true
|
|
55
|
+
onFailure:
|
|
56
|
+
- name: 'onFailureActionName'
|
|
57
|
+
type: 'goto'
|
|
58
|
+
stepId: 'buy-ticket'
|
|
59
|
+
criteria:
|
|
60
|
+
- condition: $response.body.open == true
|
|
61
|
+
- condition: $response.body.open == true
|
|
62
|
+
outputs:
|
|
63
|
+
createdEventId: $response.body.eventId
|
|
64
|
+
name: $response.body.name
|
|
65
|
+
- workflowId: get-museum-hours-2
|
|
66
|
+
description: This workflow demonstrates how to get the museum opening hours and buy tickets.
|
|
67
|
+
parameters:
|
|
68
|
+
- in: header
|
|
69
|
+
name: Authorization
|
|
70
|
+
value: Basic Og==
|
|
71
|
+
steps:
|
|
72
|
+
- stepId: get-museum-hours
|
|
73
|
+
description: >-
|
|
74
|
+
Get museum hours by resolving request details with getMuseumHours operationId from openapi.yaml description.
|
|
75
|
+
operationId: museum-api.getMuseumHours
|
|
76
|
+
successCriteria:
|
|
77
|
+
- condition: $statusCode == 200
|
|
78
|
+
`,
|
|
79
|
+
'arazzo.yaml'
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
it('should report when the duplicated criteria exists', async () => {
|
|
83
|
+
const results = await lintDocument({
|
|
84
|
+
externalRefResolver: new BaseResolver(),
|
|
85
|
+
document,
|
|
86
|
+
config: await makeConfig({
|
|
87
|
+
rules: {},
|
|
88
|
+
arazzoRules: { 'criteria-unique': 'error' },
|
|
89
|
+
}),
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
93
|
+
[
|
|
94
|
+
{
|
|
95
|
+
"location": [
|
|
96
|
+
{
|
|
97
|
+
"pointer": "#/workflows/0/steps/0/successCriteria/1",
|
|
98
|
+
"reportOnKey": false,
|
|
99
|
+
"source": "arazzo.yaml",
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
"message": "The Step SuccessCriteria items must be unique.",
|
|
103
|
+
"ruleId": "criteria-unique",
|
|
104
|
+
"severity": "error",
|
|
105
|
+
"suggest": [],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"location": [
|
|
109
|
+
{
|
|
110
|
+
"pointer": "#/workflows/0/steps/0/successCriteria/3",
|
|
111
|
+
"reportOnKey": false,
|
|
112
|
+
"source": "arazzo.yaml",
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
"message": "The Step SuccessCriteria items must be unique.",
|
|
116
|
+
"ruleId": "criteria-unique",
|
|
117
|
+
"severity": "error",
|
|
118
|
+
"suggest": [],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"location": [
|
|
122
|
+
{
|
|
123
|
+
"pointer": "#/workflows/0/steps/0/onSuccess/0/criteria/1",
|
|
124
|
+
"reportOnKey": false,
|
|
125
|
+
"source": "arazzo.yaml",
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
"message": "The SuccessAction criteria items must be unique.",
|
|
129
|
+
"ruleId": "criteria-unique",
|
|
130
|
+
"severity": "error",
|
|
131
|
+
"suggest": [],
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"location": [
|
|
135
|
+
{
|
|
136
|
+
"pointer": "#/workflows/0/steps/0/onFailure/0/criteria/1",
|
|
137
|
+
"reportOnKey": false,
|
|
138
|
+
"source": "arazzo.yaml",
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
"message": "The FailureAction criteria items must be unique.",
|
|
142
|
+
"ruleId": "criteria-unique",
|
|
143
|
+
"severity": "error",
|
|
144
|
+
"suggest": [],
|
|
145
|
+
},
|
|
146
|
+
]
|
|
147
|
+
`);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should not report when the duplicated criteria exists', async () => {
|
|
151
|
+
const results = await lintDocument({
|
|
152
|
+
externalRefResolver: new BaseResolver(),
|
|
153
|
+
document,
|
|
154
|
+
config: await makeConfig({
|
|
155
|
+
rules: {},
|
|
156
|
+
}),
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { outdent } from 'outdent';
|
|
2
|
+
import { lintDocument } from '../../../lint';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
4
|
+
import { BaseResolver } from '../../../resolve';
|
|
5
|
+
|
|
6
|
+
describe('Arazzo no-actions-type-end', () => {
|
|
7
|
+
const document = parseYamlToDocument(
|
|
8
|
+
outdent`
|
|
9
|
+
arazzo: '1.0.0'
|
|
10
|
+
info:
|
|
11
|
+
title: Cool API
|
|
12
|
+
version: 1.0.0
|
|
13
|
+
description: A cool API
|
|
14
|
+
sourceDescriptions:
|
|
15
|
+
- name: museum-api
|
|
16
|
+
type: openapi
|
|
17
|
+
url: openapi.yaml
|
|
18
|
+
workflows:
|
|
19
|
+
- workflowId: get-museum-hours
|
|
20
|
+
description: This workflow demonstrates how to get the museum opening hours and buy tickets.
|
|
21
|
+
parameters:
|
|
22
|
+
- in: header
|
|
23
|
+
name: Authorization
|
|
24
|
+
value: Basic Og==
|
|
25
|
+
steps:
|
|
26
|
+
- stepId: create-event
|
|
27
|
+
description: >-
|
|
28
|
+
Create a new special event.
|
|
29
|
+
operationPath: $sourceDescriptions.museum-api#/paths/~1special-events/post
|
|
30
|
+
requestBody:
|
|
31
|
+
payload:
|
|
32
|
+
name: 'Mermaid Treasure Identification and Analysis'
|
|
33
|
+
location: 'Under the seaaa 🦀 🎶 🌊.'
|
|
34
|
+
eventDescription: 'Join us as we review and classify a rare collection of 20 thingamabobs, gadgets, gizmos, whoosits, and whatsits, kindly donated by Ariel.'
|
|
35
|
+
dates:
|
|
36
|
+
- '2023-09-05'
|
|
37
|
+
- '2023-09-08'
|
|
38
|
+
price: 0
|
|
39
|
+
successCriteria:
|
|
40
|
+
- condition: $statusCode == 201
|
|
41
|
+
onSuccess:
|
|
42
|
+
- name: 'onSuccessActionName'
|
|
43
|
+
type: 'end'
|
|
44
|
+
stepId: 'buy-ticket'
|
|
45
|
+
onFailure:
|
|
46
|
+
- name: 'onFailureActionName'
|
|
47
|
+
type: 'end'
|
|
48
|
+
stepId: 'buy-ticket'
|
|
49
|
+
outputs:
|
|
50
|
+
createdEventId: $response.body.eventId
|
|
51
|
+
name: $response.body.name
|
|
52
|
+
- workflowId: get-museum-hours-2
|
|
53
|
+
description: This workflow demonstrates how to get the museum opening hours and buy tickets.
|
|
54
|
+
parameters:
|
|
55
|
+
- in: header
|
|
56
|
+
name: Authorization
|
|
57
|
+
value: Basic Og==
|
|
58
|
+
steps:
|
|
59
|
+
- stepId: get-museum-hours
|
|
60
|
+
description: >-
|
|
61
|
+
Get museum hours by resolving request details with getMuseumHours operationId from openapi.yaml description.
|
|
62
|
+
operationId: museum-api.getMuseumHours
|
|
63
|
+
successCriteria:
|
|
64
|
+
- condition: $statusCode == 200
|
|
65
|
+
`,
|
|
66
|
+
'arazzo.yaml'
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
it('should report when the type `end` action exists', async () => {
|
|
70
|
+
const results = await lintDocument({
|
|
71
|
+
externalRefResolver: new BaseResolver(),
|
|
72
|
+
document,
|
|
73
|
+
config: await makeConfig({
|
|
74
|
+
rules: {},
|
|
75
|
+
arazzoRules: { 'no-actions-type-end': 'error' },
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
80
|
+
[
|
|
81
|
+
{
|
|
82
|
+
"location": [
|
|
83
|
+
{
|
|
84
|
+
"pointer": "#/workflows/0/steps/0/onSuccess/0/type",
|
|
85
|
+
"reportOnKey": false,
|
|
86
|
+
"source": "arazzo.yaml",
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
"message": "The \`end\` type action is not supported by Spot.",
|
|
90
|
+
"ruleId": "no-actions-type-end",
|
|
91
|
+
"severity": "error",
|
|
92
|
+
"suggest": [],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"location": [
|
|
96
|
+
{
|
|
97
|
+
"pointer": "#/workflows/0/steps/0/onFailure/0/type",
|
|
98
|
+
"reportOnKey": false,
|
|
99
|
+
"source": "arazzo.yaml",
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
"message": "The \`end\` type action is not supported by Spot.",
|
|
103
|
+
"ruleId": "no-actions-type-end",
|
|
104
|
+
"severity": "error",
|
|
105
|
+
"suggest": [],
|
|
106
|
+
},
|
|
107
|
+
]
|
|
108
|
+
`);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should not report when the type `end` action exists', async () => {
|
|
112
|
+
const results = await lintDocument({
|
|
113
|
+
externalRefResolver: new BaseResolver(),
|
|
114
|
+
document,
|
|
115
|
+
config: await makeConfig({
|
|
116
|
+
rules: {},
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
|
|
121
|
+
});
|
|
122
|
+
});
|