@ngrx/data 21.0.0 → 21.0.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/package.json +4 -4
- package/schematics/ng-add/index.js +130 -131
- package/schematics/ng-add/index.js.map +1 -1
- package/schematics/ng-add/schema.js +2 -0
- package/schematics-core/index.js +75 -24
- package/schematics-core/index.js.map +1 -1
- package/schematics-core/utility/ast-utils.js +234 -260
- package/schematics-core/utility/ast-utils.js.map +1 -1
- package/schematics-core/utility/change.js +82 -92
- package/schematics-core/utility/change.js.map +1 -1
- package/schematics-core/utility/config.js +13 -9
- package/schematics-core/utility/config.js.map +1 -1
- package/schematics-core/utility/find-component.js +35 -30
- package/schematics-core/utility/find-component.js.map +1 -1
- package/schematics-core/utility/find-module.js +38 -33
- package/schematics-core/utility/find-module.js.map +1 -1
- package/schematics-core/utility/json-utilts.js +8 -27
- package/schematics-core/utility/json-utilts.js.map +1 -1
- package/schematics-core/utility/libs-version.js +4 -1
- package/schematics-core/utility/libs-version.js.map +1 -1
- package/schematics-core/utility/ngrx-utils.js +129 -152
- package/schematics-core/utility/ngrx-utils.js.map +1 -1
- package/schematics-core/utility/package.js +6 -4
- package/schematics-core/utility/package.js.map +1 -1
- package/schematics-core/utility/parse-name.js +8 -5
- package/schematics-core/utility/parse-name.js.map +1 -1
- package/schematics-core/utility/project.js +23 -17
- package/schematics-core/utility/project.js.map +1 -1
- package/schematics-core/utility/standalone.js +141 -214
- package/schematics-core/utility/standalone.js.map +1 -1
- package/schematics-core/utility/strings.js +32 -21
- package/schematics-core/utility/strings.js.map +1 -1
- package/schematics-core/utility/update.js +18 -15
- package/schematics-core/utility/update.js.map +1 -1
- package/schematics-core/utility/visitors.js +104 -192
- package/schematics-core/utility/visitors.js.map +1 -1
|
@@ -1,39 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
9
26
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
36
|
-
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.findNodes = findNodes;
|
|
37
|
+
exports.getSourceNodes = getSourceNodes;
|
|
38
|
+
exports.insertAfterLastOccurrence = insertAfterLastOccurrence;
|
|
39
|
+
exports.getContentOfKeyLiteral = getContentOfKeyLiteral;
|
|
40
|
+
exports.getDecoratorMetadata = getDecoratorMetadata;
|
|
41
|
+
exports.addDeclarationToModule = addDeclarationToModule;
|
|
42
|
+
exports.addImportToModule = addImportToModule;
|
|
43
|
+
exports.addProviderToModule = addProviderToModule;
|
|
44
|
+
exports.addProviderToComponent = addProviderToComponent;
|
|
45
|
+
exports.addExportToModule = addExportToModule;
|
|
46
|
+
exports.addBootstrapToModule = addBootstrapToModule;
|
|
47
|
+
exports.insertImport = insertImport;
|
|
48
|
+
exports.replaceImport = replaceImport;
|
|
49
|
+
exports.containsProperty = containsProperty;
|
|
37
50
|
/* istanbul ignore file */
|
|
38
51
|
/**
|
|
39
52
|
* @license
|
|
@@ -42,8 +55,8 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
42
55
|
* Use of this source code is governed by an MIT-style license that can be
|
|
43
56
|
* found in the LICENSE file at https://angular.io/license
|
|
44
57
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
const ts = __importStar(require("typescript"));
|
|
59
|
+
const change_1 = require("./change");
|
|
47
60
|
/**
|
|
48
61
|
* Find all nodes from the AST in the subtree of node of SyntaxKind kind.
|
|
49
62
|
* @param node
|
|
@@ -51,39 +64,27 @@ import { InsertChange, NoopChange, createReplaceChange, createRemoveChange, } fr
|
|
|
51
64
|
* @param max The maximum number of items to return.
|
|
52
65
|
* @return all nodes of kind, or [] if none is found
|
|
53
66
|
*/
|
|
54
|
-
|
|
55
|
-
var e_1, _a;
|
|
56
|
-
if (max === void 0) { max = Infinity; }
|
|
67
|
+
function findNodes(node, kind, max = Infinity) {
|
|
57
68
|
if (!node || max == 0) {
|
|
58
69
|
return [];
|
|
59
70
|
}
|
|
60
|
-
|
|
71
|
+
const arr = [];
|
|
61
72
|
if (node.kind === kind) {
|
|
62
73
|
arr.push(node);
|
|
63
74
|
max--;
|
|
64
75
|
}
|
|
65
76
|
if (max > 0) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (max > 0) {
|
|
71
|
-
arr.push(node);
|
|
72
|
-
}
|
|
73
|
-
max--;
|
|
74
|
-
});
|
|
75
|
-
if (max <= 0) {
|
|
76
|
-
break;
|
|
77
|
+
for (const child of node.getChildren()) {
|
|
78
|
+
findNodes(child, kind, max).forEach((node) => {
|
|
79
|
+
if (max > 0) {
|
|
80
|
+
arr.push(node);
|
|
77
81
|
}
|
|
82
|
+
max--;
|
|
83
|
+
});
|
|
84
|
+
if (max <= 0) {
|
|
85
|
+
break;
|
|
78
86
|
}
|
|
79
87
|
}
|
|
80
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
81
|
-
finally {
|
|
82
|
-
try {
|
|
83
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
84
|
-
}
|
|
85
|
-
finally { if (e_1) throw e_1.error; }
|
|
86
|
-
}
|
|
87
88
|
}
|
|
88
89
|
return arr;
|
|
89
90
|
}
|
|
@@ -92,15 +93,15 @@ export function findNodes(node, kind, max) {
|
|
|
92
93
|
* @param sourceFile The source file object.
|
|
93
94
|
* @returns {Observable<ts.Node>} An observable of all the nodes in the source.
|
|
94
95
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
function getSourceNodes(sourceFile) {
|
|
97
|
+
const nodes = [sourceFile];
|
|
98
|
+
const result = [];
|
|
98
99
|
while (nodes.length > 0) {
|
|
99
|
-
|
|
100
|
+
const node = nodes.shift();
|
|
100
101
|
if (node) {
|
|
101
102
|
result.push(node);
|
|
102
103
|
if (node.getChildCount(sourceFile) >= 0) {
|
|
103
|
-
nodes.unshift
|
|
104
|
+
nodes.unshift(...node.getChildren());
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
}
|
|
@@ -126,8 +127,8 @@ function nodesByPosition(first, second) {
|
|
|
126
127
|
* @return Change instance
|
|
127
128
|
* @throw Error if toInsert is first occurence but fall back is not set
|
|
128
129
|
*/
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
function insertAfterLastOccurrence(nodes, toInsert, file, fallbackPos, syntaxKind) {
|
|
131
|
+
let lastItem = nodes.sort(nodesByPosition).pop();
|
|
131
132
|
if (!lastItem) {
|
|
132
133
|
throw new Error();
|
|
133
134
|
}
|
|
@@ -135,12 +136,12 @@ export function insertAfterLastOccurrence(nodes, toInsert, file, fallbackPos, sy
|
|
|
135
136
|
lastItem = findNodes(lastItem, syntaxKind).sort(nodesByPosition).pop();
|
|
136
137
|
}
|
|
137
138
|
if (!lastItem && fallbackPos == undefined) {
|
|
138
|
-
throw new Error(
|
|
139
|
+
throw new Error(`tried to insert ${toInsert} as first occurence with no fallback position`);
|
|
139
140
|
}
|
|
140
|
-
|
|
141
|
-
return new InsertChange(file, lastItemPosition, toInsert);
|
|
141
|
+
const lastItemPosition = lastItem ? lastItem.end : fallbackPos;
|
|
142
|
+
return new change_1.InsertChange(file, lastItemPosition, toInsert);
|
|
142
143
|
}
|
|
143
|
-
|
|
144
|
+
function getContentOfKeyLiteral(_source, node) {
|
|
144
145
|
if (node.kind == ts.SyntaxKind.Identifier) {
|
|
145
146
|
return node.text;
|
|
146
147
|
}
|
|
@@ -152,9 +153,8 @@ export function getContentOfKeyLiteral(_source, node) {
|
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
function _angularImportsFromNode(node, _sourceFile) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
var modulePath;
|
|
156
|
+
const ms = node.moduleSpecifier;
|
|
157
|
+
let modulePath;
|
|
158
158
|
switch (ms.kind) {
|
|
159
159
|
case ts.SyntaxKind.StringLiteral:
|
|
160
160
|
modulePath = ms.text;
|
|
@@ -171,21 +171,19 @@ function _angularImportsFromNode(node, _sourceFile) {
|
|
|
171
171
|
return {};
|
|
172
172
|
}
|
|
173
173
|
else if (node.importClause.namedBindings) {
|
|
174
|
-
|
|
174
|
+
const nb = node.importClause.namedBindings;
|
|
175
175
|
if (nb.kind == ts.SyntaxKind.NamespaceImport) {
|
|
176
176
|
// This is of the form `import * as name from 'path'`. Return `name.`.
|
|
177
|
-
return
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
return {
|
|
178
|
+
[nb.name.text + '.']: modulePath,
|
|
179
|
+
};
|
|
180
180
|
}
|
|
181
181
|
else {
|
|
182
182
|
// This is of the form `import {a,b,c} from 'path'`
|
|
183
|
-
|
|
183
|
+
const namedImports = nb;
|
|
184
184
|
return namedImports.elements
|
|
185
|
-
.map(
|
|
186
|
-
|
|
187
|
-
})
|
|
188
|
-
.reduce(function (acc, curr) {
|
|
185
|
+
.map((is) => is.propertyName ? is.propertyName.text : is.name.text)
|
|
186
|
+
.reduce((acc, curr) => {
|
|
189
187
|
acc[curr] = modulePath;
|
|
190
188
|
return acc;
|
|
191
189
|
}, {});
|
|
@@ -198,73 +196,58 @@ function _angularImportsFromNode(node, _sourceFile) {
|
|
|
198
196
|
return {};
|
|
199
197
|
}
|
|
200
198
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
.map(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
var e_2, _a;
|
|
208
|
-
try {
|
|
209
|
-
for (var _b = __values(Object.keys(current)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
210
|
-
var key = _c.value;
|
|
211
|
-
acc[key] = current[key];
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
215
|
-
finally {
|
|
216
|
-
try {
|
|
217
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
218
|
-
}
|
|
219
|
-
finally { if (e_2) throw e_2.error; }
|
|
199
|
+
function getDecoratorMetadata(source, identifier, module) {
|
|
200
|
+
const angularImports = findNodes(source, ts.SyntaxKind.ImportDeclaration)
|
|
201
|
+
.map((node) => _angularImportsFromNode(node, source))
|
|
202
|
+
.reduce((acc, current) => {
|
|
203
|
+
for (const key of Object.keys(current)) {
|
|
204
|
+
acc[key] = current[key];
|
|
220
205
|
}
|
|
221
206
|
return acc;
|
|
222
207
|
}, {});
|
|
223
208
|
return getSourceNodes(source)
|
|
224
|
-
.filter(
|
|
209
|
+
.filter((node) => {
|
|
225
210
|
return (node.kind == ts.SyntaxKind.Decorator &&
|
|
226
211
|
node.expression.kind == ts.SyntaxKind.CallExpression);
|
|
227
212
|
})
|
|
228
|
-
.map(
|
|
229
|
-
.filter(
|
|
213
|
+
.map((node) => node.expression)
|
|
214
|
+
.filter((expr) => {
|
|
230
215
|
if (expr.expression.kind == ts.SyntaxKind.Identifier) {
|
|
231
|
-
|
|
216
|
+
const id = expr.expression;
|
|
232
217
|
return (id.getFullText(source) == identifier &&
|
|
233
218
|
angularImports[id.getFullText(source)] === module);
|
|
234
219
|
}
|
|
235
220
|
else if (expr.expression.kind == ts.SyntaxKind.PropertyAccessExpression) {
|
|
236
221
|
// This covers foo.NgModule when importing * as foo.
|
|
237
|
-
|
|
222
|
+
const paExpr = expr.expression;
|
|
238
223
|
// If the left expression is not an identifier, just give up at that point.
|
|
239
224
|
if (paExpr.expression.kind !== ts.SyntaxKind.Identifier) {
|
|
240
225
|
return false;
|
|
241
226
|
}
|
|
242
|
-
|
|
243
|
-
|
|
227
|
+
const id = paExpr.name.text;
|
|
228
|
+
const moduleId = paExpr.expression.getText(source);
|
|
244
229
|
return id === identifier && angularImports[moduleId + '.'] === module;
|
|
245
230
|
}
|
|
246
231
|
return false;
|
|
247
232
|
})
|
|
248
|
-
.filter(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
})
|
|
252
|
-
.map(function (expr) { return expr.arguments[0]; });
|
|
233
|
+
.filter((expr) => expr.arguments[0] &&
|
|
234
|
+
expr.arguments[0].kind == ts.SyntaxKind.ObjectLiteralExpression)
|
|
235
|
+
.map((expr) => expr.arguments[0]);
|
|
253
236
|
}
|
|
254
237
|
function _addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbolName, importPath) {
|
|
255
|
-
|
|
256
|
-
|
|
238
|
+
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
|
239
|
+
let node = nodes[0]; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
257
240
|
// Find the decorator declaration.
|
|
258
241
|
if (!node) {
|
|
259
242
|
return [];
|
|
260
243
|
}
|
|
261
244
|
// Get all the children property assignment of object literals.
|
|
262
|
-
|
|
263
|
-
.filter(
|
|
245
|
+
const matchingProperties = node.properties
|
|
246
|
+
.filter((prop) => prop.kind == ts.SyntaxKind.PropertyAssignment)
|
|
264
247
|
// Filter out every fields that's not "metadataField". Also handles string literals
|
|
265
248
|
// (but not expressions).
|
|
266
|
-
.filter(
|
|
267
|
-
|
|
249
|
+
.filter((prop) => {
|
|
250
|
+
const name = prop.name;
|
|
268
251
|
switch (name.kind) {
|
|
269
252
|
case ts.SyntaxKind.Identifier:
|
|
270
253
|
return name.getText(source) == metadataField;
|
|
@@ -279,36 +262,36 @@ function _addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbo
|
|
|
279
262
|
}
|
|
280
263
|
if (matchingProperties.length == 0) {
|
|
281
264
|
// We haven't found the field in the metadata declaration. Insert a new field.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
265
|
+
const expr = node;
|
|
266
|
+
let position;
|
|
267
|
+
let toInsert;
|
|
285
268
|
if (expr.properties.length == 0) {
|
|
286
|
-
|
|
287
|
-
|
|
269
|
+
position = expr.getEnd() - 1;
|
|
270
|
+
toInsert = ` ${metadataField}: [${symbolName}]\n`;
|
|
288
271
|
}
|
|
289
272
|
else {
|
|
290
273
|
node = expr.properties[expr.properties.length - 1];
|
|
291
|
-
|
|
274
|
+
position = node.getEnd();
|
|
292
275
|
// Get the indentation of the last element, if any.
|
|
293
|
-
|
|
294
|
-
|
|
276
|
+
const text = node.getFullText(source);
|
|
277
|
+
const matches = text.match(/^\r?\n\s*/);
|
|
295
278
|
if (matches.length > 0) {
|
|
296
|
-
|
|
279
|
+
toInsert = `,${matches[0]}${metadataField}: [${symbolName}]`;
|
|
297
280
|
}
|
|
298
281
|
else {
|
|
299
|
-
|
|
282
|
+
toInsert = `, ${metadataField}: [${symbolName}]`;
|
|
300
283
|
}
|
|
301
284
|
}
|
|
302
|
-
|
|
303
|
-
|
|
285
|
+
const newMetadataProperty = new change_1.InsertChange(ngModulePath, position, toInsert);
|
|
286
|
+
const newMetadataImport = insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath);
|
|
304
287
|
return [newMetadataProperty, newMetadataImport];
|
|
305
288
|
}
|
|
306
|
-
|
|
289
|
+
const assignment = matchingProperties[0];
|
|
307
290
|
// If it's not an array, nothing we can do really.
|
|
308
291
|
if (assignment.initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
|
|
309
292
|
return [];
|
|
310
293
|
}
|
|
311
|
-
|
|
294
|
+
const arrLiteral = assignment.initializer;
|
|
312
295
|
if (arrLiteral.elements.length == 0) {
|
|
313
296
|
// Forward the property.
|
|
314
297
|
node = arrLiteral;
|
|
@@ -321,43 +304,41 @@ function _addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbo
|
|
|
321
304
|
return [];
|
|
322
305
|
}
|
|
323
306
|
if (Array.isArray(node)) {
|
|
324
|
-
|
|
325
|
-
|
|
307
|
+
const nodeArray = node;
|
|
308
|
+
const symbolsArray = nodeArray.map((node) => node.getText());
|
|
326
309
|
if (symbolsArray.includes(symbolName)) {
|
|
327
310
|
return [];
|
|
328
311
|
}
|
|
329
312
|
node = node[node.length - 1];
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
symbolName.includes('EffectsModule.forFeature'));
|
|
335
|
-
});
|
|
313
|
+
const effectsModule = nodeArray.find((node) => (node.getText().includes('EffectsModule.forRoot') &&
|
|
314
|
+
symbolName.includes('EffectsModule.forRoot')) ||
|
|
315
|
+
(node.getText().includes('EffectsModule.forFeature') &&
|
|
316
|
+
symbolName.includes('EffectsModule.forFeature')));
|
|
336
317
|
if (effectsModule && symbolName.includes('EffectsModule')) {
|
|
337
|
-
|
|
318
|
+
const effectsArgs = effectsModule.arguments.shift();
|
|
338
319
|
if (effectsArgs &&
|
|
339
320
|
effectsArgs.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
|
340
|
-
|
|
321
|
+
const effectsElements = effectsArgs
|
|
341
322
|
.elements;
|
|
342
|
-
|
|
343
|
-
|
|
323
|
+
const [, effectsSymbol] = symbolName.match(/\[(.*)\]/);
|
|
324
|
+
let epos;
|
|
344
325
|
if (effectsElements.length === 0) {
|
|
345
326
|
epos = effectsArgs.getStart() + 1;
|
|
346
|
-
return [new InsertChange(ngModulePath, epos, effectsSymbol)];
|
|
327
|
+
return [new change_1.InsertChange(ngModulePath, epos, effectsSymbol)];
|
|
347
328
|
}
|
|
348
329
|
else {
|
|
349
|
-
|
|
330
|
+
const lastEffect = effectsElements[effectsElements.length - 1];
|
|
350
331
|
epos = lastEffect.getEnd();
|
|
351
332
|
// Get the indentation of the last element, if any.
|
|
352
|
-
|
|
353
|
-
|
|
333
|
+
const text = lastEffect.getFullText(source);
|
|
334
|
+
let effectInsert;
|
|
354
335
|
if (text.match('^\r?\r?\n')) {
|
|
355
|
-
effectInsert =
|
|
336
|
+
effectInsert = `,${text.match(/^\r?\n\s+/)[0]}${effectsSymbol}`;
|
|
356
337
|
}
|
|
357
338
|
else {
|
|
358
|
-
effectInsert =
|
|
339
|
+
effectInsert = `, ${effectsSymbol}`;
|
|
359
340
|
}
|
|
360
|
-
return [new InsertChange(ngModulePath, epos, effectInsert)];
|
|
341
|
+
return [new change_1.InsertChange(ngModulePath, epos, effectInsert)];
|
|
361
342
|
}
|
|
362
343
|
}
|
|
363
344
|
else {
|
|
@@ -365,62 +346,62 @@ function _addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbo
|
|
|
365
346
|
}
|
|
366
347
|
}
|
|
367
348
|
}
|
|
368
|
-
|
|
369
|
-
|
|
349
|
+
let toInsert;
|
|
350
|
+
let position = node.getEnd();
|
|
370
351
|
if (node.kind == ts.SyntaxKind.ObjectLiteralExpression) {
|
|
371
352
|
// We haven't found the field in the metadata declaration. Insert a new
|
|
372
353
|
// field.
|
|
373
|
-
|
|
354
|
+
const expr = node;
|
|
374
355
|
if (expr.properties.length == 0) {
|
|
375
356
|
position = expr.getEnd() - 1;
|
|
376
|
-
toInsert =
|
|
357
|
+
toInsert = ` ${metadataField}: [${symbolName}]\n`;
|
|
377
358
|
}
|
|
378
359
|
else {
|
|
379
360
|
node = expr.properties[expr.properties.length - 1];
|
|
380
361
|
position = node.getEnd();
|
|
381
362
|
// Get the indentation of the last element, if any.
|
|
382
|
-
|
|
363
|
+
const text = node.getFullText(source);
|
|
383
364
|
if (text.match('^\r?\r?\n')) {
|
|
384
|
-
toInsert =
|
|
365
|
+
toInsert = `,${text.match(/^\r?\n\s+/)[0]}${metadataField}: [${symbolName}]`;
|
|
385
366
|
}
|
|
386
367
|
else {
|
|
387
|
-
toInsert =
|
|
368
|
+
toInsert = `, ${metadataField}: [${symbolName}]`;
|
|
388
369
|
}
|
|
389
370
|
}
|
|
390
371
|
}
|
|
391
372
|
else if (node.kind == ts.SyntaxKind.ArrayLiteralExpression) {
|
|
392
373
|
// We found the field but it's empty. Insert it just before the `]`.
|
|
393
374
|
position--;
|
|
394
|
-
toInsert =
|
|
375
|
+
toInsert = `${symbolName}`;
|
|
395
376
|
}
|
|
396
377
|
else {
|
|
397
378
|
// Get the indentation of the last element, if any.
|
|
398
|
-
|
|
379
|
+
const text = node.getFullText(source);
|
|
399
380
|
if (text.match(/^\r?\n/)) {
|
|
400
|
-
toInsert =
|
|
381
|
+
toInsert = `,${text.match(/^\r?\n(\r?)\s+/)[0]}${symbolName}`;
|
|
401
382
|
}
|
|
402
383
|
else {
|
|
403
|
-
toInsert =
|
|
384
|
+
toInsert = `, ${symbolName}`;
|
|
404
385
|
}
|
|
405
386
|
}
|
|
406
|
-
|
|
407
|
-
|
|
387
|
+
const insert = new change_1.InsertChange(ngModulePath, position, toInsert);
|
|
388
|
+
const importInsert = insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath);
|
|
408
389
|
return [insert, importInsert];
|
|
409
390
|
}
|
|
410
391
|
function _addSymbolToComponentMetadata(source, componentPath, metadataField, symbolName, importPath) {
|
|
411
|
-
|
|
412
|
-
|
|
392
|
+
const nodes = getDecoratorMetadata(source, 'Component', '@angular/core');
|
|
393
|
+
let node = nodes[0]; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
413
394
|
// Find the decorator declaration.
|
|
414
395
|
if (!node) {
|
|
415
396
|
return [];
|
|
416
397
|
}
|
|
417
398
|
// Get all the children property assignment of object literals.
|
|
418
|
-
|
|
419
|
-
.filter(
|
|
399
|
+
const matchingProperties = node.properties
|
|
400
|
+
.filter((prop) => prop.kind == ts.SyntaxKind.PropertyAssignment)
|
|
420
401
|
// Filter out every fields that's not "metadataField". Also handles string literals
|
|
421
402
|
// (but not expressions).
|
|
422
|
-
.filter(
|
|
423
|
-
|
|
403
|
+
.filter((prop) => {
|
|
404
|
+
const name = prop.name;
|
|
424
405
|
switch (name.kind) {
|
|
425
406
|
case ts.SyntaxKind.Identifier:
|
|
426
407
|
return name.getText(source) == metadataField;
|
|
@@ -435,36 +416,36 @@ function _addSymbolToComponentMetadata(source, componentPath, metadataField, sym
|
|
|
435
416
|
}
|
|
436
417
|
if (matchingProperties.length == 0) {
|
|
437
418
|
// We haven't found the field in the metadata declaration. Insert a new field.
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
419
|
+
const expr = node;
|
|
420
|
+
let position;
|
|
421
|
+
let toInsert;
|
|
441
422
|
if (expr.properties.length == 0) {
|
|
442
|
-
|
|
443
|
-
|
|
423
|
+
position = expr.getEnd() - 1;
|
|
424
|
+
toInsert = ` ${metadataField}: [${symbolName}]\n`;
|
|
444
425
|
}
|
|
445
426
|
else {
|
|
446
427
|
node = expr.properties[expr.properties.length - 1];
|
|
447
|
-
|
|
428
|
+
position = node.getEnd();
|
|
448
429
|
// Get the indentation of the last element, if any.
|
|
449
|
-
|
|
450
|
-
|
|
430
|
+
const text = node.getFullText(source);
|
|
431
|
+
const matches = text.match(/^\r?\n\s*/);
|
|
451
432
|
if (matches.length > 0) {
|
|
452
|
-
|
|
433
|
+
toInsert = `,${matches[0]}${metadataField}: [${symbolName}]`;
|
|
453
434
|
}
|
|
454
435
|
else {
|
|
455
|
-
|
|
436
|
+
toInsert = `, ${metadataField}: [${symbolName}]`;
|
|
456
437
|
}
|
|
457
438
|
}
|
|
458
|
-
|
|
459
|
-
|
|
439
|
+
const newMetadataProperty = new change_1.InsertChange(componentPath, position, toInsert);
|
|
440
|
+
const newMetadataImport = insertImport(source, componentPath, symbolName.replace(/\..*$/, ''), importPath);
|
|
460
441
|
return [newMetadataProperty, newMetadataImport];
|
|
461
442
|
}
|
|
462
|
-
|
|
443
|
+
const assignment = matchingProperties[0];
|
|
463
444
|
// If it's not an array, nothing we can do really.
|
|
464
445
|
if (assignment.initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
|
|
465
446
|
return [];
|
|
466
447
|
}
|
|
467
|
-
|
|
448
|
+
const arrLiteral = assignment.initializer;
|
|
468
449
|
if (arrLiteral.elements.length == 0) {
|
|
469
450
|
// Forward the property.
|
|
470
451
|
node = arrLiteral;
|
|
@@ -477,91 +458,91 @@ function _addSymbolToComponentMetadata(source, componentPath, metadataField, sym
|
|
|
477
458
|
return [];
|
|
478
459
|
}
|
|
479
460
|
if (Array.isArray(node)) {
|
|
480
|
-
|
|
481
|
-
|
|
461
|
+
const nodeArray = node;
|
|
462
|
+
const symbolsArray = nodeArray.map((node) => node.getText());
|
|
482
463
|
if (symbolsArray.includes(symbolName)) {
|
|
483
464
|
return [];
|
|
484
465
|
}
|
|
485
466
|
node = node[node.length - 1];
|
|
486
467
|
}
|
|
487
|
-
|
|
488
|
-
|
|
468
|
+
let toInsert;
|
|
469
|
+
let position = node.getEnd();
|
|
489
470
|
if (node.kind == ts.SyntaxKind.ObjectLiteralExpression) {
|
|
490
471
|
// We haven't found the field in the metadata declaration. Insert a new
|
|
491
472
|
// field.
|
|
492
|
-
|
|
473
|
+
const expr = node;
|
|
493
474
|
if (expr.properties.length == 0) {
|
|
494
475
|
position = expr.getEnd() - 1;
|
|
495
|
-
toInsert =
|
|
476
|
+
toInsert = ` ${metadataField}: [${symbolName}]\n`;
|
|
496
477
|
}
|
|
497
478
|
else {
|
|
498
479
|
node = expr.properties[expr.properties.length - 1];
|
|
499
480
|
position = node.getEnd();
|
|
500
481
|
// Get the indentation of the last element, if any.
|
|
501
|
-
|
|
482
|
+
const text = node.getFullText(source);
|
|
502
483
|
if (text.match('^\r?\r?\n')) {
|
|
503
|
-
toInsert =
|
|
484
|
+
toInsert = `,${text.match(/^\r?\n\s+/)[0]}${metadataField}: [${symbolName}]`;
|
|
504
485
|
}
|
|
505
486
|
else {
|
|
506
|
-
toInsert =
|
|
487
|
+
toInsert = `, ${metadataField}: [${symbolName}]`;
|
|
507
488
|
}
|
|
508
489
|
}
|
|
509
490
|
}
|
|
510
491
|
else if (node.kind == ts.SyntaxKind.ArrayLiteralExpression) {
|
|
511
492
|
// We found the field but it's empty. Insert it just before the `]`.
|
|
512
493
|
position--;
|
|
513
|
-
toInsert =
|
|
494
|
+
toInsert = `${symbolName}`;
|
|
514
495
|
}
|
|
515
496
|
else {
|
|
516
497
|
// Get the indentation of the last element, if any.
|
|
517
|
-
|
|
498
|
+
const text = node.getFullText(source);
|
|
518
499
|
if (text.match(/^\r?\n/)) {
|
|
519
|
-
toInsert =
|
|
500
|
+
toInsert = `,${text.match(/^\r?\n(\r?)\s+/)[0]}${symbolName}`;
|
|
520
501
|
}
|
|
521
502
|
else {
|
|
522
|
-
toInsert =
|
|
503
|
+
toInsert = `, ${symbolName}`;
|
|
523
504
|
}
|
|
524
505
|
}
|
|
525
|
-
|
|
526
|
-
|
|
506
|
+
const insert = new change_1.InsertChange(componentPath, position, toInsert);
|
|
507
|
+
const importInsert = insertImport(source, componentPath, symbolName.replace(/\..*$/, ''), importPath);
|
|
527
508
|
return [insert, importInsert];
|
|
528
509
|
}
|
|
529
510
|
/**
|
|
530
511
|
* Custom function to insert a declaration (component, pipe, directive)
|
|
531
512
|
* into NgModule declarations. It also imports the component.
|
|
532
513
|
*/
|
|
533
|
-
|
|
514
|
+
function addDeclarationToModule(source, modulePath, classifiedName, importPath) {
|
|
534
515
|
return _addSymbolToNgModuleMetadata(source, modulePath, 'declarations', classifiedName, importPath);
|
|
535
516
|
}
|
|
536
517
|
/**
|
|
537
518
|
* Custom function to insert a declaration (component, pipe, directive)
|
|
538
519
|
* into NgModule declarations. It also imports the component.
|
|
539
520
|
*/
|
|
540
|
-
|
|
521
|
+
function addImportToModule(source, modulePath, classifiedName, importPath) {
|
|
541
522
|
return _addSymbolToNgModuleMetadata(source, modulePath, 'imports', classifiedName, importPath);
|
|
542
523
|
}
|
|
543
524
|
/**
|
|
544
525
|
* Custom function to insert a provider into NgModule. It also imports it.
|
|
545
526
|
*/
|
|
546
|
-
|
|
527
|
+
function addProviderToModule(source, modulePath, classifiedName, importPath) {
|
|
547
528
|
return _addSymbolToNgModuleMetadata(source, modulePath, 'providers', classifiedName, importPath);
|
|
548
529
|
}
|
|
549
530
|
/**
|
|
550
531
|
* Custom function to insert a provider into Component. It also imports it.
|
|
551
532
|
*/
|
|
552
|
-
|
|
533
|
+
function addProviderToComponent(source, componentPath, classifiedName, importPath) {
|
|
553
534
|
return _addSymbolToComponentMetadata(source, componentPath, 'providers', classifiedName, importPath);
|
|
554
535
|
}
|
|
555
536
|
/**
|
|
556
537
|
* Custom function to insert an export into NgModule. It also imports it.
|
|
557
538
|
*/
|
|
558
|
-
|
|
539
|
+
function addExportToModule(source, modulePath, classifiedName, importPath) {
|
|
559
540
|
return _addSymbolToNgModuleMetadata(source, modulePath, 'exports', classifiedName, importPath);
|
|
560
541
|
}
|
|
561
542
|
/**
|
|
562
543
|
* Custom function to insert an export into NgModule. It also imports it.
|
|
563
544
|
*/
|
|
564
|
-
|
|
545
|
+
function addBootstrapToModule(source, modulePath, classifiedName, importPath) {
|
|
565
546
|
return _addSymbolToNgModuleMetadata(source, modulePath, 'bootstrap', classifiedName, importPath);
|
|
566
547
|
}
|
|
567
548
|
/**
|
|
@@ -573,69 +554,65 @@ export function addBootstrapToModule(source, modulePath, classifiedName, importP
|
|
|
573
554
|
* @param isDefault (if true, import follows style for importing default exports)
|
|
574
555
|
* @return Change
|
|
575
556
|
*/
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
var allImports = findNodes(rootNode, ts.SyntaxKind.ImportDeclaration);
|
|
557
|
+
function insertImport(source, fileToEdit, symbolName, fileName, isDefault = false) {
|
|
558
|
+
const rootNode = source;
|
|
559
|
+
const allImports = findNodes(rootNode, ts.SyntaxKind.ImportDeclaration);
|
|
580
560
|
// get nodes that map to import statements from the file fileName
|
|
581
|
-
|
|
561
|
+
const relevantImports = allImports.filter((node) => {
|
|
582
562
|
// StringLiteral of the ImportDeclaration is the import file (fileName in this case).
|
|
583
|
-
|
|
563
|
+
const importFiles = node
|
|
584
564
|
.getChildren()
|
|
585
|
-
.filter(
|
|
586
|
-
.map(
|
|
587
|
-
return importFiles.filter(
|
|
565
|
+
.filter((child) => child.kind === ts.SyntaxKind.StringLiteral)
|
|
566
|
+
.map((n) => n.text);
|
|
567
|
+
return importFiles.filter((file) => file === fileName).length === 1;
|
|
588
568
|
});
|
|
589
569
|
if (relevantImports.length > 0) {
|
|
590
|
-
|
|
570
|
+
let importsAsterisk = false;
|
|
591
571
|
// imports from import file
|
|
592
|
-
|
|
593
|
-
relevantImports.forEach(
|
|
594
|
-
Array.prototype.push.apply(
|
|
572
|
+
const imports = [];
|
|
573
|
+
relevantImports.forEach((n) => {
|
|
574
|
+
Array.prototype.push.apply(imports, findNodes(n, ts.SyntaxKind.Identifier));
|
|
595
575
|
if (findNodes(n, ts.SyntaxKind.AsteriskToken).length > 0) {
|
|
596
|
-
|
|
576
|
+
importsAsterisk = true;
|
|
597
577
|
}
|
|
598
578
|
});
|
|
599
579
|
// if imports * from fileName, don't add symbolName
|
|
600
|
-
if (
|
|
601
|
-
return new NoopChange();
|
|
580
|
+
if (importsAsterisk) {
|
|
581
|
+
return new change_1.NoopChange();
|
|
602
582
|
}
|
|
603
|
-
|
|
583
|
+
const importTextNodes = imports.filter((n) => n.text === symbolName);
|
|
604
584
|
// insert import if it's not there
|
|
605
585
|
if (importTextNodes.length === 0) {
|
|
606
|
-
|
|
586
|
+
const fallbackPos = findNodes(relevantImports[0], ts.SyntaxKind.CloseBraceToken)[0].getStart() ||
|
|
607
587
|
findNodes(relevantImports[0], ts.SyntaxKind.FromKeyword)[0].getStart();
|
|
608
|
-
return insertAfterLastOccurrence(
|
|
588
|
+
return insertAfterLastOccurrence(imports, `, ${symbolName}`, fileToEdit, fallbackPos);
|
|
609
589
|
}
|
|
610
|
-
return new NoopChange();
|
|
590
|
+
return new change_1.NoopChange();
|
|
611
591
|
}
|
|
612
592
|
// no such import declaration exists
|
|
613
|
-
|
|
614
|
-
|
|
593
|
+
const useStrict = findNodes(rootNode, ts.SyntaxKind.StringLiteral).filter((n) => n.getText() === 'use strict');
|
|
594
|
+
let fallbackPos = 0;
|
|
615
595
|
if (useStrict.length > 0) {
|
|
616
596
|
fallbackPos = useStrict[0].end;
|
|
617
597
|
}
|
|
618
|
-
|
|
619
|
-
|
|
598
|
+
const open = isDefault ? '' : '{ ';
|
|
599
|
+
const close = isDefault ? '' : ' }';
|
|
620
600
|
// if there are no imports or 'use strict' statement, insert import at beginning of file
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
601
|
+
const insertAtBeginning = allImports.length === 0 && useStrict.length === 0;
|
|
602
|
+
const separator = insertAtBeginning ? '' : ';\n';
|
|
603
|
+
const toInsert = `${separator}import ${open}${symbolName}${close}` +
|
|
604
|
+
` from '${fileName}'${insertAtBeginning ? ';\n' : ''}`;
|
|
625
605
|
return insertAfterLastOccurrence(allImports, toInsert, fileToEdit, fallbackPos, ts.SyntaxKind.StringLiteral);
|
|
626
606
|
}
|
|
627
|
-
|
|
628
|
-
|
|
607
|
+
function replaceImport(sourceFile, path, importFrom, importAsIs, importToBe) {
|
|
608
|
+
const imports = sourceFile.statements
|
|
629
609
|
.filter(ts.isImportDeclaration)
|
|
630
|
-
.filter(
|
|
631
|
-
|
|
632
|
-
return moduleSpecifier.getText(sourceFile) === "'".concat(importFrom, "'") ||
|
|
633
|
-
moduleSpecifier.getText(sourceFile) === "\"".concat(importFrom, "\"");
|
|
634
|
-
});
|
|
610
|
+
.filter(({ moduleSpecifier }) => moduleSpecifier.getText(sourceFile) === `'${importFrom}'` ||
|
|
611
|
+
moduleSpecifier.getText(sourceFile) === `"${importFrom}"`);
|
|
635
612
|
if (imports.length === 0) {
|
|
636
613
|
return [];
|
|
637
614
|
}
|
|
638
|
-
|
|
615
|
+
const importText = (specifier) => {
|
|
639
616
|
if (specifier.name.text) {
|
|
640
617
|
return specifier.name.text;
|
|
641
618
|
}
|
|
@@ -645,44 +622,41 @@ export function replaceImport(sourceFile, path, importFrom, importAsIs, importTo
|
|
|
645
622
|
}
|
|
646
623
|
return '';
|
|
647
624
|
};
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
var namedImports = (_a = p === null || p === void 0 ? void 0 : p.importClause) === null || _a === void 0 ? void 0 : _a.namedBindings;
|
|
625
|
+
const changes = imports.map((p) => {
|
|
626
|
+
const namedImports = p?.importClause?.namedBindings;
|
|
651
627
|
if (!namedImports) {
|
|
652
628
|
return [];
|
|
653
629
|
}
|
|
654
|
-
|
|
655
|
-
|
|
630
|
+
const importSpecifiers = namedImports.elements;
|
|
631
|
+
const isAlreadyImported = importSpecifiers
|
|
656
632
|
.map(importText)
|
|
657
633
|
.includes(importToBe);
|
|
658
|
-
|
|
659
|
-
|
|
634
|
+
const importChanges = importSpecifiers.map((specifier, index) => {
|
|
635
|
+
const text = importText(specifier);
|
|
660
636
|
// import is not the one we're looking for, can be skipped
|
|
661
637
|
if (text !== importAsIs) {
|
|
662
638
|
return undefined;
|
|
663
639
|
}
|
|
664
640
|
// identifier has not been imported, simply replace the old text with the new text
|
|
665
641
|
if (!isAlreadyImported) {
|
|
666
|
-
return createReplaceChange(sourceFile, specifier, importAsIs, importToBe);
|
|
642
|
+
return (0, change_1.createReplaceChange)(sourceFile, specifier, importAsIs, importToBe);
|
|
667
643
|
}
|
|
668
|
-
|
|
644
|
+
const nextIdentifier = importSpecifiers[index + 1];
|
|
669
645
|
// identifer is not the last, also clean up the comma
|
|
670
646
|
if (nextIdentifier) {
|
|
671
|
-
return createRemoveChange(sourceFile, specifier, specifier.getStart(sourceFile), nextIdentifier.getStart(sourceFile));
|
|
647
|
+
return (0, change_1.createRemoveChange)(sourceFile, specifier, specifier.getStart(sourceFile), nextIdentifier.getStart(sourceFile));
|
|
672
648
|
}
|
|
673
649
|
// there are no imports following, just remove it
|
|
674
|
-
return createRemoveChange(sourceFile, specifier, specifier.getStart(sourceFile), specifier.getEnd());
|
|
650
|
+
return (0, change_1.createRemoveChange)(sourceFile, specifier, specifier.getStart(sourceFile), specifier.getEnd());
|
|
675
651
|
});
|
|
676
652
|
return importChanges.filter(Boolean);
|
|
677
653
|
});
|
|
678
|
-
return changes.reduce(
|
|
654
|
+
return changes.reduce((imports, curr) => imports.concat(curr), []);
|
|
679
655
|
}
|
|
680
|
-
|
|
656
|
+
function containsProperty(objectLiteral, propertyName) {
|
|
681
657
|
return (objectLiteral &&
|
|
682
|
-
objectLiteral.properties.some(
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
prop.name.text === propertyName;
|
|
686
|
-
}));
|
|
658
|
+
objectLiteral.properties.some((prop) => ts.isPropertyAssignment(prop) &&
|
|
659
|
+
ts.isIdentifier(prop.name) &&
|
|
660
|
+
prop.name.text === propertyName));
|
|
687
661
|
}
|
|
688
662
|
//# sourceMappingURL=ast-utils.js.map
|