@valkyrjaio/sindri 26.3.0 → 26.4.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/dist/bin/sindri.cjs +444 -102
- package/package.json +2 -2
- package/src/Sindri/Ast/Abstract/AstReader.ts +170 -29
- package/src/Sindri/Ast/Data/Result/RouteProviderResult.ts +7 -0
- package/src/Sindri/Ast/RouteProviderReader.ts +31 -1
- package/src/Sindri/Constant/SindriInfo.ts +2 -2
- package/src/Sindri/Generate/Abstract/GenerateDataFromAst.ts +157 -5
- package/src/Sindri/Generator/Abstract/AstFileGenerator.ts +15 -1
- package/src/Sindri/Generator/Ast/Cli/AstCliDataFileGenerator.ts +51 -13
- package/src/Sindri/Generator/Ast/Container/AstContainerDataFileGenerator.ts +16 -3
- package/src/Sindri/Generator/Ast/Event/AstEventDataFileGenerator.ts +23 -4
- package/src/Sindri/Generator/Ast/Http/AstHttpDataFileGenerator.ts +25 -9
|
@@ -14,6 +14,23 @@ import type { CliDataFileGeneratorContract } from '../../Cli/Contract/CliDataFil
|
|
|
14
14
|
import type { GenerateStatus } from '../../Enum/GenerateStatus.ts';
|
|
15
15
|
|
|
16
16
|
export class AstCliDataFileGenerator extends AstFileGenerator implements CliDataFileGeneratorContract {
|
|
17
|
+
/** The framework classes every generated CLI data file imports as values. */
|
|
18
|
+
protected static readonly FRAMEWORK_IMPORTS: Readonly<Record<string, string>> = {
|
|
19
|
+
CliRoutingData: '@valkyrjaio/valkyrja/Cli/Routing/Data/CliRoutingData.ts',
|
|
20
|
+
Route: '@valkyrjaio/valkyrja/Cli/Routing/Data/Route.ts',
|
|
21
|
+
ArgumentParameter: '@valkyrjaio/valkyrja/Cli/Routing/Data/ArgumentParameter.ts',
|
|
22
|
+
OptionParameter: '@valkyrjaio/valkyrja/Cli/Routing/Data/OptionParameter.ts',
|
|
23
|
+
ArgumentMode: '@valkyrjaio/valkyrja/Cli/Routing/Enum/ArgumentMode.ts',
|
|
24
|
+
ArgumentValueMode: '@valkyrjaio/valkyrja/Cli/Routing/Enum/ArgumentValueMode.ts',
|
|
25
|
+
OptionMode: '@valkyrjaio/valkyrja/Cli/Routing/Enum/OptionMode.ts',
|
|
26
|
+
OptionValueMode: '@valkyrjaio/valkyrja/Cli/Routing/Enum/OptionValueMode.ts',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** The framework types every generated CLI data file imports. */
|
|
30
|
+
protected static readonly FRAMEWORK_TYPE_IMPORTS: Readonly<Record<string, string>> = {
|
|
31
|
+
RouteContract: '@valkyrjaio/valkyrja/Cli/Routing/Data/Contract/RouteContract.ts',
|
|
32
|
+
};
|
|
33
|
+
|
|
17
34
|
public classImportMap: Record<string, string> = {};
|
|
18
35
|
|
|
19
36
|
private readonly printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
@@ -32,22 +49,18 @@ export class AstCliDataFileGenerator extends AstFileGenerator implements CliData
|
|
|
32
49
|
namespace: string,
|
|
33
50
|
routes: Record<string, ts.Expression>,
|
|
34
51
|
): GenerateStatus {
|
|
35
|
-
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap
|
|
52
|
+
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap, [
|
|
53
|
+
...Object.keys(AstCliDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
54
|
+
...Object.keys(AstCliDataFileGenerator.FRAMEWORK_TYPE_IMPORTS),
|
|
55
|
+
]);
|
|
36
56
|
|
|
37
57
|
const contents = this.generateClassContents(routes);
|
|
38
58
|
|
|
39
59
|
const data = [
|
|
40
60
|
'// This file was automatically generated by Sindri.',
|
|
41
61
|
'',
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
`import { ArgumentParameter } from '@valkyrjaio/valkyrja/Cli/Routing/Data/ArgumentParameter.ts';`,
|
|
45
|
-
`import { OptionParameter } from '@valkyrjaio/valkyrja/Cli/Routing/Data/OptionParameter.ts';`,
|
|
46
|
-
`import { ArgumentMode } from '@valkyrjaio/valkyrja/Cli/Routing/Enum/ArgumentMode.ts';`,
|
|
47
|
-
`import { ArgumentValueMode } from '@valkyrjaio/valkyrja/Cli/Routing/Enum/ArgumentValueMode.ts';`,
|
|
48
|
-
`import { OptionMode } from '@valkyrjaio/valkyrja/Cli/Routing/Enum/OptionMode.ts';`,
|
|
49
|
-
`import { OptionValueMode } from '@valkyrjaio/valkyrja/Cli/Routing/Enum/OptionValueMode.ts';`,
|
|
50
|
-
`import type { RouteContract } from '@valkyrjaio/valkyrja/Cli/Routing/Data/Contract/RouteContract.ts';`,
|
|
62
|
+
...this.buildFrameworkImportLines(AstCliDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
63
|
+
...this.buildFrameworkImportLines(AstCliDataFileGenerator.FRAMEWORK_TYPE_IMPORTS, true),
|
|
51
64
|
userImportsBlock,
|
|
52
65
|
`export class ${className} extends CliRoutingData {`,
|
|
53
66
|
` constructor() {`,
|
|
@@ -78,18 +91,43 @@ export class AstCliDataFileGenerator extends AstFileGenerator implements CliData
|
|
|
78
91
|
continue;
|
|
79
92
|
}
|
|
80
93
|
|
|
81
|
-
const
|
|
94
|
+
const key = this.routeKey((expr.arguments ?? [])[0]);
|
|
82
95
|
|
|
83
|
-
if (
|
|
96
|
+
if (key === undefined) {
|
|
84
97
|
continue;
|
|
85
98
|
}
|
|
86
99
|
|
|
87
|
-
routes[
|
|
100
|
+
routes[key] = expr;
|
|
88
101
|
}
|
|
89
102
|
|
|
90
103
|
return this.generateFile(directory, className, namespace, routes);
|
|
91
104
|
}
|
|
92
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Derive the map key for a route from its name argument.
|
|
108
|
+
*
|
|
109
|
+
* A literal name keys the map by its own text. A constant reference
|
|
110
|
+
* (`CliCommandName.LIST` — how the framework's own commands name
|
|
111
|
+
* themselves) is kept as a `Class::CASE` marker, so the generated file
|
|
112
|
+
* emits the constant reference as a computed key rather than baking in the
|
|
113
|
+
* value it happens to hold today.
|
|
114
|
+
*/
|
|
115
|
+
protected routeKey(nameArg: ts.Expression | undefined): string | undefined {
|
|
116
|
+
if (nameArg === undefined) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (ts.isStringLiteral(nameArg)) {
|
|
121
|
+
return nameArg.text;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (ts.isPropertyAccessExpression(nameArg) && ts.isIdentifier(nameArg.expression)) {
|
|
125
|
+
return `${nameArg.expression.text}::${nameArg.name.text}`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
|
|
93
131
|
public generateClassContents(routes: Record<string, ts.Expression>): string {
|
|
94
132
|
const entries = Object.entries(routes);
|
|
95
133
|
|
|
@@ -14,6 +14,16 @@ import type { ContainerDataFileGeneratorContract } from '../../Container/Contrac
|
|
|
14
14
|
import type { GenerateStatus } from '../../Enum/GenerateStatus.ts';
|
|
15
15
|
|
|
16
16
|
export class AstContainerDataFileGenerator extends AstFileGenerator implements ContainerDataFileGeneratorContract {
|
|
17
|
+
/** The framework class every generated container data file imports as a value. */
|
|
18
|
+
protected static readonly FRAMEWORK_IMPORTS: Readonly<Record<string, string>> = {
|
|
19
|
+
ContainerData: '@valkyrjaio/valkyrja/Container/Data/ContainerData.ts',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** The framework type every generated container data file imports. */
|
|
23
|
+
protected static readonly FRAMEWORK_TYPE_IMPORTS: Readonly<Record<string, string>> = {
|
|
24
|
+
ContainerContract: '@valkyrjaio/valkyrja/Container/Manager/Contract/ContainerContract.ts',
|
|
25
|
+
};
|
|
26
|
+
|
|
17
27
|
public classImportMap: Record<string, string> = {};
|
|
18
28
|
|
|
19
29
|
private readonly printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
@@ -32,15 +42,18 @@ export class AstContainerDataFileGenerator extends AstFileGenerator implements C
|
|
|
32
42
|
namespace: string,
|
|
33
43
|
publishers: Readonly<Record<string, readonly [string, string]>>,
|
|
34
44
|
): GenerateStatus {
|
|
35
|
-
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap
|
|
45
|
+
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap, [
|
|
46
|
+
...Object.keys(AstContainerDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
47
|
+
...Object.keys(AstContainerDataFileGenerator.FRAMEWORK_TYPE_IMPORTS),
|
|
48
|
+
]);
|
|
36
49
|
|
|
37
50
|
const contents = this.generateClassContents(publishers);
|
|
38
51
|
|
|
39
52
|
const data = [
|
|
40
53
|
'// This file was automatically generated by Sindri.',
|
|
41
54
|
'',
|
|
42
|
-
|
|
43
|
-
|
|
55
|
+
...this.buildFrameworkImportLines(AstContainerDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
56
|
+
...this.buildFrameworkImportLines(AstContainerDataFileGenerator.FRAMEWORK_TYPE_IMPORTS, true),
|
|
44
57
|
userImportsBlock,
|
|
45
58
|
`export class ${className} extends ContainerData {`,
|
|
46
59
|
` constructor() {`,
|
|
@@ -14,6 +14,21 @@ import type { EventDataFileGeneratorContract } from '../../Event/Contract/EventD
|
|
|
14
14
|
import type { GenerateStatus } from '../../Enum/GenerateStatus.ts';
|
|
15
15
|
|
|
16
16
|
export class AstEventDataFileGenerator extends AstFileGenerator implements EventDataFileGeneratorContract {
|
|
17
|
+
/** The framework class every generated event data file imports as a value. */
|
|
18
|
+
protected static readonly FRAMEWORK_IMPORTS: Readonly<Record<string, string>> = {
|
|
19
|
+
EventData: '@valkyrjaio/valkyrja/Event/Data/EventData.ts',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** The framework classes a generated event data file imports only when it holds listeners. */
|
|
23
|
+
protected static readonly LISTENER_IMPORTS: Readonly<Record<string, string>> = {
|
|
24
|
+
Listener: '@valkyrjaio/valkyrja/Event/Data/Listener.ts',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** The framework types a generated event data file imports only when it holds listeners. */
|
|
28
|
+
protected static readonly LISTENER_TYPE_IMPORTS: Readonly<Record<string, string>> = {
|
|
29
|
+
ListenerContract: '@valkyrjaio/valkyrja/Event/Data/Contract/ListenerContract.ts',
|
|
30
|
+
};
|
|
31
|
+
|
|
17
32
|
public classImportMap: Record<string, string> = {};
|
|
18
33
|
|
|
19
34
|
private readonly printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
@@ -32,7 +47,11 @@ export class AstEventDataFileGenerator extends AstFileGenerator implements Event
|
|
|
32
47
|
namespace: string,
|
|
33
48
|
listeners: Record<string, ts.Expression>,
|
|
34
49
|
): GenerateStatus {
|
|
35
|
-
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap
|
|
50
|
+
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap, [
|
|
51
|
+
...Object.keys(AstEventDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
52
|
+
...Object.keys(AstEventDataFileGenerator.LISTENER_IMPORTS),
|
|
53
|
+
...Object.keys(AstEventDataFileGenerator.LISTENER_TYPE_IMPORTS),
|
|
54
|
+
]);
|
|
36
55
|
|
|
37
56
|
const contents = this.generateClassContents(listeners);
|
|
38
57
|
|
|
@@ -42,15 +61,15 @@ export class AstEventDataFileGenerator extends AstFileGenerator implements Event
|
|
|
42
61
|
const listenerImports =
|
|
43
62
|
Object.keys(listeners).length > 0
|
|
44
63
|
? [
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
...this.buildFrameworkImportLines(AstEventDataFileGenerator.LISTENER_IMPORTS),
|
|
65
|
+
...this.buildFrameworkImportLines(AstEventDataFileGenerator.LISTENER_TYPE_IMPORTS, true),
|
|
47
66
|
]
|
|
48
67
|
: [];
|
|
49
68
|
|
|
50
69
|
const data = [
|
|
51
70
|
'// This file was automatically generated by Sindri.',
|
|
52
71
|
'',
|
|
53
|
-
|
|
72
|
+
...this.buildFrameworkImportLines(AstEventDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
54
73
|
...listenerImports,
|
|
55
74
|
userImportsBlock,
|
|
56
75
|
`export class ${className} extends EventData {`,
|
|
@@ -34,6 +34,21 @@ interface ImperativeRouteMeta {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export class AstHttpDataFileGenerator extends AstFileGenerator implements HttpDataFileGeneratorContract {
|
|
37
|
+
/** The framework classes every generated HTTP data file imports as values. */
|
|
38
|
+
protected static readonly FRAMEWORK_IMPORTS: Readonly<Record<string, string>> = {
|
|
39
|
+
HttpRoutingData: '@valkyrjaio/valkyrja/Http/Routing/Data/HttpRoutingData.ts',
|
|
40
|
+
DynamicRoute: '@valkyrjaio/valkyrja/Http/Routing/Data/DynamicRoute.ts',
|
|
41
|
+
Route: '@valkyrjaio/valkyrja/Http/Routing/Data/Route.ts',
|
|
42
|
+
Parameter: '@valkyrjaio/valkyrja/Http/Routing/Data/Parameter.ts',
|
|
43
|
+
RequestMethod: '@valkyrjaio/valkyrja/Http/Message/Enum/RequestMethod.ts',
|
|
44
|
+
Regex: '@valkyrjaio/valkyrja/Http/Routing/Constant/Regex.ts',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** The framework types every generated HTTP data file imports. */
|
|
48
|
+
protected static readonly FRAMEWORK_TYPE_IMPORTS: Readonly<Record<string, string>> = {
|
|
49
|
+
RouteContract: '@valkyrjaio/valkyrja/Http/Routing/Data/Contract/RouteContract.ts',
|
|
50
|
+
};
|
|
51
|
+
|
|
37
52
|
public classImportMap: Record<string, string> = {};
|
|
38
53
|
|
|
39
54
|
protected readonly processor: ProcessorContract;
|
|
@@ -60,7 +75,10 @@ export class AstHttpDataFileGenerator extends AstFileGenerator implements HttpDa
|
|
|
60
75
|
routes: Record<string, ts.Expression>,
|
|
61
76
|
routeData: Record<string, HttpRouteData>,
|
|
62
77
|
): GenerateStatus {
|
|
63
|
-
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap
|
|
78
|
+
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap, [
|
|
79
|
+
...Object.keys(AstHttpDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
80
|
+
...Object.keys(AstHttpDataFileGenerator.FRAMEWORK_TYPE_IMPORTS),
|
|
81
|
+
]);
|
|
64
82
|
|
|
65
83
|
const routesContent = this.getRoutesAsContent(routes, routeData);
|
|
66
84
|
const paths = this.printNestedObject(this.buildPaths(routeData));
|
|
@@ -87,7 +105,10 @@ export class AstHttpDataFileGenerator extends AstFileGenerator implements HttpDa
|
|
|
87
105
|
_namespace: string,
|
|
88
106
|
routeExprs: readonly ts.Expression[],
|
|
89
107
|
): GenerateStatus {
|
|
90
|
-
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap
|
|
108
|
+
const userImportsBlock = this.buildUserImportsBlock(this.classImportMap, [
|
|
109
|
+
...Object.keys(AstHttpDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
110
|
+
...Object.keys(AstHttpDataFileGenerator.FRAMEWORK_TYPE_IMPORTS),
|
|
111
|
+
]);
|
|
91
112
|
|
|
92
113
|
const metas = routeExprs
|
|
93
114
|
.map((expr) => this.extractRouteMeta(expr))
|
|
@@ -114,13 +135,8 @@ export class AstHttpDataFileGenerator extends AstFileGenerator implements HttpDa
|
|
|
114
135
|
return [
|
|
115
136
|
'// This file was automatically generated by Sindri.',
|
|
116
137
|
'',
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
`import { Route } from '@valkyrjaio/valkyrja/Http/Routing/Data/Route.ts';`,
|
|
120
|
-
`import { Parameter } from '@valkyrjaio/valkyrja/Http/Routing/Data/Parameter.ts';`,
|
|
121
|
-
`import { RequestMethod } from '@valkyrjaio/valkyrja/Http/Message/Enum/RequestMethod.ts';`,
|
|
122
|
-
`import { Regex } from '@valkyrjaio/valkyrja/Http/Routing/Constant/Regex.ts';`,
|
|
123
|
-
`import type { RouteContract } from '@valkyrjaio/valkyrja/Http/Routing/Data/Contract/RouteContract.ts';`,
|
|
138
|
+
...this.buildFrameworkImportLines(AstHttpDataFileGenerator.FRAMEWORK_IMPORTS),
|
|
139
|
+
...this.buildFrameworkImportLines(AstHttpDataFileGenerator.FRAMEWORK_TYPE_IMPORTS, true),
|
|
124
140
|
userImportsBlock,
|
|
125
141
|
`export class ${className} extends HttpRoutingData {`,
|
|
126
142
|
` constructor() {`,
|