agency-lang 0.0.57 → 0.0.59
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/README.md +1 -1
- package/dist/lib/backends/agencyGenerator.d.ts +4 -2
- package/dist/lib/backends/agencyGenerator.js +24 -2
- package/dist/lib/backends/typescriptGenerator.d.ts +2 -1
- package/dist/lib/backends/typescriptGenerator.js +12 -1
- package/dist/lib/cli/test.js +1 -1
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.js +2 -0
- package/dist/lib/parsers/function.js +2 -1
- package/dist/lib/parsers/importStatement.js +6 -2
- package/dist/lib/parsers/importStatement.test.js +134 -236
- package/dist/lib/simplemachine/error.d.ts +3 -0
- package/dist/lib/simplemachine/error.js +6 -0
- package/dist/lib/simplemachine/graph.d.ts +37 -0
- package/dist/lib/simplemachine/graph.js +283 -0
- package/dist/lib/simplemachine/index.d.ts +3 -0
- package/dist/lib/simplemachine/index.js +3 -0
- package/dist/lib/simplemachine/types.d.ts +39 -0
- package/dist/lib/simplemachine/types.js +23 -0
- package/dist/lib/simplemachine/util.d.ts +1 -0
- package/dist/lib/simplemachine/util.js +12 -0
- package/dist/lib/statelogClient.d.ts +74 -0
- package/dist/lib/statelogClient.js +144 -0
- package/dist/lib/templates/backends/graphGenerator/imports.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/imports.js +3 -4
- package/dist/lib/types/graphNode.d.ts +2 -0
- package/dist/lib/types/importStatement.d.ts +15 -1
- package/dist/lib/types/importStatement.js +10 -1
- package/dist/lib/types.d.ts +7 -0
- package/dist/lib/utils/node.js +6 -2
- package/package.json +1 -3
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@ import { TimeBlock } from "../types/timeBlock.js";
|
|
|
5
5
|
import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../types/access.js";
|
|
6
6
|
import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
|
|
7
7
|
import { FunctionCall, FunctionDefinition } from "../types/function.js";
|
|
8
|
-
import { GraphNodeDefinition } from "../types/graphNode.js";
|
|
8
|
+
import { GraphNodeDefinition, Visibility } from "../types/graphNode.js";
|
|
9
9
|
import { IfElse } from "../types/ifElse.js";
|
|
10
|
-
import { ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
|
|
10
|
+
import { ImportNameType, ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
|
|
11
11
|
import { MatchBlock } from "../types/matchBlock.js";
|
|
12
12
|
import { ReturnStatement } from "../types/returnStatement.js";
|
|
13
13
|
import { UsesTool } from "../types/tools.js";
|
|
@@ -55,8 +55,10 @@ export declare class AgencyGenerator extends BaseGenerator {
|
|
|
55
55
|
protected processReturnStatement(node: ReturnStatement): string;
|
|
56
56
|
protected processComment(node: AgencyComment): string;
|
|
57
57
|
protected processImportStatement(node: ImportStatement): string;
|
|
58
|
+
protected processImportNameType(node: ImportNameType): string;
|
|
58
59
|
protected processImportNodeStatement(node: ImportNodeStatement): string;
|
|
59
60
|
protected processImportToolStatement(node: ImportToolStatement): string;
|
|
61
|
+
protected visibilityToString(vis: Visibility): string;
|
|
60
62
|
protected processGraphNode(node: GraphNodeDefinition): string;
|
|
61
63
|
protected processTool(node: FunctionDefinition): string;
|
|
62
64
|
protected processUsesTool(node: UsesTool): string;
|
|
@@ -341,15 +341,36 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
341
341
|
return this.indentStr(`//${node.content}`);
|
|
342
342
|
}
|
|
343
343
|
processImportStatement(node) {
|
|
344
|
-
const
|
|
344
|
+
const importedNames = node.importedNames.map((name) => this.processImportNameType(name));
|
|
345
|
+
const str = this.indentStr(`import ${importedNames.join(", ")} from "${node.modulePath}"`);
|
|
345
346
|
return str;
|
|
346
347
|
}
|
|
348
|
+
processImportNameType(node) {
|
|
349
|
+
switch (node.type) {
|
|
350
|
+
case "namedImport":
|
|
351
|
+
return `{ ${node.importedNames.join(", ")} }`;
|
|
352
|
+
case "namespaceImport":
|
|
353
|
+
return `* as ${node.importedNames}`;
|
|
354
|
+
case "defaultImport":
|
|
355
|
+
return `${node.importedNames}`;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
347
358
|
processImportNodeStatement(node) {
|
|
348
359
|
return `import node { ${node.importedNodes.join(", ")} } from "${node.agencyFile}"`;
|
|
349
360
|
}
|
|
350
361
|
processImportToolStatement(node) {
|
|
351
362
|
return `import tool { ${node.importedTools.join(", ")} } from "${node.agencyFile}"`;
|
|
352
363
|
}
|
|
364
|
+
visibilityToString(vis) {
|
|
365
|
+
switch (vis) {
|
|
366
|
+
case "public":
|
|
367
|
+
return "public ";
|
|
368
|
+
case "private":
|
|
369
|
+
return "private ";
|
|
370
|
+
case undefined:
|
|
371
|
+
return "";
|
|
372
|
+
}
|
|
373
|
+
}
|
|
353
374
|
processGraphNode(node) {
|
|
354
375
|
// Graph nodes use similar syntax to functions
|
|
355
376
|
const { nodeName, body, parameters } = node;
|
|
@@ -361,7 +382,8 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
361
382
|
const returnTypeStr = node.returnType
|
|
362
383
|
? ": " + variableTypeToString(node.returnType, this.typeAliases)
|
|
363
384
|
: "";
|
|
364
|
-
|
|
385
|
+
const visibilityStr = this.visibilityToString(node.visibility);
|
|
386
|
+
let result = this.indentStr(`${visibilityStr}node ${nodeName}(${params})${returnTypeStr} {\n`);
|
|
365
387
|
this.increaseIndent();
|
|
366
388
|
const lines = [];
|
|
367
389
|
for (const stmt of body) {
|
|
@@ -6,7 +6,7 @@ import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../
|
|
|
6
6
|
import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
|
|
7
7
|
import { FunctionCall, FunctionDefinition } from "../types/function.js";
|
|
8
8
|
import { IfElse } from "../types/ifElse.js";
|
|
9
|
-
import { ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
|
|
9
|
+
import { ImportNameType, ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
|
|
10
10
|
import { MatchBlock } from "../types/matchBlock.js";
|
|
11
11
|
import { ReturnStatement } from "../types/returnStatement.js";
|
|
12
12
|
import { UsesTool } from "../types/tools.js";
|
|
@@ -68,6 +68,7 @@ export declare class TypeScriptGenerator extends BaseGenerator {
|
|
|
68
68
|
prompt: PromptLiteral;
|
|
69
69
|
}): string;
|
|
70
70
|
protected processImportStatement(node: ImportStatement): string;
|
|
71
|
+
protected processImportNameType(node: ImportNameType): string;
|
|
71
72
|
protected processImportNodeStatement(node: ImportNodeStatement): string;
|
|
72
73
|
protected processImportToolStatement(node: ImportToolStatement): string;
|
|
73
74
|
protected processWhileLoop(node: WhileLoop): string;
|
|
@@ -479,7 +479,18 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
479
479
|
});
|
|
480
480
|
}
|
|
481
481
|
processImportStatement(node) {
|
|
482
|
-
|
|
482
|
+
const importedNames = node.importedNames.map((name) => this.processImportNameType(name));
|
|
483
|
+
return `import ${importedNames.join(", ")} from "${node.modulePath.replace(/\.agency$/, ".js")}";`;
|
|
484
|
+
}
|
|
485
|
+
processImportNameType(node) {
|
|
486
|
+
switch (node.type) {
|
|
487
|
+
case "namedImport":
|
|
488
|
+
return `{ ${node.importedNames.join(", ")} }`;
|
|
489
|
+
case "namespaceImport":
|
|
490
|
+
return `* as ${node.importedNames}`;
|
|
491
|
+
case "defaultImport":
|
|
492
|
+
return `${node.importedNames}`;
|
|
493
|
+
}
|
|
483
494
|
}
|
|
484
495
|
processImportNodeStatement(node) {
|
|
485
496
|
return ""; // handled in preprocess in graphgenerator
|
package/dist/lib/cli/test.js
CHANGED
|
@@ -18,7 +18,7 @@ function writeTestCase(agencyFilename, nodeName, input, expectedOutput, evaluati
|
|
|
18
18
|
tests = JSON.parse(fs.readFileSync(testFilePath, "utf-8"));
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
|
-
tests = { sourceFile: agencyFilename, tests: [] };
|
|
21
|
+
tests = { sourceFile: path.basename(agencyFilename), tests: [] };
|
|
22
22
|
}
|
|
23
23
|
const testCase = {
|
|
24
24
|
nodeName,
|
package/dist/lib/index.d.ts
CHANGED
package/dist/lib/index.js
CHANGED
|
@@ -100,4 +100,5 @@ export const syncFunctionParser = (input) => {
|
|
|
100
100
|
return mappedParser(input);
|
|
101
101
|
};
|
|
102
102
|
export const functionParser = or(asyncFunctionParser, syncFunctionParser, _functionParser);
|
|
103
|
-
|
|
103
|
+
const visibilityParser = or(str("public"), str("private"), succeed(undefined));
|
|
104
|
+
export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), capture(visibilityParser, "visibility"), optionalSpaces, str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(sepBy(comma, or(functionParameterParserWithTypeHint, functionParameterParser)), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"), optionalSpacesOrNewline, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { alphanum, capture, captureCaptures, char, many1Till, many1WithJoin, map, newline, oneOf, optional, or, parseError, sepBy1, seqC, set, spaces, str, trace, } from "tarsec";
|
|
1
|
+
import { alphanum, capture, captureCaptures, char, many1Till, many1WithJoin, map, newline, oneOf, optional, or, parseError, sepBy, sepBy1, seqC, set, spaces, str, trace, } from "tarsec";
|
|
2
2
|
import { optionalSemicolon } from "./parserUtils.js";
|
|
3
3
|
import { comma, optionalSpaces } from "./utils.js";
|
|
4
4
|
// Helper parser for quoted file paths - supports both single and double quotes
|
|
@@ -7,4 +7,8 @@ const singleQuotedPath = seqC(char("'"), capture(many1Till(char("'")), "path"),
|
|
|
7
7
|
const quotedPath = map(or(doubleQuotedPath, singleQuotedPath), (res) => res.path);
|
|
8
8
|
export const importNodeStatmentParser = trace("importNodeStatement", seqC(set("type", "importNodeStatement"), str("import"), spaces, or(str("nodes"), str("node")), captureCaptures(parseError("expected a statement of the form `import nodes { x, y } from 'filename.agency'`", spaces, char("{"), optionalSpaces, capture(sepBy1(comma, many1WithJoin(alphanum)), "importedNodes"), optionalSpaces, char("}"), spaces, str("from"), spaces, capture(quotedPath, "agencyFile"), optionalSemicolon, optional(newline)))));
|
|
9
9
|
export const importToolStatmentParser = trace("importToolStatement", seqC(set("type", "importToolStatement"), str("import"), spaces, or(str("tools"), str("tool")), captureCaptures(parseError("expected a statement of the form `import tools { x, y } from 'filename.agency'`", spaces, char("{"), optionalSpaces, capture(sepBy1(comma, many1WithJoin(alphanum)), "importedTools"), optionalSpaces, char("}"), spaces, str("from"), spaces, capture(quotedPath, "agencyFile"), optionalSemicolon, optional(newline)))));
|
|
10
|
-
|
|
10
|
+
const namedImportParser = trace("namedImportParser", seqC(char("{"), optionalSpaces, capture(sepBy1(comma, many1WithJoin(alphanum)), "importedNames"), optionalSpaces, char("}"), set("type", "namedImport")));
|
|
11
|
+
const namespaceImportParser = trace("namespaceImportParser", seqC(many1Till(spaces), spaces, str("as"), spaces, capture(many1WithJoin(alphanum), "importedNames"), set("type", "namespaceImport")));
|
|
12
|
+
const defaultImportParser = trace("defaultImportParser", seqC(capture(many1WithJoin(alphanum), "importedNames"), set("type", "defaultImport")));
|
|
13
|
+
const importNameTypeParser = sepBy(comma, or(namedImportParser, namespaceImportParser, defaultImportParser));
|
|
14
|
+
export const importStatmentParser = trace("importStatement", seqC(set("type", "importStatement"), str("import"), captureCaptures(parseError("expected a statement of the form `import { x, y } from 'filename'`", spaces, capture(importNameTypeParser, "importedNames"), spaces, str("from"), spaces, oneOf(`'"`), capture(many1Till(oneOf(`'"`)), "modulePath"), oneOf(`'"`), optionalSemicolon, optional(newline)))));
|
|
@@ -1,249 +1,147 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import { importStatmentParser, importNodeStatmentParser, importToolStatmentParser, } from "./importStatement.js";
|
|
3
3
|
describe("importStatmentParser", () => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
expected: { success: false },
|
|
14
|
-
throws: true,
|
|
15
|
-
},
|
|
16
|
-
// Module paths with double quotes
|
|
17
|
-
{
|
|
18
|
-
input: 'import foo from "bar";',
|
|
19
|
-
expected: {
|
|
20
|
-
success: true,
|
|
21
|
-
result: {
|
|
22
|
-
type: "importStatement",
|
|
23
|
-
importedNames: "foo ",
|
|
24
|
-
modulePath: "bar",
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
input: 'import foo from "./local/path.js";',
|
|
30
|
-
expected: {
|
|
31
|
-
success: true,
|
|
32
|
-
result: {
|
|
33
|
-
type: "importStatement",
|
|
34
|
-
importedNames: "foo ",
|
|
35
|
-
modulePath: "./local/path.js",
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
input: 'import bar from "../utils/helper.js";',
|
|
41
|
-
expected: {
|
|
42
|
-
success: true,
|
|
43
|
-
result: {
|
|
44
|
-
type: "importStatement",
|
|
45
|
-
importedNames: "bar ",
|
|
46
|
-
modulePath: "../utils/helper.js",
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
input: 'import { useState } from "react";',
|
|
52
|
-
expected: {
|
|
53
|
-
success: true,
|
|
54
|
-
result: {
|
|
55
|
-
type: "importStatement",
|
|
56
|
-
importedNames: "{ useState } ",
|
|
57
|
-
modulePath: "react",
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
// Module paths with single quotes
|
|
62
|
-
{
|
|
63
|
-
input: "import foo from 'bar';",
|
|
64
|
-
expected: {
|
|
65
|
-
success: true,
|
|
66
|
-
result: {
|
|
67
|
-
type: "importStatement",
|
|
68
|
-
importedNames: "foo ",
|
|
69
|
-
modulePath: "bar",
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
input: "import test from './module.js';",
|
|
75
|
-
expected: {
|
|
76
|
-
success: true,
|
|
77
|
-
result: {
|
|
78
|
-
type: "importStatement",
|
|
79
|
-
importedNames: "test ",
|
|
80
|
-
modulePath: "./module.js",
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
// Without semicolon - unquoted paths no longer supported (start with "import" -> throw)
|
|
85
|
-
{
|
|
86
|
-
input: "import foo from bar\n",
|
|
87
|
-
expected: { success: false },
|
|
88
|
-
throws: true,
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
input: "import test from module",
|
|
92
|
-
expected: { success: false },
|
|
93
|
-
throws: true,
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
input: 'import foo from "bar"\n',
|
|
97
|
-
expected: {
|
|
98
|
-
success: true,
|
|
99
|
-
result: {
|
|
100
|
-
type: "importStatement",
|
|
101
|
-
importedNames: "foo ",
|
|
102
|
-
modulePath: "bar",
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
// Multiple imported names (destructured imports) - unquoted paths no longer supported (start with "import" -> throw)
|
|
107
|
-
{
|
|
108
|
-
input: "import { foo, bar } from module;",
|
|
109
|
-
expected: { success: false },
|
|
110
|
-
throws: true,
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
input: 'import { foo, bar, baz } from "myModule";',
|
|
114
|
-
expected: {
|
|
115
|
-
success: true,
|
|
116
|
-
result: {
|
|
117
|
-
type: "importStatement",
|
|
118
|
-
importedNames: "{ foo, bar, baz } ",
|
|
119
|
-
modulePath: "myModule",
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
// Default and named imports
|
|
124
|
-
{
|
|
125
|
-
input: 'import React, { useState } from "react";',
|
|
126
|
-
expected: {
|
|
127
|
-
success: true,
|
|
128
|
-
result: {
|
|
129
|
-
type: "importStatement",
|
|
130
|
-
importedNames: "React, { useState } ",
|
|
131
|
-
modulePath: "react",
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
// Namespace imports
|
|
136
|
-
{
|
|
137
|
-
input: 'import * as utils from "utils";',
|
|
138
|
-
expected: {
|
|
139
|
-
success: true,
|
|
140
|
-
result: {
|
|
141
|
-
type: "importStatement",
|
|
142
|
-
importedNames: "* as utils ",
|
|
143
|
-
modulePath: "utils",
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
// Scoped packages
|
|
148
|
-
{
|
|
149
|
-
input: 'import { Parser } from "@typescript-eslint/parser";',
|
|
150
|
-
expected: {
|
|
151
|
-
success: true,
|
|
152
|
-
result: {
|
|
153
|
-
type: "importStatement",
|
|
154
|
-
importedNames: "{ Parser } ",
|
|
155
|
-
modulePath: "@typescript-eslint/parser",
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
// Spaces around keywords - unquoted paths no longer supported (start with "import" -> throw)
|
|
160
|
-
{
|
|
161
|
-
input: "import foo from bar;",
|
|
162
|
-
expected: { success: false },
|
|
163
|
-
throws: true,
|
|
164
|
-
},
|
|
165
|
-
// Edge cases - single character names with unquoted path (start with "import" -> throw)
|
|
166
|
-
{
|
|
167
|
-
input: "import x from y;",
|
|
168
|
-
expected: { success: false },
|
|
169
|
-
throws: true,
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
input: 'import x from "y";',
|
|
173
|
-
expected: {
|
|
174
|
-
success: true,
|
|
175
|
-
result: {
|
|
176
|
-
type: "importStatement",
|
|
177
|
-
importedNames: "x ",
|
|
178
|
-
modulePath: "y",
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
// Complex paths - unquoted paths no longer supported (start with "import" -> throw)
|
|
183
|
-
{
|
|
184
|
-
input: "import foo from ../../../utils/helpers;",
|
|
185
|
-
expected: { success: false },
|
|
186
|
-
throws: true,
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
input: 'import foo from "../../../utils/helpers.js";',
|
|
190
|
-
expected: {
|
|
191
|
-
success: true,
|
|
192
|
-
result: {
|
|
193
|
-
type: "importStatement",
|
|
194
|
-
importedNames: "foo ",
|
|
195
|
-
modulePath: "../../../utils/helpers.js",
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
// Aliased imports
|
|
200
|
-
{
|
|
201
|
-
input: 'import { foo as bar } from "module";',
|
|
202
|
-
expected: {
|
|
203
|
-
success: true,
|
|
204
|
-
result: {
|
|
205
|
-
type: "importStatement",
|
|
206
|
-
importedNames: "{ foo as bar } ",
|
|
207
|
-
modulePath: "module",
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
// Failure cases - missing keywords (don't start with "import" -> don't throw)
|
|
212
|
-
{ input: "foo from bar;", expected: { success: false }, throws: false },
|
|
213
|
-
{ input: "from bar;", expected: { success: false }, throws: false },
|
|
214
|
-
{ input: "import foo bar;", expected: { success: false }, throws: true },
|
|
215
|
-
// Failure cases - missing parts (start with "import" -> throw)
|
|
216
|
-
{ input: "import from bar;", expected: { success: false }, throws: true },
|
|
217
|
-
{ input: "import foo from;", expected: { success: false }, throws: true },
|
|
218
|
-
{ input: "import;", expected: { success: false }, throws: true },
|
|
219
|
-
// Failure cases - empty input (doesn't start with "import" -> don't throw)
|
|
220
|
-
{ input: "", expected: { success: false }, throws: false },
|
|
221
|
-
// Failure cases - just keyword
|
|
222
|
-
{ input: "import", expected: { success: false }, throws: true },
|
|
223
|
-
{ input: "from", expected: { success: false }, throws: false },
|
|
224
|
-
];
|
|
225
|
-
testCases.forEach(({ input, expected, throws }) => {
|
|
226
|
-
if (expected.success) {
|
|
227
|
-
it(`should parse "${input}" successfully`, () => {
|
|
228
|
-
const result = importStatmentParser(input);
|
|
229
|
-
expect(result.success).toBe(true);
|
|
230
|
-
if (result.success) {
|
|
231
|
-
expect(result.result).toEqual(expected.result);
|
|
232
|
-
}
|
|
4
|
+
// Default imports
|
|
5
|
+
it('should parse: import foo from "./foo.ts"', () => {
|
|
6
|
+
const result = importStatmentParser('import foo from "./foo.ts"');
|
|
7
|
+
expect(result.success).toBe(true);
|
|
8
|
+
if (result.success) {
|
|
9
|
+
expect(result.result).toEqual({
|
|
10
|
+
type: "importStatement",
|
|
11
|
+
importedNames: [{ type: "defaultImport", importedNames: "foo" }],
|
|
12
|
+
modulePath: "./foo.ts",
|
|
233
13
|
});
|
|
234
14
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
15
|
+
});
|
|
16
|
+
// Named imports
|
|
17
|
+
it('should parse: import { foo } from "./foo.ts"', () => {
|
|
18
|
+
const result = importStatmentParser('import { foo } from "./foo.ts"');
|
|
19
|
+
expect(result.success).toBe(true);
|
|
20
|
+
if (result.success) {
|
|
21
|
+
expect(result.result).toEqual({
|
|
22
|
+
type: "importStatement",
|
|
23
|
+
importedNames: [{ type: "namedImport", importedNames: ["foo"] }],
|
|
24
|
+
modulePath: "./foo.ts",
|
|
238
25
|
});
|
|
239
26
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
27
|
+
});
|
|
28
|
+
// Default + named imports
|
|
29
|
+
it('should parse: import foo, { bar } from "./foo.ts"', () => {
|
|
30
|
+
const result = importStatmentParser('import foo, { bar } from "./foo.ts"');
|
|
31
|
+
expect(result.success).toBe(true);
|
|
32
|
+
if (result.success) {
|
|
33
|
+
expect(result.result).toEqual({
|
|
34
|
+
type: "importStatement",
|
|
35
|
+
importedNames: [
|
|
36
|
+
{ type: "defaultImport", importedNames: "foo" },
|
|
37
|
+
{ type: "namedImport", importedNames: ["bar"] },
|
|
38
|
+
],
|
|
39
|
+
modulePath: "./foo.ts",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
// Namespace imports
|
|
44
|
+
it('should parse: import * as foo from "./foo.ts"', () => {
|
|
45
|
+
const result = importStatmentParser('import * as foo from "./foo.ts"');
|
|
46
|
+
expect(result.success).toBe(true);
|
|
47
|
+
if (result.success) {
|
|
48
|
+
expect(result.result).toEqual({
|
|
49
|
+
type: "importStatement",
|
|
50
|
+
importedNames: [{ type: "namespaceImport", importedNames: "foo" }],
|
|
51
|
+
modulePath: "./foo.ts",
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// Default + namespace imports
|
|
56
|
+
it('should parse: import foo, * as bar from "./foo.ts"', () => {
|
|
57
|
+
const result = importStatmentParser('import foo, * as bar from "./foo.ts"');
|
|
58
|
+
expect(result.success).toBe(true);
|
|
59
|
+
if (result.success) {
|
|
60
|
+
expect(result.result).toEqual({
|
|
61
|
+
type: "importStatement",
|
|
62
|
+
importedNames: [
|
|
63
|
+
{ type: "defaultImport", importedNames: "foo" },
|
|
64
|
+
{ type: "namespaceImport", importedNames: "bar" },
|
|
65
|
+
],
|
|
66
|
+
modulePath: "./foo.ts",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
// .agency file imports
|
|
71
|
+
it('should parse: import foo from "./foo.agency"', () => {
|
|
72
|
+
const result = importStatmentParser('import foo from "./foo.agency"');
|
|
73
|
+
expect(result.success).toBe(true);
|
|
74
|
+
if (result.success) {
|
|
75
|
+
expect(result.result).toEqual({
|
|
76
|
+
type: "importStatement",
|
|
77
|
+
importedNames: [{ type: "defaultImport", importedNames: "foo" }],
|
|
78
|
+
modulePath: "./foo.agency",
|
|
244
79
|
});
|
|
245
80
|
}
|
|
246
81
|
});
|
|
82
|
+
it('should parse: import { foo } from "./foo.agency"', () => {
|
|
83
|
+
const result = importStatmentParser('import { foo } from "./foo.agency"');
|
|
84
|
+
expect(result.success).toBe(true);
|
|
85
|
+
if (result.success) {
|
|
86
|
+
expect(result.result).toEqual({
|
|
87
|
+
type: "importStatement",
|
|
88
|
+
importedNames: [{ type: "namedImport", importedNames: ["foo"] }],
|
|
89
|
+
modulePath: "./foo.agency",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// node/tool imports are handled by their own parsers, not importStatmentParser
|
|
94
|
+
it('should not parse: import node { foo } from "./foo.agency"', () => {
|
|
95
|
+
expect(() => importStatmentParser('import node { foo } from "./foo.agency"')).toThrow();
|
|
96
|
+
});
|
|
97
|
+
it('should not parse: import tool { foo } from "./foo.agency"', () => {
|
|
98
|
+
expect(() => importStatmentParser('import tool { foo } from "./foo.agency"')).toThrow();
|
|
99
|
+
});
|
|
100
|
+
// Multiple named imports
|
|
101
|
+
it('should parse: import { foo, bar, baz } from "myModule"', () => {
|
|
102
|
+
const result = importStatmentParser('import { foo, bar, baz } from "myModule"');
|
|
103
|
+
expect(result.success).toBe(true);
|
|
104
|
+
if (result.success) {
|
|
105
|
+
expect(result.result).toEqual({
|
|
106
|
+
type: "importStatement",
|
|
107
|
+
importedNames: [
|
|
108
|
+
{ type: "namedImport", importedNames: ["foo", "bar", "baz"] },
|
|
109
|
+
],
|
|
110
|
+
modulePath: "myModule",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
// With semicolons
|
|
115
|
+
it('should parse imports with semicolons', () => {
|
|
116
|
+
const result = importStatmentParser('import foo from "./foo.ts";');
|
|
117
|
+
expect(result.success).toBe(true);
|
|
118
|
+
if (result.success) {
|
|
119
|
+
expect(result.result.modulePath).toBe("./foo.ts");
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
// With single quotes
|
|
123
|
+
it("should parse imports with single quotes", () => {
|
|
124
|
+
const result = importStatmentParser("import foo from './foo.ts'");
|
|
125
|
+
expect(result.success).toBe(true);
|
|
126
|
+
if (result.success) {
|
|
127
|
+
expect(result.result.modulePath).toBe("./foo.ts");
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
// Failure cases
|
|
131
|
+
it("should fail on empty input", () => {
|
|
132
|
+
const result = importStatmentParser("");
|
|
133
|
+
expect(result.success).toBe(false);
|
|
134
|
+
});
|
|
135
|
+
it("should fail on non-import input", () => {
|
|
136
|
+
const result = importStatmentParser("foo from bar;");
|
|
137
|
+
expect(result.success).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
it("should throw on unquoted paths", () => {
|
|
140
|
+
expect(() => importStatmentParser("import foo from bar;")).toThrow();
|
|
141
|
+
});
|
|
142
|
+
it("should throw on missing parts", () => {
|
|
143
|
+
expect(() => importStatmentParser("import foo from;")).toThrow();
|
|
144
|
+
});
|
|
247
145
|
});
|
|
248
146
|
describe("importNodeStatmentParser", () => {
|
|
249
147
|
const testCases = [
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ConditionalFunc, Edge, SimpleMachineConfig } from "./types.js";
|
|
2
|
+
export declare class GoToNode<T> {
|
|
3
|
+
to: string;
|
|
4
|
+
data: T;
|
|
5
|
+
constructor(to: string, data: T);
|
|
6
|
+
}
|
|
7
|
+
export declare function goToNode<T>(to: string, data: T): GoToNode<T>;
|
|
8
|
+
export declare class SimpleMachine<T> {
|
|
9
|
+
private nodes;
|
|
10
|
+
private edges;
|
|
11
|
+
private config;
|
|
12
|
+
private statelogClient;
|
|
13
|
+
private nodesTraversed;
|
|
14
|
+
constructor(config?: SimpleMachineConfig<T>);
|
|
15
|
+
node(id: string, func: (data: T) => Promise<T | GoToNode<T>>): void;
|
|
16
|
+
edge(from: string, to: string): void;
|
|
17
|
+
conditionalEdge<const Adjacent extends string>(from: string, adjacentNodes: readonly Adjacent[], to?: ConditionalFunc<T, Adjacent>): void;
|
|
18
|
+
debug(message: string, data?: T): void;
|
|
19
|
+
getNodesTraversed(): readonly string[];
|
|
20
|
+
run(startId: string, input: T): Promise<T>;
|
|
21
|
+
runAndValidate(nodeFunc: (data: T) => Promise<T | GoToNode<T>>, currentId: string, _data: T, retries?: number): Promise<T | GoToNode<T>>;
|
|
22
|
+
prettyPrint(): void;
|
|
23
|
+
prettyPrintEdge(edge: Edge<T, string>): string;
|
|
24
|
+
toMermaid(): string;
|
|
25
|
+
merge(another: SimpleMachine<T>): void;
|
|
26
|
+
toJSON(): {
|
|
27
|
+
nodes: string[];
|
|
28
|
+
edges: Record<string, string[]>;
|
|
29
|
+
config: {
|
|
30
|
+
debug: {
|
|
31
|
+
log?: boolean;
|
|
32
|
+
logData?: boolean;
|
|
33
|
+
} | undefined;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
private validateGoToNodeTarget;
|
|
37
|
+
}
|