igniteui-cli 13.2.1-beta.0 → 13.2.2-beta.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/lib/templates/IgniteUIForReactTemplate.d.ts +1 -0
- package/lib/templates/IgniteUIForReactTemplate.js +36 -11
- package/lib/templates/IgniteUIForWebComponentsTemplate.js +33 -5
- package/package.json +3 -3
- package/templates/react/ReactTypeScriptFileUpdate.d.ts +10 -49
- package/templates/react/ReactTypeScriptFileUpdate.js +60 -336
- package/templates/react/types/ReactRouteEntry.d.ts +6 -0
- package/templates/react/types/ReactRouteEntry.js +2 -0
- package/templates/react/types/ReactRouteLike.d.ts +25 -0
- package/templates/react/types/ReactRouteLike.js +2 -0
- package/templates/react/types/ReactRouteTarget.d.ts +7 -0
- package/templates/react/types/ReactRouteTarget.js +11 -0
- package/templates/react/types/index.d.ts +3 -0
- package/templates/react/types/index.js +19 -0
- package/templates/webcomponents/WebComponentsTypeScriptFileUpdate.d.ts +11 -0
- package/templates/webcomponents/WebComponentsTypeScriptFileUpdate.js +82 -0
- package/templates/webcomponents/TypeScriptFileUpdate.d.ts +0 -52
- package/templates/webcomponents/TypeScriptFileUpdate.js +0 -341
|
@@ -28,6 +28,7 @@ export declare class IgniteUIForReactTemplate implements Template {
|
|
|
28
28
|
getExtraConfiguration(): ControlExtraConfiguration[];
|
|
29
29
|
setExtraConfiguration(extraConfigKeys: {}): void;
|
|
30
30
|
protected folderName(pathName: string): string;
|
|
31
|
+
protected fileName(pathName: string): string;
|
|
31
32
|
protected registerJSONRoute(projectPath: string, name: string, routingModulePath: string): void;
|
|
32
33
|
protected getViewLink(name: string): string;
|
|
33
34
|
protected getToolbarLink(name: string): string;
|
|
@@ -5,6 +5,7 @@ const cli_core_1 = require("@igniteui/cli-core");
|
|
|
5
5
|
const fs = require("fs-extra");
|
|
6
6
|
const path = require("path");
|
|
7
7
|
const ReactTypeScriptFileUpdate_1 = require("../../templates/react/ReactTypeScriptFileUpdate");
|
|
8
|
+
const typescript_1 = require("typescript");
|
|
8
9
|
class IgniteUIForReactTemplate {
|
|
9
10
|
/**
|
|
10
11
|
* Base ReactTemplate constructor
|
|
@@ -53,20 +54,40 @@ class IgniteUIForReactTemplate {
|
|
|
53
54
|
const routeModulePath = options.parentRoutingModulePath;
|
|
54
55
|
if (!(options && options.skipRoute)
|
|
55
56
|
&& cli_core_1.App.container.get(cli_core_1.FS_TOKEN).fileExists(routeModulePath)) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
const routingModule = new ReactTypeScriptFileUpdate_1.ReactTypeScriptFileUpdate(path.join(projectPath, routeModulePath), { convertTabsToSpaces: false, indentSize: 4, singleQuotes: true }, { jsx: typescript_1.JsxEmit.Preserve });
|
|
58
|
+
const modulePath = `./${cli_core_1.Util.lowerDashed(name)}/${cli_core_1.Util.lowerDashed(name)}-routes`;
|
|
59
|
+
const child = {
|
|
60
|
+
identifierName: cli_core_1.ROUTES_VARIABLE_NAME,
|
|
61
|
+
aliasName: options.routerChildren,
|
|
62
|
+
modulePath
|
|
63
|
+
};
|
|
60
64
|
if (defaultPath) {
|
|
61
|
-
routingModule.addRoute(
|
|
65
|
+
routingModule.addRoute({
|
|
66
|
+
index: true,
|
|
67
|
+
redirectTo: options.path,
|
|
68
|
+
});
|
|
62
69
|
}
|
|
63
|
-
|
|
70
|
+
const children = routeModulePath.includes(cli_core_1.REACT_APP_ROUTING_NAME)
|
|
71
|
+
? child
|
|
72
|
+
: undefined;
|
|
64
73
|
if (options.hasChildren) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
routingModule.addRoute({
|
|
75
|
+
path: this.fileName(name),
|
|
76
|
+
element: cli_core_1.Util.className(name),
|
|
77
|
+
text: cli_core_1.Util.nameFromPath(name),
|
|
78
|
+
children
|
|
79
|
+
});
|
|
69
80
|
}
|
|
81
|
+
else {
|
|
82
|
+
routingModule.addRoute({
|
|
83
|
+
path: this.fileName(name),
|
|
84
|
+
element: cli_core_1.Util.className(name),
|
|
85
|
+
text: cli_core_1.Util.nameFromPath(name)
|
|
86
|
+
}, false, // multiline
|
|
87
|
+
false // prepend
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
routingModule.finalize();
|
|
70
91
|
}
|
|
71
92
|
}
|
|
72
93
|
getExtraConfiguration() {
|
|
@@ -90,11 +111,15 @@ class IgniteUIForReactTemplate {
|
|
|
90
111
|
cli_core_1.Util.error(`Path ${"src/views/" + folderName} is not valid!`, "red");
|
|
91
112
|
process.exit(1);
|
|
92
113
|
}
|
|
93
|
-
//clean up potential leading spaces in folder names (`path/
|
|
114
|
+
//clean up potential leading spaces in folder names (`path/ name`):
|
|
94
115
|
folderName = folderName.replace(/\/\s+/g, "/");
|
|
95
116
|
}
|
|
96
117
|
return cli_core_1.Util.lowerDashed(folderName);
|
|
97
118
|
}
|
|
119
|
+
fileName(pathName) {
|
|
120
|
+
const name = cli_core_1.Util.nameFromPath(pathName);
|
|
121
|
+
return cli_core_1.Util.lowerDashed(name);
|
|
122
|
+
}
|
|
98
123
|
registerJSONRoute(projectPath, name, routingModulePath) {
|
|
99
124
|
const configFile = fs.readFileSync(path.join(projectPath, routingModulePath), "utf8");
|
|
100
125
|
const viewsArr = JSON.parse(configFile);
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.IgniteUIForWebComponentsTemplate = void 0;
|
|
4
4
|
const cli_core_1 = require("@igniteui/cli-core");
|
|
5
5
|
const path = require("path");
|
|
6
|
-
const
|
|
6
|
+
const WebComponentsTypeScriptFileUpdate_1 = require("../../templates/webcomponents/WebComponentsTypeScriptFileUpdate");
|
|
7
7
|
class IgniteUIForWebComponentsTemplate {
|
|
8
8
|
get templatePaths() {
|
|
9
9
|
return [path.join(this.rootPath, "files")];
|
|
@@ -31,16 +31,44 @@ class IgniteUIForWebComponentsTemplate {
|
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
const routeModulePath = options.parentRoutingModulePath;
|
|
34
|
-
const routingModule = new
|
|
34
|
+
const routingModule = new WebComponentsTypeScriptFileUpdate_1.WebComponentsTypeScriptFileUpdate(path.join(projectPath, routeModulePath), { convertTabsToSpaces: false, indentSize: 4, singleQuotes: false });
|
|
35
35
|
if (!(options && options.skipRoute) && cli_core_1.App.container.get(cli_core_1.FS_TOKEN)
|
|
36
36
|
.fileExists(routeModulePath)) {
|
|
37
|
+
const modulePath = `./${cli_core_1.Util.lowerDashed(fullName)}/${cli_core_1.Util.lowerDashed(fullName)}-routing`;
|
|
38
|
+
const child = {
|
|
39
|
+
identifierName: cli_core_1.ROUTES_VARIABLE_NAME,
|
|
40
|
+
aliasName: options.routerChildren,
|
|
41
|
+
modulePath
|
|
42
|
+
};
|
|
43
|
+
const children = routeModulePath.includes(cli_core_1.WC_APP_ROUTING_NAME)
|
|
44
|
+
? child
|
|
45
|
+
: undefined;
|
|
37
46
|
if (defaultPath) {
|
|
38
|
-
routingModule.addRoute(
|
|
47
|
+
routingModule.addRoute({
|
|
48
|
+
path: "",
|
|
49
|
+
redirectTo: options.selector,
|
|
50
|
+
name: cli_core_1.Util.nameFromPath(fullName),
|
|
51
|
+
children
|
|
52
|
+
});
|
|
39
53
|
}
|
|
40
|
-
routingModule.addRoute(this.fileName(fullName), options.selector, cli_core_1.Util.nameFromPath(fullName), options.routerChildren, undefined);
|
|
41
54
|
if (options.hasChildren) {
|
|
42
|
-
routingModule.addRoute(
|
|
55
|
+
routingModule.addRoute({
|
|
56
|
+
path: this.fileName(fullName),
|
|
57
|
+
identifierName: options.selector,
|
|
58
|
+
name: cli_core_1.Util.nameFromPath(fullName),
|
|
59
|
+
children
|
|
60
|
+
});
|
|
43
61
|
}
|
|
62
|
+
else {
|
|
63
|
+
routingModule.addRoute({
|
|
64
|
+
path: this.fileName(fullName),
|
|
65
|
+
identifierName: options.selector,
|
|
66
|
+
name: cli_core_1.Util.nameFromPath(fullName)
|
|
67
|
+
}, false, // multiline
|
|
68
|
+
false // prepend
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
routingModule.finalize();
|
|
44
72
|
}
|
|
45
73
|
}
|
|
46
74
|
getExtraConfiguration() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "igniteui-cli",
|
|
3
|
-
"version": "13.2.
|
|
3
|
+
"version": "13.2.2-beta.0",
|
|
4
4
|
"description": "CLI tool for creating Ignite UI projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"all": true
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@igniteui/angular-templates": "~17.2.
|
|
76
|
-
"@igniteui/cli-core": "~13.2.
|
|
75
|
+
"@igniteui/angular-templates": "~17.2.1322-beta.0",
|
|
76
|
+
"@igniteui/cli-core": "~13.2.2-beta.0",
|
|
77
77
|
"chalk": "^2.3.2",
|
|
78
78
|
"fs-extra": "^3.0.1",
|
|
79
79
|
"glob": "^7.1.2",
|
|
@@ -1,50 +1,11 @@
|
|
|
1
|
-
import * as ts from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
protected
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
private fileSystem;
|
|
13
|
-
private targetSource;
|
|
14
|
-
private importsMeta;
|
|
15
|
-
private requestedImports;
|
|
16
|
-
private createdStringLiterals;
|
|
17
|
-
/** Create updates for a file. Use `add<X>` methods to add transformations and `finalize` to apply and save them. */
|
|
18
|
-
constructor(targetPath: string);
|
|
19
|
-
/** Applies accumulated transforms, saves and formats the file */
|
|
20
|
-
finalize(): void;
|
|
21
|
-
addRoute(path: string, component: string, name: string, filePath: string, routerChildren: string, importAlias: string, defaultRoute?: boolean): void;
|
|
22
|
-
/** Initializes existing imports info, [re]sets import and `NgModule` edits */
|
|
23
|
-
protected initState(): void;
|
|
24
|
-
protected loadImportsMeta(): {
|
|
25
|
-
lastIndex: number;
|
|
26
|
-
modulePaths: any[];
|
|
27
|
-
};
|
|
28
|
-
protected addRouteModuleEntry(path: string, component: string, name: string, filePath: string, routerChildren: string, importAlias: string, defaultRoute?: boolean): void;
|
|
29
|
-
protected requestImport(modulePath: string, routerAlias: string, componentName: string, namedImport?: boolean): void;
|
|
30
|
-
/** Add `import` statements not previously found in the file */
|
|
31
|
-
protected addNewFileImports(): void;
|
|
32
|
-
protected createIdentifierImport(importPath: string, as: string, component: string, namedImport: boolean): ts.ImportDeclaration;
|
|
33
|
-
/** Transformation to apply edits to existing named import declarations */
|
|
34
|
-
protected importsTransformer: ts.TransformerFactory<ts.Node>;
|
|
35
|
-
/** Format a TS source file, very TBD */
|
|
36
|
-
protected formatFile(filePath: string): void;
|
|
37
|
-
/** Try and parse formatting from project `.editorconfig` / `tslint.json` */
|
|
38
|
-
protected readFormatConfigs(): void;
|
|
39
|
-
/**
|
|
40
|
-
* Apply formatting changes (position based) in reverse
|
|
41
|
-
* from https://github.com/Microsoft/TypeScript/issues/1651#issuecomment-69877863
|
|
42
|
-
*/
|
|
43
|
-
private applyChanges;
|
|
44
|
-
/** Return source file formatting options */
|
|
45
|
-
private getFormattingOptions;
|
|
46
|
-
/** Get language service host, sloppily */
|
|
47
|
-
private getLanguageHost;
|
|
48
|
-
private createVisitor;
|
|
49
|
-
private createRouteEntry;
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { FormatSettings, PropertyAssignment, TypeScriptFileUpdate } from '@igniteui/cli-core';
|
|
3
|
+
import { ReactRouteLike } from './types';
|
|
4
|
+
export declare class ReactTypeScriptFileUpdate extends TypeScriptFileUpdate {
|
|
5
|
+
constructor(filePath: string, formatSettings?: FormatSettings, compilerOptions?: ts.CompilerOptions);
|
|
6
|
+
addRoute(route: ReactRouteLike, multiline?: boolean, prepend?: boolean, anchorElement?: PropertyAssignment): ts.SourceFile;
|
|
7
|
+
protected addRouteEntry(route: ReactRouteLike, visitCondition: (node: ts.Node) => boolean, multiline: boolean, prepend: boolean, anchorElement: PropertyAssignment): ts.SourceFile;
|
|
8
|
+
protected addRedirectRouteEntry(route: ReactRouteLike, visitCondition: (node: ts.Node) => boolean, multiline?: boolean, prepend?: boolean, anchorElement?: PropertyAssignment): ts.SourceFile;
|
|
9
|
+
protected addChildRouteEntry(route: ReactRouteLike, asIdentifier?: boolean, multiline?: boolean, prepend?: boolean): ts.SourceFile;
|
|
10
|
+
private requestImportForRouteLoader;
|
|
50
11
|
}
|
|
@@ -1,347 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ReactTypeScriptFileUpdate = void 0;
|
|
4
|
-
const cli_core_1 = require("@igniteui/cli-core");
|
|
5
4
|
const ts = require("typescript");
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
node = ts.visitEachChild(node, visitor, context);
|
|
28
|
-
}
|
|
29
|
-
return node;
|
|
30
|
-
};
|
|
31
|
-
function visitImport(node) {
|
|
32
|
-
node = ts.visitEachChild(node, visitImport, context);
|
|
33
|
-
return node;
|
|
34
|
-
}
|
|
35
|
-
return ts.visitNode(rootNode, visitor);
|
|
36
|
-
};
|
|
37
|
-
this.fileSystem = cli_core_1.App.container.get(cli_core_1.FS_TOKEN);
|
|
38
|
-
this.initState();
|
|
39
|
-
}
|
|
40
|
-
/** Applies accumulated transforms, saves and formats the file */
|
|
41
|
-
finalize() {
|
|
42
|
-
// add new import statements after visitor walks:
|
|
43
|
-
this.addNewFileImports();
|
|
44
|
-
cli_core_1.TypeScriptUtils.saveFile(this.targetPath, this.targetSource);
|
|
45
|
-
this.formatFile(this.targetPath);
|
|
46
|
-
// reset state in case of further updates
|
|
47
|
-
this.initState();
|
|
48
|
-
}
|
|
49
|
-
addRoute(path, component, name, filePath, routerChildren, importAlias, defaultRoute = false) {
|
|
50
|
-
this.addRouteModuleEntry(path, component, name, filePath, routerChildren, importAlias, defaultRoute);
|
|
51
|
-
}
|
|
52
|
-
//#region File state
|
|
53
|
-
/** Initializes existing imports info, [re]sets import and `NgModule` edits */
|
|
54
|
-
initState() {
|
|
55
|
-
this.targetSource = cli_core_1.TypeScriptUtils.getFileSource(this.targetPath);
|
|
56
|
-
this.importsMeta = this.loadImportsMeta();
|
|
57
|
-
this.requestedImports = [];
|
|
58
|
-
this.createdStringLiterals = [];
|
|
59
|
-
}
|
|
60
|
-
/* load some metadata about imports */
|
|
61
|
-
loadImportsMeta() {
|
|
62
|
-
const meta = { lastIndex: 0, modulePaths: [] };
|
|
63
|
-
for (let i = 0; i < this.targetSource.statements.length; i++) {
|
|
64
|
-
const statement = this.targetSource.statements[i];
|
|
65
|
-
switch (statement.kind) {
|
|
66
|
-
case ts.SyntaxKind.ImportDeclaration:
|
|
67
|
-
const importStmt = statement;
|
|
68
|
-
if (importStmt.importClause && importStmt.importClause.namedBindings &&
|
|
69
|
-
importStmt.importClause.namedBindings.kind !== ts.SyntaxKind.NamespaceImport) {
|
|
70
|
-
// don't add imports without named (e.g. `import $ from "JQuery"` or `import "./my-module.js";`)
|
|
71
|
-
// don't add namespace imports (`import * as fs`) as available for editing, maybe in the future
|
|
72
|
-
meta.modulePaths.push(importStmt.moduleSpecifier.text);
|
|
73
|
-
}
|
|
74
|
-
// don't add equals imports (`import url = require("url")`) as available for editing, maybe in the future
|
|
75
|
-
case ts.SyntaxKind.ImportEqualsDeclaration:
|
|
76
|
-
meta.lastIndex = i + 1;
|
|
77
|
-
break;
|
|
78
|
-
default:
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return meta;
|
|
83
|
-
}
|
|
84
|
-
//#endregion File state
|
|
85
|
-
addRouteModuleEntry(path, component, name, filePath, routerChildren, importAlias, defaultRoute = false) {
|
|
86
|
-
const isRouting = path.indexOf(DEFAULT_ROUTES_VARIABLE) >= 0;
|
|
87
|
-
if (isRouting && this.targetSource.text.indexOf(path.slice(0, -4)) > 0) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
if (defaultRoute) {
|
|
91
|
-
this.requestImport("react-router-dom", undefined, "redirect", true);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
const relativePath = cli_core_1.Util.relativePath(this.targetPath, filePath, true, true);
|
|
95
|
-
this.requestImport(relativePath, importAlias, component);
|
|
96
|
-
}
|
|
97
|
-
// https://github.com/Microsoft/TypeScript/issues/14419#issuecomment-307256171
|
|
98
|
-
const transformer = (context) => (rootNode) => {
|
|
99
|
-
// the visitor that should be used when adding routes to the main route array
|
|
100
|
-
const conditionalVisitor = (node) => {
|
|
101
|
-
if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
|
102
|
-
const newObject = this.createRouteEntry(path, component, name, routerChildren, defaultRoute);
|
|
103
|
-
const array = node;
|
|
104
|
-
this.createdStringLiterals.push(path, name);
|
|
105
|
-
const notFoundWildCard = ".*";
|
|
106
|
-
const nodes = ts.visitNodes(array.elements, visitor);
|
|
107
|
-
const errorRouteNode = nodes.filter(element => element.getText().includes(notFoundWildCard))[0];
|
|
108
|
-
let resultNodes = null;
|
|
109
|
-
if (errorRouteNode) {
|
|
110
|
-
resultNodes = nodes
|
|
111
|
-
.slice(0, nodes.indexOf(errorRouteNode))
|
|
112
|
-
.concat(newObject)
|
|
113
|
-
.concat(errorRouteNode);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
resultNodes = nodes
|
|
117
|
-
.concat(newObject);
|
|
118
|
-
}
|
|
119
|
-
const elements = ts.factory.createNodeArray([
|
|
120
|
-
...resultNodes
|
|
121
|
-
]);
|
|
122
|
-
return ts.factory.updateArrayLiteralExpression(array, elements);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
return ts.visitEachChild(node, conditionalVisitor, context);
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
let visitCondition;
|
|
129
|
-
if (!isRouting) {
|
|
130
|
-
visitCondition = (node) => {
|
|
131
|
-
return node.kind === ts.SyntaxKind.VariableDeclaration &&
|
|
132
|
-
node.name.getText() === DEFAULT_ROUTES_VARIABLE;
|
|
133
|
-
// no type currently
|
|
134
|
-
//(node as ts.VariableDeclaration).type.getText() === "Route[]";
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
visitCondition = (node) => {
|
|
139
|
-
return undefined;
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
const visitor = this.createVisitor(conditionalVisitor, visitCondition, context);
|
|
143
|
-
context.enableSubstitution(ts.SyntaxKind.ClassDeclaration);
|
|
144
|
-
return ts.visitNode(rootNode, visitor);
|
|
145
|
-
};
|
|
146
|
-
this.targetSource = ts.transform(this.targetSource, [transformer], {
|
|
147
|
-
pretty: true // oh well..
|
|
148
|
-
}).transformed[0];
|
|
149
|
-
this.finalize();
|
|
150
|
-
}
|
|
151
|
-
requestImport(modulePath, routerAlias, componentName, namedImport = false) {
|
|
152
|
-
const existing = this.requestedImports.find(x => x.from === modulePath);
|
|
153
|
-
// TODO: better check for named imports. There could be several named imports from same modulePath
|
|
154
|
-
if (!existing) {
|
|
155
|
-
// new imports, check if already exists in file
|
|
156
|
-
this.requestedImports.push({
|
|
157
|
-
as: routerAlias,
|
|
158
|
-
from: modulePath,
|
|
159
|
-
component: componentName,
|
|
160
|
-
edit: this.importsMeta.modulePaths.indexOf(modulePath) !== -1,
|
|
161
|
-
namedImport
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
/** Add `import` statements not previously found in the file */
|
|
166
|
-
addNewFileImports() {
|
|
167
|
-
const newImports = this.requestedImports.filter(x => !x.edit);
|
|
168
|
-
if (!newImports.length) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
const newStatements = ts.factory.createNodeArray([
|
|
172
|
-
...this.targetSource.statements.slice(0, this.importsMeta.lastIndex),
|
|
173
|
-
...newImports.map(x => this.createIdentifierImport(x.from, x.as, x.component, x.namedImport)),
|
|
174
|
-
...this.targetSource.statements.slice(this.importsMeta.lastIndex)
|
|
175
|
-
]);
|
|
176
|
-
newImports.forEach(x => this.createdStringLiterals.push(x.from));
|
|
177
|
-
this.targetSource = ts.factory.updateSourceFile(this.targetSource, newStatements);
|
|
178
|
-
}
|
|
179
|
-
createIdentifierImport(importPath, as, component, namedImport) {
|
|
180
|
-
let exportedObject;
|
|
181
|
-
let exportedObjectName;
|
|
182
|
-
let importClause;
|
|
183
|
-
if (as) {
|
|
184
|
-
exportedObject = "routes";
|
|
185
|
-
exportedObjectName = as.replace(/\s/g, "");
|
|
186
|
-
importClause = ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
|
|
187
|
-
ts.factory.createImportSpecifier(false, ts.factory.createIdentifier(exportedObject), ts.factory.createIdentifier(exportedObjectName))
|
|
188
|
-
]));
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
if (namedImport) {
|
|
192
|
-
const importSpecifier = ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(component));
|
|
193
|
-
const imports = ts.factory.createNamedImports([importSpecifier]);
|
|
194
|
-
importClause = ts.factory.createImportClause(false, undefined, imports);
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
importClause = ts.factory.createImportClause(false, ts.factory.createIdentifier(component), undefined);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
const importDeclaration = ts.factory.createImportDeclaration(undefined, importClause, ts.factory.createStringLiteral(importPath, true), undefined);
|
|
201
|
-
return importDeclaration;
|
|
202
|
-
}
|
|
203
|
-
//#endregion ts.TransformerFactory
|
|
204
|
-
//#region Formatting
|
|
205
|
-
/** Format a TS source file, very TBD */
|
|
206
|
-
formatFile(filePath) {
|
|
207
|
-
// formatting via LanguageService https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
|
|
208
|
-
// https://github.com/Microsoft/TypeScript/issues/1651
|
|
209
|
-
let text = this.fileSystem.readFile(filePath);
|
|
210
|
-
// create the language service files
|
|
211
|
-
const services = ts.createLanguageService(this.getLanguageHost(filePath), ts.createDocumentRegistry());
|
|
212
|
-
this.readFormatConfigs();
|
|
213
|
-
const textChanges = services.getFormattingEditsForDocument(filePath, this.getFormattingOptions());
|
|
214
|
-
text = this.applyChanges(text, textChanges);
|
|
215
|
-
if (this.formatOptions.singleQuotes) {
|
|
216
|
-
for (const str of this.createdStringLiterals) {
|
|
217
|
-
// there shouldn't be duplicate strings of these
|
|
218
|
-
text = text.replace(`"${str}"`, `'${str}'`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
this.fileSystem.writeFile(filePath, text);
|
|
222
|
-
}
|
|
223
|
-
/** Try and parse formatting from project `.editorconfig` / `tslint.json` */
|
|
224
|
-
readFormatConfigs() {
|
|
225
|
-
if (this.fileSystem.fileExists(".editorconfig")) {
|
|
226
|
-
// very basic parsing support
|
|
227
|
-
const text = this.fileSystem.readFile(".editorconfig", "utf-8");
|
|
228
|
-
const options = text
|
|
229
|
-
.replace(/\s*[#;].*([\r\n])/g, "$1") //remove comments
|
|
230
|
-
.replace(/\[(?!\*\]|\*.ts).+\][^\[]+/g, "") // leave [*]/[*.ts] sections
|
|
231
|
-
.split(/\r\n|\r|\n/)
|
|
232
|
-
.reduce((obj, x) => {
|
|
233
|
-
if (x.indexOf("=") !== -1) {
|
|
234
|
-
const pair = x.split("=");
|
|
235
|
-
obj[pair[0].trim()] = pair[1].trim();
|
|
236
|
-
}
|
|
237
|
-
return obj;
|
|
238
|
-
}, {});
|
|
239
|
-
this.formatOptions.spaces = options["indent_style"] === "space";
|
|
240
|
-
if (options["indent_size"]) {
|
|
241
|
-
this.formatOptions.indentSize = parseInt(options["indent_size"], 10) || this.formatOptions.indentSize;
|
|
242
|
-
}
|
|
243
|
-
if (options["quote_type"]) {
|
|
244
|
-
this.formatOptions.singleQuotes = options["quote_type"] === "single";
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
if (this.fileSystem.fileExists("tslint.json")) {
|
|
248
|
-
// tslint prio - overrides other settings
|
|
249
|
-
const options = JSON.parse(this.fileSystem.readFile("tslint.json", "utf-8"));
|
|
250
|
-
if (options.rules && options.rules.indent && options.rules.indent[0]) {
|
|
251
|
-
this.formatOptions.spaces = options.rules.indent[1] === "spaces";
|
|
252
|
-
if (options.rules.indent[2]) {
|
|
253
|
-
this.formatOptions.indentSize = parseInt(options.rules.indent[2], 10);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
if (options.rules && options.rules.quotemark && options.rules.quotemark[0]) {
|
|
257
|
-
this.formatOptions.singleQuotes = options.rules.quotemark.indexOf("single") !== -1;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Apply formatting changes (position based) in reverse
|
|
263
|
-
* from https://github.com/Microsoft/TypeScript/issues/1651#issuecomment-69877863
|
|
264
|
-
*/
|
|
265
|
-
applyChanges(orig, changes) {
|
|
266
|
-
let result = orig;
|
|
267
|
-
for (let i = changes.length - 1; i >= 0; i--) {
|
|
268
|
-
const change = changes[i];
|
|
269
|
-
const head = result.slice(0, change.span.start);
|
|
270
|
-
const tail = result.slice(change.span.start + change.span.length);
|
|
271
|
-
result = head + change.newText + tail;
|
|
5
|
+
const cli_core_1 = require("@igniteui/cli-core");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
class ReactTypeScriptFileUpdate extends cli_core_1.TypeScriptFileUpdate {
|
|
8
|
+
constructor(filePath, formatSettings, compilerOptions) {
|
|
9
|
+
super(filePath, formatSettings, compilerOptions);
|
|
10
|
+
}
|
|
11
|
+
//#region Overridden Public API
|
|
12
|
+
addRoute(route, multiline = false, prepend = false, anchorElement) {
|
|
13
|
+
return this.addRedirectOrSimpleRouteEntry(Object.assign(Object.assign({}, route), { identifierName: route.identifierName || route.element, name: route.name || route.text }), (0, cli_core_1.RoutesVariableAsParentCondition)(this.astTransformer), multiline, prepend, anchorElement);
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region Overrides
|
|
17
|
+
addRouteEntry(route, visitCondition, multiline = false, prepend = false, anchorElement) {
|
|
18
|
+
const routeName = cli_core_1.Util.lowerDashed(route.name || route.path);
|
|
19
|
+
const modulePath = `./${routeName}/${routeName}`;
|
|
20
|
+
this.requestImportForRouteIdentifier(Object.assign(Object.assign({}, route), { modulePath }), true // is default - for React, we import the component as `import X from 'module'`.
|
|
21
|
+
);
|
|
22
|
+
if (route.children &&
|
|
23
|
+
!Array.isArray(route.children) &&
|
|
24
|
+
(route.children.identifierName || route.children.aliasName)) {
|
|
25
|
+
this.requestImportForRouteIdentifier(route.children);
|
|
272
26
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
insertSpaceAfterKeywordsInControlFlowStatements: true,
|
|
288
|
-
insertSpaceAfterTypeAssertion: true
|
|
289
|
-
// tslint:enable:object-literal-sort-keys
|
|
290
|
-
};
|
|
291
|
-
return formatOptions;
|
|
292
|
-
}
|
|
293
|
-
/** Get language service host, sloppily */
|
|
294
|
-
getLanguageHost(filePath) {
|
|
295
|
-
const files = {};
|
|
296
|
-
files[filePath] = { version: 0 };
|
|
297
|
-
// create the language service host to allow the LS to communicate with the host
|
|
298
|
-
const servicesHost = {
|
|
299
|
-
getCompilationSettings: () => ({}),
|
|
300
|
-
getScriptFileNames: () => Object.keys(files),
|
|
301
|
-
getScriptVersion: fileName => files[fileName] && files[fileName].version.toString(),
|
|
302
|
-
getScriptSnapshot: fileName => {
|
|
303
|
-
if (!this.fileSystem.fileExists(fileName)) {
|
|
304
|
-
return undefined;
|
|
305
|
-
}
|
|
306
|
-
return ts.ScriptSnapshot.fromString(this.fileSystem.readFile(fileName));
|
|
27
|
+
const structure = [
|
|
28
|
+
{
|
|
29
|
+
name: cli_core_1.RouteTarget.Path,
|
|
30
|
+
value: ts.factory.createStringLiteral(route.path),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: types_1.ReactRouteTarget.Element,
|
|
34
|
+
value: ts.factory.createJsxSelfClosingElement(ts.factory.createIdentifier(route.element || route.identifierName), undefined, // type arguments
|
|
35
|
+
undefined // jsx attributes
|
|
36
|
+
),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: types_1.ReactRouteTarget.Text,
|
|
40
|
+
value: ts.factory.createStringLiteral(route.text || route.name),
|
|
307
41
|
},
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
42
|
+
];
|
|
43
|
+
const newRoute = this.astTransformer.createObjectLiteralExpression(structure, multiline);
|
|
44
|
+
return this.astTransformer.addMembersToArrayLiteral(visitCondition, [newRoute], prepend, anchorElement);
|
|
45
|
+
}
|
|
46
|
+
addRedirectRouteEntry(route, visitCondition, multiline = false, prepend = false, anchorElement) {
|
|
47
|
+
const loaderPropertyAssignment = this.createArrowFunctionWithCallExpression(types_1.ReactRouteTarget.Loader, route.loader || cli_core_1.REACT_ROUTER_DOM_REDIRECT, route.redirectTo);
|
|
48
|
+
this.requestImportForRouteLoader(route);
|
|
49
|
+
const structure = [
|
|
50
|
+
{
|
|
51
|
+
name: types_1.ReactRouteTarget.Index,
|
|
52
|
+
value: route.index ? ts.factory.createTrue() : ts.factory.createFalse(),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: types_1.ReactRouteTarget.Loader,
|
|
56
|
+
value: loaderPropertyAssignment.value,
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
const newRoute = this.astTransformer.createObjectLiteralExpression(structure, multiline);
|
|
60
|
+
return this.astTransformer.addMembersToArrayLiteral(visitCondition, [newRoute], prepend, anchorElement);
|
|
315
61
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
if (visitCondition(node)) {
|
|
320
|
-
node = ts.visitEachChild(node, conditionalVisitor, nodeContext);
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
node = ts.visitEachChild(node, visitor, nodeContext);
|
|
324
|
-
}
|
|
325
|
-
return node;
|
|
326
|
-
};
|
|
62
|
+
addChildRouteEntry(route, asIdentifier = true, multiline = false, prepend = false) {
|
|
63
|
+
return super.addChildRouteEntry(Object.assign(Object.assign({}, route), { identifierName: route.identifierName || route.element }), asIdentifier || true, // for React the `children` member should always be added in the form { children: identifier }
|
|
64
|
+
multiline, prepend);
|
|
327
65
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const index = ts.factory.createPropertyAssignment("index", ts.factory.createTrue());
|
|
332
|
-
const loader = ts.factory.createArrowFunction(undefined, undefined, [], undefined, undefined, ts.factory.createCallExpression(ts.factory.createIdentifier("redirect"), [], [ts.factory.createStringLiteral(path, true)]));
|
|
333
|
-
const redirect = ts.factory.createPropertyAssignment("loader", loader);
|
|
334
|
-
return ts.factory.createObjectLiteralExpression([index, redirect]);
|
|
335
|
-
}
|
|
336
|
-
const routePath = ts.factory.createPropertyAssignment("path", ts.factory.createStringLiteral(path, true));
|
|
337
|
-
const jsxElement = ts.factory.createJsxSelfClosingElement(ts.factory.createIdentifier(component), [], undefined);
|
|
338
|
-
const routeComponent = ts.factory.createPropertyAssignment("element", jsxElement);
|
|
339
|
-
const routeData = ts.factory.createPropertyAssignment("text", ts.factory.createStringLiteral(name, true));
|
|
340
|
-
if (routerAlias) {
|
|
341
|
-
const childrenData = ts.factory.createPropertyAssignment("children", ts.factory.createIdentifier(routerAlias));
|
|
342
|
-
return ts.factory.createObjectLiteralExpression([routePath, routeComponent, routeData, childrenData]);
|
|
343
|
-
}
|
|
344
|
-
return ts.factory.createObjectLiteralExpression([routePath, routeComponent, routeData]);
|
|
66
|
+
//#endregion
|
|
67
|
+
requestImportForRouteLoader(route, isDefault) {
|
|
68
|
+
return this.requestImportForRouteIdentifier(Object.assign(Object.assign({}, route), { identifierName: route.loader || cli_core_1.REACT_ROUTER_DOM_REDIRECT, modulePath: cli_core_1.REACT_ROUTER_DOM_MODULE }), isDefault);
|
|
345
69
|
}
|
|
346
70
|
}
|
|
347
71
|
exports.ReactTypeScriptFileUpdate = ReactTypeScriptFileUpdate;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { RouteEntry, RouteTarget } from "@igniteui/cli-core";
|
|
2
|
+
import { ReactRouteTarget } from "./ReactRouteTarget";
|
|
3
|
+
/** Represents a React route entry in a routes collection. */
|
|
4
|
+
export interface ReactRouteEntry extends Pick<RouteEntry, "value"> {
|
|
5
|
+
name: RouteTarget | ReactRouteTarget;
|
|
6
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { RouteLike } from '@igniteui/cli-core';
|
|
2
|
+
/** A route member in a React routes collection. */
|
|
3
|
+
export interface ReactRouteLike extends RouteLike {
|
|
4
|
+
/**
|
|
5
|
+
* Determines if the route is an index route.
|
|
6
|
+
* Index routes render into their parent's {@link https://reactrouter.com/en/main/components/outlet|Outlet} at their parent's URL (like a default child route).
|
|
7
|
+
*/
|
|
8
|
+
index?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The route loader is called before the route renders and provides data for the element through {@link https://reactrouter.com/en/main/hooks/use-loader-data|useLoaderData}.
|
|
11
|
+
*/
|
|
12
|
+
loader?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The React Element/Component to render when the route matches the URL.
|
|
15
|
+
*/
|
|
16
|
+
element?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The name the page.
|
|
19
|
+
*/
|
|
20
|
+
text?: string;
|
|
21
|
+
/**
|
|
22
|
+
* An array of child `Route` objects that specifies a nested route configuration.
|
|
23
|
+
*/
|
|
24
|
+
children?: ReactRouteLike | ReactRouteLike[];
|
|
25
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReactRouteTarget = void 0;
|
|
4
|
+
/** Represents possible members in a React route object. */
|
|
5
|
+
var ReactRouteTarget;
|
|
6
|
+
(function (ReactRouteTarget) {
|
|
7
|
+
ReactRouteTarget["Index"] = "index";
|
|
8
|
+
ReactRouteTarget["Element"] = "element";
|
|
9
|
+
ReactRouteTarget["Text"] = "text";
|
|
10
|
+
ReactRouteTarget["Loader"] = "loader";
|
|
11
|
+
})(ReactRouteTarget || (exports.ReactRouteTarget = ReactRouteTarget = {}));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./ReactRouteTarget"), exports);
|
|
18
|
+
__exportStar(require("./ReactRouteEntry"), exports);
|
|
19
|
+
__exportStar(require("./ReactRouteLike"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { FormatSettings, PropertyAssignment, RouteLike, TypeScriptFileUpdate } from '@igniteui/cli-core';
|
|
3
|
+
export declare class WebComponentsTypeScriptFileUpdate extends TypeScriptFileUpdate {
|
|
4
|
+
filePath: string;
|
|
5
|
+
constructor(filePath: string, formatSettings?: FormatSettings);
|
|
6
|
+
addRoute(route: RouteLike, multiline?: boolean, prepend?: boolean, anchorElement?: PropertyAssignment): ts.SourceFile;
|
|
7
|
+
addChildRoute(parentPath: string, route: RouteLike, asIdentifier?: boolean, multiline?: boolean, prepend?: boolean, anchorElement?: PropertyAssignment): ts.SourceFile;
|
|
8
|
+
protected addRouteEntry(route: RouteLike, visitCondition: (node: ts.Node) => boolean, multiline: boolean, prepend: boolean, anchorElement: PropertyAssignment): ts.SourceFile;
|
|
9
|
+
protected addRedirectRouteEntry(route: RouteLike, visitCondition: (node: ts.Node) => boolean, multiline: boolean, prepend: boolean, anchorElement: PropertyAssignment): ts.SourceFile;
|
|
10
|
+
protected addChildRouteEntry(route: RouteLike, asIdentifier?: boolean, multiline?: boolean, prepend?: boolean): ts.SourceFile;
|
|
11
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebComponentsTypeScriptFileUpdate = void 0;
|
|
4
|
+
const ts = require("typescript");
|
|
5
|
+
const cli_core_1 = require("@igniteui/cli-core");
|
|
6
|
+
class WebComponentsTypeScriptFileUpdate extends cli_core_1.TypeScriptFileUpdate {
|
|
7
|
+
constructor(filePath, formatSettings) {
|
|
8
|
+
super(filePath, formatSettings);
|
|
9
|
+
this.filePath = filePath;
|
|
10
|
+
}
|
|
11
|
+
//#region Overridden Public API
|
|
12
|
+
addRoute(route, multiline = false, prepend = true, anchorElement = cli_core_1.WC_ANCHOR_ELEMENT) {
|
|
13
|
+
return this.addRedirectOrSimpleRouteEntry(route, (0, cli_core_1.RoutesVariableAsParentCondition)(this.astTransformer), multiline, prepend, anchorElement);
|
|
14
|
+
}
|
|
15
|
+
addChildRoute(parentPath, route, asIdentifier = true, multiline, prepend, anchorElement) {
|
|
16
|
+
return super.addChildRoute(parentPath, route, asIdentifier, multiline, prepend, anchorElement);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region Overrides
|
|
20
|
+
addRouteEntry(route, visitCondition, multiline = false, prepend = false, anchorElement) {
|
|
21
|
+
const routeName = cli_core_1.Util.lowerDashed(route.name || route.path);
|
|
22
|
+
this.requestSideEffectsImportForModule(`./${routeName}/${routeName}`);
|
|
23
|
+
if (route.children &&
|
|
24
|
+
!Array.isArray(route.children) &&
|
|
25
|
+
(route.children.identifierName || route.children.aliasName)) {
|
|
26
|
+
this.requestImportForRouteIdentifier(route.children);
|
|
27
|
+
}
|
|
28
|
+
const structure = [
|
|
29
|
+
{
|
|
30
|
+
name: cli_core_1.RouteTarget.Path,
|
|
31
|
+
value: ts.factory.createStringLiteral(route.path),
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: cli_core_1.RouteTarget.Component,
|
|
35
|
+
value: ts.factory.createStringLiteral(route.aliasName || route.identifierName),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: cli_core_1.RouteTarget.Name,
|
|
39
|
+
value: ts.factory.createStringLiteral(route.name),
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
const newRoute = this.astTransformer.createObjectLiteralExpression(structure, multiline);
|
|
43
|
+
return this.astTransformer.addMembersToArrayLiteral(visitCondition, [newRoute], prepend, anchorElement);
|
|
44
|
+
}
|
|
45
|
+
addRedirectRouteEntry(route, visitCondition, multiline = false, prepend = false, anchorElement) {
|
|
46
|
+
const routeName = cli_core_1.Util.lowerDashed(route.name || route.path);
|
|
47
|
+
this.requestSideEffectsImportForModule(`./${routeName}/${routeName}`);
|
|
48
|
+
const childRoute = route.children;
|
|
49
|
+
if (childRoute) {
|
|
50
|
+
this.requestImportForRouteIdentifier(childRoute);
|
|
51
|
+
}
|
|
52
|
+
const structure = [
|
|
53
|
+
{
|
|
54
|
+
name: cli_core_1.RouteTarget.Path,
|
|
55
|
+
value: ts.factory.createStringLiteral(route.path || ''),
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
// vaadin/router uses the component's tag name when navigating
|
|
59
|
+
name: cli_core_1.RouteTarget.Component,
|
|
60
|
+
value: ts.factory.createStringLiteral(route.redirectTo),
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: cli_core_1.RouteTarget.Name,
|
|
64
|
+
value: ts.factory.createStringLiteral(route.name),
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
if (childRoute) {
|
|
68
|
+
structure.push({
|
|
69
|
+
// the identifier name in this case will be the alias of the routes variable
|
|
70
|
+
name: cli_core_1.RouteTarget.Children,
|
|
71
|
+
value: ts.factory.createIdentifier(childRoute.aliasName || childRoute.identifierName),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
const newRoute = this.astTransformer.createObjectLiteralExpression(structure, multiline);
|
|
75
|
+
return this.astTransformer.addMembersToArrayLiteral(visitCondition, [newRoute], prepend, anchorElement);
|
|
76
|
+
}
|
|
77
|
+
addChildRouteEntry(route, asIdentifier = true, multiline = false, prepend = false) {
|
|
78
|
+
return super.addChildRouteEntry(route, asIdentifier || true, // for WC the `children` member should always be added in the form { children: identifier }
|
|
79
|
+
multiline, prepend);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.WebComponentsTypeScriptFileUpdate = WebComponentsTypeScriptFileUpdate;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import * as ts from "typescript";
|
|
2
|
-
/**
|
|
3
|
-
* Apply various updates to typescript files using AST
|
|
4
|
-
*/
|
|
5
|
-
export declare class TypeScriptFileUpdate {
|
|
6
|
-
private targetPath;
|
|
7
|
-
protected formatOptions: {
|
|
8
|
-
spaces: boolean;
|
|
9
|
-
indentSize: number;
|
|
10
|
-
singleQuotes: boolean;
|
|
11
|
-
};
|
|
12
|
-
private fileSystem;
|
|
13
|
-
private targetSource;
|
|
14
|
-
private importsMeta;
|
|
15
|
-
private requestedImports;
|
|
16
|
-
private createdStringLiterals;
|
|
17
|
-
/** Create updates for a file. Use `add<X>` methods to add transformations and `finalize` to apply and save them. */
|
|
18
|
-
constructor(targetPath: string);
|
|
19
|
-
/** Applies accumulated transforms, saves and formats the file */
|
|
20
|
-
finalize(): void;
|
|
21
|
-
addRoute(path: string, component: string, name: string, routerChildren: string, importAlias: string, routesVariable?: string): void;
|
|
22
|
-
/** Initializes existing imports info, [re]sets import and `NgModule` edits */
|
|
23
|
-
protected initState(): void;
|
|
24
|
-
protected loadImportsMeta(): {
|
|
25
|
-
lastIndex: number;
|
|
26
|
-
modulePaths: any[];
|
|
27
|
-
};
|
|
28
|
-
protected addRouteModuleEntry(path: string, component: string, name: string, routerChildren: string, importAlias: string, routesVariable?: string): void;
|
|
29
|
-
protected requestImport(modulePath: string, routerAlias: string): void;
|
|
30
|
-
/** Add `import` statements not previously found in the file */
|
|
31
|
-
protected addNewFileImports(): void;
|
|
32
|
-
protected createIdentifierImport(importPath: string, as: string): ts.ImportDeclaration;
|
|
33
|
-
/** Transformation to apply edits to existing named import declarations */
|
|
34
|
-
protected importsTransformer: ts.TransformerFactory<ts.Node>;
|
|
35
|
-
/** Format a TS source file, very TBD */
|
|
36
|
-
protected formatFile(filePath: string): void;
|
|
37
|
-
/** Try and parse formatting from project `.editorconfig` / `tslint.json` */
|
|
38
|
-
protected readFormatConfigs(): void;
|
|
39
|
-
/**
|
|
40
|
-
* Apply formatting changes (position based) in reverse
|
|
41
|
-
* from https://github.com/Microsoft/TypeScript/issues/1651#issuecomment-69877863
|
|
42
|
-
*/
|
|
43
|
-
private applyChanges;
|
|
44
|
-
/** Return source file formatting options */
|
|
45
|
-
private getFormattingOptions;
|
|
46
|
-
/** Get language service host, sloppily */
|
|
47
|
-
private getLanguageHost;
|
|
48
|
-
/** Convert a string or string array union to array. Splits strings as comma delimited */
|
|
49
|
-
private asArray;
|
|
50
|
-
private createVisitor;
|
|
51
|
-
private createRouteEntry;
|
|
52
|
-
}
|
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TypeScriptFileUpdate = void 0;
|
|
4
|
-
const cli_core_1 = require("@igniteui/cli-core");
|
|
5
|
-
const ts = require("typescript");
|
|
6
|
-
const DEFAULT_ROUTES_VARIABLE = "routes";
|
|
7
|
-
/**
|
|
8
|
-
* Apply various updates to typescript files using AST
|
|
9
|
-
*/
|
|
10
|
-
class TypeScriptFileUpdate {
|
|
11
|
-
/** Create updates for a file. Use `add<X>` methods to add transformations and `finalize` to apply and save them. */
|
|
12
|
-
constructor(targetPath) {
|
|
13
|
-
this.targetPath = targetPath;
|
|
14
|
-
this.formatOptions = { spaces: false, indentSize: 4, singleQuotes: false };
|
|
15
|
-
//#region ts.TransformerFactory
|
|
16
|
-
/** Transformation to apply edits to existing named import declarations */
|
|
17
|
-
this.importsTransformer = (context) => (rootNode) => {
|
|
18
|
-
const editImports = this.requestedImports.filter(x => x.edit);
|
|
19
|
-
// https://github.com/Microsoft/TypeScript/issues/14419#issuecomment-307256171
|
|
20
|
-
const visitor = (node) => {
|
|
21
|
-
if (node.kind === ts.SyntaxKind.ImportDeclaration &&
|
|
22
|
-
editImports.find(x => x.from === node.moduleSpecifier.text)) {
|
|
23
|
-
// visit just the source file main array (second visit)
|
|
24
|
-
return visitImport(node);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
node = ts.visitEachChild(node, visitor, context);
|
|
28
|
-
}
|
|
29
|
-
return node;
|
|
30
|
-
};
|
|
31
|
-
function visitImport(node) {
|
|
32
|
-
node = ts.visitEachChild(node, visitImport, context);
|
|
33
|
-
return node;
|
|
34
|
-
}
|
|
35
|
-
return ts.visitNode(rootNode, visitor);
|
|
36
|
-
};
|
|
37
|
-
this.fileSystem = cli_core_1.App.container.get(cli_core_1.FS_TOKEN);
|
|
38
|
-
this.initState();
|
|
39
|
-
}
|
|
40
|
-
/** Applies accumulated transforms, saves and formats the file */
|
|
41
|
-
finalize() {
|
|
42
|
-
// add new import statements after visitor walks:
|
|
43
|
-
this.addNewFileImports();
|
|
44
|
-
cli_core_1.TypeScriptUtils.saveFile(this.targetPath, this.targetSource);
|
|
45
|
-
this.formatFile(this.targetPath);
|
|
46
|
-
// reset state in case of further updates
|
|
47
|
-
this.initState();
|
|
48
|
-
}
|
|
49
|
-
addRoute(path, component, name, routerChildren, importAlias, routesVariable = DEFAULT_ROUTES_VARIABLE) {
|
|
50
|
-
this.addRouteModuleEntry(path, component, name, routerChildren, importAlias, routesVariable);
|
|
51
|
-
}
|
|
52
|
-
//#region File state
|
|
53
|
-
/** Initializes existing imports info, [re]sets import and `NgModule` edits */
|
|
54
|
-
initState() {
|
|
55
|
-
this.targetSource = cli_core_1.TypeScriptUtils.getFileSource(this.targetPath);
|
|
56
|
-
this.importsMeta = this.loadImportsMeta();
|
|
57
|
-
this.requestedImports = [];
|
|
58
|
-
this.createdStringLiterals = [];
|
|
59
|
-
}
|
|
60
|
-
/* load some metadata about imports */
|
|
61
|
-
loadImportsMeta() {
|
|
62
|
-
const meta = { lastIndex: 0, modulePaths: [] };
|
|
63
|
-
for (let i = 0; i < this.targetSource.statements.length; i++) {
|
|
64
|
-
const statement = this.targetSource.statements[i];
|
|
65
|
-
switch (statement.kind) {
|
|
66
|
-
case ts.SyntaxKind.ImportDeclaration:
|
|
67
|
-
const importStmt = statement;
|
|
68
|
-
if (importStmt.importClause && importStmt.importClause.namedBindings &&
|
|
69
|
-
importStmt.importClause.namedBindings.kind !== ts.SyntaxKind.NamespaceImport) {
|
|
70
|
-
// don't add imports without named (e.g. `import $ from "JQuery"` or `import "./my-module.js";`)
|
|
71
|
-
// don't add namespace imports (`import * as fs`) as available for editing, maybe in the future
|
|
72
|
-
meta.modulePaths.push(importStmt.moduleSpecifier.text);
|
|
73
|
-
}
|
|
74
|
-
// don't add equals imports (`import url = require("url")`) as available for editing, maybe in the future
|
|
75
|
-
case ts.SyntaxKind.ImportEqualsDeclaration:
|
|
76
|
-
meta.lastIndex = i + 1;
|
|
77
|
-
break;
|
|
78
|
-
default:
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return meta;
|
|
83
|
-
}
|
|
84
|
-
//#endregion File state
|
|
85
|
-
addRouteModuleEntry(path, component, name, routerChildren, importAlias, routesVariable = DEFAULT_ROUTES_VARIABLE) {
|
|
86
|
-
const isRouting = path.indexOf("routing") >= 0;
|
|
87
|
-
if (isRouting && this.targetSource.text.indexOf(path.slice(0, -3)) > 0) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const moduleName = path.substring(0, path.indexOf("-routing"));
|
|
91
|
-
if (path) {
|
|
92
|
-
const relativePath = isRouting ?
|
|
93
|
-
"./" + moduleName + "/" + path.slice(0, -3) : "./" + path + "/" + path;
|
|
94
|
-
this.requestImport(relativePath, importAlias);
|
|
95
|
-
}
|
|
96
|
-
// https://github.com/Microsoft/TypeScript/issues/14419#issuecomment-307256171
|
|
97
|
-
const transformer = (context) => (rootNode) => {
|
|
98
|
-
// the visitor that should be used when adding routes to the main route array
|
|
99
|
-
const conditionalVisitor = (node) => {
|
|
100
|
-
if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
|
101
|
-
const newObject = this.createRouteEntry(path, component, name, routerChildren);
|
|
102
|
-
const array = node;
|
|
103
|
-
this.createdStringLiterals.push(path, name);
|
|
104
|
-
const notFoundWildCard = ".*";
|
|
105
|
-
const nodes = ts.visitNodes(array.elements, visitor);
|
|
106
|
-
const errorRouteNode = nodes.filter(element => element.getText().includes(notFoundWildCard))[0];
|
|
107
|
-
let resultNodes = null;
|
|
108
|
-
if (errorRouteNode) {
|
|
109
|
-
resultNodes = nodes
|
|
110
|
-
.slice(0, nodes.indexOf(errorRouteNode))
|
|
111
|
-
.concat(newObject)
|
|
112
|
-
.concat(errorRouteNode);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
resultNodes = nodes
|
|
116
|
-
.concat(newObject);
|
|
117
|
-
}
|
|
118
|
-
const elements = ts.factory.createNodeArray([
|
|
119
|
-
...resultNodes
|
|
120
|
-
]);
|
|
121
|
-
return ts.factory.updateArrayLiteralExpression(array, elements);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
return ts.visitEachChild(node, conditionalVisitor, context);
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
let visitCondition;
|
|
128
|
-
if (!isRouting) {
|
|
129
|
-
visitCondition = (node) => {
|
|
130
|
-
return node.kind === ts.SyntaxKind.VariableDeclaration &&
|
|
131
|
-
node.name.getText() === routesVariable &&
|
|
132
|
-
node.type.getText() === "Route[]";
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
visitCondition = (node) => {
|
|
137
|
-
return undefined;
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
const visitor = this.createVisitor(conditionalVisitor, visitCondition, context);
|
|
141
|
-
context.enableSubstitution(ts.SyntaxKind.ClassDeclaration);
|
|
142
|
-
return ts.visitNode(rootNode, visitor);
|
|
143
|
-
};
|
|
144
|
-
this.targetSource = ts.transform(this.targetSource, [transformer], {
|
|
145
|
-
pretty: true // oh well..
|
|
146
|
-
}).transformed[0];
|
|
147
|
-
this.finalize();
|
|
148
|
-
}
|
|
149
|
-
requestImport(modulePath, routerAlias) {
|
|
150
|
-
const existing = this.requestedImports.find(x => x.from === modulePath);
|
|
151
|
-
if (!existing) {
|
|
152
|
-
// new imports, check if already exists in file
|
|
153
|
-
this.requestedImports.push({
|
|
154
|
-
as: routerAlias,
|
|
155
|
-
from: modulePath,
|
|
156
|
-
edit: this.importsMeta.modulePaths.indexOf(modulePath) !== -1
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
/** Add `import` statements not previously found in the file */
|
|
164
|
-
addNewFileImports() {
|
|
165
|
-
const newImports = this.requestedImports.filter(x => !x.edit);
|
|
166
|
-
if (!newImports.length) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
const newStatements = ts.factory.createNodeArray([
|
|
170
|
-
...this.targetSource.statements.slice(0, this.importsMeta.lastIndex),
|
|
171
|
-
...newImports.map(x => this.createIdentifierImport(x.from, x.as)),
|
|
172
|
-
...this.targetSource.statements.slice(this.importsMeta.lastIndex)
|
|
173
|
-
]);
|
|
174
|
-
newImports.forEach(x => this.createdStringLiterals.push(x.from));
|
|
175
|
-
this.targetSource = ts.factory.updateSourceFile(this.targetSource, newStatements);
|
|
176
|
-
}
|
|
177
|
-
createIdentifierImport(importPath, as) {
|
|
178
|
-
let exportedObject;
|
|
179
|
-
let exportedObjectName;
|
|
180
|
-
let importClause;
|
|
181
|
-
if (as) {
|
|
182
|
-
exportedObject = "routes";
|
|
183
|
-
exportedObjectName = as.replace(/\s/g, "");
|
|
184
|
-
importClause = ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
|
|
185
|
-
ts.factory.createImportSpecifier(false, ts.factory.createIdentifier(exportedObject), ts.factory.createIdentifier(exportedObjectName))
|
|
186
|
-
]));
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
importClause = undefined;
|
|
190
|
-
}
|
|
191
|
-
const importDeclaration = ts.factory.createImportDeclaration(undefined, importClause, ts.factory.createStringLiteral(importPath, true), undefined);
|
|
192
|
-
return importDeclaration;
|
|
193
|
-
}
|
|
194
|
-
//#endregion ts.TransformerFactory
|
|
195
|
-
//#region Formatting
|
|
196
|
-
/** Format a TS source file, very TBD */
|
|
197
|
-
formatFile(filePath) {
|
|
198
|
-
// formatting via LanguageService https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
|
|
199
|
-
// https://github.com/Microsoft/TypeScript/issues/1651
|
|
200
|
-
let text = this.fileSystem.readFile(filePath);
|
|
201
|
-
// create the language service files
|
|
202
|
-
const services = ts.createLanguageService(this.getLanguageHost(filePath), ts.createDocumentRegistry());
|
|
203
|
-
this.readFormatConfigs();
|
|
204
|
-
const textChanges = services.getFormattingEditsForDocument(filePath, this.getFormattingOptions());
|
|
205
|
-
text = this.applyChanges(text, textChanges);
|
|
206
|
-
if (this.formatOptions.singleQuotes) {
|
|
207
|
-
for (const str of this.createdStringLiterals) {
|
|
208
|
-
// there shouldn't be duplicate strings of these
|
|
209
|
-
text = text.replace(`"${str}"`, `'${str}'`);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
this.fileSystem.writeFile(filePath, text);
|
|
213
|
-
}
|
|
214
|
-
/** Try and parse formatting from project `.editorconfig` / `tslint.json` */
|
|
215
|
-
readFormatConfigs() {
|
|
216
|
-
if (this.fileSystem.fileExists(".editorconfig")) {
|
|
217
|
-
// very basic parsing support
|
|
218
|
-
const text = this.fileSystem.readFile(".editorconfig", "utf-8");
|
|
219
|
-
const options = text
|
|
220
|
-
.replace(/\s*[#;].*([\r\n])/g, "$1") //remove comments
|
|
221
|
-
.replace(/\[(?!\*\]|\*.ts).+\][^\[]+/g, "") // leave [*]/[*.ts] sections
|
|
222
|
-
.split(/\r\n|\r|\n/)
|
|
223
|
-
.reduce((obj, x) => {
|
|
224
|
-
if (x.indexOf("=") !== -1) {
|
|
225
|
-
const pair = x.split("=");
|
|
226
|
-
obj[pair[0].trim()] = pair[1].trim();
|
|
227
|
-
}
|
|
228
|
-
return obj;
|
|
229
|
-
}, {});
|
|
230
|
-
this.formatOptions.spaces = options["indent_style"] === "space";
|
|
231
|
-
if (options["indent_size"]) {
|
|
232
|
-
this.formatOptions.indentSize = parseInt(options["indent_size"], 10) || this.formatOptions.indentSize;
|
|
233
|
-
}
|
|
234
|
-
if (options["quote_type"]) {
|
|
235
|
-
this.formatOptions.singleQuotes = options["quote_type"] === "single";
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if (this.fileSystem.fileExists("tslint.json")) {
|
|
239
|
-
// tslint prio - overrides other settings
|
|
240
|
-
const options = JSON.parse(this.fileSystem.readFile("tslint.json", "utf-8"));
|
|
241
|
-
if (options.rules && options.rules.indent && options.rules.indent[0]) {
|
|
242
|
-
this.formatOptions.spaces = options.rules.indent[1] === "spaces";
|
|
243
|
-
if (options.rules.indent[2]) {
|
|
244
|
-
this.formatOptions.indentSize = parseInt(options.rules.indent[2], 10);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
if (options.rules && options.rules.quotemark && options.rules.quotemark[0]) {
|
|
248
|
-
this.formatOptions.singleQuotes = options.rules.quotemark.indexOf("single") !== -1;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Apply formatting changes (position based) in reverse
|
|
254
|
-
* from https://github.com/Microsoft/TypeScript/issues/1651#issuecomment-69877863
|
|
255
|
-
*/
|
|
256
|
-
applyChanges(orig, changes) {
|
|
257
|
-
let result = orig;
|
|
258
|
-
for (let i = changes.length - 1; i >= 0; i--) {
|
|
259
|
-
const change = changes[i];
|
|
260
|
-
const head = result.slice(0, change.span.start);
|
|
261
|
-
const tail = result.slice(change.span.start + change.span.length);
|
|
262
|
-
result = head + change.newText + tail;
|
|
263
|
-
}
|
|
264
|
-
return result;
|
|
265
|
-
}
|
|
266
|
-
/** Return source file formatting options */
|
|
267
|
-
getFormattingOptions() {
|
|
268
|
-
const formatOptions = {
|
|
269
|
-
// tslint:disable:object-literal-sort-keys
|
|
270
|
-
indentSize: this.formatOptions.indentSize,
|
|
271
|
-
tabSize: 4,
|
|
272
|
-
newLineCharacter: ts.sys.newLine,
|
|
273
|
-
convertTabsToSpaces: this.formatOptions.spaces,
|
|
274
|
-
indentStyle: ts.IndentStyle.Smart,
|
|
275
|
-
insertSpaceAfterCommaDelimiter: true,
|
|
276
|
-
insertSpaceAfterSemicolonInForStatements: true,
|
|
277
|
-
insertSpaceBeforeAndAfterBinaryOperators: true,
|
|
278
|
-
insertSpaceAfterKeywordsInControlFlowStatements: true,
|
|
279
|
-
insertSpaceAfterTypeAssertion: true
|
|
280
|
-
// tslint:enable:object-literal-sort-keys
|
|
281
|
-
};
|
|
282
|
-
return formatOptions;
|
|
283
|
-
}
|
|
284
|
-
/** Get language service host, sloppily */
|
|
285
|
-
getLanguageHost(filePath) {
|
|
286
|
-
const files = {};
|
|
287
|
-
files[filePath] = { version: 0 };
|
|
288
|
-
// create the language service host to allow the LS to communicate with the host
|
|
289
|
-
const servicesHost = {
|
|
290
|
-
getCompilationSettings: () => ({}),
|
|
291
|
-
getScriptFileNames: () => Object.keys(files),
|
|
292
|
-
getScriptVersion: fileName => files[fileName] && files[fileName].version.toString(),
|
|
293
|
-
getScriptSnapshot: fileName => {
|
|
294
|
-
if (!this.fileSystem.fileExists(fileName)) {
|
|
295
|
-
return undefined;
|
|
296
|
-
}
|
|
297
|
-
return ts.ScriptSnapshot.fromString(this.fileSystem.readFile(fileName));
|
|
298
|
-
},
|
|
299
|
-
getCurrentDirectory: () => process.cwd(),
|
|
300
|
-
getDefaultLibFileName: options => ts.getDefaultLibFilePath(options),
|
|
301
|
-
readDirectory: ts.sys.readDirectory,
|
|
302
|
-
readFile: ts.sys.readFile,
|
|
303
|
-
fileExists: ts.sys.fileExists
|
|
304
|
-
};
|
|
305
|
-
return servicesHost;
|
|
306
|
-
}
|
|
307
|
-
//#endregion Formatting
|
|
308
|
-
/** Convert a string or string array union to array. Splits strings as comma delimited */
|
|
309
|
-
asArray(value, variables) {
|
|
310
|
-
let result = [];
|
|
311
|
-
if (value) {
|
|
312
|
-
result = typeof value === "string" ? value.split(/\s*,\s*/) : value;
|
|
313
|
-
result = result.map(x => cli_core_1.Util.applyConfigTransformation(x, variables));
|
|
314
|
-
}
|
|
315
|
-
return result;
|
|
316
|
-
}
|
|
317
|
-
createVisitor(conditionalVisitor, visitCondition, nodeContext) {
|
|
318
|
-
return function visitor(node) {
|
|
319
|
-
if (visitCondition(node)) {
|
|
320
|
-
node = ts.visitEachChild(node, conditionalVisitor, nodeContext);
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
node = ts.visitEachChild(node, visitor, nodeContext);
|
|
324
|
-
}
|
|
325
|
-
return node;
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
createRouteEntry(filePath, className, linkText, routerAlias) {
|
|
329
|
-
const routePath = ts.factory.createPropertyAssignment("path", ts.factory.createStringLiteral(filePath, true));
|
|
330
|
-
const routeComponent = ts.factory.createPropertyAssignment("component", ts.factory.createStringLiteral(className, true));
|
|
331
|
-
const routeData = ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(linkText, true));
|
|
332
|
-
if (routerAlias) {
|
|
333
|
-
const childrenData = ts.factory.createPropertyAssignment("children", ts.factory.createIdentifier(routerAlias));
|
|
334
|
-
return ts.factory.createObjectLiteralExpression([routePath, routeComponent, routeData, childrenData]);
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
return ts.factory.createObjectLiteralExpression([routePath, routeComponent, routeData]);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
exports.TypeScriptFileUpdate = TypeScriptFileUpdate;
|