@lithent/lithent-template-parser 0.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/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/codegen/createElement.d.ts +10 -0
- package/dist/codegen/index.d.ts +1 -0
- package/dist/compiler.d.ts +26 -0
- package/dist/docPipe/index.d.ts +40 -0
- package/dist/docPipe/scan.d.ts +6 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.mjs +2302 -0
- package/dist/index.mjs.map +1 -0
- package/dist/index.umd.cjs +13 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/parser/ast.d.ts +207 -0
- package/dist/parser/lexer.d.ts +109 -0
- package/dist/parser/parser.d.ts +79 -0
- package/dist/parser/tokens.d.ts +51 -0
- package/dist/transform/directives.d.ts +30 -0
- package/dist/transform/index.d.ts +14 -0
- package/dist/transform/optimize.d.ts +21 -0
- package/package.json +53 -0
- package/src/codegen/createElement.ts +661 -0
- package/src/codegen/index.ts +1 -0
- package/src/compiler.ts +70 -0
- package/src/docPipe/index.ts +104 -0
- package/src/docPipe/scan.ts +318 -0
- package/src/index.ts +16 -0
- package/src/parser/ast.ts +478 -0
- package/src/parser/lexer.ts +561 -0
- package/src/parser/parser.ts +514 -0
- package/src/parser/tokens.ts +84 -0
- package/src/playground/main.ts +206 -0
- package/src/playground/style.css +135 -0
- package/src/shims/babel-env.ts +17 -0
- package/src/tests/compiler.test.ts +434 -0
- package/src/tests/docPipe.test.ts +41 -0
- package/src/tests/helpers.ts +96 -0
- package/src/tests/lexer.test.ts +282 -0
- package/src/tests/parser.test.ts +691 -0
- package/src/transform/directives.ts +160 -0
- package/src/transform/index.ts +29 -0
- package/src/transform/optimize.ts +203 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Position } from './tokens';
|
|
2
|
+
/**
|
|
3
|
+
* Base AST Node interface
|
|
4
|
+
*/
|
|
5
|
+
export interface BaseNode {
|
|
6
|
+
type: string;
|
|
7
|
+
start: Position;
|
|
8
|
+
end: Position;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Node types
|
|
12
|
+
*/
|
|
13
|
+
export declare enum NodeType {
|
|
14
|
+
ROOT = "Root",
|
|
15
|
+
ELEMENT = "Element",
|
|
16
|
+
FRAGMENT = "Fragment",
|
|
17
|
+
TEXT = "Text",
|
|
18
|
+
INTERPOLATION = "Interpolation",
|
|
19
|
+
COMMENT = "Comment",
|
|
20
|
+
ATTRIBUTE = "Attribute",
|
|
21
|
+
DIRECTIVE_IF = "DirectiveIf",
|
|
22
|
+
DIRECTIVE_ELSE_IF = "DirectiveElseIf",
|
|
23
|
+
DIRECTIVE_ELSE = "DirectiveElse",
|
|
24
|
+
DIRECTIVE_FOR = "DirectiveFor"
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Root node - represents the entire template
|
|
28
|
+
*/
|
|
29
|
+
export interface RootNode extends BaseNode {
|
|
30
|
+
type: NodeType.ROOT;
|
|
31
|
+
children: TemplateNode[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Element node - represents HTML element or component
|
|
35
|
+
*/
|
|
36
|
+
export interface ElementNode extends BaseNode {
|
|
37
|
+
type: NodeType.ELEMENT;
|
|
38
|
+
tag: string;
|
|
39
|
+
isComponent: boolean;
|
|
40
|
+
isSelfClosing: boolean;
|
|
41
|
+
attributes: AttributeNode[];
|
|
42
|
+
directives: DirectiveNode[];
|
|
43
|
+
children: TemplateNode[];
|
|
44
|
+
ref?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Fragment node - represents <></>
|
|
48
|
+
*/
|
|
49
|
+
export interface FragmentNode extends BaseNode {
|
|
50
|
+
type: NodeType.FRAGMENT;
|
|
51
|
+
children: TemplateNode[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Text node - represents plain text content
|
|
55
|
+
*/
|
|
56
|
+
export interface TextNode extends BaseNode {
|
|
57
|
+
type: NodeType.TEXT;
|
|
58
|
+
content: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Interpolation node - represents {expression}
|
|
62
|
+
*/
|
|
63
|
+
export interface InterpolationNode extends BaseNode {
|
|
64
|
+
type: NodeType.INTERPOLATION;
|
|
65
|
+
expression: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Comment node - represents HTML comments
|
|
69
|
+
*/
|
|
70
|
+
export interface CommentNode extends BaseNode {
|
|
71
|
+
type: NodeType.COMMENT;
|
|
72
|
+
content: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Attribute node - represents element attributes
|
|
76
|
+
*/
|
|
77
|
+
export interface AttributeNode extends BaseNode {
|
|
78
|
+
type: NodeType.ATTRIBUTE;
|
|
79
|
+
name: string;
|
|
80
|
+
value: AttributeValue | null;
|
|
81
|
+
isDynamic: boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Attribute value can be static string or expression
|
|
85
|
+
*/
|
|
86
|
+
export type AttributeValue = string | {
|
|
87
|
+
expression: string;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Base directive node
|
|
91
|
+
*/
|
|
92
|
+
export interface BaseDirectiveNode extends BaseNode {
|
|
93
|
+
type: NodeType.DIRECTIVE_IF | NodeType.DIRECTIVE_ELSE_IF | NodeType.DIRECTIVE_ELSE | NodeType.DIRECTIVE_FOR;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* l-if directive
|
|
97
|
+
*/
|
|
98
|
+
export interface DirectiveIfNode extends BaseDirectiveNode {
|
|
99
|
+
type: NodeType.DIRECTIVE_IF;
|
|
100
|
+
condition: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* l-else-if directive
|
|
104
|
+
*/
|
|
105
|
+
export interface DirectiveElseIfNode extends BaseDirectiveNode {
|
|
106
|
+
type: NodeType.DIRECTIVE_ELSE_IF;
|
|
107
|
+
condition: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* l-else directive
|
|
111
|
+
*/
|
|
112
|
+
export interface DirectiveElseNode extends BaseDirectiveNode {
|
|
113
|
+
type: NodeType.DIRECTIVE_ELSE;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* l-for directive
|
|
117
|
+
*/
|
|
118
|
+
export interface DirectiveForNode extends BaseDirectiveNode {
|
|
119
|
+
type: NodeType.DIRECTIVE_FOR;
|
|
120
|
+
item: string;
|
|
121
|
+
index?: string;
|
|
122
|
+
list: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Union type for all directive nodes
|
|
126
|
+
*/
|
|
127
|
+
export type DirectiveNode = DirectiveIfNode | DirectiveElseIfNode | DirectiveElseNode | DirectiveForNode;
|
|
128
|
+
/**
|
|
129
|
+
* Union type for all template nodes (excluding Root)
|
|
130
|
+
*/
|
|
131
|
+
export type TemplateNode = ElementNode | FragmentNode | TextNode | InterpolationNode | CommentNode;
|
|
132
|
+
/**
|
|
133
|
+
* Type guard for Element nodes
|
|
134
|
+
*/
|
|
135
|
+
export declare function isElementNode(node: TemplateNode): node is ElementNode;
|
|
136
|
+
/**
|
|
137
|
+
* Type guard for Fragment nodes
|
|
138
|
+
*/
|
|
139
|
+
export declare function isFragmentNode(node: TemplateNode): node is FragmentNode;
|
|
140
|
+
/**
|
|
141
|
+
* Type guard for Text nodes
|
|
142
|
+
*/
|
|
143
|
+
export declare function isTextNode(node: TemplateNode): node is TextNode;
|
|
144
|
+
/**
|
|
145
|
+
* Type guard for Interpolation nodes
|
|
146
|
+
*/
|
|
147
|
+
export declare function isInterpolationNode(node: TemplateNode): node is InterpolationNode;
|
|
148
|
+
/**
|
|
149
|
+
* Type guard for Comment nodes
|
|
150
|
+
*/
|
|
151
|
+
export declare function isCommentNode(node: TemplateNode): node is CommentNode;
|
|
152
|
+
/**
|
|
153
|
+
* Type guard for directive nodes
|
|
154
|
+
*/
|
|
155
|
+
export declare function isDirective(node: AttributeNode | DirectiveNode): node is DirectiveNode;
|
|
156
|
+
/**
|
|
157
|
+
* Create a root node
|
|
158
|
+
*/
|
|
159
|
+
export declare function createRootNode(children: TemplateNode[], start: Position, end: Position): RootNode;
|
|
160
|
+
/**
|
|
161
|
+
* Create an element node
|
|
162
|
+
*/
|
|
163
|
+
export declare function createElementNode(tag: string, attributes: AttributeNode[], directives: DirectiveNode[], children: TemplateNode[], isSelfClosing: boolean, start: Position, end: Position): ElementNode;
|
|
164
|
+
/**
|
|
165
|
+
* Create a fragment node
|
|
166
|
+
*/
|
|
167
|
+
export declare function createFragmentNode(children: TemplateNode[], start: Position, end: Position): FragmentNode;
|
|
168
|
+
/**
|
|
169
|
+
* Create a text node
|
|
170
|
+
*/
|
|
171
|
+
export declare function createTextNode(content: string, start: Position, end: Position): TextNode;
|
|
172
|
+
/**
|
|
173
|
+
* Create an interpolation node
|
|
174
|
+
*/
|
|
175
|
+
export declare function createInterpolationNode(expression: string, start: Position, end: Position): InterpolationNode;
|
|
176
|
+
/**
|
|
177
|
+
* Create a comment node
|
|
178
|
+
*/
|
|
179
|
+
export declare function createCommentNode(content: string, start: Position, end: Position): CommentNode;
|
|
180
|
+
/**
|
|
181
|
+
* Create an attribute node
|
|
182
|
+
*/
|
|
183
|
+
export declare function createAttributeNode(name: string, value: AttributeValue | null, isDynamic: boolean, start: Position, end: Position): AttributeNode;
|
|
184
|
+
/**
|
|
185
|
+
* Create a l-if directive node
|
|
186
|
+
*/
|
|
187
|
+
export declare function createDirectiveIfNode(condition: string, start: Position, end: Position): DirectiveIfNode;
|
|
188
|
+
/**
|
|
189
|
+
* Create a l-else-if directive node
|
|
190
|
+
*/
|
|
191
|
+
export declare function createDirectiveElseIfNode(condition: string, start: Position, end: Position): DirectiveElseIfNode;
|
|
192
|
+
/**
|
|
193
|
+
* Create a l-else directive node
|
|
194
|
+
*/
|
|
195
|
+
export declare function createDirectiveElseNode(start: Position, end: Position): DirectiveElseNode;
|
|
196
|
+
/**
|
|
197
|
+
* Create a l-for directive node
|
|
198
|
+
*/
|
|
199
|
+
export declare function createDirectiveForNode(item: string, list: string, index: string | undefined, start: Position, end: Position): DirectiveForNode;
|
|
200
|
+
/**
|
|
201
|
+
* Walk through AST and call visitor function for each node
|
|
202
|
+
*/
|
|
203
|
+
export declare function walk(node: RootNode | TemplateNode, visitor: (node: TemplateNode) => void): void;
|
|
204
|
+
/**
|
|
205
|
+
* Transform AST by applying a transformer function to each node
|
|
206
|
+
*/
|
|
207
|
+
export declare function transformTree(node: RootNode | TemplateNode, transformer: (node: TemplateNode) => TemplateNode): RootNode | TemplateNode;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Token } from './tokens';
|
|
2
|
+
/**
|
|
3
|
+
* Lexer for Lithent templates
|
|
4
|
+
* Converts template string into a stream of tokens
|
|
5
|
+
*/
|
|
6
|
+
export declare class Lexer {
|
|
7
|
+
private input;
|
|
8
|
+
private position;
|
|
9
|
+
private line;
|
|
10
|
+
private column;
|
|
11
|
+
private tokens;
|
|
12
|
+
constructor(input: string);
|
|
13
|
+
/**
|
|
14
|
+
* Tokenize the entire input
|
|
15
|
+
*/
|
|
16
|
+
tokenize(): Token[];
|
|
17
|
+
/**
|
|
18
|
+
* Get current position
|
|
19
|
+
*/
|
|
20
|
+
private getCurrentPosition;
|
|
21
|
+
/**
|
|
22
|
+
* Peek at character without consuming
|
|
23
|
+
*/
|
|
24
|
+
private peek;
|
|
25
|
+
/**
|
|
26
|
+
* Consume and return current character
|
|
27
|
+
*/
|
|
28
|
+
private advance;
|
|
29
|
+
/**
|
|
30
|
+
* Check if we've reached the end
|
|
31
|
+
*/
|
|
32
|
+
private isEOF;
|
|
33
|
+
/**
|
|
34
|
+
* Read next token
|
|
35
|
+
*/
|
|
36
|
+
private readToken;
|
|
37
|
+
/**
|
|
38
|
+
* Read HTML comment
|
|
39
|
+
*/
|
|
40
|
+
private readComment;
|
|
41
|
+
/**
|
|
42
|
+
* Read opening tag <
|
|
43
|
+
*/
|
|
44
|
+
private readOpenTag;
|
|
45
|
+
/**
|
|
46
|
+
* Read closing tag </
|
|
47
|
+
*/
|
|
48
|
+
private readCloseTag;
|
|
49
|
+
/**
|
|
50
|
+
* Read tag content (tag name and attributes)
|
|
51
|
+
*/
|
|
52
|
+
private readTagContent;
|
|
53
|
+
/**
|
|
54
|
+
* Read an attribute (name and optional value)
|
|
55
|
+
*/
|
|
56
|
+
private readAttribute;
|
|
57
|
+
/**
|
|
58
|
+
* Read identifier (tag name or attribute name)
|
|
59
|
+
*/
|
|
60
|
+
private readIdentifier;
|
|
61
|
+
/**
|
|
62
|
+
* Determine token type for identifier
|
|
63
|
+
*/
|
|
64
|
+
private getIdentifierTokenType;
|
|
65
|
+
/**
|
|
66
|
+
* Read string literal
|
|
67
|
+
*/
|
|
68
|
+
private readStringLiteral;
|
|
69
|
+
/**
|
|
70
|
+
* Read fragment open <>
|
|
71
|
+
*/
|
|
72
|
+
private readFragmentOpen;
|
|
73
|
+
/**
|
|
74
|
+
* Read fragment close </>
|
|
75
|
+
*/
|
|
76
|
+
private readFragmentClose;
|
|
77
|
+
/**
|
|
78
|
+
* Read expression content inside {}
|
|
79
|
+
*/
|
|
80
|
+
private readExpression;
|
|
81
|
+
/**
|
|
82
|
+
* Read text content
|
|
83
|
+
*/
|
|
84
|
+
private readText;
|
|
85
|
+
/**
|
|
86
|
+
* Read whitespace
|
|
87
|
+
*/
|
|
88
|
+
private readWhitespace;
|
|
89
|
+
/**
|
|
90
|
+
* Skip whitespace without creating tokens
|
|
91
|
+
*/
|
|
92
|
+
private skipWhitespace;
|
|
93
|
+
/**
|
|
94
|
+
* Check if character is whitespace
|
|
95
|
+
*/
|
|
96
|
+
private isWhitespace;
|
|
97
|
+
/**
|
|
98
|
+
* Check if character can start an identifier
|
|
99
|
+
*/
|
|
100
|
+
private isIdentifierStart;
|
|
101
|
+
/**
|
|
102
|
+
* Check if character can be part of an identifier
|
|
103
|
+
*/
|
|
104
|
+
private isIdentifierPart;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Tokenize a template string
|
|
108
|
+
*/
|
|
109
|
+
export declare function tokenize(input: string): Token[];
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Token } from './tokens';
|
|
2
|
+
import { RootNode } from './ast';
|
|
3
|
+
/**
|
|
4
|
+
* Parser for Lithent templates
|
|
5
|
+
* Converts token stream into AST
|
|
6
|
+
*/
|
|
7
|
+
export declare class Parser {
|
|
8
|
+
private tokens;
|
|
9
|
+
private position;
|
|
10
|
+
constructor(tokens: Token[]);
|
|
11
|
+
/**
|
|
12
|
+
* Parse tokens into AST
|
|
13
|
+
*/
|
|
14
|
+
parse(): RootNode;
|
|
15
|
+
/**
|
|
16
|
+
* Parse a single template node
|
|
17
|
+
*/
|
|
18
|
+
private parseTemplateNode;
|
|
19
|
+
/**
|
|
20
|
+
* Parse fragment node
|
|
21
|
+
*/
|
|
22
|
+
private parseFragment;
|
|
23
|
+
/**
|
|
24
|
+
* Parse element
|
|
25
|
+
*/
|
|
26
|
+
private parseElement;
|
|
27
|
+
/**
|
|
28
|
+
* Parse attributes and directives
|
|
29
|
+
*/
|
|
30
|
+
private parseAttributesAndDirectives;
|
|
31
|
+
/**
|
|
32
|
+
* Parse attribute
|
|
33
|
+
*/
|
|
34
|
+
private parseAttribute;
|
|
35
|
+
/**
|
|
36
|
+
* Parse directive
|
|
37
|
+
*/
|
|
38
|
+
private parseDirective;
|
|
39
|
+
/**
|
|
40
|
+
* Parse l-for expression
|
|
41
|
+
*/
|
|
42
|
+
private parseForExpression;
|
|
43
|
+
/**
|
|
44
|
+
* Parse text node
|
|
45
|
+
*/
|
|
46
|
+
private parseText;
|
|
47
|
+
/**
|
|
48
|
+
* Parse interpolation node
|
|
49
|
+
*/
|
|
50
|
+
private parseInterpolation;
|
|
51
|
+
/**
|
|
52
|
+
* Parse comment node
|
|
53
|
+
*/
|
|
54
|
+
private parseComment;
|
|
55
|
+
/**
|
|
56
|
+
* Peek at current token without consuming
|
|
57
|
+
*/
|
|
58
|
+
private peek;
|
|
59
|
+
/**
|
|
60
|
+
* Advance to next token and return current
|
|
61
|
+
*/
|
|
62
|
+
private advance;
|
|
63
|
+
/**
|
|
64
|
+
* Check if current token matches type
|
|
65
|
+
*/
|
|
66
|
+
private check;
|
|
67
|
+
/**
|
|
68
|
+
* Expect a token of specific type, throw error if not found
|
|
69
|
+
*/
|
|
70
|
+
private expect;
|
|
71
|
+
/**
|
|
72
|
+
* Check if we've reached EOF
|
|
73
|
+
*/
|
|
74
|
+
private isEOF;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Parse template string into AST
|
|
78
|
+
*/
|
|
79
|
+
export declare function parse(tokens: Token[]): RootNode;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token types for Lithent template lexer
|
|
3
|
+
*/
|
|
4
|
+
export declare enum TokenType {
|
|
5
|
+
TAG_OPEN_START = "TAG_OPEN_START",
|
|
6
|
+
TAG_OPEN_END = "TAG_OPEN_END",
|
|
7
|
+
TAG_CLOSE_START = "TAG_CLOSE_START",
|
|
8
|
+
TAG_SELF_CLOSE = "TAG_SELF_CLOSE",
|
|
9
|
+
IDENTIFIER = "IDENTIFIER",
|
|
10
|
+
ATTRIBUTE_EQUALS = "ATTRIBUTE_EQUALS",
|
|
11
|
+
STRING_LITERAL = "STRING_LITERAL",
|
|
12
|
+
EXPRESSION_START = "EXPRESSION_START",
|
|
13
|
+
EXPRESSION_END = "EXPRESSION_END",
|
|
14
|
+
EXPRESSION_CONTENT = "EXPRESSION_CONTENT",
|
|
15
|
+
DIRECTIVE_IF = "DIRECTIVE_IF",
|
|
16
|
+
DIRECTIVE_ELSE_IF = "DIRECTIVE_ELSE_IF",
|
|
17
|
+
DIRECTIVE_ELSE = "DIRECTIVE_ELSE",
|
|
18
|
+
DIRECTIVE_FOR = "DIRECTIVE_FOR",
|
|
19
|
+
FRAGMENT_OPEN = "FRAGMENT_OPEN",
|
|
20
|
+
FRAGMENT_CLOSE = "FRAGMENT_CLOSE",
|
|
21
|
+
KEYWORD_REF = "KEYWORD_REF",
|
|
22
|
+
TEXT = "TEXT",
|
|
23
|
+
COMMENT = "COMMENT",
|
|
24
|
+
WHITESPACE = "WHITESPACE",
|
|
25
|
+
EOF = "EOF"
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Position information for error reporting
|
|
29
|
+
*/
|
|
30
|
+
export interface Position {
|
|
31
|
+
line: number;
|
|
32
|
+
column: number;
|
|
33
|
+
offset: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Token interface
|
|
37
|
+
*/
|
|
38
|
+
export interface Token {
|
|
39
|
+
type: TokenType;
|
|
40
|
+
value: string;
|
|
41
|
+
start: Position;
|
|
42
|
+
end: Position;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a position object
|
|
46
|
+
*/
|
|
47
|
+
export declare function createPosition(line: number, column: number, offset: number): Position;
|
|
48
|
+
/**
|
|
49
|
+
* Create a token
|
|
50
|
+
*/
|
|
51
|
+
export declare function createToken(type: TokenType, value: string, start: Position, end: Position): Token;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { RootNode, ElementNode, NodeType, DirectiveIfNode, DirectiveElseIfNode, DirectiveElseNode } from '../parser/ast';
|
|
2
|
+
/**
|
|
3
|
+
* Group conditional elements (l-if/l-else-if/l-else chain)
|
|
4
|
+
* This transform marks related conditional elements for easier codegen
|
|
5
|
+
*/
|
|
6
|
+
export interface ConditionalGroup {
|
|
7
|
+
if: ElementNode;
|
|
8
|
+
elseIfs: ElementNode[];
|
|
9
|
+
else?: ElementNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Transform directives in the AST
|
|
13
|
+
* Currently handles:
|
|
14
|
+
* - Grouping l-if/l-else-if/l-else chains
|
|
15
|
+
*/
|
|
16
|
+
export declare function transformDirectives(ast: RootNode): RootNode;
|
|
17
|
+
/**
|
|
18
|
+
* Get conditional group if element is part of one
|
|
19
|
+
*/
|
|
20
|
+
export declare function getConditionalGroup(element: ElementNode): ConditionalGroup | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Check if element has a specific directive type
|
|
23
|
+
*/
|
|
24
|
+
export declare function hasDirective(element: ElementNode, directiveType: NodeType): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Get directive of specific type from element
|
|
27
|
+
*/
|
|
28
|
+
export declare function getDirective(element: ElementNode, directiveType: NodeType.DIRECTIVE_IF): DirectiveIfNode | undefined;
|
|
29
|
+
export declare function getDirective(element: ElementNode, directiveType: NodeType.DIRECTIVE_ELSE_IF): DirectiveElseIfNode | undefined;
|
|
30
|
+
export declare function getDirective(element: ElementNode, directiveType: NodeType.DIRECTIVE_ELSE): DirectiveElseNode | undefined;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RootNode } from '../parser/ast';
|
|
2
|
+
import { transformDirectives } from './directives';
|
|
3
|
+
import { optimize, OptimizeOptions } from './optimize';
|
|
4
|
+
/**
|
|
5
|
+
* Apply all transformations to the AST
|
|
6
|
+
*/
|
|
7
|
+
export declare function transform(ast: RootNode, options?: TransformOptions): RootNode;
|
|
8
|
+
export interface TransformOptions {
|
|
9
|
+
optimize?: boolean;
|
|
10
|
+
optimizeOptions?: OptimizeOptions;
|
|
11
|
+
}
|
|
12
|
+
export { transformDirectives, optimize };
|
|
13
|
+
export * from './directives';
|
|
14
|
+
export * from './optimize';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RootNode, TemplateNode, TextNode } from '../parser/ast';
|
|
2
|
+
/**
|
|
3
|
+
* Optimize the AST
|
|
4
|
+
* - Merge consecutive text nodes
|
|
5
|
+
* - Remove empty text nodes (whitespace-only)
|
|
6
|
+
* - Trim text nodes at boundaries
|
|
7
|
+
*/
|
|
8
|
+
export declare function optimize(ast: RootNode, options?: OptimizeOptions): RootNode;
|
|
9
|
+
export interface OptimizeOptions {
|
|
10
|
+
mergeTextNodes?: boolean;
|
|
11
|
+
removeWhitespace?: boolean;
|
|
12
|
+
trimText?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check if a text node is whitespace-only
|
|
16
|
+
*/
|
|
17
|
+
export declare function isWhitespaceOnly(node: TextNode): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Count nodes in the tree
|
|
20
|
+
*/
|
|
21
|
+
export declare function countNodes(node: RootNode | TemplateNode): number;
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"name": "@lithent/lithent-template-parser",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Lithent Template Parser",
|
|
6
|
+
"main": "./dist/index.umd.cjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.umd.cjs",
|
|
14
|
+
"default": "./dist/index.mjs"
|
|
15
|
+
},
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"magic-string": "^0.30.11"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"lithent": "1.20.1"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"lithent",
|
|
26
|
+
"vite",
|
|
27
|
+
"hmr"
|
|
28
|
+
],
|
|
29
|
+
"author": "superlucky84",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"homepage": "https://github.com/superlucky84/lithent",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/superlucky84/lithent.git"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"src"
|
|
40
|
+
],
|
|
41
|
+
"volta": {
|
|
42
|
+
"node": "20.3.0",
|
|
43
|
+
"pnpm": "9.12.3"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"dev": "vite",
|
|
47
|
+
"dev:plugin": "vite --config vite.config.plugin.ts",
|
|
48
|
+
"build": "vite build",
|
|
49
|
+
"watch": "vite build --watch",
|
|
50
|
+
"test": "vitest run --reporter verbose",
|
|
51
|
+
"test:dev": "vitest"
|
|
52
|
+
}
|
|
53
|
+
}
|