@speclynx/apidom-ns-json-schema-draft-4 4.0.2 → 4.0.3

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 (125) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +6 -7
  3. package/src/elements/JSONReference.cjs +29 -0
  4. package/src/elements/JSONReference.mjs +25 -0
  5. package/src/elements/JSONReference.ts +33 -0
  6. package/src/elements/JSONSchema.cjs +296 -0
  7. package/src/elements/JSONSchema.mjs +292 -0
  8. package/src/elements/JSONSchema.ts +391 -0
  9. package/src/elements/LinkDescription.cjs +65 -0
  10. package/src/elements/LinkDescription.mjs +61 -0
  11. package/src/elements/LinkDescription.ts +85 -0
  12. package/src/elements/Media.cjs +29 -0
  13. package/src/elements/Media.mjs +25 -0
  14. package/src/elements/Media.ts +35 -0
  15. package/src/index.cjs +69 -0
  16. package/src/index.mjs +23 -0
  17. package/src/index.ts +142 -0
  18. package/src/media-types.cjs +34 -0
  19. package/src/media-types.mjs +30 -0
  20. package/src/media-types.ts +40 -0
  21. package/src/namespace.cjs +25 -0
  22. package/src/namespace.mjs +20 -0
  23. package/src/namespace.ts +24 -0
  24. package/src/predicates.cjs +32 -0
  25. package/src/predicates.mjs +23 -0
  26. package/src/predicates.ts +28 -0
  27. package/src/refractor/index.cjs +96 -0
  28. package/src/refractor/index.mjs +85 -0
  29. package/src/refractor/index.ts +110 -0
  30. package/src/refractor/inspect.cjs +55 -0
  31. package/src/refractor/inspect.mjs +47 -0
  32. package/src/refractor/inspect.ts +61 -0
  33. package/src/refractor/plugins/replace-empty-element.cjs +208 -0
  34. package/src/refractor/plugins/replace-empty-element.mjs +202 -0
  35. package/src/refractor/plugins/replace-empty-element.ts +233 -0
  36. package/src/refractor/predicates.cjs +16 -0
  37. package/src/refractor/predicates.mjs +12 -0
  38. package/src/refractor/predicates.ts +17 -0
  39. package/src/refractor/specification.cjs +193 -0
  40. package/src/refractor/specification.mjs +188 -0
  41. package/src/refractor/specification.ts +134 -0
  42. package/src/refractor/toolbox.cjs +28 -0
  43. package/src/refractor/toolbox.mjs +21 -0
  44. package/src/refractor/toolbox.ts +24 -0
  45. package/src/refractor/visitors/FallbackVisitor.cjs +25 -0
  46. package/src/refractor/visitors/FallbackVisitor.mjs +19 -0
  47. package/src/refractor/visitors/FallbackVisitor.ts +25 -0
  48. package/src/refractor/visitors/SpecificationVisitor.cjs +75 -0
  49. package/src/refractor/visitors/SpecificationVisitor.mjs +69 -0
  50. package/src/refractor/visitors/SpecificationVisitor.ts +82 -0
  51. package/src/refractor/visitors/Visitor.cjs +36 -0
  52. package/src/refractor/visitors/Visitor.mjs +33 -0
  53. package/src/refractor/visitors/Visitor.ts +49 -0
  54. package/src/refractor/visitors/generics/AlternatingVisitor.cjs +42 -0
  55. package/src/refractor/visitors/generics/AlternatingVisitor.mjs +35 -0
  56. package/src/refractor/visitors/generics/AlternatingVisitor.ts +45 -0
  57. package/src/refractor/visitors/generics/FixedFieldsVisitor.cjs +57 -0
  58. package/src/refractor/visitors/generics/FixedFieldsVisitor.mjs +50 -0
  59. package/src/refractor/visitors/generics/FixedFieldsVisitor.ts +79 -0
  60. package/src/refractor/visitors/generics/MapVisitor.cjs +21 -0
  61. package/src/refractor/visitors/generics/MapVisitor.mjs +15 -0
  62. package/src/refractor/visitors/generics/MapVisitor.ts +25 -0
  63. package/src/refractor/visitors/generics/PatternedFieldsVisitor.cjs +58 -0
  64. package/src/refractor/visitors/generics/PatternedFieldsVisitor.mjs +52 -0
  65. package/src/refractor/visitors/generics/PatternedFieldsVisitor.ts +76 -0
  66. package/src/refractor/visitors/json-schema/AllOfVisitor.cjs +32 -0
  67. package/src/refractor/visitors/json-schema/AllOfVisitor.mjs +27 -0
  68. package/src/refractor/visitors/json-schema/AllOfVisitor.ts +44 -0
  69. package/src/refractor/visitors/json-schema/AnyOfVisitor.cjs +32 -0
  70. package/src/refractor/visitors/json-schema/AnyOfVisitor.mjs +27 -0
  71. package/src/refractor/visitors/json-schema/AnyOfVisitor.ts +44 -0
  72. package/src/refractor/visitors/json-schema/DefinitionsVisitor.cjs +23 -0
  73. package/src/refractor/visitors/json-schema/DefinitionsVisitor.mjs +18 -0
  74. package/src/refractor/visitors/json-schema/DefinitionsVisitor.ts +36 -0
  75. package/src/refractor/visitors/json-schema/DependenciesVisitor.cjs +23 -0
  76. package/src/refractor/visitors/json-schema/DependenciesVisitor.mjs +18 -0
  77. package/src/refractor/visitors/json-schema/DependenciesVisitor.ts +36 -0
  78. package/src/refractor/visitors/json-schema/EnumVisitor.cjs +16 -0
  79. package/src/refractor/visitors/json-schema/EnumVisitor.mjs +11 -0
  80. package/src/refractor/visitors/json-schema/EnumVisitor.ts +20 -0
  81. package/src/refractor/visitors/json-schema/ItemsVisitor.cjs +35 -0
  82. package/src/refractor/visitors/json-schema/ItemsVisitor.mjs +30 -0
  83. package/src/refractor/visitors/json-schema/ItemsVisitor.ts +52 -0
  84. package/src/refractor/visitors/json-schema/JSONSchemaOrJSONReferenceVisitor.cjs +24 -0
  85. package/src/refractor/visitors/json-schema/JSONSchemaOrJSONReferenceVisitor.mjs +19 -0
  86. package/src/refractor/visitors/json-schema/JSONSchemaOrJSONReferenceVisitor.ts +21 -0
  87. package/src/refractor/visitors/json-schema/LinksVisitor.cjs +30 -0
  88. package/src/refractor/visitors/json-schema/LinksVisitor.mjs +25 -0
  89. package/src/refractor/visitors/json-schema/LinksVisitor.ts +43 -0
  90. package/src/refractor/visitors/json-schema/OneOfVisitor.cjs +32 -0
  91. package/src/refractor/visitors/json-schema/OneOfVisitor.mjs +27 -0
  92. package/src/refractor/visitors/json-schema/OneOfVisitor.ts +44 -0
  93. package/src/refractor/visitors/json-schema/ParentSchemaAwareVisitor.cjs +20 -0
  94. package/src/refractor/visitors/json-schema/ParentSchemaAwareVisitor.mjs +16 -0
  95. package/src/refractor/visitors/json-schema/ParentSchemaAwareVisitor.ts +21 -0
  96. package/src/refractor/visitors/json-schema/PatternPropertiesVisitor.cjs +23 -0
  97. package/src/refractor/visitors/json-schema/PatternPropertiesVisitor.mjs +18 -0
  98. package/src/refractor/visitors/json-schema/PatternPropertiesVisitor.ts +36 -0
  99. package/src/refractor/visitors/json-schema/PropertiesVisitor.cjs +23 -0
  100. package/src/refractor/visitors/json-schema/PropertiesVisitor.mjs +18 -0
  101. package/src/refractor/visitors/json-schema/PropertiesVisitor.ts +36 -0
  102. package/src/refractor/visitors/json-schema/RequiredVisitor.cjs +16 -0
  103. package/src/refractor/visitors/json-schema/RequiredVisitor.mjs +11 -0
  104. package/src/refractor/visitors/json-schema/RequiredVisitor.ts +20 -0
  105. package/src/refractor/visitors/json-schema/TypeVisitor.cjs +20 -0
  106. package/src/refractor/visitors/json-schema/TypeVisitor.mjs +15 -0
  107. package/src/refractor/visitors/json-schema/TypeVisitor.ts +25 -0
  108. package/src/refractor/visitors/json-schema/bases.cjs +45 -0
  109. package/src/refractor/visitors/json-schema/bases.mjs +39 -0
  110. package/src/refractor/visitors/json-schema/bases.ts +70 -0
  111. package/src/refractor/visitors/json-schema/index.cjs +65 -0
  112. package/src/refractor/visitors/json-schema/index.mjs +59 -0
  113. package/src/refractor/visitors/json-schema/index.ts +85 -0
  114. package/src/refractor/visitors/json-schema/json-reference/$RefVisitor.cjs +16 -0
  115. package/src/refractor/visitors/json-schema/json-reference/$RefVisitor.mjs +11 -0
  116. package/src/refractor/visitors/json-schema/json-reference/$RefVisitor.ts +20 -0
  117. package/src/refractor/visitors/json-schema/json-reference/index.cjs +33 -0
  118. package/src/refractor/visitors/json-schema/json-reference/index.mjs +27 -0
  119. package/src/refractor/visitors/json-schema/json-reference/index.ts +41 -0
  120. package/src/refractor/visitors/json-schema/link-description/index.cjs +23 -0
  121. package/src/refractor/visitors/json-schema/link-description/index.mjs +17 -0
  122. package/src/refractor/visitors/json-schema/link-description/index.ts +30 -0
  123. package/src/refractor/visitors/json-schema/media/index.cjs +23 -0
  124. package/src/refractor/visitors/json-schema/media/index.mjs +17 -0
  125. package/src/refractor/visitors/json-schema/media/index.ts +29 -0
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
7
+ var _apidomCore = require("@speclynx/apidom-core");
8
+ var _apidomTraverse = require("@speclynx/apidom-traverse");
9
+ var _JSONSchema = _interopRequireDefault(require("../../elements/JSONSchema.cjs"));
10
+ var _LinkDescription = _interopRequireDefault(require("../../elements/LinkDescription.cjs"));
11
+ var _Media = _interopRequireDefault(require("../../elements/Media.cjs"));
12
+ /**
13
+ * JSON Schema Draft 4 specification elements.
14
+ */
15
+
16
+ /**
17
+ * This plugin is specific to YAML 1.2 format, which allows defining key-value pairs
18
+ * with empty key, empty value, or both. If the value is not provided in YAML format,
19
+ * this plugin compensates for this missing value with the most appropriate semantic element type.
20
+ *
21
+ * https://yaml.org/spec/1.2.2/#72-empty-nodes
22
+ *
23
+ * @example
24
+ *
25
+ * ```yaml
26
+ * $schema: http://json-schema.org/draft-04/schema#
27
+ * items:
28
+ * ```
29
+ * Refracting result without this plugin:
30
+ *
31
+ * (JSONSchemaElement
32
+ * (MemberElement
33
+ * (StringElement)
34
+ * (StringElement))
35
+ * (MemberElement
36
+ * (StringElement)
37
+ * (StringElement))
38
+ *
39
+ * Refracting result with this plugin:
40
+ *
41
+ * (JSONSchemaElement
42
+ * (MemberElement
43
+ * (StringElement)
44
+ * (StringElement))
45
+ * (MemberElement
46
+ * (StringElement)
47
+ * (JSONSchemaElement))
48
+ */
49
+
50
+ const isEmptyElement = element => (0, _apidomDatamodel.isStringElement)(element) && (0, _apidomDatamodel.includesClasses)(element, ['yaml-e-node', 'yaml-e-scalar']);
51
+ const schema = {
52
+ JSONSchemaDraft4Element: {
53
+ additionalItems(...args) {
54
+ return new _JSONSchema.default(...args);
55
+ },
56
+ items(...args) {
57
+ return new _JSONSchema.default(...args);
58
+ },
59
+ required(...args) {
60
+ const element = new _apidomDatamodel.ArrayElement(...args);
61
+ element.classes.push('json-schema-required');
62
+ return element;
63
+ },
64
+ properties(...args) {
65
+ const element = new _apidomDatamodel.ObjectElement(...args);
66
+ element.classes.push('json-schema-properties');
67
+ return element;
68
+ },
69
+ additionalProperties(...args) {
70
+ return new _JSONSchema.default(...args);
71
+ },
72
+ patternProperties(...args) {
73
+ const element = new _apidomDatamodel.ObjectElement(...args);
74
+ element.classes.push('json-schema-patternProperties');
75
+ return element;
76
+ },
77
+ dependencies(...args) {
78
+ const element = new _apidomDatamodel.ObjectElement(...args);
79
+ element.classes.push('json-schema-dependencies');
80
+ return element;
81
+ },
82
+ enum(...args) {
83
+ const element = new _apidomDatamodel.ArrayElement(...args);
84
+ element.classes.push('json-schema-enum');
85
+ return element;
86
+ },
87
+ allOf(...args) {
88
+ const element = new _apidomDatamodel.ArrayElement(...args);
89
+ element.classes.push('json-schema-allOf');
90
+ return element;
91
+ },
92
+ anyOf(...args) {
93
+ const element = new _apidomDatamodel.ArrayElement(...args);
94
+ element.classes.push('json-schema-anyOf');
95
+ return element;
96
+ },
97
+ oneOf(...args) {
98
+ const element = new _apidomDatamodel.ArrayElement(...args);
99
+ element.classes.push('json-schema-oneOf');
100
+ return element;
101
+ },
102
+ not(...args) {
103
+ return new _JSONSchema.default(...args);
104
+ },
105
+ definitions(...args) {
106
+ const element = new _apidomDatamodel.ObjectElement(...args);
107
+ element.classes.push('json-schema-definitions');
108
+ return element;
109
+ },
110
+ links(...args) {
111
+ const element = new _apidomDatamodel.ArrayElement(...args);
112
+ element.classes.push('json-schema-links');
113
+ return element;
114
+ },
115
+ media(...args) {
116
+ return new _Media.default(...args);
117
+ }
118
+ },
119
+ LinkDescriptionElement: {
120
+ targetSchema(...args) {
121
+ return new _JSONSchema.default(...args);
122
+ },
123
+ schema(...args) {
124
+ return new _JSONSchema.default(...args);
125
+ }
126
+ },
127
+ 'json-schema-properties': {
128
+ '[key: *]': function key(...args) {
129
+ return new _JSONSchema.default(...args);
130
+ }
131
+ },
132
+ 'json-schema-patternProperties': {
133
+ '[key: *]': function key(...args) {
134
+ return new _JSONSchema.default(...args);
135
+ }
136
+ },
137
+ 'json-schema-dependencies': {
138
+ '[key: *]': function key(...args) {
139
+ return new _JSONSchema.default(...args);
140
+ }
141
+ },
142
+ 'json-schema-allOf': {
143
+ '<*>': function asterisk(...args) {
144
+ return new _JSONSchema.default(...args);
145
+ }
146
+ },
147
+ 'json-schema-anyOf': {
148
+ '<*>': function asterisk(...args) {
149
+ return new _JSONSchema.default(...args);
150
+ }
151
+ },
152
+ 'json-schema-oneOf': {
153
+ '<*>': function asterisk(...args) {
154
+ return new _JSONSchema.default(...args);
155
+ }
156
+ },
157
+ 'json-schema-definitions': {
158
+ '[key: *]': function key(...args) {
159
+ return new _JSONSchema.default(...args);
160
+ }
161
+ },
162
+ 'json-schema-links': {
163
+ '<*>': function asterisk(...args) {
164
+ return new _LinkDescription.default(...args);
165
+ }
166
+ }
167
+ };
168
+ const findElementFactory = (ancestor, keyName) => {
169
+ const elementType = (0, _apidomTraverse.getNodeType)(ancestor);
170
+ const classType = ancestor.isMetaEmpty ? undefined : ancestor.classes.at(0); // @ts-ignore
171
+ const keyMapping = schema[elementType] || schema[classType];
172
+ return typeof keyMapping === 'undefined' ? undefined : Object.hasOwn(keyMapping, '[key: *]') ? keyMapping['[key: *]'] : keyMapping[keyName];
173
+ };
174
+
175
+ /**
176
+ * @public
177
+ */
178
+ const plugin = () => () => ({
179
+ visitor: {
180
+ StringElement(path) {
181
+ const element = path.node;
182
+ if (!isEmptyElement(element)) return;
183
+
184
+ // getAncestorNodes() returns [parent, grandparent, ..., root], so reverse to get [root, ..., parent]
185
+ const lineage = path.getAncestorNodes().reverse().filter(_apidomDatamodel.isElement);
186
+ const parentElement = lineage.at(-1);
187
+ let elementFactory;
188
+ let context;
189
+ if ((0, _apidomDatamodel.isArrayElement)(parentElement)) {
190
+ context = element;
191
+ elementFactory = findElementFactory(parentElement, '<*>');
192
+ } else if ((0, _apidomDatamodel.isMemberElement)(parentElement)) {
193
+ context = lineage.at(-2);
194
+ elementFactory = findElementFactory(context, (0, _apidomCore.toValue)(parentElement.key));
195
+ }
196
+
197
+ // no element factory found
198
+ if (typeof elementFactory !== 'function') return;
199
+ const replacement = elementFactory.call({
200
+ context
201
+ }, undefined, element.isMetaEmpty ? undefined : element.meta.cloneDeep(), element.isAttributesEmpty ? undefined : (0, _apidomDatamodel.cloneDeep)(element.attributes));
202
+ _apidomDatamodel.SourceMapElement.transfer(element, replacement);
203
+ _apidomDatamodel.StyleElement.transfer(element, replacement);
204
+ path.replaceWith(replacement);
205
+ }
206
+ }
207
+ });
208
+ var _default = exports.default = plugin;
@@ -0,0 +1,202 @@
1
+ import { ArrayElement, ObjectElement, isArrayElement, isElement, isMemberElement, isStringElement, includesClasses, cloneDeep, SourceMapElement, StyleElement } from '@speclynx/apidom-datamodel';
2
+ import { toValue } from '@speclynx/apidom-core';
3
+ import { getNodeType } from '@speclynx/apidom-traverse';
4
+
5
+ /**
6
+ * JSON Schema Draft 4 specification elements.
7
+ */
8
+ import JSONSchemaElement from "../../elements/JSONSchema.mjs";
9
+ import LinkDescriptionElement from "../../elements/LinkDescription.mjs";
10
+ import MediaElement from "../../elements/Media.mjs";
11
+ /**
12
+ * This plugin is specific to YAML 1.2 format, which allows defining key-value pairs
13
+ * with empty key, empty value, or both. If the value is not provided in YAML format,
14
+ * this plugin compensates for this missing value with the most appropriate semantic element type.
15
+ *
16
+ * https://yaml.org/spec/1.2.2/#72-empty-nodes
17
+ *
18
+ * @example
19
+ *
20
+ * ```yaml
21
+ * $schema: http://json-schema.org/draft-04/schema#
22
+ * items:
23
+ * ```
24
+ * Refracting result without this plugin:
25
+ *
26
+ * (JSONSchemaElement
27
+ * (MemberElement
28
+ * (StringElement)
29
+ * (StringElement))
30
+ * (MemberElement
31
+ * (StringElement)
32
+ * (StringElement))
33
+ *
34
+ * Refracting result with this plugin:
35
+ *
36
+ * (JSONSchemaElement
37
+ * (MemberElement
38
+ * (StringElement)
39
+ * (StringElement))
40
+ * (MemberElement
41
+ * (StringElement)
42
+ * (JSONSchemaElement))
43
+ */
44
+ const isEmptyElement = element => isStringElement(element) && includesClasses(element, ['yaml-e-node', 'yaml-e-scalar']);
45
+ const schema = {
46
+ JSONSchemaDraft4Element: {
47
+ additionalItems(...args) {
48
+ return new JSONSchemaElement(...args);
49
+ },
50
+ items(...args) {
51
+ return new JSONSchemaElement(...args);
52
+ },
53
+ required(...args) {
54
+ const element = new ArrayElement(...args);
55
+ element.classes.push('json-schema-required');
56
+ return element;
57
+ },
58
+ properties(...args) {
59
+ const element = new ObjectElement(...args);
60
+ element.classes.push('json-schema-properties');
61
+ return element;
62
+ },
63
+ additionalProperties(...args) {
64
+ return new JSONSchemaElement(...args);
65
+ },
66
+ patternProperties(...args) {
67
+ const element = new ObjectElement(...args);
68
+ element.classes.push('json-schema-patternProperties');
69
+ return element;
70
+ },
71
+ dependencies(...args) {
72
+ const element = new ObjectElement(...args);
73
+ element.classes.push('json-schema-dependencies');
74
+ return element;
75
+ },
76
+ enum(...args) {
77
+ const element = new ArrayElement(...args);
78
+ element.classes.push('json-schema-enum');
79
+ return element;
80
+ },
81
+ allOf(...args) {
82
+ const element = new ArrayElement(...args);
83
+ element.classes.push('json-schema-allOf');
84
+ return element;
85
+ },
86
+ anyOf(...args) {
87
+ const element = new ArrayElement(...args);
88
+ element.classes.push('json-schema-anyOf');
89
+ return element;
90
+ },
91
+ oneOf(...args) {
92
+ const element = new ArrayElement(...args);
93
+ element.classes.push('json-schema-oneOf');
94
+ return element;
95
+ },
96
+ not(...args) {
97
+ return new JSONSchemaElement(...args);
98
+ },
99
+ definitions(...args) {
100
+ const element = new ObjectElement(...args);
101
+ element.classes.push('json-schema-definitions');
102
+ return element;
103
+ },
104
+ links(...args) {
105
+ const element = new ArrayElement(...args);
106
+ element.classes.push('json-schema-links');
107
+ return element;
108
+ },
109
+ media(...args) {
110
+ return new MediaElement(...args);
111
+ }
112
+ },
113
+ LinkDescriptionElement: {
114
+ targetSchema(...args) {
115
+ return new JSONSchemaElement(...args);
116
+ },
117
+ schema(...args) {
118
+ return new JSONSchemaElement(...args);
119
+ }
120
+ },
121
+ 'json-schema-properties': {
122
+ '[key: *]': function key(...args) {
123
+ return new JSONSchemaElement(...args);
124
+ }
125
+ },
126
+ 'json-schema-patternProperties': {
127
+ '[key: *]': function key(...args) {
128
+ return new JSONSchemaElement(...args);
129
+ }
130
+ },
131
+ 'json-schema-dependencies': {
132
+ '[key: *]': function key(...args) {
133
+ return new JSONSchemaElement(...args);
134
+ }
135
+ },
136
+ 'json-schema-allOf': {
137
+ '<*>': function asterisk(...args) {
138
+ return new JSONSchemaElement(...args);
139
+ }
140
+ },
141
+ 'json-schema-anyOf': {
142
+ '<*>': function asterisk(...args) {
143
+ return new JSONSchemaElement(...args);
144
+ }
145
+ },
146
+ 'json-schema-oneOf': {
147
+ '<*>': function asterisk(...args) {
148
+ return new JSONSchemaElement(...args);
149
+ }
150
+ },
151
+ 'json-schema-definitions': {
152
+ '[key: *]': function key(...args) {
153
+ return new JSONSchemaElement(...args);
154
+ }
155
+ },
156
+ 'json-schema-links': {
157
+ '<*>': function asterisk(...args) {
158
+ return new LinkDescriptionElement(...args);
159
+ }
160
+ }
161
+ };
162
+ const findElementFactory = (ancestor, keyName) => {
163
+ const elementType = getNodeType(ancestor);
164
+ const classType = ancestor.isMetaEmpty ? undefined : ancestor.classes.at(0); // @ts-ignore
165
+ const keyMapping = schema[elementType] || schema[classType];
166
+ return typeof keyMapping === 'undefined' ? undefined : Object.hasOwn(keyMapping, '[key: *]') ? keyMapping['[key: *]'] : keyMapping[keyName];
167
+ };
168
+
169
+ /**
170
+ * @public
171
+ */
172
+ const plugin = () => () => ({
173
+ visitor: {
174
+ StringElement(path) {
175
+ const element = path.node;
176
+ if (!isEmptyElement(element)) return;
177
+
178
+ // getAncestorNodes() returns [parent, grandparent, ..., root], so reverse to get [root, ..., parent]
179
+ const lineage = path.getAncestorNodes().reverse().filter(isElement);
180
+ const parentElement = lineage.at(-1);
181
+ let elementFactory;
182
+ let context;
183
+ if (isArrayElement(parentElement)) {
184
+ context = element;
185
+ elementFactory = findElementFactory(parentElement, '<*>');
186
+ } else if (isMemberElement(parentElement)) {
187
+ context = lineage.at(-2);
188
+ elementFactory = findElementFactory(context, toValue(parentElement.key));
189
+ }
190
+
191
+ // no element factory found
192
+ if (typeof elementFactory !== 'function') return;
193
+ const replacement = elementFactory.call({
194
+ context
195
+ }, undefined, element.isMetaEmpty ? undefined : element.meta.cloneDeep(), element.isAttributesEmpty ? undefined : cloneDeep(element.attributes));
196
+ SourceMapElement.transfer(element, replacement);
197
+ StyleElement.transfer(element, replacement);
198
+ path.replaceWith(replacement);
199
+ }
200
+ }
201
+ });
202
+ export default plugin;
@@ -0,0 +1,233 @@
1
+ import {
2
+ ArrayElement,
3
+ ObjectElement,
4
+ StringElement,
5
+ isArrayElement,
6
+ isElement,
7
+ isMemberElement,
8
+ isStringElement,
9
+ includesClasses,
10
+ cloneDeep,
11
+ SourceMapElement,
12
+ StyleElement,
13
+ } from '@speclynx/apidom-datamodel';
14
+ import { toValue } from '@speclynx/apidom-core';
15
+ import { Path, getNodeType } from '@speclynx/apidom-traverse';
16
+
17
+ /**
18
+ * JSON Schema Draft 4 specification elements.
19
+ */
20
+ import JSONSchemaElement from '../../elements/JSONSchema.ts';
21
+ import LinkDescriptionElement from '../../elements/LinkDescription.ts';
22
+ import MediaElement from '../../elements/Media.ts';
23
+
24
+ /**
25
+ * This plugin is specific to YAML 1.2 format, which allows defining key-value pairs
26
+ * with empty key, empty value, or both. If the value is not provided in YAML format,
27
+ * this plugin compensates for this missing value with the most appropriate semantic element type.
28
+ *
29
+ * https://yaml.org/spec/1.2.2/#72-empty-nodes
30
+ *
31
+ * @example
32
+ *
33
+ * ```yaml
34
+ * $schema: http://json-schema.org/draft-04/schema#
35
+ * items:
36
+ * ```
37
+ * Refracting result without this plugin:
38
+ *
39
+ * (JSONSchemaElement
40
+ * (MemberElement
41
+ * (StringElement)
42
+ * (StringElement))
43
+ * (MemberElement
44
+ * (StringElement)
45
+ * (StringElement))
46
+ *
47
+ * Refracting result with this plugin:
48
+ *
49
+ * (JSONSchemaElement
50
+ * (MemberElement
51
+ * (StringElement)
52
+ * (StringElement))
53
+ * (MemberElement
54
+ * (StringElement)
55
+ * (JSONSchemaElement))
56
+ */
57
+
58
+ const isEmptyElement = (element: any) =>
59
+ isStringElement(element) && includesClasses(element, ['yaml-e-node', 'yaml-e-scalar']);
60
+
61
+ const schema = {
62
+ JSONSchemaDraft4Element: {
63
+ additionalItems(...args: any[]) {
64
+ return new JSONSchemaElement(...args);
65
+ },
66
+ items(...args: any[]) {
67
+ return new JSONSchemaElement(...args);
68
+ },
69
+ required(...args: any[]) {
70
+ const element = new ArrayElement(...args);
71
+ element.classes.push('json-schema-required');
72
+ return element;
73
+ },
74
+ properties(...args: any[]) {
75
+ const element = new ObjectElement(...args);
76
+ element.classes.push('json-schema-properties');
77
+ return element;
78
+ },
79
+ additionalProperties(...args: any[]) {
80
+ return new JSONSchemaElement(...args);
81
+ },
82
+ patternProperties(...args: any[]) {
83
+ const element = new ObjectElement(...args);
84
+ element.classes.push('json-schema-patternProperties');
85
+ return element;
86
+ },
87
+ dependencies(...args: any[]) {
88
+ const element = new ObjectElement(...args);
89
+ element.classes.push('json-schema-dependencies');
90
+ return element;
91
+ },
92
+ enum(...args: any[]) {
93
+ const element = new ArrayElement(...args);
94
+ element.classes.push('json-schema-enum');
95
+ return element;
96
+ },
97
+ allOf(...args: any[]) {
98
+ const element = new ArrayElement(...args);
99
+ element.classes.push('json-schema-allOf');
100
+ return element;
101
+ },
102
+ anyOf(...args: any[]) {
103
+ const element = new ArrayElement(...args);
104
+ element.classes.push('json-schema-anyOf');
105
+ return element;
106
+ },
107
+ oneOf(...args: any[]) {
108
+ const element = new ArrayElement(...args);
109
+ element.classes.push('json-schema-oneOf');
110
+ return element;
111
+ },
112
+ not(...args: any[]) {
113
+ return new JSONSchemaElement(...args);
114
+ },
115
+ definitions(...args: any[]) {
116
+ const element = new ObjectElement(...args);
117
+ element.classes.push('json-schema-definitions');
118
+ return element;
119
+ },
120
+ links(...args: any[]) {
121
+ const element = new ArrayElement(...args);
122
+ element.classes.push('json-schema-links');
123
+ return element;
124
+ },
125
+ media(...args: any[]) {
126
+ return new MediaElement(...args);
127
+ },
128
+ },
129
+ LinkDescriptionElement: {
130
+ targetSchema(...args: any[]) {
131
+ return new JSONSchemaElement(...args);
132
+ },
133
+ schema(...args: any[]) {
134
+ return new JSONSchemaElement(...args);
135
+ },
136
+ },
137
+ 'json-schema-properties': {
138
+ '[key: *]': function key(...args: any[]) {
139
+ return new JSONSchemaElement(...args);
140
+ },
141
+ },
142
+ 'json-schema-patternProperties': {
143
+ '[key: *]': function key(...args: any[]) {
144
+ return new JSONSchemaElement(...args);
145
+ },
146
+ },
147
+ 'json-schema-dependencies': {
148
+ '[key: *]': function key(...args: any[]) {
149
+ return new JSONSchemaElement(...args);
150
+ },
151
+ },
152
+ 'json-schema-allOf': {
153
+ '<*>': function asterisk(...args: any[]) {
154
+ return new JSONSchemaElement(...args);
155
+ },
156
+ },
157
+ 'json-schema-anyOf': {
158
+ '<*>': function asterisk(...args: any[]) {
159
+ return new JSONSchemaElement(...args);
160
+ },
161
+ },
162
+ 'json-schema-oneOf': {
163
+ '<*>': function asterisk(...args: any[]) {
164
+ return new JSONSchemaElement(...args);
165
+ },
166
+ },
167
+ 'json-schema-definitions': {
168
+ '[key: *]': function key(...args: any[]) {
169
+ return new JSONSchemaElement(...args);
170
+ },
171
+ },
172
+ 'json-schema-links': {
173
+ '<*>': function asterisk(...args: any[]) {
174
+ return new LinkDescriptionElement(...args);
175
+ },
176
+ },
177
+ };
178
+
179
+ const findElementFactory = (ancestor: any, keyName: string) => {
180
+ const elementType = getNodeType(ancestor);
181
+ const classType = ancestor.isMetaEmpty ? undefined : ancestor.classes.at(0); // @ts-ignore
182
+ const keyMapping = schema[elementType] || schema[classType];
183
+
184
+ return typeof keyMapping === 'undefined'
185
+ ? undefined
186
+ : Object.hasOwn(keyMapping, '[key: *]')
187
+ ? keyMapping['[key: *]']
188
+ : keyMapping[keyName];
189
+ };
190
+
191
+ /**
192
+ * @public
193
+ */
194
+ const plugin = () => () => ({
195
+ visitor: {
196
+ StringElement(path: Path<StringElement>) {
197
+ const element = path.node;
198
+
199
+ if (!isEmptyElement(element)) return;
200
+
201
+ // getAncestorNodes() returns [parent, grandparent, ..., root], so reverse to get [root, ..., parent]
202
+ const lineage = path.getAncestorNodes().reverse().filter(isElement);
203
+ const parentElement = lineage.at(-1);
204
+ let elementFactory;
205
+ let context;
206
+
207
+ if (isArrayElement(parentElement)) {
208
+ context = element;
209
+ elementFactory = findElementFactory(parentElement, '<*>');
210
+ } else if (isMemberElement(parentElement)) {
211
+ context = lineage.at(-2);
212
+ elementFactory = findElementFactory(context, toValue(parentElement.key) as string);
213
+ }
214
+
215
+ // no element factory found
216
+ if (typeof elementFactory !== 'function') return;
217
+
218
+ const replacement = elementFactory.call(
219
+ { context },
220
+ undefined,
221
+ element.isMetaEmpty ? undefined : element.meta.cloneDeep(),
222
+ element.isAttributesEmpty ? undefined : cloneDeep(element.attributes),
223
+ );
224
+
225
+ SourceMapElement.transfer(element, replacement);
226
+ StyleElement.transfer(element, replacement);
227
+
228
+ path.replaceWith(replacement);
229
+ },
230
+ },
231
+ });
232
+
233
+ export default plugin;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.isJSONReferenceLikeElement = void 0;
5
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
6
+ /**
7
+ * @public
8
+ */
9
+
10
+ /**
11
+ * @public
12
+ */
13
+ const isJSONReferenceLikeElement = element => {
14
+ return (0, _apidomDatamodel.isObjectElement)(element) && element.hasKey('$ref');
15
+ };
16
+ exports.isJSONReferenceLikeElement = isJSONReferenceLikeElement;
@@ -0,0 +1,12 @@
1
+ import { isObjectElement } from '@speclynx/apidom-datamodel';
2
+
3
+ /**
4
+ * @public
5
+ */
6
+
7
+ /**
8
+ * @public
9
+ */
10
+ export const isJSONReferenceLikeElement = element => {
11
+ return isObjectElement(element) && element.hasKey('$ref');
12
+ };
@@ -0,0 +1,17 @@
1
+ import { isObjectElement, ObjectElement } from '@speclynx/apidom-datamodel';
2
+
3
+ /**
4
+ * @public
5
+ */
6
+ export interface JSONReferenceLikeElement extends ObjectElement {
7
+ hasKey: (value: '$ref') => true;
8
+ }
9
+
10
+ /**
11
+ * @public
12
+ */
13
+ export const isJSONReferenceLikeElement = (
14
+ element: unknown,
15
+ ): element is JSONReferenceLikeElement => {
16
+ return isObjectElement(element) && element.hasKey('$ref');
17
+ };