@speclynx/apidom-ns-openapi-3-1 4.0.5 → 4.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@speclynx/apidom-ns-openapi-3-1",
3
- "version": "4.0.5",
3
+ "version": "4.1.0",
4
4
  "description": "OpenAPI 3.1.x namespace for ApiDOM.",
5
5
  "keywords": [
6
6
  "apidom",
@@ -60,12 +60,12 @@
60
60
  "license": "Apache-2.0",
61
61
  "dependencies": {
62
62
  "@babel/runtime-corejs3": "^7.28.4",
63
- "@speclynx/apidom-core": "4.0.5",
64
- "@speclynx/apidom-datamodel": "4.0.5",
65
- "@speclynx/apidom-json-pointer": "4.0.5",
66
- "@speclynx/apidom-ns-json-schema-2020-12": "4.0.5",
67
- "@speclynx/apidom-ns-openapi-3-0": "4.0.5",
68
- "@speclynx/apidom-traverse": "4.0.5",
63
+ "@speclynx/apidom-core": "4.1.0",
64
+ "@speclynx/apidom-datamodel": "4.1.0",
65
+ "@speclynx/apidom-json-pointer": "4.1.0",
66
+ "@speclynx/apidom-ns-json-schema-2020-12": "4.1.0",
67
+ "@speclynx/apidom-ns-openapi-3-0": "4.1.0",
68
+ "@speclynx/apidom-traverse": "4.1.0",
69
69
  "ramda": "~0.32.0",
70
70
  "ramda-adjunct": "^6.0.0",
71
71
  "ts-mixer": "^6.0.4"
@@ -80,5 +80,5 @@
80
80
  "README.md",
81
81
  "CHANGELOG.md"
82
82
  ],
83
- "gitHead": "5a85d2a832eeefb07d03760faa391b457447e966"
83
+ "gitHead": "41d4a41ac6157808b01e08d271019e53c4c8d6c5"
84
84
  }
