@speclynx/apidom-parser-adapter-yaml-1-2 1.12.1 → 2.0.1
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 +24 -0
- package/NOTICE +16 -7
- package/README.md +34 -7
- package/dist/167.apidom-parser-adapter-yaml-1-2.browser.min.js +1 -1
- package/dist/451.apidom-parser-adapter-yaml-1-2.browser.min.js +1 -1
- package/dist/apidom-parser-adapter-yaml-1-2.browser.js +19340 -16731
- package/dist/apidom-parser-adapter-yaml-1-2.browser.min.js +1 -1
- package/package.json +10 -9
- package/src/adapter.cjs +28 -16
- package/src/adapter.mjs +25 -15
- package/src/tree-sitter/index.cjs +44 -0
- package/src/tree-sitter/index.mjs +38 -0
- package/src/{lexical-analysis → tree-sitter/lexical-analysis}/index.cjs +1 -1
- package/src/{lexical-analysis → tree-sitter/lexical-analysis}/index.mjs +1 -1
- package/src/tree-sitter/syntactic-analysis/CstTransformer.cjs +625 -0
- package/src/tree-sitter/syntactic-analysis/CstTransformer.mjs +618 -0
- package/src/tree-sitter/syntactic-analysis/YamlAstTransformer.cjs +271 -0
- package/src/tree-sitter/syntactic-analysis/YamlAstTransformer.mjs +263 -0
- package/src/tree-sitter/syntactic-analysis/ast/Error.cjs +30 -0
- package/src/tree-sitter/syntactic-analysis/ast/Error.mjs +24 -0
- package/src/tree-sitter/syntactic-analysis/ast/Literal.cjs +27 -0
- package/src/tree-sitter/syntactic-analysis/ast/Literal.mjs +21 -0
- package/src/tree-sitter/syntactic-analysis/ast/Node.cjs +60 -0
- package/src/tree-sitter/syntactic-analysis/ast/Node.mjs +56 -0
- package/src/tree-sitter/syntactic-analysis/ast/ParseResult.cjs +17 -0
- package/src/tree-sitter/syntactic-analysis/ast/ParseResult.mjs +12 -0
- package/src/tree-sitter/syntactic-analysis/ast/anchors-aliases/ReferenceManager.cjs +23 -0
- package/src/tree-sitter/syntactic-analysis/ast/anchors-aliases/ReferenceManager.mjs +18 -0
- package/src/tree-sitter/syntactic-analysis/ast/errors/YamlError.cjs +10 -0
- package/src/tree-sitter/syntactic-analysis/ast/errors/YamlError.mjs +7 -0
- package/src/tree-sitter/syntactic-analysis/ast/errors/YamlSchemaError.cjs +11 -0
- package/src/tree-sitter/syntactic-analysis/ast/errors/YamlSchemaError.mjs +6 -0
- package/src/tree-sitter/syntactic-analysis/ast/errors/YamlTagError.cjs +43 -0
- package/src/tree-sitter/syntactic-analysis/ast/errors/YamlTagError.mjs +37 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlAlias.cjs +27 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlAlias.mjs +21 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlAnchor.cjs +27 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlAnchor.mjs +21 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlCollection.cjs +11 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlCollection.mjs +6 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlComment.cjs +27 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlComment.mjs +21 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlDirective.cjs +39 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlDirective.mjs +32 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlDocument.cjs +13 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlDocument.mjs +8 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlKeyValuePair.cjs +48 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlKeyValuePair.mjs +42 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlMapping.cjs +20 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlMapping.mjs +15 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlNode.cjs +35 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlNode.mjs +29 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlScalar.cjs +27 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlScalar.mjs +21 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlSequence.cjs +23 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlSequence.mjs +18 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlStream.cjs +20 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlStream.mjs +15 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlStyle.cjs +27 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlStyle.mjs +24 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlTag.cjs +38 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/YamlTag.mjs +35 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/predicates.cjs +26 -0
- package/src/tree-sitter/syntactic-analysis/ast/nodes/predicates.mjs +14 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/ScalarTag.cjs +33 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/ScalarTag.mjs +29 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/Tag.cjs +20 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/Tag.mjs +16 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/canonical-format.cjs +127 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/canonical-format.mjs +122 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/failsafe/GenericMapping.cjs +14 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/failsafe/GenericMapping.mjs +9 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/failsafe/GenericSequence.cjs +14 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/failsafe/GenericSequence.mjs +9 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/failsafe/GenericString.cjs +10 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/failsafe/GenericString.mjs +5 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/failsafe/index.cjs +116 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/failsafe/index.mjs +111 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/Boolean.cjs +19 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/Boolean.mjs +14 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/FloatingPoint.cjs +19 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/FloatingPoint.mjs +14 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/Integer.cjs +19 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/Integer.mjs +14 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/Null.cjs +18 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/Null.mjs +13 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/index.cjs +43 -0
- package/src/tree-sitter/syntactic-analysis/ast/schemas/json/index.mjs +38 -0
- package/src/tree-sitter/syntactic-analysis/index.cjs +39 -0
- package/src/tree-sitter/syntactic-analysis/index.mjs +33 -0
- package/src/yaml/index.cjs +31 -0
- package/src/yaml/index.mjs +26 -0
- package/types/apidom-parser-adapter-yaml-1-2.d.ts +11 -3
- package/src/syntactic-analysis/TreeCursorIterator.cjs +0 -93
- package/src/syntactic-analysis/TreeCursorIterator.mjs +0 -88
- package/src/syntactic-analysis/TreeCursorSyntaxNode.cjs +0 -80
- package/src/syntactic-analysis/TreeCursorSyntaxNode.mjs +0 -76
- package/src/syntactic-analysis/indirect/index.cjs +0 -51
- package/src/syntactic-analysis/indirect/index.mjs +0 -44
- package/src/syntactic-analysis/indirect/visitors/CstVisitor.cjs +0 -553
- package/src/syntactic-analysis/indirect/visitors/CstVisitor.mjs +0 -547
- package/src/syntactic-analysis/indirect/visitors/YamlAstVisitor.cjs +0 -164
- package/src/syntactic-analysis/indirect/visitors/YamlAstVisitor.mjs +0 -158
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.transformYamlAstToApiDOM = exports.default = void 0;
|
|
5
|
+
var _apidomDatamodel = require("@speclynx/apidom-datamodel");
|
|
6
|
+
var _YamlStyle = require("./ast/nodes/YamlStyle.cjs");
|
|
7
|
+
// Transform context passed through transformation
|
|
8
|
+
|
|
9
|
+
// Node with type property and flat position properties
|
|
10
|
+
|
|
11
|
+
// Helper to add source map to element
|
|
12
|
+
const maybeAddSourceMap = (node, element, ctx) => {
|
|
13
|
+
if (!ctx.sourceMap) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
_apidomDatamodel.SourceMapElement.transfer(node, element);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Transform a single node based on its type
|
|
20
|
+
const transform = (node, ctx) => {
|
|
21
|
+
if (node === null || node === undefined) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const typedNode = node;
|
|
25
|
+
const nodeType = typedNode.type;
|
|
26
|
+
switch (nodeType) {
|
|
27
|
+
case 'stream':
|
|
28
|
+
return transformStream(typedNode, ctx);
|
|
29
|
+
case 'document':
|
|
30
|
+
return transformDocument(typedNode, ctx);
|
|
31
|
+
case 'mapping':
|
|
32
|
+
return transformMapping(typedNode, ctx);
|
|
33
|
+
case 'keyValuePair':
|
|
34
|
+
return transformKeyValuePair(typedNode, ctx);
|
|
35
|
+
case 'sequence':
|
|
36
|
+
return transformSequence(typedNode, ctx);
|
|
37
|
+
case 'scalar':
|
|
38
|
+
return transformScalar(typedNode, ctx);
|
|
39
|
+
case 'comment':
|
|
40
|
+
return transformComment(typedNode, ctx);
|
|
41
|
+
case 'literal':
|
|
42
|
+
return transformLiteral(typedNode, ctx);
|
|
43
|
+
case 'error':
|
|
44
|
+
return transformError(typedNode, ctx);
|
|
45
|
+
default:
|
|
46
|
+
// Unknown node type - skip
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Transform children array and flatten results
|
|
52
|
+
const transformChildren = (children, ctx) => {
|
|
53
|
+
const results = [];
|
|
54
|
+
for (const child of children) {
|
|
55
|
+
const result = transform(child, ctx);
|
|
56
|
+
if (result === null) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (Array.isArray(result)) {
|
|
60
|
+
results.push(...result);
|
|
61
|
+
} else {
|
|
62
|
+
results.push(result);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return results;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Stream: Wraps transformed children in ParseResultElement
|
|
69
|
+
const transformStream = (node, ctx) => {
|
|
70
|
+
const element = new _apidomDatamodel.ParseResultElement();
|
|
71
|
+
|
|
72
|
+
// Transform all children
|
|
73
|
+
const children = transformChildren(node.children || [], ctx);
|
|
74
|
+
|
|
75
|
+
// Flatten and set content
|
|
76
|
+
// @ts-ignore
|
|
77
|
+
element._content = children.flat(1);
|
|
78
|
+
|
|
79
|
+
// Mark first primitive element as result
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
const elements = element.findElements(_apidomDatamodel.isPrimitiveElement);
|
|
82
|
+
if (elements.length > 0) {
|
|
83
|
+
const resultElement = elements[0];
|
|
84
|
+
resultElement.classes.push('result');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Add collected annotations
|
|
88
|
+
ctx.annotations.forEach(annotationElement => {
|
|
89
|
+
element.push(annotationElement);
|
|
90
|
+
});
|
|
91
|
+
ctx.annotations = [];
|
|
92
|
+
return element;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Document: Returns transformed children for first doc, warns for subsequent docs
|
|
96
|
+
const transformDocument = (node, ctx) => {
|
|
97
|
+
const shouldWarnAboutMoreDocuments = ctx.processedDocumentCount === 1;
|
|
98
|
+
const shouldSkipVisitingMoreDocuments = ctx.processedDocumentCount >= 1;
|
|
99
|
+
if (shouldWarnAboutMoreDocuments) {
|
|
100
|
+
const message = 'Only first document within YAML stream will be used. Rest will be discarded.';
|
|
101
|
+
const element = new _apidomDatamodel.AnnotationElement(message);
|
|
102
|
+
element.classes.push('warning');
|
|
103
|
+
maybeAddSourceMap(node, element, ctx);
|
|
104
|
+
ctx.annotations.push(element);
|
|
105
|
+
}
|
|
106
|
+
if (shouldSkipVisitingMoreDocuments) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
ctx.processedDocumentCount += 1;
|
|
110
|
+
|
|
111
|
+
// Transform and return children
|
|
112
|
+
return transformChildren(node.children || [], ctx);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Mapping: Transforms to ObjectElement
|
|
116
|
+
const transformMapping = (node, ctx) => {
|
|
117
|
+
const element = new _apidomDatamodel.ObjectElement();
|
|
118
|
+
// @ts-ignore
|
|
119
|
+
element._content = transformChildren(node.children || [], ctx);
|
|
120
|
+
maybeAddSourceMap(node, element, ctx);
|
|
121
|
+
return element;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// KeyValuePair: Transforms to MemberElement
|
|
125
|
+
const transformKeyValuePair = (node, ctx) => {
|
|
126
|
+
const element = new _apidomDatamodel.MemberElement();
|
|
127
|
+
|
|
128
|
+
// Transform key and value (these are dynamically defined properties)
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
130
|
+
const keyResult = transform(node.key, ctx);
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
|
+
const valueResult = transform(node.value, ctx);
|
|
133
|
+
|
|
134
|
+
// @ts-ignore
|
|
135
|
+
element.content.key = keyResult;
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
element.content.value = valueResult;
|
|
138
|
+
maybeAddSourceMap(node, element, ctx);
|
|
139
|
+
|
|
140
|
+
// Process any errors in children
|
|
141
|
+
(node.children || []
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
143
|
+
).filter(child => child?.type === 'error')
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
145
|
+
.forEach(errorNode => {
|
|
146
|
+
transformErrorAsAnnotation(errorNode, ctx);
|
|
147
|
+
});
|
|
148
|
+
return element;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Sequence: Transforms to ArrayElement
|
|
152
|
+
const transformSequence = (node, ctx) => {
|
|
153
|
+
const element = new _apidomDatamodel.ArrayElement();
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
element._content = transformChildren(node.children || [], ctx);
|
|
156
|
+
maybeAddSourceMap(node, element, ctx);
|
|
157
|
+
return element;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Scalar: Converts to Element via namespace
|
|
161
|
+
const transformScalar = (node, ctx) => {
|
|
162
|
+
const element = ctx.namespace.toElement(node.content);
|
|
163
|
+
|
|
164
|
+
// Translate style information about empty nodes
|
|
165
|
+
if (node.content === '' && node.style === _YamlStyle.YamlStyle.Plain) {
|
|
166
|
+
element.classes.push('yaml-e-node');
|
|
167
|
+
element.classes.push('yaml-e-scalar');
|
|
168
|
+
}
|
|
169
|
+
maybeAddSourceMap(node, element, ctx);
|
|
170
|
+
return element;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Comment: Returns CommentElement for pre-document comments only
|
|
174
|
+
const transformComment = (node, ctx) => {
|
|
175
|
+
const isStreamComment = ctx.processedDocumentCount === 0;
|
|
176
|
+
|
|
177
|
+
// Only interested in stream comments before the first document
|
|
178
|
+
if (isStreamComment) {
|
|
179
|
+
// @ts-ignore
|
|
180
|
+
const element = new _apidomDatamodel.CommentElement(node.content);
|
|
181
|
+
maybeAddSourceMap(node, element, ctx);
|
|
182
|
+
return element;
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// Literal: Handles missing nodes (creates warning annotation)
|
|
188
|
+
const transformLiteral = (node, ctx) => {
|
|
189
|
+
if (node.isMissing) {
|
|
190
|
+
const message = `(Missing ${node.value})`;
|
|
191
|
+
const element = new _apidomDatamodel.AnnotationElement(message);
|
|
192
|
+
element.classes.push('warning');
|
|
193
|
+
maybeAddSourceMap(node, element, ctx);
|
|
194
|
+
ctx.annotations.push(element);
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// Error as annotation (used by keyValuePair)
|
|
200
|
+
const transformErrorAsAnnotation = (node, ctx) => {
|
|
201
|
+
const message = node.isUnexpected ? '(Unexpected YAML syntax error)' : '(Error YAML syntax error)';
|
|
202
|
+
const element = new _apidomDatamodel.AnnotationElement(message);
|
|
203
|
+
element.classes.push('error');
|
|
204
|
+
maybeAddSourceMap(node, element, ctx);
|
|
205
|
+
ctx.annotations.push(element);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// Error: Creates error annotation (adds to annotations array)
|
|
209
|
+
const transformError = (node, ctx) => {
|
|
210
|
+
const message = node.isUnexpected ? '(Unexpected YAML syntax error)' : '(Error YAML syntax error)';
|
|
211
|
+
const element = new _apidomDatamodel.AnnotationElement(message);
|
|
212
|
+
element.classes.push('error');
|
|
213
|
+
maybeAddSourceMap(node, element, ctx);
|
|
214
|
+
ctx.annotations.push(element);
|
|
215
|
+
return null;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Error at root level: Creates ParseResultElement with error annotation
|
|
219
|
+
const transformRootError = (node, ctx) => {
|
|
220
|
+
const message = node.isUnexpected ? '(Unexpected YAML syntax error)' : '(Error YAML syntax error)';
|
|
221
|
+
const element = new _apidomDatamodel.AnnotationElement(message);
|
|
222
|
+
element.classes.push('error');
|
|
223
|
+
maybeAddSourceMap(node, element, ctx);
|
|
224
|
+
const parseResultElement = new _apidomDatamodel.ParseResultElement();
|
|
225
|
+
parseResultElement.push(element);
|
|
226
|
+
return parseResultElement;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* Transforms YAML AST to ApiDOM ParseResultElement.
|
|
230
|
+
* @public
|
|
231
|
+
*/
|
|
232
|
+
const transformYamlAstToApiDOM = (yamlAst, {
|
|
233
|
+
sourceMap = false
|
|
234
|
+
} = {}) => {
|
|
235
|
+
const ctx = {
|
|
236
|
+
sourceMap,
|
|
237
|
+
namespace: new _apidomDatamodel.Namespace(),
|
|
238
|
+
annotations: [],
|
|
239
|
+
processedDocumentCount: 0
|
|
240
|
+
};
|
|
241
|
+
const rootNode = yamlAst.rootNode;
|
|
242
|
+
|
|
243
|
+
// Handle empty parse result
|
|
244
|
+
if (!rootNode) {
|
|
245
|
+
return new _apidomDatamodel.ParseResultElement();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Handle root-level error (no valid stream, just an error node)
|
|
249
|
+
if (rootNode.type === 'error') {
|
|
250
|
+
return transformRootError(rootNode, ctx);
|
|
251
|
+
}
|
|
252
|
+
const result = transform(rootNode, ctx);
|
|
253
|
+
|
|
254
|
+
// Result should be a ParseResultElement from transformStream
|
|
255
|
+
if (result instanceof _apidomDatamodel.ParseResultElement) {
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Fallback: wrap in ParseResultElement
|
|
260
|
+
const parseResult = new _apidomDatamodel.ParseResultElement();
|
|
261
|
+
if (result !== null) {
|
|
262
|
+
if (Array.isArray(result)) {
|
|
263
|
+
result.forEach(el => parseResult.push(el));
|
|
264
|
+
} else {
|
|
265
|
+
parseResult.push(result);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return parseResult;
|
|
269
|
+
};
|
|
270
|
+
exports.transformYamlAstToApiDOM = transformYamlAstToApiDOM;
|
|
271
|
+
var _default = exports.default = transformYamlAstToApiDOM;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { ParseResultElement, AnnotationElement, CommentElement, MemberElement, ObjectElement, ArrayElement, isPrimitiveElement, Namespace, SourceMapElement } from '@speclynx/apidom-datamodel';
|
|
2
|
+
import { YamlStyle } from "./ast/nodes/YamlStyle.mjs"; // Transform context passed through transformation
|
|
3
|
+
// Node with type property and flat position properties
|
|
4
|
+
// Helper to add source map to element
|
|
5
|
+
const maybeAddSourceMap = (node, element, ctx) => {
|
|
6
|
+
if (!ctx.sourceMap) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
SourceMapElement.transfer(node, element);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// Transform a single node based on its type
|
|
13
|
+
const transform = (node, ctx) => {
|
|
14
|
+
if (node === null || node === undefined) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const typedNode = node;
|
|
18
|
+
const nodeType = typedNode.type;
|
|
19
|
+
switch (nodeType) {
|
|
20
|
+
case 'stream':
|
|
21
|
+
return transformStream(typedNode, ctx);
|
|
22
|
+
case 'document':
|
|
23
|
+
return transformDocument(typedNode, ctx);
|
|
24
|
+
case 'mapping':
|
|
25
|
+
return transformMapping(typedNode, ctx);
|
|
26
|
+
case 'keyValuePair':
|
|
27
|
+
return transformKeyValuePair(typedNode, ctx);
|
|
28
|
+
case 'sequence':
|
|
29
|
+
return transformSequence(typedNode, ctx);
|
|
30
|
+
case 'scalar':
|
|
31
|
+
return transformScalar(typedNode, ctx);
|
|
32
|
+
case 'comment':
|
|
33
|
+
return transformComment(typedNode, ctx);
|
|
34
|
+
case 'literal':
|
|
35
|
+
return transformLiteral(typedNode, ctx);
|
|
36
|
+
case 'error':
|
|
37
|
+
return transformError(typedNode, ctx);
|
|
38
|
+
default:
|
|
39
|
+
// Unknown node type - skip
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Transform children array and flatten results
|
|
45
|
+
const transformChildren = (children, ctx) => {
|
|
46
|
+
const results = [];
|
|
47
|
+
for (const child of children) {
|
|
48
|
+
const result = transform(child, ctx);
|
|
49
|
+
if (result === null) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (Array.isArray(result)) {
|
|
53
|
+
results.push(...result);
|
|
54
|
+
} else {
|
|
55
|
+
results.push(result);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return results;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Stream: Wraps transformed children in ParseResultElement
|
|
62
|
+
const transformStream = (node, ctx) => {
|
|
63
|
+
const element = new ParseResultElement();
|
|
64
|
+
|
|
65
|
+
// Transform all children
|
|
66
|
+
const children = transformChildren(node.children || [], ctx);
|
|
67
|
+
|
|
68
|
+
// Flatten and set content
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
element._content = children.flat(1);
|
|
71
|
+
|
|
72
|
+
// Mark first primitive element as result
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
const elements = element.findElements(isPrimitiveElement);
|
|
75
|
+
if (elements.length > 0) {
|
|
76
|
+
const resultElement = elements[0];
|
|
77
|
+
resultElement.classes.push('result');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Add collected annotations
|
|
81
|
+
ctx.annotations.forEach(annotationElement => {
|
|
82
|
+
element.push(annotationElement);
|
|
83
|
+
});
|
|
84
|
+
ctx.annotations = [];
|
|
85
|
+
return element;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// Document: Returns transformed children for first doc, warns for subsequent docs
|
|
89
|
+
const transformDocument = (node, ctx) => {
|
|
90
|
+
const shouldWarnAboutMoreDocuments = ctx.processedDocumentCount === 1;
|
|
91
|
+
const shouldSkipVisitingMoreDocuments = ctx.processedDocumentCount >= 1;
|
|
92
|
+
if (shouldWarnAboutMoreDocuments) {
|
|
93
|
+
const message = 'Only first document within YAML stream will be used. Rest will be discarded.';
|
|
94
|
+
const element = new AnnotationElement(message);
|
|
95
|
+
element.classes.push('warning');
|
|
96
|
+
maybeAddSourceMap(node, element, ctx);
|
|
97
|
+
ctx.annotations.push(element);
|
|
98
|
+
}
|
|
99
|
+
if (shouldSkipVisitingMoreDocuments) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
ctx.processedDocumentCount += 1;
|
|
103
|
+
|
|
104
|
+
// Transform and return children
|
|
105
|
+
return transformChildren(node.children || [], ctx);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// Mapping: Transforms to ObjectElement
|
|
109
|
+
const transformMapping = (node, ctx) => {
|
|
110
|
+
const element = new ObjectElement();
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
element._content = transformChildren(node.children || [], ctx);
|
|
113
|
+
maybeAddSourceMap(node, element, ctx);
|
|
114
|
+
return element;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// KeyValuePair: Transforms to MemberElement
|
|
118
|
+
const transformKeyValuePair = (node, ctx) => {
|
|
119
|
+
const element = new MemberElement();
|
|
120
|
+
|
|
121
|
+
// Transform key and value (these are dynamically defined properties)
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
123
|
+
const keyResult = transform(node.key, ctx);
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
const valueResult = transform(node.value, ctx);
|
|
126
|
+
|
|
127
|
+
// @ts-ignore
|
|
128
|
+
element.content.key = keyResult;
|
|
129
|
+
// @ts-ignore
|
|
130
|
+
element.content.value = valueResult;
|
|
131
|
+
maybeAddSourceMap(node, element, ctx);
|
|
132
|
+
|
|
133
|
+
// Process any errors in children
|
|
134
|
+
(node.children || []
|
|
135
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
136
|
+
).filter(child => child?.type === 'error')
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
138
|
+
.forEach(errorNode => {
|
|
139
|
+
transformErrorAsAnnotation(errorNode, ctx);
|
|
140
|
+
});
|
|
141
|
+
return element;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Sequence: Transforms to ArrayElement
|
|
145
|
+
const transformSequence = (node, ctx) => {
|
|
146
|
+
const element = new ArrayElement();
|
|
147
|
+
// @ts-ignore
|
|
148
|
+
element._content = transformChildren(node.children || [], ctx);
|
|
149
|
+
maybeAddSourceMap(node, element, ctx);
|
|
150
|
+
return element;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// Scalar: Converts to Element via namespace
|
|
154
|
+
const transformScalar = (node, ctx) => {
|
|
155
|
+
const element = ctx.namespace.toElement(node.content);
|
|
156
|
+
|
|
157
|
+
// Translate style information about empty nodes
|
|
158
|
+
if (node.content === '' && node.style === YamlStyle.Plain) {
|
|
159
|
+
element.classes.push('yaml-e-node');
|
|
160
|
+
element.classes.push('yaml-e-scalar');
|
|
161
|
+
}
|
|
162
|
+
maybeAddSourceMap(node, element, ctx);
|
|
163
|
+
return element;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// Comment: Returns CommentElement for pre-document comments only
|
|
167
|
+
const transformComment = (node, ctx) => {
|
|
168
|
+
const isStreamComment = ctx.processedDocumentCount === 0;
|
|
169
|
+
|
|
170
|
+
// Only interested in stream comments before the first document
|
|
171
|
+
if (isStreamComment) {
|
|
172
|
+
// @ts-ignore
|
|
173
|
+
const element = new CommentElement(node.content);
|
|
174
|
+
maybeAddSourceMap(node, element, ctx);
|
|
175
|
+
return element;
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Literal: Handles missing nodes (creates warning annotation)
|
|
181
|
+
const transformLiteral = (node, ctx) => {
|
|
182
|
+
if (node.isMissing) {
|
|
183
|
+
const message = `(Missing ${node.value})`;
|
|
184
|
+
const element = new AnnotationElement(message);
|
|
185
|
+
element.classes.push('warning');
|
|
186
|
+
maybeAddSourceMap(node, element, ctx);
|
|
187
|
+
ctx.annotations.push(element);
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
// Error as annotation (used by keyValuePair)
|
|
193
|
+
const transformErrorAsAnnotation = (node, ctx) => {
|
|
194
|
+
const message = node.isUnexpected ? '(Unexpected YAML syntax error)' : '(Error YAML syntax error)';
|
|
195
|
+
const element = new AnnotationElement(message);
|
|
196
|
+
element.classes.push('error');
|
|
197
|
+
maybeAddSourceMap(node, element, ctx);
|
|
198
|
+
ctx.annotations.push(element);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// Error: Creates error annotation (adds to annotations array)
|
|
202
|
+
const transformError = (node, ctx) => {
|
|
203
|
+
const message = node.isUnexpected ? '(Unexpected YAML syntax error)' : '(Error YAML syntax error)';
|
|
204
|
+
const element = new AnnotationElement(message);
|
|
205
|
+
element.classes.push('error');
|
|
206
|
+
maybeAddSourceMap(node, element, ctx);
|
|
207
|
+
ctx.annotations.push(element);
|
|
208
|
+
return null;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Error at root level: Creates ParseResultElement with error annotation
|
|
212
|
+
const transformRootError = (node, ctx) => {
|
|
213
|
+
const message = node.isUnexpected ? '(Unexpected YAML syntax error)' : '(Error YAML syntax error)';
|
|
214
|
+
const element = new AnnotationElement(message);
|
|
215
|
+
element.classes.push('error');
|
|
216
|
+
maybeAddSourceMap(node, element, ctx);
|
|
217
|
+
const parseResultElement = new ParseResultElement();
|
|
218
|
+
parseResultElement.push(element);
|
|
219
|
+
return parseResultElement;
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Transforms YAML AST to ApiDOM ParseResultElement.
|
|
223
|
+
* @public
|
|
224
|
+
*/
|
|
225
|
+
export const transformYamlAstToApiDOM = (yamlAst, {
|
|
226
|
+
sourceMap = false
|
|
227
|
+
} = {}) => {
|
|
228
|
+
const ctx = {
|
|
229
|
+
sourceMap,
|
|
230
|
+
namespace: new Namespace(),
|
|
231
|
+
annotations: [],
|
|
232
|
+
processedDocumentCount: 0
|
|
233
|
+
};
|
|
234
|
+
const rootNode = yamlAst.rootNode;
|
|
235
|
+
|
|
236
|
+
// Handle empty parse result
|
|
237
|
+
if (!rootNode) {
|
|
238
|
+
return new ParseResultElement();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Handle root-level error (no valid stream, just an error node)
|
|
242
|
+
if (rootNode.type === 'error') {
|
|
243
|
+
return transformRootError(rootNode, ctx);
|
|
244
|
+
}
|
|
245
|
+
const result = transform(rootNode, ctx);
|
|
246
|
+
|
|
247
|
+
// Result should be a ParseResultElement from transformStream
|
|
248
|
+
if (result instanceof ParseResultElement) {
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Fallback: wrap in ParseResultElement
|
|
253
|
+
const parseResult = new ParseResultElement();
|
|
254
|
+
if (result !== null) {
|
|
255
|
+
if (Array.isArray(result)) {
|
|
256
|
+
result.forEach(el => parseResult.push(el));
|
|
257
|
+
} else {
|
|
258
|
+
parseResult.push(result);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return parseResult;
|
|
262
|
+
};
|
|
263
|
+
export default transformYamlAstToApiDOM;
|
|
@@ -0,0 +1,30 @@
|
|
|
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 _Node = _interopRequireDefault(require("./Node.cjs"));
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
class Error extends _Node.default {
|
|
15
|
+
static type = 'error';
|
|
16
|
+
value;
|
|
17
|
+
isUnexpected;
|
|
18
|
+
constructor({
|
|
19
|
+
value,
|
|
20
|
+
isUnexpected = false,
|
|
21
|
+
...rest
|
|
22
|
+
} = {}) {
|
|
23
|
+
super({
|
|
24
|
+
...rest
|
|
25
|
+
});
|
|
26
|
+
this.value = value;
|
|
27
|
+
this.isUnexpected = isUnexpected;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
var _default = exports.default = Error;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Node from "./Node.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
class Error extends Node {
|
|
9
|
+
static type = 'error';
|
|
10
|
+
value;
|
|
11
|
+
isUnexpected;
|
|
12
|
+
constructor({
|
|
13
|
+
value,
|
|
14
|
+
isUnexpected = false,
|
|
15
|
+
...rest
|
|
16
|
+
} = {}) {
|
|
17
|
+
super({
|
|
18
|
+
...rest
|
|
19
|
+
});
|
|
20
|
+
this.value = value;
|
|
21
|
+
this.isUnexpected = isUnexpected;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export default Error;
|
|
@@ -0,0 +1,27 @@
|
|
|
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 _Node = _interopRequireDefault(require("./Node.cjs"));
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
class Literal extends _Node.default {
|
|
15
|
+
static type = 'literal';
|
|
16
|
+
value;
|
|
17
|
+
constructor({
|
|
18
|
+
value,
|
|
19
|
+
...rest
|
|
20
|
+
} = {}) {
|
|
21
|
+
super({
|
|
22
|
+
...rest
|
|
23
|
+
});
|
|
24
|
+
this.value = value;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
var _default = exports.default = Literal;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Node from "./Node.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
class Literal extends Node {
|
|
9
|
+
static type = 'literal';
|
|
10
|
+
value;
|
|
11
|
+
constructor({
|
|
12
|
+
value,
|
|
13
|
+
...rest
|
|
14
|
+
} = {}) {
|
|
15
|
+
super({
|
|
16
|
+
...rest
|
|
17
|
+
});
|
|
18
|
+
this.value = value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export default Literal;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
class Node {
|
|
13
|
+
static type = 'node';
|
|
14
|
+
type = 'node';
|
|
15
|
+
isMissing;
|
|
16
|
+
children;
|
|
17
|
+
startLine;
|
|
18
|
+
startCharacter;
|
|
19
|
+
startOffset;
|
|
20
|
+
endLine;
|
|
21
|
+
endCharacter;
|
|
22
|
+
endOffset;
|
|
23
|
+
constructor({
|
|
24
|
+
children = [],
|
|
25
|
+
startLine,
|
|
26
|
+
startCharacter,
|
|
27
|
+
startOffset,
|
|
28
|
+
endLine,
|
|
29
|
+
endCharacter,
|
|
30
|
+
endOffset,
|
|
31
|
+
isMissing = false
|
|
32
|
+
} = {}) {
|
|
33
|
+
this.type = this.constructor.type;
|
|
34
|
+
this.isMissing = isMissing;
|
|
35
|
+
this.children = children;
|
|
36
|
+
this.startLine = startLine;
|
|
37
|
+
this.startCharacter = startCharacter;
|
|
38
|
+
this.startOffset = startOffset;
|
|
39
|
+
this.endLine = endLine;
|
|
40
|
+
this.endCharacter = endCharacter;
|
|
41
|
+
this.endOffset = endOffset;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// creates shallow clone of node
|
|
45
|
+
clone() {
|
|
46
|
+
// 1. copy has same prototype as orig
|
|
47
|
+
const copy = Object.create(Object.getPrototypeOf(this));
|
|
48
|
+
|
|
49
|
+
// 2. copy has all of orig’s properties
|
|
50
|
+
Object.getOwnPropertyNames(this) // (1)
|
|
51
|
+
.forEach(propKey => {
|
|
52
|
+
// (2)
|
|
53
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, propKey); // (3)
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
Object.defineProperty(copy, propKey, descriptor); // (4)
|
|
56
|
+
});
|
|
57
|
+
return copy;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
var _default = exports.default = Node;
|