@flexiberry/berrycore 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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapter/cli-adapter.d.ts +37 -0
  3. package/dist/adapter/cli-adapter.js +119 -0
  4. package/dist/berry-core.d.ts +108 -0
  5. package/dist/berry-core.js +258 -0
  6. package/dist/index.d.ts +13 -0
  7. package/dist/index.js +18 -0
  8. package/dist/interpreter/environment.d.ts +45 -0
  9. package/dist/interpreter/environment.js +96 -0
  10. package/dist/interpreter/errors.d.ts +16 -0
  11. package/dist/interpreter/errors.js +27 -0
  12. package/dist/interpreter/interpreter.d.ts +111 -0
  13. package/dist/interpreter/interpreter.js +682 -0
  14. package/dist/interpreter/interpreter.types.d.ts +182 -0
  15. package/dist/interpreter/interpreter.types.js +73 -0
  16. package/dist/parser/ast/ast.engine.d.ts +103 -0
  17. package/dist/parser/ast/ast.engine.js +526 -0
  18. package/dist/parser/ast/ast.types.d.ts +242 -0
  19. package/dist/parser/ast/ast.types.js +37 -0
  20. package/dist/parser/formatter/formatter.d.ts +44 -0
  21. package/dist/parser/formatter/formatter.js +214 -0
  22. package/dist/parser/tokenizer/reader/grammer/api.grammer.d.ts +2 -0
  23. package/dist/parser/tokenizer/reader/grammer/api.grammer.js +102 -0
  24. package/dist/parser/tokenizer/reader/grammer/capture.grammer.d.ts +2 -0
  25. package/dist/parser/tokenizer/reader/grammer/capture.grammer.js +21 -0
  26. package/dist/parser/tokenizer/reader/grammer/check.grammer.d.ts +2 -0
  27. package/dist/parser/tokenizer/reader/grammer/check.grammer.js +21 -0
  28. package/dist/parser/tokenizer/reader/grammer/comment.grammer.d.ts +2 -0
  29. package/dist/parser/tokenizer/reader/grammer/comment.grammer.js +13 -0
  30. package/dist/parser/tokenizer/reader/grammer/conditions.grammer.d.ts +2 -0
  31. package/dist/parser/tokenizer/reader/grammer/conditions.grammer.js +68 -0
  32. package/dist/parser/tokenizer/reader/grammer/input.grammer.d.ts +2 -0
  33. package/dist/parser/tokenizer/reader/grammer/input.grammer.js +17 -0
  34. package/dist/parser/tokenizer/reader/grammer/keyvalue.grammer.d.ts +2 -0
  35. package/dist/parser/tokenizer/reader/grammer/keyvalue.grammer.js +240 -0
  36. package/dist/parser/tokenizer/reader/grammer/link.grammer.d.ts +2 -0
  37. package/dist/parser/tokenizer/reader/grammer/link.grammer.js +17 -0
  38. package/dist/parser/tokenizer/reader/grammer/params.grammer.d.ts +2 -0
  39. package/dist/parser/tokenizer/reader/grammer/params.grammer.js +21 -0
  40. package/dist/parser/tokenizer/reader/grammer/step.grammer.d.ts +2 -0
  41. package/dist/parser/tokenizer/reader/grammer/step.grammer.js +25 -0
  42. package/dist/parser/tokenizer/reader/grammer/task.grammer.d.ts +2 -0
  43. package/dist/parser/tokenizer/reader/grammer/task.grammer.js +17 -0
  44. package/dist/parser/tokenizer/reader/grammer/var.grammer.d.ts +2 -0
  45. package/dist/parser/tokenizer/reader/grammer/var.grammer.js +47 -0
  46. package/dist/parser/tokenizer/reader/lexer.engine.d.ts +43 -0
  47. package/dist/parser/tokenizer/reader/lexer.engine.js +178 -0
  48. package/dist/parser/tokenizer/reader/lexer.types.d.ts +18 -0
  49. package/dist/parser/tokenizer/reader/lexer.types.js +1 -0
  50. package/dist/parser/tokenizer/token.d.ts +13 -0
  51. package/dist/parser/tokenizer/token.js +13 -0
  52. package/dist/parser/tokenizer/tokenType.d.ts +58 -0
  53. package/dist/parser/tokenizer/tokenType.js +64 -0
  54. package/dist/script/format-util.d.ts +33 -0
  55. package/dist/script/format-util.js +94 -0
  56. package/dist/script/postman.util.d.ts +88 -0
  57. package/dist/script/postman.util.js +176 -0
  58. package/dist/script/swagger.util.d.ts +80 -0
  59. package/dist/script/swagger.util.js +202 -0
  60. package/dist/util/store-util.d.ts +5 -0
  61. package/dist/util/store-util.js +22 -0
  62. package/package.json +25 -0
  63. package/readme.md +107 -0