package/src/index.cjs CHANGED
@@ -22,45 +22,45 @@ var _normalizeOperationIds = _interopRequireDefault(require("./refractor/plugins
22
22
  exports.refractorPluginNormalizeOperationIds = _normalizeOperationIds.default;
23
23
  var _normalizeParameterExamples = _interopRequireDefault(require("./refractor/plugins/normalize-parameter-examples.cjs"));
24
24
  exports.refractorPluginNormalizeParameterExamples = _normalizeParameterExamples.default;
25
- var _index = _interopRequireDefault(require("./refractor/plugins/normalize-header-examples/index.cjs"));
26
- exports.refractorPluginNormalizeHeaderExamples = _index.default;
25
+ var _normalizeHeaderExamples = _interopRequireDefault(require("./refractor/plugins/normalize-header-examples.cjs"));
26
+ exports.refractorPluginNormalizeHeaderExamples = _normalizeHeaderExamples.default;
27
27
  var _toolbox = _interopRequireDefault(require("./refractor/toolbox.cjs"));
28
28
  exports.createToolbox = _toolbox.default;
29
29
  var _specification = _interopRequireDefault(require("./refractor/specification.cjs"));
30
30
  exports.specificationObj = _specification.default;
31
- var _index2 = _interopRequireWildcard(require("./refractor/index.cjs"));
32
- exports.refract = _index2.default;
33
- exports.refractOpenApi3_1 = _index2.refractOpenApi3_1;
34
- exports.refractInfo = _index2.refractInfo;
35
- exports.refractContact = _index2.refractContact;
36
- exports.refractLicense = _index2.refractLicense;
37
- exports.refractServer = _index2.refractServer;
38
- exports.refractServerVariable = _index2.refractServerVariable;
39
- exports.refractComponents = _index2.refractComponents;
40
- exports.refractPaths = _index2.refractPaths;
41
- exports.refractPathItem = _index2.refractPathItem;
42
- exports.refractOperation = _index2.refractOperation;
43
- exports.refractExternalDocumentation = _index2.refractExternalDocumentation;
44
- exports.refractParameter = _index2.refractParameter;
45
- exports.refractRequestBody = _index2.refractRequestBody;
46
- exports.refractMediaType = _index2.refractMediaType;
47
- exports.refractEncoding = _index2.refractEncoding;
48
- exports.refractResponses = _index2.refractResponses;
49
- exports.refractResponse = _index2.refractResponse;
50
- exports.refractCallback = _index2.refractCallback;
51
- exports.refractExample = _index2.refractExample;
52
- exports.refractLink = _index2.refractLink;
53
- exports.refractHeader = _index2.refractHeader;
54
- exports.refractTag = _index2.refractTag;
55
- exports.refractReference = _index2.refractReference;
56
- exports.refractSchema = _index2.refractSchema;
57
- exports.refractDiscriminator = _index2.refractDiscriminator;
58
- exports.refractXml = _index2.refractXml;
59
- exports.refractSecurityScheme = _index2.refractSecurityScheme;
60
- exports.refractOAuthFlows = _index2.refractOAuthFlows;
61
- exports.refractOAuthFlow = _index2.refractOAuthFlow;
62
- exports.refractSecurityRequirement = _index2.refractSecurityRequirement;
63
- exports.refractJsonSchemaDialect = _index2.refractJsonSchemaDialect;
31
+ var _index = _interopRequireWildcard(require("./refractor/index.cjs"));
32
+ exports.refract = _index.default;
33
+ exports.refractOpenApi3_1 = _index.refractOpenApi3_1;
34
+ exports.refractInfo = _index.refractInfo;
35
+ exports.refractContact = _index.refractContact;
36
+ exports.refractLicense = _index.refractLicense;
37
+ exports.refractServer = _index.refractServer;
38
+ exports.refractServerVariable = _index.refractServerVariable;
39
+ exports.refractComponents = _index.refractComponents;
40
+ exports.refractPaths = _index.refractPaths;
41
+ exports.refractPathItem = _index.refractPathItem;
42
+ exports.refractOperation = _index.refractOperation;
43
+ exports.refractExternalDocumentation = _index.refractExternalDocumentation;
44
+ exports.refractParameter = _index.refractParameter;
45
+ exports.refractRequestBody = _index.refractRequestBody;
46
+ exports.refractMediaType = _index.refractMediaType;
47
+ exports.refractEncoding = _index.refractEncoding;
48
+ exports.refractResponses = _index.refractResponses;
49
+ exports.refractResponse = _index.refractResponse;
50
+ exports.refractCallback = _index.refractCallback;
51
+ exports.refractExample = _index.refractExample;
52
+ exports.refractLink = _index.refractLink;
53
+ exports.refractHeader = _index.refractHeader;
54
+ exports.refractTag = _index.refractTag;
55
+ exports.refractReference = _index.refractReference;
56
+ exports.refractSchema = _index.refractSchema;
57
+ exports.refractDiscriminator = _index.refractDiscriminator;
58
+ exports.refractXml = _index.refractXml;
59
+ exports.refractSecurityScheme = _index.refractSecurityScheme;
60
+ exports.refractOAuthFlows = _index.refractOAuthFlows;
61
+ exports.refractOAuthFlow = _index.refractOAuthFlow;
62
+ exports.refractSecurityRequirement = _index.refractSecurityRequirement;
63
+ exports.refractJsonSchemaDialect = _index.refractJsonSchemaDialect;
64
64
  var _apidomNsOpenapi = require("@speclynx/apidom-ns-openapi-3-0");
65
65
  exports.AlternatingVisitor = _apidomNsOpenapi.AlternatingVisitor;
66
66
  exports.FixedFieldsVisitor = _apidomNsOpenapi.FixedFieldsVisitor;
package/src/index.mjs CHANGED
@@ -6,7 +6,7 @@ export { default as refractorPluginNormalizeSecurityRequirements } from "./refra
6
6
  export { default as refractorPluginNormalizeServers } from "./refractor/plugins/normalize-servers.mjs";
7
7
  export { default as refractorPluginNormalizeOperationIds } from "./refractor/plugins/normalize-operation-ids.mjs";
8
8
  export { default as refractorPluginNormalizeParameterExamples } from "./refractor/plugins/normalize-parameter-examples.mjs";
9
- export { default as refractorPluginNormalizeHeaderExamples } from "./refractor/plugins/normalize-header-examples/index.mjs";
9
+ export { default as refractorPluginNormalizeHeaderExamples } from "./refractor/plugins/normalize-header-examples.mjs";
10
10
  export { default as createToolbox } from "./refractor/toolbox.mjs";
11
11
  export { default as specificationObj } from "./refractor/specification.mjs";
12
12
  export { default as refract, refractOpenApi3_1, refractInfo, refractContact, refractLicense, refractServer, refractServerVariable, refractComponents, refractPaths, refractPathItem, refractOperation, refractExternalDocumentation, refractParameter, refractRequestBody, refractMediaType, refractEncoding, refractResponses, refractResponse, refractCallback, refractExample, refractLink, refractHeader, refractTag, refractReference, refractSchema, refractDiscriminator, refractXml, refractSecurityScheme, refractOAuthFlows, refractOAuthFlow, refractSecurityRequirement, refractJsonSchemaDialect } from "./refractor/index.mjs";
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequ
4
4
  exports.__esModule = true;
5
5
  exports.default = void 0;
6
6
  var _apidomDatamodel = require("@speclynx/apidom-datamodel");
7
- var _NormalizeStorage = _interopRequireDefault(require("./NormalizeStorage.cjs"));
7
+ var _index = _interopRequireDefault(require("./normalize-storage/index.cjs"));
8
8
  /**
9
9
  * Override of Schema.example and Schema.examples field inside the Header Objects.
10
10
  *
@@ -28,8 +28,7 @@ const plugin = ({
28
28
  storageField = 'x-normalized'
29
29
  } = {}) => toolbox => {
30
30
  const {
31
- predicates,
32
- ancestorLineageToJSONPointer
31
+ predicates
33
32
  } = toolbox;
34
33
  let storage;
35
34
  return {
@@ -37,7 +36,7 @@ const plugin = ({
37
36
  OpenApi3_1Element: {
38
37
  enter(path) {
39
38
  const element = path.node;
40
- storage = new _NormalizeStorage.default(element, storageField, 'header-examples');
39
+ storage = new _index.default(element, storageField, 'header-examples');
41
40
  },
42
41
  leave() {
43
42
  storage = undefined;
@@ -61,7 +60,7 @@ const plugin = ({
61
60
  if (typeof headerElement.schema?.example === 'undefined' && typeof headerElement.schema?.examples === 'undefined') {
62
61
  return;
63
62
  }
64
- const headerJSONPointer = ancestorLineageToJSONPointer([...ancestors, headerElement]);
63
+ const headerJSONPointer = path.formatPath();
65
64
 
66
65
  // skip visiting this Header Object if it's already normalized
67
66
  if (storage.includes(headerJSONPointer)) {
@@ -1,5 +1,5 @@
1
1
  import { cloneDeep } from '@speclynx/apidom-datamodel';
2
- import NormalizeStorage from "./NormalizeStorage.mjs";
2
+ import NormalizeStorage from "./normalize-storage/index.mjs";
3
3
  /**
4
4
  * Override of Schema.example and Schema.examples field inside the Header Objects.
5
5
  *
@@ -22,8 +22,7 @@ const plugin = ({
22
22
  storageField = 'x-normalized'
23
23
  } = {}) => toolbox => {
24
24
  const {
25
- predicates,
26
- ancestorLineageToJSONPointer
25
+ predicates
27
26
  } = toolbox;
28
27
  let storage;
29
28
  return {
@@ -55,7 +54,7 @@ const plugin = ({
55
54
  if (typeof headerElement.schema?.example === 'undefined' && typeof headerElement.schema?.examples === 'undefined') {
56
55
  return;
57
56
  }
58
- const headerJSONPointer = ancestorLineageToJSONPointer([...ancestors, headerElement]);
57
+ const headerJSONPointer = path.formatPath();
59
58
 
60
59
  // skip visiting this Header Object if it's already normalized
61
60
  if (storage.includes(headerJSONPointer)) {
@@ -6,7 +6,7 @@ exports.default = void 0;
6
6
  var _ramda = require("ramda");
7
7
  var _apidomDatamodel = require("@speclynx/apidom-datamodel");
8
8
  var _apidomCore = require("@speclynx/apidom-core");
9
- var _NormalizeStorage = _interopRequireDefault(require("./normalize-header-examples/NormalizeStorage.cjs"));
9
+ var _index = _interopRequireDefault(require("./normalize-storage/index.cjs"));
10
10
  const removeSpaces = operationId => {
11
11
  return operationId.replace(/\s/g, '');
12
12
  };
@@ -53,7 +53,6 @@ const plugin = ({
53
53
  } = {}) => toolbox => {
54
54
  const {
55
55
  predicates,
56
- ancestorLineageToJSONPointer,
57
56
  namespace
58
57
  } = toolbox;
59
58
  const pathTemplates = [];
@@ -65,7 +64,7 @@ const plugin = ({
65
64
  OpenApi3_1Element: {
66
65
  enter(path) {
67
66
  const element = path.node;
68
- storage = new _NormalizeStorage.default(element, storageField, 'operation-ids');
67
+ storage = new _index.default(element, storageField, 'operation-ids');
69
68
  },
70
69
  leave() {
71
70
  // group normalized operations by normalized operationId
@@ -120,11 +119,10 @@ const plugin = ({
120
119
  OperationElement: {
121
120
  enter(path) {
122
121
  const operationElement = path.node;
123
- const ancestors = path.getAncestorNodes().reverse(); // root to parent order
124
122
 
125
123
  // operationId field is undefined, needs no normalization
126
124
  if (typeof operationElement.operationId === 'undefined') return;
127
- const operationJSONPointer = ancestorLineageToJSONPointer([...ancestors, operationElement]);
125
+ const operationJSONPointer = path.formatPath();
128
126
 
129
127
  // skip visiting this Operation Object if it's already normalized
130
128
  if (storage.includes(operationJSONPointer)) {
@@ -1,7 +1,7 @@
1
1
  import { last, defaultTo, groupBy } from 'ramda';
2
2
  import { cloneDeep } from '@speclynx/apidom-datamodel';
3
3
  import { toValue } from '@speclynx/apidom-core';
4
- import NormalizeStorage from "./normalize-header-examples/NormalizeStorage.mjs";
4
+ import NormalizeStorage from "./normalize-storage/index.mjs";
5
5
  const removeSpaces = operationId => {
6
6
  return operationId.replace(/\s/g, '');
7
7
  };
@@ -48,7 +48,6 @@ const plugin = ({
48
48
  } = {}) => toolbox => {
49
49
  const {
50
50
  predicates,
51
- ancestorLineageToJSONPointer,
52
51
  namespace
53
52
  } = toolbox;
54
53
  const pathTemplates = [];
@@ -115,11 +114,10 @@ const plugin = ({
115
114
  OperationElement: {
116
115
  enter(path) {
117
116
  const operationElement = path.node;
118
- const ancestors = path.getAncestorNodes().reverse(); // root to parent order
119
117
 
120
118
  // operationId field is undefined, needs no normalization
121
119
  if (typeof operationElement.operationId === 'undefined') return;
122
- const operationJSONPointer = ancestorLineageToJSONPointer([...ancestors, operationElement]);
120
+ const operationJSONPointer = path.formatPath();
123
121
 
124
122
  // skip visiting this Operation Object if it's already normalized
125
123
  if (storage.includes(operationJSONPointer)) {
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequ
4
4
  exports.__esModule = true;
5
5
  exports.default = void 0;
6
6
  var _apidomDatamodel = require("@speclynx/apidom-datamodel");
7
- var _NormalizeStorage = _interopRequireDefault(require("./normalize-header-examples/NormalizeStorage.cjs"));
7
+ var _index = _interopRequireDefault(require("./normalize-storage/index.cjs"));
8
8
  /**
9
9
  * Override of Schema.example and Schema.examples field inside the Parameter Objects.
10
10
  *
@@ -28,8 +28,7 @@ const plugin = ({
28
28
  storageField = 'x-normalized'
29
29
  } = {}) => toolbox => {
30
30
  const {
31
- predicates,
32
- ancestorLineageToJSONPointer
31
+ predicates
33
32
  } = toolbox;
34
33
  let storage;
35
34
  return {
@@ -37,7 +36,7 @@ const plugin = ({
37
36
  OpenApi3_1Element: {
38
37
  enter(path) {
39
38
  const element = path.node;
40
- storage = new _NormalizeStorage.default(element, storageField, 'parameter-examples');
39
+ storage = new _index.default(element, storageField, 'parameter-examples');
41
40
  },
42
41
  leave() {
43
42
  storage = undefined;
@@ -61,7 +60,7 @@ const plugin = ({
61
60
  if (typeof parameterElement.schema?.example === 'undefined' && typeof parameterElement.schema?.examples === 'undefined') {
62
61
  return;
63
62
  }
64
- const parameterJSONPointer = ancestorLineageToJSONPointer([...ancestors, parameterElement]);
63
+ const parameterJSONPointer = path.formatPath();
65
64
 
66
65
  // skip visiting this Parameter Object if it's already normalized
67
66
  if (storage.includes(parameterJSONPointer)) {
@@ -1,5 +1,5 @@
1
1
  import { cloneDeep } from '@speclynx/apidom-datamodel';
2
- import NormalizeStorage from "./normalize-header-examples/NormalizeStorage.mjs";
2
+ import NormalizeStorage from "./normalize-storage/index.mjs";
3
3
  /**
4
4
  * Override of Schema.example and Schema.examples field inside the Parameter Objects.
5
5
  *
@@ -22,8 +22,7 @@ const plugin = ({
22
22
  storageField = 'x-normalized'
23
23
  } = {}) => toolbox => {
24
24
  const {
25
- predicates,
26
- ancestorLineageToJSONPointer
25
+ predicates
27
26
  } = toolbox;
28
27
  let storage;
29
28
  return {
@@ -55,7 +54,7 @@ const plugin = ({
55
54
  if (typeof parameterElement.schema?.example === 'undefined' && typeof parameterElement.schema?.examples === 'undefined') {
56
55
  return;
57
56
  }
58
- const parameterJSONPointer = ancestorLineageToJSONPointer([...ancestors, parameterElement]);
57
+ const parameterJSONPointer = path.formatPath();
59
58
 
60
59
  // skip visiting this Parameter Object if it's already normalized
61
60
  if (storage.includes(parameterJSONPointer)) {
@@ -5,8 +5,10 @@ exports.__esModule = true;
5
5
  exports.default = void 0;
6
6
  var _ramda = require("ramda");
7
7
  var _apidomCore = require("@speclynx/apidom-core");
8
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
8
9
  var _apidomNsOpenapi = require("@speclynx/apidom-ns-openapi-3-0");
9
- var _NormalizeStorage = _interopRequireDefault(require("./normalize-header-examples/NormalizeStorage.cjs"));
10
+ var _index = _interopRequireDefault(require("./normalize-storage/index.cjs"));
11
+ var _predicates = require("../../predicates.cjs");
10
12
  /**
11
13
  * Inheritance of Parameter Objects.
12
14
  *
@@ -20,6 +22,38 @@ var _NormalizeStorage = _interopRequireDefault(require("./normalize-header-examp
20
22
  * @public
21
23
  */
22
24
 
25
+ /**
26
+ * Establishes identity between two Parameter Objects.
27
+ * A unique parameter is defined by a combination of a name and location.
28
+ *
29
+ * {@link https://spec.openapis.org/oas/v3.1.2.html#operation-parameters}
30
+ */
31
+ const parameterEquals = (parameter1, parameter2) => {
32
+ if (!(0, _predicates.isParameterElement)(parameter1)) return false;
33
+ if (!(0, _predicates.isParameterElement)(parameter2)) return false;
34
+ if (!(0, _apidomDatamodel.isStringElement)(parameter1.name)) return false;
35
+ if (!(0, _apidomDatamodel.isStringElement)(parameter1.in)) return false;
36
+ if (!(0, _apidomDatamodel.isStringElement)(parameter2.name)) return false;
37
+ if (!(0, _apidomDatamodel.isStringElement)(parameter2.in)) return false;
38
+ return (0, _apidomCore.toValue)(parameter1.name) === (0, _apidomCore.toValue)(parameter2.name) && (0, _apidomCore.toValue)(parameter1.in) === (0, _apidomCore.toValue)(parameter2.in);
39
+ };
40
+
41
+ /**
42
+ * Inherits parameters from a PathItem into an Operation element.
43
+ * Operation parameters take precedence; PathItem parameters are merged in
44
+ * for any (name, in) combination not already defined at the Operation level.
45
+ * @public
46
+ */
47
+ const inheritParametersToOperation = (operationElement, pathItemElement) => {
48
+ const pathItemParams = (0, _apidomDatamodel.isArrayElement)(pathItemElement.parameters) ? [...pathItemElement.parameters] : [];
49
+ if (pathItemParams.length === 0) return;
50
+ const operationParams = (0, _apidomDatamodel.isArrayElement)(operationElement.parameters) ? [...operationElement.parameters] : [];
51
+
52
+ // prefers the first item if two items compare equal based on the predicate
53
+ const mergedParameters = (0, _ramda.uniqWith)(parameterEquals, [...operationParams, ...pathItemParams]);
54
+ operationElement.parameters = new _apidomNsOpenapi.OperationParametersElement(mergedParameters);
55
+ };
56
+
23
57
  /**
24
58
  * @public
25
59
  */
@@ -27,83 +61,47 @@ const plugin = ({
27
61
  storageField = 'x-normalized'
28
62
  } = {}) => toolbox => {
29
63
  const {
30
- predicates,
31
- ancestorLineageToJSONPointer
64
+ predicates
32
65
  } = toolbox;
33
- /**
34
- * Establishes identity between two Parameter Objects.
35
- *
36
- * {@link https://spec.openapis.org/oas/v3.1.2.html#operation-parameters}
37
- */
38
- const parameterEquals = (parameter1, parameter2) => {
39
- if (!predicates.isParameterElement(parameter1)) return false;
40
- if (!predicates.isParameterElement(parameter2)) return false;
41
- if (!predicates.isStringElement(parameter1.name)) return false;
42
- if (!predicates.isStringElement(parameter1.in)) return false;
43
- if (!predicates.isStringElement(parameter2.name)) return false;
44
- if (!predicates.isStringElement(parameter2.in)) return false;
45
- return (0, _apidomCore.toValue)(parameter1.name) === (0, _apidomCore.toValue)(parameter2.name) && (0, _apidomCore.toValue)(parameter1.in) === (0, _apidomCore.toValue)(parameter2.in);
46
- };
47
- const pathItemParameters = [];
48
66
  let storage;
49
67
  return {
50
68
  visitor: {
51
69
  OpenApi3_1Element: {
52
70
  enter(path) {
53
71
  const element = path.node;
54
- storage = new _NormalizeStorage.default(element, storageField, 'parameters');
72
+ storage = new _index.default(element, storageField, 'parameters');
55
73
  },
56
74
  leave() {
57
75
  storage = undefined;
58
76
  }
59
77
  },
60
- PathItemElement: {
61
- enter(path) {
62
- const pathItemElement = path.node;
63
- const ancestors = path.getAncestorNodes().reverse(); // root to parent order
78
+ OperationElement: {
79
+ leave(path) {
80
+ const operationElement = path.node;
81
+ const ancestors = path.getAncestorNodes(); // parent to root order
64
82
 
65
- // skip visiting this Path Item
83
+ // skip visiting this Operation
66
84
  if (ancestors.some(predicates.isComponentsElement)) {
67
85
  return;
68
86
  }
69
- const {
70
- parameters
71
- } = pathItemElement;
72
- if (predicates.isArrayElement(parameters)) {
73
- pathItemParameters.push([...(parameters.content ?? [])]);
74
- } else {
75
- pathItemParameters.push([]);
76
- }
77
- },
78
- leave() {
79
- pathItemParameters.pop();
80
- }
81
- },
82
- OperationElement: {
83
- leave(path) {
84
- const operationElement = path.node;
85
- const ancestors = path.getAncestorNodes().reverse(); // root to parent order
86
- const parentPathItemParameters = (0, _ramda.last)(pathItemParameters);
87
+ const parentPathItemElement = ancestors.find(predicates.isPathItemElement);
87
88
 
88
- // no Path Item Object parameters to inherit from
89
- if (!Array.isArray(parentPathItemParameters) || parentPathItemParameters.length === 0) {
89
+ // no parent Path Item to inherit from
90
+ if (!predicates.isPathItemElement(parentPathItemElement)) {
90
91
  return;
91
92
  }
92
- const operationJSONPointer = ancestorLineageToJSONPointer([...ancestors, operationElement]);
93
+ const operationJSONPointer = path.formatPath();
93
94
 
94
95
  // skip visiting this Operation Object if it's already normalized
95
96
  if (storage.includes(operationJSONPointer)) {
96
97
  return;
97
98
  }
98
- const operationParameters = (0, _ramda.pathOr)([], ['parameters', 'content'], operationElement);
99
-
100
- // prefers the first item if two items compare equal based on the predicate
101
- const mergedParameters = (0, _ramda.uniqWith)(parameterEquals, [...operationParameters, ...parentPathItemParameters]);
102
- operationElement.parameters = new _apidomNsOpenapi.OperationParametersElement(mergedParameters);
99
+ inheritParametersToOperation(operationElement, parentPathItemElement);
103
100
  storage.append(operationJSONPointer);
104
101
  }
105
102
  }
106
103
  }
107
104
  };
108
105
  };
106
+ plugin.inheritParametersToOperation = inheritParametersToOperation;
109
107
  var _default = exports.default = plugin;
@@ -1,7 +1,9 @@
1
- import { uniqWith, pathOr, last } from 'ramda';
1
+ import { uniqWith } from 'ramda';
2
2
  import { toValue } from '@speclynx/apidom-core';
3
+ import { isStringElement, isArrayElement } from '@speclynx/apidom-datamodel';
3
4
  import { OperationParametersElement } from '@speclynx/apidom-ns-openapi-3-0';
4
- import NormalizeStorage from "./normalize-header-examples/NormalizeStorage.mjs";
5
+ import NormalizeStorage from "./normalize-storage/index.mjs";
6
+ import { isParameterElement } from "../../predicates.mjs";
5
7
  /**
6
8
  * Inheritance of Parameter Objects.
7
9
  *
@@ -14,6 +16,38 @@ import NormalizeStorage from "./normalize-header-examples/NormalizeStorage.mjs";
14
16
  * NOTE: this plugin is idempotent
15
17
  * @public
16
18
  */
19
+ /**
20
+ * Establishes identity between two Parameter Objects.
21
+ * A unique parameter is defined by a combination of a name and location.
22
+ *
23
+ * {@link https://spec.openapis.org/oas/v3.1.2.html#operation-parameters}
24
+ */
25
+ const parameterEquals = (parameter1, parameter2) => {
26
+ if (!isParameterElement(parameter1)) return false;
27
+ if (!isParameterElement(parameter2)) return false;
28
+ if (!isStringElement(parameter1.name)) return false;
29
+ if (!isStringElement(parameter1.in)) return false;
30
+ if (!isStringElement(parameter2.name)) return false;
31
+ if (!isStringElement(parameter2.in)) return false;
32
+ return toValue(parameter1.name) === toValue(parameter2.name) && toValue(parameter1.in) === toValue(parameter2.in);
33
+ };
34
+
35
+ /**
36
+ * Inherits parameters from a PathItem into an Operation element.
37
+ * Operation parameters take precedence; PathItem parameters are merged in
38
+ * for any (name, in) combination not already defined at the Operation level.
39
+ * @public
40
+ */
41
+ const inheritParametersToOperation = (operationElement, pathItemElement) => {
42
+ const pathItemParams = isArrayElement(pathItemElement.parameters) ? [...pathItemElement.parameters] : [];
43
+ if (pathItemParams.length === 0) return;
44
+ const operationParams = isArrayElement(operationElement.parameters) ? [...operationElement.parameters] : [];
45
+
46
+ // prefers the first item if two items compare equal based on the predicate
47
+ const mergedParameters = uniqWith(parameterEquals, [...operationParams, ...pathItemParams]);
48
+ operationElement.parameters = new OperationParametersElement(mergedParameters);
49
+ };
50
+
17
51
  /**
18
52
  * @public
19
53
  */
@@ -21,24 +55,8 @@ const plugin = ({
21
55
  storageField = 'x-normalized'
22
56
  } = {}) => toolbox => {
23
57
  const {
24
- predicates,
25
- ancestorLineageToJSONPointer
58
+ predicates
26
59
  } = toolbox;
27
- /**
28
- * Establishes identity between two Parameter Objects.
29
- *
30
- * {@link https://spec.openapis.org/oas/v3.1.2.html#operation-parameters}
31
- */
32
- const parameterEquals = (parameter1, parameter2) => {
33
- if (!predicates.isParameterElement(parameter1)) return false;
34
- if (!predicates.isParameterElement(parameter2)) return false;
35
- if (!predicates.isStringElement(parameter1.name)) return false;
36
- if (!predicates.isStringElement(parameter1.in)) return false;
37
- if (!predicates.isStringElement(parameter2.name)) return false;
38
- if (!predicates.isStringElement(parameter2.in)) return false;
39
- return toValue(parameter1.name) === toValue(parameter2.name) && toValue(parameter1.in) === toValue(parameter2.in);
40
- };
41
- const pathItemParameters = [];
42
60
  let storage;
43
61
  return {
44
62
  visitor: {
@@ -51,53 +69,33 @@ const plugin = ({
51
69
  storage = undefined;
52
70
  }
53
71
  },
54
- PathItemElement: {
55
- enter(path) {
56
- const pathItemElement = path.node;
57
- const ancestors = path.getAncestorNodes().reverse(); // root to parent order
72
+ OperationElement: {
73
+ leave(path) {
74
+ const operationElement = path.node;
75
+ const ancestors = path.getAncestorNodes(); // parent to root order
58
76
 
59
- // skip visiting this Path Item
77
+ // skip visiting this Operation
60
78
  if (ancestors.some(predicates.isComponentsElement)) {
61
79
  return;
62
80
  }
63
- const {
64
- parameters
65
- } = pathItemElement;
66
- if (predicates.isArrayElement(parameters)) {
67
- pathItemParameters.push([...(parameters.content ?? [])]);
68
- } else {
69
- pathItemParameters.push([]);
70
- }
71
- },
72
- leave() {
73
- pathItemParameters.pop();
74
- }
75
- },
76
- OperationElement: {
77
- leave(path) {
78
- const operationElement = path.node;
79
- const ancestors = path.getAncestorNodes().reverse(); // root to parent order
80
- const parentPathItemParameters = last(pathItemParameters);
81
+ const parentPathItemElement = ancestors.find(predicates.isPathItemElement);
81
82
 
82
- // no Path Item Object parameters to inherit from
83
- if (!Array.isArray(parentPathItemParameters) || parentPathItemParameters.length === 0) {
83
+ // no parent Path Item to inherit from
84
+ if (!predicates.isPathItemElement(parentPathItemElement)) {
84
85
  return;
85
86
  }
86
- const operationJSONPointer = ancestorLineageToJSONPointer([...ancestors, operationElement]);
87
+ const operationJSONPointer = path.formatPath();
87
88
 
88
89
  // skip visiting this Operation Object if it's already normalized
89
90
  if (storage.includes(operationJSONPointer)) {
90
91
  return;
91
92
  }
92
- const operationParameters = pathOr([], ['parameters', 'content'], operationElement);
93
-
94
- // prefers the first item if two items compare equal based on the predicate
95
- const mergedParameters = uniqWith(parameterEquals, [...operationParameters, ...parentPathItemParameters]);
96
- operationElement.parameters = new OperationParametersElement(mergedParameters);
93
+ inheritParametersToOperation(operationElement, parentPathItemElement);
97
94
  storage.append(operationJSONPointer);
98
95
  }
99
96
  }
100
97
  }
101
98
  };
102
99
  };
100
+ plugin.inheritParametersToOperation = inheritParametersToOperation;
103
101
  export default plugin;