igniteui-cli 13.2.2-beta.1 → 13.3.0-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.
Files changed (60) hide show
  1. package/lib/templates/AngularTemplate.js +8 -29
  2. package/lib/templates/IgniteUIForReactTemplate.d.ts +0 -1
  3. package/lib/templates/IgniteUIForReactTemplate.js +11 -36
  4. package/lib/templates/IgniteUIForWebComponentsTemplate.js +5 -35
  5. package/migrations/update-5_0_0/index.js +2 -3
  6. package/package.json +3 -3
  7. package/templates/react/ReactTypeScriptFileUpdate.d.ts +49 -10
  8. package/templates/react/ReactTypeScriptFileUpdate.js +336 -60
  9. package/templates/webcomponents/TypeScriptFileUpdate.d.ts +52 -0
  10. package/templates/webcomponents/TypeScriptFileUpdate.js +341 -0
  11. package/templates/webcomponents/igc-ts/accordion/default/index.js +3 -0
  12. package/templates/webcomponents/igc-ts/avatar/default/index.js +3 -0
  13. package/templates/webcomponents/igc-ts/badge/default/index.js +3 -0
  14. package/templates/webcomponents/igc-ts/button/default/index.js +3 -0
  15. package/templates/webcomponents/igc-ts/button-group/default/index.js +3 -0
  16. package/templates/webcomponents/igc-ts/calendar/default/index.js +3 -0
  17. package/templates/webcomponents/igc-ts/card/default/index.js +3 -0
  18. package/templates/webcomponents/igc-ts/checkbox/default/index.js +3 -0
  19. package/templates/webcomponents/igc-ts/chip/default/index.js +3 -0
  20. package/templates/webcomponents/igc-ts/circular-progress/default/index.js +3 -0
  21. package/templates/webcomponents/igc-ts/custom-templates/subscription-form/index.js +3 -0
  22. package/templates/webcomponents/igc-ts/date-time-input/default/index.js +3 -0
  23. package/templates/webcomponents/igc-ts/dock-manager/default/index.js +3 -0
  24. package/templates/webcomponents/igc-ts/dropdown/default/index.js +3 -0
  25. package/templates/webcomponents/igc-ts/expansion-panel/default/index.js +3 -0
  26. package/templates/webcomponents/igc-ts/financial-chart/default/index.js +3 -0
  27. package/templates/webcomponents/igc-ts/form/default/index.js +3 -0
  28. package/templates/webcomponents/igc-ts/grid/default/index.js +3 -0
  29. package/templates/webcomponents/igc-ts/grid/grid-editing/index.js +3 -0
  30. package/templates/webcomponents/igc-ts/grid/grid-summaries/index.js +3 -0
  31. package/templates/webcomponents/igc-ts/icon/default/index.js +3 -0
  32. package/templates/webcomponents/igc-ts/icon-button/default/index.js +3 -0
  33. package/templates/webcomponents/igc-ts/input/default/index.js +3 -0
  34. package/templates/webcomponents/igc-ts/linear-gauge/default/index.js +3 -0
  35. package/templates/webcomponents/igc-ts/linear-progress/default/index.js +3 -0
  36. package/templates/webcomponents/igc-ts/list/default/index.js +3 -0
  37. package/templates/webcomponents/igc-ts/navbar/default/index.js +3 -0
  38. package/templates/webcomponents/igc-ts/pie-chart/default/index.js +3 -0
  39. package/templates/webcomponents/igc-ts/projects/_base/files/package.json +1 -1
  40. package/templates/webcomponents/igc-ts/projects/_base_with_home/files/package.json +7 -7
  41. package/templates/webcomponents/igc-ts/radial-gauge/default/index.js +3 -0
  42. package/templates/webcomponents/igc-ts/radio-group/default/index.js +3 -0
  43. package/templates/webcomponents/igc-ts/rating/default/index.js +3 -0
  44. package/templates/webcomponents/igc-ts/ripple/default/index.js +3 -0
  45. package/templates/webcomponents/igc-ts/slider/default/index.js +3 -0
  46. package/templates/webcomponents/igc-ts/switch/default/index.js +3 -0
  47. package/templates/webcomponents/igc-ts/tabs/default/index.js +3 -0
  48. package/templates/webcomponents/igc-ts/text-area/default/index.js +3 -0
  49. package/templates/webcomponents/igc-ts/text-area/index.js +3 -0
  50. package/templates/webcomponents/igc-ts/tree/default/index.js +3 -0
  51. package/templates/react/types/ReactRouteEntry.d.ts +0 -6
  52. package/templates/react/types/ReactRouteEntry.js +0 -2
  53. package/templates/react/types/ReactRouteLike.d.ts +0 -25
  54. package/templates/react/types/ReactRouteLike.js +0 -2
  55. package/templates/react/types/ReactRouteTarget.d.ts +0 -7
  56. package/templates/react/types/ReactRouteTarget.js +0 -11
  57. package/templates/react/types/index.d.ts +0 -3
  58. package/templates/react/types/index.js +0 -19
  59. package/templates/webcomponents/WebComponentsTypeScriptFileUpdate.d.ts +0 -11
  60. package/templates/webcomponents/WebComponentsTypeScriptFileUpdate.js +0 -82
@@ -1,71 +1,347 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ReactTypeScriptFileUpdate = void 0;
4
- const ts = require("typescript");
5
4
  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);
5
+ const ts = require("typescript");
6
+ const DEFAULT_ROUTES_VARIABLE = "routes";
7
+ /**
8
+ * Apply various updates to typescript files using AST
9
+ */
10
+ class ReactTypeScriptFileUpdate {
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, 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
+ }
26
81
  }
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),
41
- },
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,
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;
272
+ }
273
+ return result;
274
+ }
275
+ /** Return source file formatting options */
276
+ getFormattingOptions() {
277
+ const formatOptions = {
278
+ // tslint:disable:object-literal-sort-keys
279
+ indentSize: this.formatOptions.indentSize,
280
+ tabSize: 4,
281
+ newLineCharacter: ts.sys.newLine,
282
+ convertTabsToSpaces: this.formatOptions.spaces,
283
+ indentStyle: ts.IndentStyle.Smart,
284
+ insertSpaceAfterCommaDelimiter: true,
285
+ insertSpaceAfterSemicolonInForStatements: true,
286
+ insertSpaceBeforeAndAfterBinaryOperators: true,
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));
57
307
  },
58
- ];
59
- const newRoute = this.astTransformer.createObjectLiteralExpression(structure, multiline);
60
- return this.astTransformer.addMembersToArrayLiteral(visitCondition, [newRoute], prepend, anchorElement);
308
+ getCurrentDirectory: () => process.cwd(),
309
+ getDefaultLibFileName: options => ts.getDefaultLibFilePath(options),
310
+ readDirectory: ts.sys.readDirectory,
311
+ readFile: ts.sys.readFile,
312
+ fileExists: ts.sys.fileExists
313
+ };
314
+ return servicesHost;
61
315
  }
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);
316
+ //#endregion Formatting
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
+ };
65
327
  }
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);
328
+ createRouteEntry(path, component, name, routerAlias, defaultRoute = false) {
329
+ if (defaultRoute) {
330
+ // for default route in React we should generate index: true, loader: () => redirect(path)
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]);
69
345
  }
70
346
  }
71
347
  exports.ReactTypeScriptFileUpdate = ReactTypeScriptFileUpdate;
@@ -0,0 +1,52 @@
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
+ }