@@ -0,0 +1,242 @@
1
+ /**
2
+ * AST Node Types for Flexiberry DSL
3
+ *
4
+ * Pure data interfaces — no methods, no logic.
5
+ * Each node type maps to a specific lexer grammar rule from reader_v2.
6
+ */
7
+ export declare enum NodeType {
8
+ Program = "Program",
9
+ VarDeclaration = "VarDeclaration",
10
+ PointerReference = "PointerReference",
11
+ LinkStatement = "LinkStatement",
12
+ InputStatement = "InputStatement",
13
+ ApiBlock = "ApiBlock",
14
+ UrlStatement = "UrlStatement",
15
+ HeaderBlock = "HeaderBlock",
16
+ BodyBlock = "BodyBlock",
17
+ TaskBlock = "TaskBlock",
18
+ StepBlock = "StepBlock",
19
+ ParamsBlock = "ParamsBlock",
20
+ CaptureBlock = "CaptureBlock",
21
+ CheckBlock = "CheckBlock",
22
+ KeyValuePair = "KeyValuePair",
23
+ Condition = "Condition",
24
+ BinaryExpression = "BinaryExpression",
25
+ Identifier = "Identifier",
26
+ Literal = "Literal",
27
+ Comment = "Comment"
28
+ }
29
+ /** Source location attached to every AST node */
30
+ export interface NodePosition {
31
+ readonly line: number;
32
+ readonly column: number;
33
+ }
34
+ export interface BaseNode {
35
+ readonly type: NodeType;
36
+ readonly position: NodePosition;
37
+ }
38
+ /** Top-level program — an ordered list of declarations */
39
+ export interface ProgramNode extends BaseNode {
40
+ readonly type: NodeType.Program;
41
+ readonly body: ReadonlyArray<StatementNode>;
42
+ }
43
+ export type StatementNode = VarDeclarationNode | LinkStatementNode | InputStatementNode | ApiBlockNode | TaskBlockNode | StepBlockNode | ParamsBlockNode | CaptureBlockNode | CheckBlockNode | CommentNode;
44
+ /**
45
+ * `Var @pointed title`
46
+ * followed by key-value pairs on subsequent lines
47
+ *
48
+ * Grammar: var.grammer.ts
49
+ * Tokens: Var, optional (Pointer + Pointed + Title), then keyValueGrammer loop
50
+ */
51
+ export interface VarDeclarationNode extends BaseNode {
52
+ readonly type: NodeType.VarDeclaration;
53
+ readonly title: string | null;
54
+ readonly pointer: PointerReferenceNode | null;
55
+ readonly entries: ReadonlyArray<KeyValuePairNode>;
56
+ }
57
+ /**
58
+ * `@pointed` reference inside a Var declaration
59
+ *
60
+ * Tokens: Pointer (@), Pointed (name)
61
+ */
62
+ export interface PointerReferenceNode extends BaseNode {
63
+ readonly type: NodeType.PointerReference;
64
+ readonly symbol: string;
65
+ readonly target: string;
66
+ }
67
+ /**
68
+ * `Link path/to/file.berry` or `Link http://example.com/file.berry`
69
+ *
70
+ * Grammar: link.grammer.ts
71
+ * Tokens: Link, LinkPath
72
+ */
73
+ export interface LinkStatementNode extends BaseNode {
74
+ readonly type: NodeType.LinkStatement;
75
+ readonly path: string;
76
+ }
77
+ /**
78
+ * `Input path/to/file.csv`
79
+ *
80
+ * Grammar: input.grammer.ts
81
+ * Tokens: Input, InputPath
82
+ */
83
+ export interface InputStatementNode extends BaseNode {
84
+ readonly type: NodeType.InputStatement;
85
+ readonly path: string;
86
+ }
87
+ /**
88
+ * `Api GET #myApi Some Title`
89
+ * followed by Url, Header, Body sub-blocks
90
+ *
91
+ * Grammar: api.grammer.ts
92
+ * Tokens: Api, ApiMethod, Hash, Identifier, Title
93
+ */
94
+ export interface ApiBlockNode extends BaseNode {
95
+ readonly type: NodeType.ApiBlock;
96
+ readonly method: string | null;
97
+ readonly name: string;
98
+ readonly title: string | null;
99
+ readonly url: UrlStatementNode | null;
100
+ readonly headers: HeaderBlockNode | null;
101
+ readonly body: BodyBlockNode | null;
102
+ }
103
+ /**
104
+ * `Url https://example.com/api`
105
+ *
106
+ * Grammar: api.grammer.ts (url rule)
107
+ * Tokens: Url, Value
108
+ */
109
+ export interface UrlStatementNode extends BaseNode {
110
+ readonly type: NodeType.UrlStatement;
111
+ readonly value: string;
112
+ }
113
+ /**
114
+ * `Header` followed by key-value pairs
115
+ *
116
+ * Grammar: api.grammer.ts (Header rule)
117
+ * Tokens: Header, then keyValueGrammer loop
118
+ */
119
+ export interface HeaderBlockNode extends BaseNode {
120
+ readonly type: NodeType.HeaderBlock;
121
+ readonly entries: ReadonlyArray<KeyValuePairNode>;
122
+ }
123
+ /**
124
+ * `Body json` followed by backtick-wrapped content
125
+ *
126
+ * Grammar: api.grammer.ts (Body rule)
127
+ * Tokens: Body, BodyType, Backtick, Scalar, Backtick
128
+ */
129
+ export interface BodyBlockNode extends BaseNode {
130
+ readonly type: NodeType.BodyBlock;
131
+ readonly bodyType: string;
132
+ readonly content: string;
133
+ }
134
+ /**
135
+ * `Task My Test Suite`
136
+ *
137
+ * Grammar: task.grammer.ts
138
+ * Tokens: Task, Title
139
+ */
140
+ export interface TaskBlockNode extends BaseNode {
141
+ readonly type: NodeType.TaskBlock;
142
+ readonly title: string | null;
143
+ readonly steps: ReadonlyArray<StepBlockNode>;
144
+ }
145
+ /**
146
+ * `Step Call Api myApi`
147
+ *
148
+ * Grammar: step.grammer.ts
149
+ * Tokens: Step, Call, Api, Identifier
150
+ */
151
+ export interface StepBlockNode extends BaseNode {
152
+ readonly type: NodeType.StepBlock;
153
+ readonly callType: string;
154
+ readonly targetType: string;
155
+ readonly targetName: string;
156
+ readonly params: ParamsBlockNode | null;
157
+ readonly capture: CaptureBlockNode | null;
158
+ readonly check: CheckBlockNode | null;
159
+ }
160
+ /**
161
+ * `Params` followed by key-value pairs
162
+ *
163
+ * Grammar: params.grammer.ts
164
+ * Tokens: Params, then keyValueGrammer loop
165
+ */
166
+ export interface ParamsBlockNode extends BaseNode {
167
+ readonly type: NodeType.ParamsBlock;
168
+ readonly entries: ReadonlyArray<KeyValuePairNode>;
169
+ }
170
+ /**
171
+ * `Capture` followed by key-value pairs
172
+ *
173
+ * Grammar: capture.grammer.ts
174
+ * Tokens: Capture, then keyValueGrammer loop
175
+ */
176
+ export interface CaptureBlockNode extends BaseNode {
177
+ readonly type: NodeType.CaptureBlock;
178
+ readonly entries: ReadonlyArray<KeyValuePairNode>;
179
+ }
180
+ /**
181
+ * `Check` followed by condition lines
182
+ *
183
+ * Grammar: check.grammer.ts
184
+ * Tokens: Check, then conditionGrammer loop
185
+ */
186
+ export interface CheckBlockNode extends BaseNode {
187
+ readonly type: NodeType.CheckBlock;
188
+ readonly conditions: ReadonlyArray<ConditionNode>;
189
+ }
190
+ /**
191
+ * `- key: value` or `- "key": "value"` or `- key: \`multiline\``
192
+ *
193
+ * Grammar: keyvalue.grammer.ts
194
+ * Tokens: Hyphen, (Quote?, Identifier, Quote?, Colon), (Quote?, Scalar/Identifier, Quote?) or (Backtick, Scalar, Backtick)
195
+ */
196
+ export interface KeyValuePairNode extends BaseNode {
197
+ readonly type: NodeType.KeyValuePair;
198
+ readonly key: string;
199
+ readonly value: string;
200
+ readonly isKeyQuoted: boolean;
201
+ readonly isValueQuoted: boolean;
202
+ readonly isMultiline: boolean;
203
+ readonly isEncrypted?: boolean;
204
+ }
205
+ /**
206
+ * `- lhs == rhs` with optional `OR` chains
207
+ *
208
+ * Grammar: conditions.grammer.ts
209
+ * Tokens: Hyphen, Lhs, Operator, Rhs, optional (Or, Lhs, Operator, Rhs)+
210
+ */
211
+ export interface ConditionNode extends BaseNode {
212
+ readonly type: NodeType.Condition;
213
+ readonly lhs: string;
214
+ readonly operator: string;
215
+ readonly rhs: string;
216
+ readonly orConditions: ReadonlyArray<BinaryExpressionNode>;
217
+ }
218
+ /**
219
+ * An OR-chained binary expression within a condition
220
+ *
221
+ * Tokens: Or, Lhs, Operator, Rhs
222
+ */
223
+ export interface BinaryExpressionNode extends BaseNode {
224
+ readonly type: NodeType.BinaryExpression;
225
+ readonly lhs: string;
226
+ readonly operator: string;
227
+ readonly rhs: string;
228
+ }
229
+ export interface IdentifierNode extends BaseNode {
230
+ readonly type: NodeType.Identifier;
231
+ readonly name: string;
232
+ }
233
+ export interface LiteralNode extends BaseNode {
234
+ readonly type: NodeType.Literal;
235
+ readonly value: string | number | boolean;
236
+ readonly raw: string;
237
+ }
238
+ export interface CommentNode extends BaseNode {
239
+ readonly type: NodeType.Comment;
240
+ readonly text: string;
241
+ }
242
+ export type ASTNode = ProgramNode | VarDeclarationNode | LinkStatementNode | InputStatementNode | PointerReferenceNode | ApiBlockNode | UrlStatementNode | HeaderBlockNode | BodyBlockNode | TaskBlockNode | StepBlockNode | ParamsBlockNode | CaptureBlockNode | CheckBlockNode | KeyValuePairNode | ConditionNode | BinaryExpressionNode | IdentifierNode | LiteralNode | CommentNode;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * AST Node Types for Flexiberry DSL
3
+ *
4
+ * Pure data interfaces — no methods, no logic.
5
+ * Each node type maps to a specific lexer grammar rule from reader_v2.
6
+ */
7
+ // ─── Node Type Discriminator ────────────────────────────────────────────────
8
+ export var NodeType;
9
+ (function (NodeType) {
10
+ NodeType["Program"] = "Program";
11
+ // Variable constructs
12
+ NodeType["VarDeclaration"] = "VarDeclaration";
13
+ NodeType["PointerReference"] = "PointerReference";
14
+ // Link & Input constructs
15
+ NodeType["LinkStatement"] = "LinkStatement";
16
+ NodeType["InputStatement"] = "InputStatement";
17
+ // API constructs
18
+ NodeType["ApiBlock"] = "ApiBlock";
19
+ NodeType["UrlStatement"] = "UrlStatement";
20
+ NodeType["HeaderBlock"] = "HeaderBlock";
21
+ NodeType["BodyBlock"] = "BodyBlock";
22
+ // Task / Step constructs
23
+ NodeType["TaskBlock"] = "TaskBlock";
24
+ NodeType["StepBlock"] = "StepBlock";
25
+ // Data constructs
26
+ NodeType["ParamsBlock"] = "ParamsBlock";
27
+ NodeType["CaptureBlock"] = "CaptureBlock";
28
+ NodeType["CheckBlock"] = "CheckBlock";
29
+ // Shared primitives
30
+ NodeType["KeyValuePair"] = "KeyValuePair";
31
+ NodeType["Condition"] = "Condition";
32
+ NodeType["BinaryExpression"] = "BinaryExpression";
33
+ // Terminals
34
+ NodeType["Identifier"] = "Identifier";
35
+ NodeType["Literal"] = "Literal";
36
+ NodeType["Comment"] = "Comment";
37
+ })(NodeType || (NodeType = {}));
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Berry Code Formatter
3
+ *
4
+ * Walks a ProgramNode AST and emits properly formatted Berry source code.
5
+ * This is a pure code-generator — no side effects, no runtime logic.
6
+ *
7
+ * Formatting rules:
8
+ * - Top-level blocks (Var, Api, Task) separated by blank lines
9
+ * - Api sub-blocks (Url, Header, Body) indented with no extra blank lines
10
+ * - Task → Step indented 1 level (8 spaces)
11
+ * - Step → Params/Capture/Check indented 2 levels (16 spaces)
12
+ * - Key-value entries indented under their parent with "- key: value"
13
+ * - Conditions indented under Check with "- lhs operator rhs"
14
+ */
15
+ import { ProgramNode } from "../ast/ast.types.js";
16
+ export interface FormatterOptions {
17
+ /** Number of spaces per indent level (default: 8) */
18
+ readonly indentSize: number;
19
+ /** Blank lines between top-level blocks (default: 1) */
20
+ readonly blankLinesBetweenBlocks: number;
21
+ /** Whether to quote key-value string values (default: true) */
22
+ readonly quoteValues: boolean;
23
+ }
24
+ export declare class BerryFormatter {
25
+ private readonly options;
26
+ constructor(options?: Partial<FormatterOptions>);
27
+ /** Format an entire AST back into Berry source code */
28
+ format(ast: ProgramNode): string;
29
+ private formatStatement;
30
+ private formatVarDeclaration;
31
+ private formatApiBlock;
32
+ private formatUrlStatement;
33
+ private formatHeaderBlock;
34
+ private formatBodyBlock;
35
+ private formatTaskBlock;
36
+ private formatStepBlock;
37
+ private formatParamsBlock;
38
+ private formatCaptureBlock;
39
+ private formatCheckBlock;
40
+ private formatKeyValuePair;
41
+ private formatCondition;
42
+ private formatComment;
43
+ private indent;
44
+ }
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Berry Code Formatter
3
+ *
4
+ * Walks a ProgramNode AST and emits properly formatted Berry source code.
5
+ * This is a pure code-generator — no side effects, no runtime logic.
6
+ *
7
+ * Formatting rules:
8
+ * - Top-level blocks (Var, Api, Task) separated by blank lines
9
+ * - Api sub-blocks (Url, Header, Body) indented with no extra blank lines
10
+ * - Task → Step indented 1 level (8 spaces)
11
+ * - Step → Params/Capture/Check indented 2 levels (16 spaces)
12
+ * - Key-value entries indented under their parent with "- key: value"
13
+ * - Conditions indented under Check with "- lhs operator rhs"
14
+ */
15
+ import { NodeType, } from "../ast/ast.types.js";
16
+ const DEFAULT_OPTIONS = {
17
+ indentSize: 8,
18
+ blankLinesBetweenBlocks: 1,
19
+ quoteValues: true,
20
+ };
21
+ // ─── Formatter ──────────────────────────────────────────────────────────────
22
+ export class BerryFormatter {
23
+ options;
24
+ constructor(options = {}) {
25
+ this.options = { ...DEFAULT_OPTIONS, ...options };
26
+ }
27
+ /** Format an entire AST back into Berry source code */
28
+ format(ast) {
29
+ const blocks = [];
30
+ for (const node of ast.body) {
31
+ const formatted = this.formatStatement(node);
32
+ if (formatted !== null) {
33
+ blocks.push(formatted);
34
+ }
35
+ }
36
+ const separator = "\n" + "\n".repeat(this.options.blankLinesBetweenBlocks);
37
+ return blocks.join(separator) + "\n";
38
+ }
39
+ // ── Statement Dispatch ──────────────────────────────────────────────────
40
+ formatStatement(node) {
41
+ switch (node.type) {
42
+ case NodeType.VarDeclaration:
43
+ return this.formatVarDeclaration(node);
44
+ case NodeType.ApiBlock:
45
+ return this.formatApiBlock(node);
46
+ case NodeType.TaskBlock:
47
+ return this.formatTaskBlock(node);
48
+ case NodeType.StepBlock:
49
+ return this.formatStepBlock(node, 0);
50
+ case NodeType.ParamsBlock:
51
+ return this.formatParamsBlock(node, 0);
52
+ case NodeType.CaptureBlock:
53
+ return this.formatCaptureBlock(node, 0);
54
+ case NodeType.CheckBlock:
55
+ return this.formatCheckBlock(node, 0);
56
+ case NodeType.Comment:
57
+ return this.formatComment(node);
58
+ default:
59
+ return null;
60
+ }
61
+ }
62
+ // ── Var Declaration ─────────────────────────────────────────────────────
63
+ formatVarDeclaration(node) {
64
+ const lines = [];
65
+ // Var header
66
+ let header = "Var";
67
+ if (node.pointer) {
68
+ header += ` ${node.pointer.symbol}${node.pointer.target}`;
69
+ }
70
+ if (node.title) {
71
+ header += ` ${node.title}`;
72
+ }
73
+ lines.push(header);
74
+ // Key-value entries (indented 1 level)
75
+ for (const entry of node.entries) {
76
+ lines.push(this.formatKeyValuePair(entry, 1));
77
+ }
78
+ return lines.join("\n");
79
+ }
80
+ // ── Api Block ───────────────────────────────────────────────────────────
81
+ formatApiBlock(node) {
82
+ const lines = [];
83
+ // Api header: Api METHOD #name title
84
+ let header = "Api";
85
+ if (node.method) {
86
+ header += ` ${node.method}`;
87
+ }
88
+ header += ` #${node.name}`;
89
+ if (node.title) {
90
+ header += ` ${node.title}`;
91
+ }
92
+ lines.push(header);
93
+ // Url
94
+ if (node.url) {
95
+ lines.push(this.formatUrlStatement(node.url));
96
+ }
97
+ // Header
98
+ if (node.headers) {
99
+ lines.push(this.formatHeaderBlock(node.headers));
100
+ }
101
+ // Body
102
+ if (node.body) {
103
+ lines.push(this.formatBodyBlock(node.body));
104
+ }
105
+ return lines.join("\n");
106
+ }
107
+ formatUrlStatement(node) {
108
+ return `Url ${node.value}`;
109
+ }
110
+ formatHeaderBlock(node) {
111
+ const lines = ["Header"];
112
+ for (const entry of node.entries) {
113
+ lines.push(this.formatKeyValuePair(entry, 0));
114
+ }
115
+ return lines.join("\n");
116
+ }
117
+ formatBodyBlock(node) {
118
+ return `Body ${node.bodyType} \`${node.content}\``;
119
+ }
120
+ // ── Task Block ──────────────────────────────────────────────────────────
121
+ formatTaskBlock(node) {
122
+ const lines = [];
123
+ let header = "Task";
124
+ if (node.title) {
125
+ header += ` ${node.title.trim()}`;
126
+ }
127
+ lines.push(header);
128
+ // Steps indented 1 level under Task
129
+ for (const step of node.steps) {
130
+ lines.push(this.formatStepBlock(step, 1));
131
+ }
132
+ return lines.join("\n");
133
+ }
134
+ // ── Step Block ──────────────────────────────────────────────────────────
135
+ formatStepBlock(node, indent) {
136
+ const lines = [];
137
+ const pad = this.indent(indent);
138
+ // Step Call Api <name>
139
+ lines.push(`${pad}Step ${node.callType} ${node.targetType} ${node.targetName}`);
140
+ // Sub-blocks indented one more level
141
+ const subIndent = indent + 1;
142
+ if (node.params) {
143
+ lines.push(this.formatParamsBlock(node.params, subIndent));
144
+ }
145
+ if (node.capture) {
146
+ lines.push(this.formatCaptureBlock(node.capture, subIndent));
147
+ }
148
+ if (node.check) {
149
+ lines.push(this.formatCheckBlock(node.check, subIndent));
150
+ }
151
+ return lines.join("\n");
152
+ }
153
+ // ── Params / Capture / Check ────────────────────────────────────────────
154
+ formatParamsBlock(node, indent) {
155
+ const pad = this.indent(indent);
156
+ const lines = [`${pad}Params`];
157
+ for (const entry of node.entries) {
158
+ lines.push(this.formatKeyValuePair(entry, indent));
159
+ }
160
+ return lines.join("\n");
161
+ }
162
+ formatCaptureBlock(node, indent) {
163
+ const pad = this.indent(indent);
164
+ const lines = [`${pad}Capture`];
165
+ for (const entry of node.entries) {
166
+ lines.push(this.formatKeyValuePair(entry, indent));
167
+ }
168
+ return lines.join("\n");
169
+ }
170
+ formatCheckBlock(node, indent) {
171
+ const pad = this.indent(indent);
172
+ const lines = [`${pad}Check`];
173
+ for (const condition of node.conditions) {
174
+ lines.push(this.formatCondition(condition, indent));
175
+ }
176
+ return lines.join("\n");
177
+ }
178
+ // ── Key-Value Pair ──────────────────────────────────────────────────────
179
+ formatKeyValuePair(node, indent) {
180
+ const pad = this.indent(indent);
181
+ // Format key
182
+ const key = node.isKeyQuoted ? `'${node.key}'` : node.key;
183
+ // Format value
184
+ let value;
185
+ if (node.isMultiline) {
186
+ value = `\`${node.value}\``;
187
+ }
188
+ else if (node.isValueQuoted || this.options.quoteValues) {
189
+ value = `'${node.value}'`;
190
+ }
191
+ else {
192
+ value = node.value;
193
+ }
194
+ return `${pad}- ${key}: ${value}`;
195
+ }
196
+ // ── Condition ─────────────────────────────────────────────────────────
197
+ formatCondition(node, indent) {
198
+ const pad = this.indent(indent);
199
+ let line = `${pad}- ${node.lhs} ${node.operator} ${node.rhs}`;
200
+ // Append OR chains
201
+ for (const orExpr of node.orConditions) {
202
+ line += ` OR ${orExpr.lhs} ${orExpr.operator} ${orExpr.rhs}`;
203
+ }
204
+ return line;
205
+ }
206
+ // ── Comment ─────────────────────────────────────────────────────────────
207
+ formatComment(node) {
208
+ return `##${node.text}`;
209
+ }
210
+ // ── Helpers ─────────────────────────────────────────────────────────────
211
+ indent(level) {
212
+ return " ".repeat(level * this.options.indentSize);
213
+ }
214
+ }
@@ -0,0 +1,2 @@
1
+ import { LexerGrammer } from "../lexer.types.js";
2
+ export declare const apiGrammer: LexerGrammer[];
@@ -0,0 +1,102 @@
1
+ import { TokenType } from "../../tokenType.js";
2
+ import { keyValueGrammer } from "./keyvalue.grammer.js";
3
+ export const apiGrammer = [
4
+ {
5
+ name: "api statement",
6
+ regex: /^\s*(Api)(?:\s+(GET|POST|PUT|DELETE|PATCH))?\s+((#)(\S+))(?:\s+(.*))?$/,
7
+ groups: [
8
+ {
9
+ tokenType: TokenType.Api,
10
+ index: 1,
11
+ },
12
+ {
13
+ tokenType: TokenType.ApiMethod,
14
+ index: 2,
15
+ },
16
+ {
17
+ tokenType: TokenType.Hash,
18
+ index: 4,
19
+ },
20
+ {
21
+ tokenType: TokenType.Identifier,
22
+ index: 5,
23
+ },
24
+ {
25
+ tokenType: TokenType.Title,
26
+ index: 6,
27
+ },
28
+ ],
29
+ isOptional: true,
30
+ isMultiline: false,
31
+ },
32
+ {
33
+ name: "url",
34
+ regex: /^\s*(Url)\s+(.*)$/,
35
+ groups: [
36
+ {
37
+ tokenType: TokenType.Url,
38
+ index: 1,
39
+ },
40
+ {
41
+ tokenType: TokenType.Value,
42
+ index: 2,
43
+ },
44
+ ],
45
+ isMultiline: false,
46
+ },
47
+ {
48
+ name: "Header",
49
+ regex: /^\s*(Header)/,
50
+ groups: [
51
+ {
52
+ tokenType: TokenType.Header,
53
+ index: 1,
54
+ },
55
+ ],
56
+ next: [
57
+ {
58
+ ...keyValueGrammer,
59
+ moveNextLine: true,
60
+ },
61
+ ],
62
+ isMultiline: false,
63
+ },
64
+ {
65
+ name: "Body",
66
+ regex: /^\s*(Body)\s(\w+)\s*/,
67
+ groups: [
68
+ {
69
+ tokenType: TokenType.Body,
70
+ index: 1,
71
+ },
72
+ {
73
+ tokenType: TokenType.BodyType,
74
+ index: 2,
75
+ },
76
+ ],
77
+ next: [
78
+ {
79
+ name: "multilineValue",
80
+ regex: /(`)([\s\S]*?)(`)/,
81
+ isOptional: false,
82
+ groups: [
83
+ {
84
+ tokenType: TokenType.Backtick,
85
+ index: 1,
86
+ },
87
+ {
88
+ tokenType: TokenType.Scalar,
89
+ index: 2,
90
+ },
91
+ {
92
+ tokenType: TokenType.Backtick,
93
+ index: 3,
94
+ },
95
+ ],
96
+ start: /(`)([\s\S]*?)/,
97
+ end: /(`)([\s\S]*?)(`)/,
98
+ mergeLines: true,
99
+ },
100
+ ],
101
+ },
102
+ ];
@@ -0,0 +1,2 @@
1
+ import { LexerGrammer } from "../lexer.types.js";
2
+ export declare const captureGrammer: LexerGrammer;
@@ -0,0 +1,21 @@
1
+ import { TokenType } from "../../tokenType.js";
2
+ import { keyValueGrammer } from "./keyvalue.grammer.js";
3
+ export const captureGrammer = {
4
+ name: "Capture",
5
+ regex: /^\s*(Capture)/,
6
+ groups: [
7
+ {
8
+ tokenType: TokenType.Capture,
9
+ index: 1,
10
+ },
11
+ ],
12
+ next: [
13
+ {
14
+ ...keyValueGrammer,
15
+ moveNextLine: true,
16
+ },
17
+ ],
18
+ isOptional: true,
19
+ isMultiline: false,
20
+ moveNextLine: true,
21
+ };
@@ -0,0 +1,2 @@
1
+ import { LexerGrammer } from "../lexer.types.js";
2
+ export declare const checkGrammer: LexerGrammer;
@@ -0,0 +1,21 @@
1
+ import { TokenType } from "../../tokenType.js";
2
+ import { conditionGrammer } from "./conditions.grammer.js";
3
+ export const checkGrammer = {
4
+ name: "Check",
5
+ regex: /^\s*(Check)/,
6
+ groups: [
7
+ {
8
+ tokenType: TokenType.Check,
9
+ index: 1,
10
+ },
11
+ ],
12
+ next: [
13
+ {
14
+ ...conditionGrammer,
15
+ moveNextLine: true,
16
+ },
17
+ ],
18
+ isOptional: true,
19
+ isMultiline: false,
20
+ moveNextLine: true,
21
+ };