@nstudio/angular 15.0.4-rc.0 → 15.0.4-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/collection.json +0 -5
- package/package.json +2 -2
- package/src/schematics/elements/index.js +11 -9
- package/src/schematics/feature/index.js +1 -1
- package/src/schematics/feature/index.spec.js +1 -1
- package/src/utils/ast.d.ts +10 -75
- package/src/utils/ast.js +84 -262
- package/src/utils/generator.d.ts +1 -1
- package/src/utils/generator.js +31 -36
- package/src/utils/versions.d.ts +3 -2
- package/src/utils/versions.js +5 -4
- package/src/utils/xplat.js +2 -3
- package/src/schematics/helpers/applitools/index.d.ts +0 -2
- package/src/schematics/helpers/applitools/index.js +0 -115
- package/src/schematics/helpers/applitools/index.js.map +0 -1
- package/src/schematics/helpers/index.d.ts +0 -2
- package/src/schematics/helpers/index.js +0 -27
- package/src/schematics/helpers/index.spec.d.ts +0 -1
- package/src/schematics/helpers/index.spec.js +0 -95
- package/src/schematics/helpers/schema.json +0 -22
package/src/utils/ast.js
CHANGED
@@ -1,28 +1,23 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
4
|
-
const ensure_typescript_1 = require("@nrwl/js/src/utils/typescript/ensure-typescript");
|
5
|
-
const typescript_1 = require("nx/src/utils/typescript");
|
3
|
+
exports.getDecoratorPropertyValueNode = exports.readBootstrapInfo = exports.addEntryComponents = exports.addDeclarationToModule = exports.addProviderToModule = exports.addRoute = exports.getBootstrapComponent = exports.addImportToTestBed = exports.addImportToModule = exports.removeFromNgModule = exports.addSymbolToNgModuleMetadata = exports.addToCollection = void 0;
|
6
4
|
const ts = require("typescript");
|
7
|
-
const
|
8
|
-
const
|
9
|
-
const
|
10
|
-
|
11
|
-
function addToCollection(
|
5
|
+
const typescript_1 = require("nx/src/utils/typescript");
|
6
|
+
const path = require("path");
|
7
|
+
const xplat_utils_1 = require("@nstudio/xplat-utils");
|
8
|
+
const xplat_1 = require("@nstudio/xplat");
|
9
|
+
function addToCollection(source, barrelIndexPath, symbolName, insertSpaces = '') {
|
12
10
|
const collection = getCollection(source);
|
13
11
|
if (!collection)
|
14
12
|
return [];
|
15
13
|
// if (!collection) return [new NoopChange()];
|
16
14
|
// return [new NoopChange()];
|
17
|
-
console.log('collection.hasTrailingComma:', collection.hasTrailingComma);
|
18
15
|
if (collection.hasTrailingComma || collection.length === 0) {
|
19
|
-
return [
|
20
|
-
(0, js_1.insertChange)(tree, source, barrelIndexPath, collection.end, symbolName),
|
21
|
-
];
|
16
|
+
return [new xplat_1.InsertChange(barrelIndexPath, collection.end, symbolName)];
|
22
17
|
}
|
23
18
|
else {
|
24
19
|
return [
|
25
|
-
|
20
|
+
new xplat_1.InsertChange(barrelIndexPath, collection.end, `,\n${insertSpaces}${symbolName}`),
|
26
21
|
];
|
27
22
|
}
|
28
23
|
}
|
@@ -41,13 +36,10 @@ function getCollection(source) {
|
|
41
36
|
return null;
|
42
37
|
}
|
43
38
|
function _angularImportsFromNode(node, _sourceFile) {
|
44
|
-
if (!tsModule) {
|
45
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
46
|
-
}
|
47
39
|
const ms = node.moduleSpecifier;
|
48
40
|
let modulePath;
|
49
41
|
switch (ms.kind) {
|
50
|
-
case
|
42
|
+
case ts.SyntaxKind.StringLiteral:
|
51
43
|
modulePath = ms.text;
|
52
44
|
break;
|
53
45
|
default:
|
@@ -63,10 +55,10 @@ function _angularImportsFromNode(node, _sourceFile) {
|
|
63
55
|
}
|
64
56
|
else if (node.importClause.namedBindings) {
|
65
57
|
const nb = node.importClause.namedBindings;
|
66
|
-
if (nb.kind ==
|
58
|
+
if (nb.kind == ts.SyntaxKind.NamespaceImport) {
|
67
59
|
// This is of the form `import * as name from 'path'`. Return `name.`.
|
68
60
|
return {
|
69
|
-
[
|
61
|
+
[nb.name.text + '.']: modulePath,
|
70
62
|
};
|
71
63
|
}
|
72
64
|
else {
|
@@ -87,21 +79,8 @@ function _angularImportsFromNode(node, _sourceFile) {
|
|
87
79
|
return {};
|
88
80
|
}
|
89
81
|
}
|
90
|
-
/**
|
91
|
-
* Check if the Component, Directive or Pipe is standalone
|
92
|
-
* @param sourceFile TS Source File containing the token to check
|
93
|
-
* @param decoratorName The type of decorator to check (Component, Directive, Pipe)
|
94
|
-
*/
|
95
|
-
function isStandalone(sourceFile, decoratorName) {
|
96
|
-
const decoratorMetadata = getDecoratorMetadata(sourceFile, decoratorName, '@angular/core');
|
97
|
-
return decoratorMetadata.some((node) => node.getText().includes('standalone: true'));
|
98
|
-
}
|
99
|
-
exports.isStandalone = isStandalone;
|
100
82
|
function getDecoratorMetadata(source, identifier, module) {
|
101
|
-
|
102
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
103
|
-
}
|
104
|
-
const angularImports = (0, typescript_1.findNodes)(source, tsModule.SyntaxKind.ImportDeclaration)
|
83
|
+
const angularImports = (0, typescript_1.findNodes)(source, ts.SyntaxKind.ImportDeclaration)
|
105
84
|
.map((node) => _angularImportsFromNode(node, source))
|
106
85
|
.reduce((acc, current) => {
|
107
86
|
for (const key of Object.keys(current)) {
|
@@ -109,65 +88,60 @@ function getDecoratorMetadata(source, identifier, module) {
|
|
109
88
|
}
|
110
89
|
return acc;
|
111
90
|
}, {});
|
112
|
-
return (0,
|
91
|
+
return (0, xplat_1.getSourceNodes)(source)
|
113
92
|
.filter((node) => {
|
114
|
-
return (node.kind ==
|
115
|
-
node.expression.kind ==
|
116
|
-
tsModule.SyntaxKind.CallExpression);
|
93
|
+
return (node.kind == ts.SyntaxKind.Decorator &&
|
94
|
+
node.expression.kind == ts.SyntaxKind.CallExpression);
|
117
95
|
})
|
118
96
|
.map((node) => node.expression)
|
119
97
|
.filter((expr) => {
|
120
|
-
if (expr.expression.kind ==
|
98
|
+
if (expr.expression.kind == ts.SyntaxKind.Identifier) {
|
121
99
|
const id = expr.expression;
|
122
100
|
return (id.getFullText(source) == identifier &&
|
123
101
|
angularImports[id.getFullText(source)] === module);
|
124
102
|
}
|
125
|
-
else if (expr.expression.kind ==
|
103
|
+
else if (expr.expression.kind == ts.SyntaxKind.PropertyAccessExpression) {
|
126
104
|
// This covers foo.NgModule when importing * as foo.
|
127
105
|
const paExpr = expr.expression;
|
128
106
|
// If the left expression is not an identifier, just give up at that point.
|
129
|
-
if (paExpr.expression.kind !==
|
107
|
+
if (paExpr.expression.kind !== ts.SyntaxKind.Identifier) {
|
130
108
|
return false;
|
131
109
|
}
|
132
110
|
const id = paExpr.name.text;
|
133
111
|
const moduleId = paExpr.expression.getText(source);
|
134
|
-
return id === identifier && angularImports[
|
112
|
+
return id === identifier && angularImports[moduleId + '.'] === module;
|
135
113
|
}
|
136
114
|
return false;
|
137
115
|
})
|
138
116
|
.filter((expr) => expr.arguments[0] &&
|
139
|
-
expr.arguments[0].kind ==
|
117
|
+
expr.arguments[0].kind == ts.SyntaxKind.ObjectLiteralExpression)
|
140
118
|
.map((expr) => expr.arguments[0]);
|
141
119
|
}
|
142
|
-
|
143
|
-
|
144
|
-
const nodes = getDecoratorMetadata(source, decoratorName, '@angular/core');
|
120
|
+
function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, expression) {
|
121
|
+
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
145
122
|
let node = nodes[0]; // tslint:disable-line:no-any
|
146
123
|
// Find the decorator declaration.
|
147
124
|
if (!node) {
|
148
|
-
return
|
149
|
-
}
|
150
|
-
if (!tsModule) {
|
151
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
125
|
+
return [];
|
152
126
|
}
|
153
127
|
// Get all the children property assignment of object literals.
|
154
128
|
const matchingProperties = node.properties
|
155
|
-
.filter((prop) => prop.kind ==
|
129
|
+
.filter((prop) => prop.kind == ts.SyntaxKind.PropertyAssignment)
|
156
130
|
// Filter out every fields that's not "metadataField". Also handles string literals
|
157
131
|
// (but not expressions).
|
158
132
|
.filter((prop) => {
|
159
133
|
const name = prop.name;
|
160
134
|
switch (name.kind) {
|
161
|
-
case
|
135
|
+
case ts.SyntaxKind.Identifier:
|
162
136
|
return name.getText(source) == metadataField;
|
163
|
-
case
|
137
|
+
case ts.SyntaxKind.StringLiteral:
|
164
138
|
return name.text == metadataField;
|
165
139
|
}
|
166
140
|
return false;
|
167
141
|
});
|
168
142
|
// Get the last node of the array literal.
|
169
143
|
if (!matchingProperties) {
|
170
|
-
return
|
144
|
+
return [];
|
171
145
|
}
|
172
146
|
if (matchingProperties.length == 0) {
|
173
147
|
// We haven't found the field in the metadata declaration. Insert a new field.
|
@@ -190,12 +164,13 @@ function _addSymbolToDecoratorMetadata(host, source, filePath, metadataField, ex
|
|
190
164
|
toInsert = `, ${metadataField}: [${expression}]`;
|
191
165
|
}
|
192
166
|
}
|
193
|
-
|
167
|
+
const newMetadataProperty = new xplat_1.InsertChange(ngModulePath, position, toInsert);
|
168
|
+
return [newMetadataProperty];
|
194
169
|
}
|
195
170
|
const assignment = matchingProperties[0];
|
196
171
|
// If it's not an array, nothing we can do really.
|
197
|
-
if (assignment.initializer.kind !==
|
198
|
-
return
|
172
|
+
if (assignment.initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
|
173
|
+
return [];
|
199
174
|
}
|
200
175
|
const arrLiteral = assignment.initializer;
|
201
176
|
if (arrLiteral.elements.length == 0) {
|
@@ -207,20 +182,20 @@ function _addSymbolToDecoratorMetadata(host, source, filePath, metadataField, ex
|
|
207
182
|
}
|
208
183
|
if (!node) {
|
209
184
|
console.log('No app module found. Please add your new class to your component.');
|
210
|
-
return
|
185
|
+
return [];
|
211
186
|
}
|
212
187
|
const isArray = Array.isArray(node);
|
213
188
|
if (isArray) {
|
214
189
|
const nodeArray = node;
|
215
190
|
const symbolsArray = nodeArray.map((node) => node.getText());
|
216
191
|
if (symbolsArray.includes(expression)) {
|
217
|
-
return
|
192
|
+
return [];
|
218
193
|
}
|
219
194
|
node = node[node.length - 1];
|
220
195
|
}
|
221
196
|
let toInsert;
|
222
197
|
let position = node.getEnd();
|
223
|
-
if (!isArray && node.kind ==
|
198
|
+
if (!isArray && node.kind == ts.SyntaxKind.ObjectLiteralExpression) {
|
224
199
|
// We haven't found the field in the metadata declaration. Insert a new
|
225
200
|
// field.
|
226
201
|
const expr = node;
|
@@ -241,8 +216,7 @@ function _addSymbolToDecoratorMetadata(host, source, filePath, metadataField, ex
|
|
241
216
|
}
|
242
217
|
}
|
243
218
|
}
|
244
|
-
else if (!isArray &&
|
245
|
-
node.kind == tsModule.SyntaxKind.ArrayLiteralExpression) {
|
219
|
+
else if (!isArray && node.kind == ts.SyntaxKind.ArrayLiteralExpression) {
|
246
220
|
// We found the field but it's empty. Insert it just before the `]`.
|
247
221
|
position--;
|
248
222
|
toInsert = `${expression}`;
|
@@ -257,130 +231,54 @@ function _addSymbolToDecoratorMetadata(host, source, filePath, metadataField, ex
|
|
257
231
|
toInsert = `, ${expression}`;
|
258
232
|
}
|
259
233
|
}
|
260
|
-
|
261
|
-
|
262
|
-
function _addSymbolToNgModuleMetadata(host, source, ngModulePath, metadataField, expression) {
|
263
|
-
return _addSymbolToDecoratorMetadata(host, source, ngModulePath, metadataField, expression, 'NgModule');
|
234
|
+
const insert = new xplat_1.InsertChange(ngModulePath, position, toInsert);
|
235
|
+
return [insert];
|
264
236
|
}
|
265
|
-
exports.
|
266
|
-
function removeFromNgModule(
|
237
|
+
exports.addSymbolToNgModuleMetadata = addSymbolToNgModuleMetadata;
|
238
|
+
function removeFromNgModule(source, modulePath, property) {
|
267
239
|
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
268
240
|
let node = nodes[0]; // tslint:disable-line:no-any
|
269
241
|
// Find the decorator declaration.
|
270
242
|
if (!node) {
|
271
|
-
return
|
243
|
+
return [];
|
272
244
|
}
|
273
245
|
// Get all the children property assignment of object literals.
|
274
246
|
const matchingProperty = getMatchingProperty(source, property, 'NgModule', '@angular/core');
|
275
247
|
if (matchingProperty) {
|
276
|
-
return
|
248
|
+
return [
|
249
|
+
new xplat_1.RemoveChange(modulePath, matchingProperty.getStart(source), matchingProperty.getFullText(source)),
|
250
|
+
];
|
251
|
+
}
|
252
|
+
else {
|
253
|
+
return [];
|
277
254
|
}
|
278
255
|
}
|
279
256
|
exports.removeFromNgModule = removeFromNgModule;
|
280
|
-
|
281
|
-
|
282
|
-
* @param host Virtual Tree
|
283
|
-
* @param source TS Source File containing the Component
|
284
|
-
* @param componentPath The path to the Component
|
285
|
-
* @param symbolName The import to add to the Component
|
286
|
-
*/
|
287
|
-
function addImportToComponent(host, source, componentPath, symbolName) {
|
288
|
-
return _addSymbolToDecoratorMetadata(host, source, componentPath, 'imports', symbolName, 'Component');
|
289
|
-
}
|
290
|
-
exports.addImportToComponent = addImportToComponent;
|
291
|
-
/**
|
292
|
-
* Add an import to a Standalone Directive
|
293
|
-
* @param host Virtual Tree
|
294
|
-
* @param source TS Source File containing the Directive
|
295
|
-
* @param directivePath The path to the Directive
|
296
|
-
* @param symbolName The import to add to the Directive
|
297
|
-
*/
|
298
|
-
function addImportToDirective(host, source, directivePath, symbolName) {
|
299
|
-
return _addSymbolToDecoratorMetadata(host, source, directivePath, 'imports', symbolName, 'Directive');
|
300
|
-
}
|
301
|
-
exports.addImportToDirective = addImportToDirective;
|
302
|
-
/**
|
303
|
-
* Add an import to a Standalone Pipe
|
304
|
-
* @param host Virtual Tree
|
305
|
-
* @param source TS Source File containing the Pipe
|
306
|
-
* @param pipePath The path to the Pipe
|
307
|
-
* @param symbolName The import to add to the Pipe
|
308
|
-
*/
|
309
|
-
function addImportToPipe(host, source, pipePath, symbolName) {
|
310
|
-
return _addSymbolToDecoratorMetadata(host, source, pipePath, 'imports', symbolName, 'Pipe');
|
311
|
-
}
|
312
|
-
exports.addImportToPipe = addImportToPipe;
|
313
|
-
/**
|
314
|
-
* Add an import to an NgModule
|
315
|
-
* @param host Virtual Tree
|
316
|
-
* @param source TS Source File containing the NgModule
|
317
|
-
* @param modulePath The path to the NgModule
|
318
|
-
* @param symbolName The import to add to the NgModule
|
319
|
-
*/
|
320
|
-
function addImportToModule(host, source, modulePath, symbolName) {
|
321
|
-
return _addSymbolToNgModuleMetadata(host, source, modulePath, 'imports', symbolName);
|
257
|
+
function addImportToModule(source, modulePath, symbolName) {
|
258
|
+
return addSymbolToNgModuleMetadata(source, modulePath, 'imports', symbolName);
|
322
259
|
}
|
323
260
|
exports.addImportToModule = addImportToModule;
|
324
|
-
function addImportToTestBed(
|
325
|
-
|
326
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
327
|
-
}
|
328
|
-
const allCalls = ((0, typescript_1.findNodes)(source, tsModule.SyntaxKind.CallExpression));
|
329
|
-
const configureTestingModuleObjectLiterals = allCalls
|
330
|
-
.filter((c) => c.expression.kind === tsModule.SyntaxKind.PropertyAccessExpression)
|
331
|
-
.filter((c) => c.expression.name.getText(source) === 'configureTestingModule')
|
332
|
-
.map((c) => c.arguments[0].kind === tsModule.SyntaxKind.ObjectLiteralExpression
|
333
|
-
? c.arguments[0]
|
334
|
-
: null);
|
335
|
-
if (configureTestingModuleObjectLiterals.length > 0) {
|
336
|
-
const startPosition = configureTestingModuleObjectLiterals[0]
|
337
|
-
.getFirstToken(source)
|
338
|
-
.getEnd();
|
339
|
-
return (0, js_1.insertChange)(host, source, specPath, startPosition, `imports: [${symbolName}], `);
|
340
|
-
}
|
341
|
-
return source;
|
342
|
-
}
|
343
|
-
exports.addImportToTestBed = addImportToTestBed;
|
344
|
-
function addDeclarationsToTestBed(host, source, specPath, symbolName) {
|
345
|
-
if (!tsModule) {
|
346
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
347
|
-
}
|
348
|
-
const allCalls = ((0, typescript_1.findNodes)(source, tsModule.SyntaxKind.CallExpression));
|
261
|
+
function addImportToTestBed(source, specPath, symbolName) {
|
262
|
+
const allCalls = ((0, typescript_1.findNodes)(source, ts.SyntaxKind.CallExpression));
|
349
263
|
const configureTestingModuleObjectLiterals = allCalls
|
350
|
-
.filter((c) => c.expression.kind ===
|
264
|
+
.filter((c) => c.expression.kind === ts.SyntaxKind.PropertyAccessExpression)
|
351
265
|
.filter((c) => c.expression.name.getText(source) === 'configureTestingModule')
|
352
|
-
.map((c) => c.arguments[0].kind ===
|
266
|
+
.map((c) => c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
353
267
|
? c.arguments[0]
|
354
268
|
: null);
|
355
269
|
if (configureTestingModuleObjectLiterals.length > 0) {
|
356
270
|
const startPosition = configureTestingModuleObjectLiterals[0]
|
357
271
|
.getFirstToken(source)
|
358
272
|
.getEnd();
|
359
|
-
return
|
360
|
-
|
361
|
-
|
362
|
-
}
|
363
|
-
exports.addDeclarationsToTestBed = addDeclarationsToTestBed;
|
364
|
-
function replaceIntoToTestBed(host, source, specPath, newSymbol, previousSymbol) {
|
365
|
-
if (!tsModule) {
|
366
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
273
|
+
return [
|
274
|
+
new xplat_1.InsertChange(specPath, startPosition, `imports: [${symbolName}], `),
|
275
|
+
];
|
367
276
|
}
|
368
|
-
|
369
|
-
|
370
|
-
.filter((c) => c.expression.kind === tsModule.SyntaxKind.PropertyAccessExpression)
|
371
|
-
.filter((c) => c.expression.name.getText(source) === 'configureTestingModule')
|
372
|
-
.map((c) => c.arguments[0].kind === tsModule.SyntaxKind.ObjectLiteralExpression
|
373
|
-
? c.arguments[0]
|
374
|
-
: null);
|
375
|
-
if (configureTestingModuleObjectLiterals.length > 0) {
|
376
|
-
const startPosition = configureTestingModuleObjectLiterals[0]
|
377
|
-
.getFirstToken(source)
|
378
|
-
.getEnd();
|
379
|
-
return (0, js_1.replaceChange)(host, source, specPath, startPosition, newSymbol, previousSymbol);
|
277
|
+
else {
|
278
|
+
return [];
|
380
279
|
}
|
381
|
-
return source;
|
382
280
|
}
|
383
|
-
exports.
|
281
|
+
exports.addImportToTestBed = addImportToTestBed;
|
384
282
|
function getBootstrapComponent(source, moduleClassName) {
|
385
283
|
const bootstrap = getMatchingProperty(source, 'bootstrap', 'NgModule', '@angular/core');
|
386
284
|
if (!bootstrap) {
|
@@ -403,113 +301,56 @@ function getMatchingProperty(source, property, identifier, module) {
|
|
403
301
|
// Get all the children property assignment of object literals.
|
404
302
|
return getMatchingObjectLiteralElement(node, source, property);
|
405
303
|
}
|
406
|
-
function
|
304
|
+
function addRoute(ngModulePath, source, route) {
|
407
305
|
const routes = getListOfRoutes(source);
|
408
306
|
if (!routes)
|
409
|
-
return
|
307
|
+
return [];
|
410
308
|
if (routes.hasTrailingComma || routes.length === 0) {
|
411
|
-
return
|
309
|
+
return [new xplat_1.InsertChange(ngModulePath, routes.end, route)];
|
412
310
|
}
|
413
311
|
else {
|
414
|
-
return
|
312
|
+
return [new xplat_1.InsertChange(ngModulePath, routes.end, `, ${route}`)];
|
415
313
|
}
|
416
314
|
}
|
417
|
-
exports.
|
315
|
+
exports.addRoute = addRoute;
|
418
316
|
function getListOfRoutes(source) {
|
419
|
-
if (!tsModule) {
|
420
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
421
|
-
}
|
422
317
|
const imports = getMatchingProperty(source, 'imports', 'NgModule', '@angular/core');
|
423
|
-
if (
|
318
|
+
if (imports.initializer.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
424
319
|
const a = imports.initializer;
|
425
|
-
for (
|
426
|
-
if (e.kind ===
|
320
|
+
for (let e of a.elements) {
|
321
|
+
if (e.kind === ts.SyntaxKind.CallExpression) {
|
427
322
|
const ee = e;
|
428
323
|
const text = ee.expression.getText(source);
|
429
324
|
if ((text === 'RouterModule.forRoot' ||
|
430
325
|
text === 'RouterModule.forChild') &&
|
431
326
|
ee.arguments.length > 0) {
|
432
327
|
const routes = ee.arguments[0];
|
433
|
-
if (routes.kind ===
|
328
|
+
if (routes.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
434
329
|
return routes.elements;
|
435
330
|
}
|
436
|
-
else if (routes.kind === tsModule.SyntaxKind.Identifier) {
|
437
|
-
// find the array expression
|
438
|
-
const variableDeclarations = (0, typescript_1.findNodes)(source, tsModule.SyntaxKind.VariableDeclaration);
|
439
|
-
const routesDeclaration = variableDeclarations.find((x) => {
|
440
|
-
return x.name.getText() === routes.getText();
|
441
|
-
});
|
442
|
-
if (routesDeclaration) {
|
443
|
-
return routesDeclaration.initializer.elements;
|
444
|
-
}
|
445
|
-
}
|
446
331
|
}
|
447
332
|
}
|
448
333
|
}
|
449
334
|
}
|
450
335
|
return null;
|
451
336
|
}
|
452
|
-
|
453
|
-
|
454
|
-
* @param tree Virtual Tree
|
455
|
-
* @param filePath Path to the file containing the bootstrapApplication call
|
456
|
-
* @param providerToAdd Provider to add
|
457
|
-
*/
|
458
|
-
function addProviderToBootstrapApplication(tree, filePath, providerToAdd) {
|
459
|
-
(0, ensure_typescript_1.ensureTypescript)();
|
460
|
-
const { tsquery } = require('@phenomnomnominal/tsquery');
|
461
|
-
const PROVIDERS_ARRAY_SELECTOR = 'CallExpression:has(Identifier[name=bootstrapApplication]) ObjectLiteralExpression > PropertyAssignment:has(Identifier[name=providers]) > ArrayLiteralExpression';
|
462
|
-
const fileContents = tree.read(filePath, 'utf-8');
|
463
|
-
const ast = tsquery.ast(fileContents);
|
464
|
-
const providersArrayNodes = tsquery(ast, PROVIDERS_ARRAY_SELECTOR, {
|
465
|
-
visitAllChildren: true,
|
466
|
-
});
|
467
|
-
if (providersArrayNodes.length === 0) {
|
468
|
-
throw new Error(`Providers does not exist in the bootstrapApplication call within ${filePath}.`);
|
469
|
-
}
|
470
|
-
const arrayNode = providersArrayNodes[0];
|
471
|
-
const newFileContents = `${fileContents.slice(0, arrayNode.getStart() + 1)}${providerToAdd},${fileContents.slice(arrayNode.getStart() + 1, fileContents.length)}`;
|
472
|
-
tree.write(filePath, newFileContents);
|
473
|
-
}
|
474
|
-
exports.addProviderToBootstrapApplication = addProviderToBootstrapApplication;
|
475
|
-
/**
|
476
|
-
* Add a provider to an NgModule
|
477
|
-
* @param host Virtual Tree
|
478
|
-
* @param source TS Source File containing the NgModule
|
479
|
-
* @param modulePath Path to the NgModule
|
480
|
-
* @param symbolName The provider to add
|
481
|
-
*/
|
482
|
-
function addProviderToModule(host, source, modulePath, symbolName) {
|
483
|
-
return _addSymbolToNgModuleMetadata(host, source, modulePath, 'providers', symbolName);
|
337
|
+
function addProviderToModule(source, modulePath, symbolName) {
|
338
|
+
return addSymbolToNgModuleMetadata(source, modulePath, 'providers', symbolName);
|
484
339
|
}
|
485
340
|
exports.addProviderToModule = addProviderToModule;
|
486
|
-
|
487
|
-
|
488
|
-
* @param host Virtual Tree
|
489
|
-
* @param source TS Source File containing the Component
|
490
|
-
* @param componentPath Path to the Component
|
491
|
-
* @param symbolName The provider to add
|
492
|
-
*/
|
493
|
-
function addProviderToComponent(host, source, componentPath, symbolName) {
|
494
|
-
return _addSymbolToDecoratorMetadata(host, source, componentPath, 'providers', symbolName, 'Component');
|
495
|
-
}
|
496
|
-
exports.addProviderToComponent = addProviderToComponent;
|
497
|
-
function addDeclarationToModule(host, source, modulePath, symbolName) {
|
498
|
-
return _addSymbolToNgModuleMetadata(host, source, modulePath, 'declarations', symbolName);
|
341
|
+
function addDeclarationToModule(source, modulePath, symbolName) {
|
342
|
+
return addSymbolToNgModuleMetadata(source, modulePath, 'declarations', symbolName);
|
499
343
|
}
|
500
344
|
exports.addDeclarationToModule = addDeclarationToModule;
|
501
|
-
function addEntryComponents(
|
502
|
-
return
|
345
|
+
function addEntryComponents(source, modulePath, symbolName) {
|
346
|
+
return addSymbolToNgModuleMetadata(source, modulePath, 'entryComponents', symbolName);
|
503
347
|
}
|
504
348
|
exports.addEntryComponents = addEntryComponents;
|
505
349
|
function readBootstrapInfo(host, app) {
|
506
|
-
|
507
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
508
|
-
}
|
509
|
-
const config = (0, devkit_1.readProjectConfiguration)(host, app);
|
350
|
+
const config = (0, xplat_1.getProjectConfig)(host, app);
|
510
351
|
let mainPath;
|
511
352
|
try {
|
512
|
-
mainPath = config.
|
353
|
+
mainPath = config.architect.build.options.main;
|
513
354
|
}
|
514
355
|
catch (e) {
|
515
356
|
throw new Error('Main file cannot be located');
|
@@ -518,21 +359,21 @@ function readBootstrapInfo(host, app) {
|
|
518
359
|
throw new Error('Main file cannot be located');
|
519
360
|
}
|
520
361
|
const mainSource = host.read(mainPath).toString('utf-8');
|
521
|
-
const main =
|
522
|
-
const moduleImports = (0,
|
362
|
+
const main = ts.createSourceFile(mainPath, mainSource, ts.ScriptTarget.Latest, true);
|
363
|
+
const moduleImports = (0, xplat_1.getImport)(main, (s) => s.indexOf('.module') > -1);
|
523
364
|
if (moduleImports.length !== 1) {
|
524
365
|
throw new Error(`main.ts can only import a single module`);
|
525
366
|
}
|
526
367
|
const moduleImport = moduleImports[0];
|
527
368
|
const moduleClassName = moduleImport.bindings.filter((b) => b.endsWith('Module'))[0];
|
528
|
-
const modulePath = `${
|
369
|
+
const modulePath = `${path.join(path.dirname(mainPath), moduleImport.moduleSpec)}.ts`;
|
529
370
|
if (!host.exists(modulePath)) {
|
530
371
|
throw new Error(`Cannot find '${modulePath}'`);
|
531
372
|
}
|
532
373
|
const moduleSourceText = host.read(modulePath).toString('utf-8');
|
533
|
-
const moduleSource =
|
374
|
+
const moduleSource = ts.createSourceFile(modulePath, moduleSourceText, ts.ScriptTarget.Latest, true);
|
534
375
|
const bootstrapComponentClassName = getBootstrapComponent(moduleSource, moduleClassName);
|
535
|
-
const bootstrapComponentFileName = `./${
|
376
|
+
const bootstrapComponentFileName = `./${path.join(path.dirname(moduleImport.moduleSpec), `${(0, xplat_utils_1.toFileName)(bootstrapComponentClassName.substring(0, bootstrapComponentClassName.length - 9))}.component`)}`;
|
536
377
|
return {
|
537
378
|
moduleSpec: moduleImport.moduleSpec,
|
538
379
|
mainPath,
|
@@ -545,44 +386,25 @@ function readBootstrapInfo(host, app) {
|
|
545
386
|
}
|
546
387
|
exports.readBootstrapInfo = readBootstrapInfo;
|
547
388
|
function getDecoratorPropertyValueNode(host, modulePath, identifier, property, module) {
|
548
|
-
if (!tsModule) {
|
549
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
550
|
-
}
|
551
389
|
const moduleSourceText = host.read(modulePath).toString('utf-8');
|
552
|
-
const moduleSource =
|
390
|
+
const moduleSource = ts.createSourceFile(modulePath, moduleSourceText, ts.ScriptTarget.Latest, true);
|
553
391
|
const templateNode = getMatchingProperty(moduleSource, property, identifier, module);
|
554
392
|
return templateNode.getChildAt(templateNode.getChildCount() - 1);
|
555
393
|
}
|
556
394
|
exports.getDecoratorPropertyValueNode = getDecoratorPropertyValueNode;
|
557
395
|
function getMatchingObjectLiteralElement(node, source, property) {
|
558
|
-
if (!tsModule) {
|
559
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
560
|
-
}
|
561
396
|
return (node.properties
|
562
|
-
.filter((prop) => prop.kind ==
|
397
|
+
.filter((prop) => prop.kind == ts.SyntaxKind.PropertyAssignment)
|
563
398
|
// Filter out every fields that's not "metadataField". Also handles string literals
|
564
399
|
// (but not expressions).
|
565
400
|
.filter((prop) => {
|
566
401
|
const name = prop.name;
|
567
402
|
switch (name.kind) {
|
568
|
-
case
|
403
|
+
case ts.SyntaxKind.Identifier:
|
569
404
|
return name.getText(source) === property;
|
570
|
-
case
|
405
|
+
case ts.SyntaxKind.StringLiteral:
|
571
406
|
return name.text === property;
|
572
407
|
}
|
573
408
|
return false;
|
574
409
|
})[0]);
|
575
410
|
}
|
576
|
-
function getTsSourceFile(host, path) {
|
577
|
-
if (!tsModule) {
|
578
|
-
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
579
|
-
}
|
580
|
-
const buffer = host.read(path);
|
581
|
-
if (!buffer) {
|
582
|
-
throw new Error(`Could not read TS file (${path}).`);
|
583
|
-
}
|
584
|
-
const content = buffer.toString();
|
585
|
-
const source = tsModule.createSourceFile(path, content, tsModule.ScriptTarget.Latest, true);
|
586
|
-
return source;
|
587
|
-
}
|
588
|
-
exports.getTsSourceFile = getTsSourceFile;
|
package/src/utils/generator.d.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Tree, Rule } from '@angular-devkit/schematics';
|
2
2
|
import { XplatFeatureHelpers } from '@nstudio/xplat';
|
3
3
|
import { PlatformTypes } from '@nstudio/xplat-utils';
|
4
|
-
export
|
4
|
+
export type IGenerateType = 'component' | 'directive' | 'pipe' | 'service' | 'state';
|
5
5
|
export interface IGenerateOptions {
|
6
6
|
name: string;
|
7
7
|
feature?: string;
|