1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.isAngularSecondaryEntrypoint = exports.groupImports = exports.isTerminalRun = exports.mapProjectGraphFiles = exports.hasBuildExecutor = exports.isDirectDependency = exports.hasBannedDependencies = exports.findTransitiveExternalDependencies = exports.hasBannedImport = exports.getSourceFilePath = exports.onlyLoadChildren = exports.findConstraintsFor = exports.findProjectUsingImport = exports.isAbsoluteImportIntoAnotherProject = exports.findTargetProject = exports.findSourceProject = exports.findProjectUsingFile = exports.getTargetProjectBasedOnRelativeImport = exports.isRelative = exports.matchImportWithWildcard = exports.removeExt = exports.findDependenciesWithTags = exports.hasNoneOfTheseTags = exports.stringifyTags = void 0;
|
4 | const path = require("path");
|
5 | const devkit_1 = require("@nrwl/devkit");
|
6 | const path_1 = require("path");
|
7 | const app_root_1 = require("./app-root");
|
8 | const graph_utils_1 = require("./graph-utils");
|
9 | const fs_1 = require("fs");
|
10 | const file_utils_1 = require("nx/src/project-graph/file-utils");
|
11 | function stringifyTags(tags) {
|
12 | return tags.map((t) => `"${t}"`).join(', ');
|
13 | }
|
14 | exports.stringifyTags = stringifyTags;
|
15 | function hasNoneOfTheseTags(proj, tags) {
|
16 | return tags.filter((tag) => hasTag(proj, tag)).length === 0;
|
17 | }
|
18 | exports.hasNoneOfTheseTags = hasNoneOfTheseTags;
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | function findDependenciesWithTags(targetProject, tags, graph) {
|
26 |
|
27 |
|
28 | const allReachableProjects = Object.keys(graph.nodes).filter((projectName) => (0, graph_utils_1.pathExists)(graph, targetProject.name, projectName) &&
|
29 | tags.some((tag) => hasTag(graph.nodes[projectName], tag)));
|
30 |
|
31 | return allReachableProjects.map((project) => targetProject.name === project
|
32 | ? [targetProject]
|
33 | : (0, graph_utils_1.getPath)(graph, targetProject.name, project));
|
34 | }
|
35 | exports.findDependenciesWithTags = findDependenciesWithTags;
|
36 | function hasTag(proj, tag) {
|
37 | return tag === '*' || (proj.data.tags || []).indexOf(tag) > -1;
|
38 | }
|
39 | function removeExt(file) {
|
40 | return file.replace(/(?<!(^|\/))\.[^/.]+$/, '');
|
41 | }
|
42 | exports.removeExt = removeExt;
|
43 | function matchImportWithWildcard(
|
44 | // This may or may not contain wildcards ("*")
|
45 | allowableImport, extractedImport) {
|
46 | if (allowableImport.endsWith('/**')) {
|
47 | const prefix = allowableImport.substring(0, allowableImport.length - 2);
|
48 | return extractedImport.startsWith(prefix);
|
49 | }
|
50 | else if (allowableImport.endsWith('/*')) {
|
51 | const prefix = allowableImport.substring(0, allowableImport.length - 1);
|
52 | if (!extractedImport.startsWith(prefix))
|
53 | return false;
|
54 | return extractedImport.substring(prefix.length).indexOf('/') === -1;
|
55 | }
|
56 | else if (allowableImport.indexOf('/**/') > -1) {
|
57 | const [prefix, suffix] = allowableImport.split('/**/');
|
58 | return (extractedImport.startsWith(prefix) && extractedImport.endsWith(suffix));
|
59 | }
|
60 | else {
|
61 | return new RegExp(allowableImport).test(extractedImport);
|
62 | }
|
63 | }
|
64 | exports.matchImportWithWildcard = matchImportWithWildcard;
|
65 | function isRelative(s) {
|
66 | return s.startsWith('.');
|
67 | }
|
68 | exports.isRelative = isRelative;
|
69 | function getTargetProjectBasedOnRelativeImport(imp, projectPath, projectGraph, sourceFilePath) {
|
70 | if (!isRelative(imp)) {
|
71 | return undefined;
|
72 | }
|
73 | const sourceDir = path.join(projectPath, path.dirname(sourceFilePath));
|
74 | const targetFile = (0, devkit_1.normalizePath)(path.resolve(sourceDir, imp)).substring(projectPath.length + 1);
|
75 | return findTargetProject(projectGraph, targetFile);
|
76 | }
|
77 | exports.getTargetProjectBasedOnRelativeImport = getTargetProjectBasedOnRelativeImport;
|
78 | function findProjectUsingFile(projectGraph, file) {
|
79 | return projectGraph.nodes[projectGraph.allFiles[file]];
|
80 | }
|
81 | exports.findProjectUsingFile = findProjectUsingFile;
|
82 | function findSourceProject(projectGraph, sourceFilePath) {
|
83 | const targetFile = removeExt(sourceFilePath);
|
84 | return findProjectUsingFile(projectGraph, targetFile);
|
85 | }
|
86 | exports.findSourceProject = findSourceProject;
|
87 | function findTargetProject(projectGraph, targetFile) {
|
88 | let targetProject = findProjectUsingFile(projectGraph, targetFile);
|
89 | if (!targetProject) {
|
90 | targetProject = findProjectUsingFile(projectGraph, (0, devkit_1.normalizePath)(path.join(targetFile, 'index')));
|
91 | }
|
92 | if (!targetProject) {
|
93 | targetProject = findProjectUsingFile(projectGraph, (0, devkit_1.normalizePath)(path.join(targetFile, 'src', 'index')));
|
94 | }
|
95 | return targetProject;
|
96 | }
|
97 | exports.findTargetProject = findTargetProject;
|
98 | function isAbsoluteImportIntoAnotherProject(imp, workspaceLayout = { libsDir: 'libs', appsDir: 'apps' }) {
|
99 | return (imp.startsWith(`${workspaceLayout.libsDir}/`) ||
|
100 | imp.startsWith(`/${workspaceLayout.libsDir}/`) ||
|
101 | imp.startsWith(`${workspaceLayout.appsDir}/`) ||
|
102 | imp.startsWith(`/${workspaceLayout.appsDir}/`));
|
103 | }
|
104 | exports.isAbsoluteImportIntoAnotherProject = isAbsoluteImportIntoAnotherProject;
|
105 | function findProjectUsingImport(projectGraph, targetProjectLocator, filePath, imp) {
|
106 | var _a;
|
107 | const target = targetProjectLocator.findProjectWithImport(imp, filePath);
|
108 | return projectGraph.nodes[target] || ((_a = projectGraph.externalNodes) === null || _a === void 0 ? void 0 : _a[target]);
|
109 | }
|
110 | exports.findProjectUsingImport = findProjectUsingImport;
|
111 | function findConstraintsFor(depConstraints, sourceProject) {
|
112 | return depConstraints.filter((f) => hasTag(sourceProject, f.sourceTag));
|
113 | }
|
114 | exports.findConstraintsFor = findConstraintsFor;
|
115 | function onlyLoadChildren(graph, sourceProjectName, targetProjectName, visited) {
|
116 | if (visited.indexOf(sourceProjectName) > -1)
|
117 | return false;
|
118 | return ((graph.dependencies[sourceProjectName] || []).filter((d) => {
|
119 | if (d.type !== devkit_1.DependencyType.dynamic)
|
120 | return false;
|
121 | if (d.target === targetProjectName)
|
122 | return true;
|
123 | return onlyLoadChildren(graph, d.target, targetProjectName, [
|
124 | ...visited,
|
125 | sourceProjectName,
|
126 | ]);
|
127 | }).length > 0);
|
128 | }
|
129 | exports.onlyLoadChildren = onlyLoadChildren;
|
130 | function getSourceFilePath(sourceFileName, projectPath) {
|
131 | const relativePath = sourceFileName.slice(projectPath.length + 1);
|
132 | return (0, devkit_1.normalizePath)(relativePath);
|
133 | }
|
134 | exports.getSourceFilePath = getSourceFilePath;
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | function isConstraintBanningProject(externalProject, constraint) {
|
142 | return constraint.bannedExternalImports.some((importDefinition) => parseImportWildcards(importDefinition).test(externalProject.data.packageName));
|
143 | }
|
144 | function hasBannedImport(source, target, depConstraints) {
|
145 |
|
146 | depConstraints = depConstraints.filter((c) => (source.data.tags || []).includes(c.sourceTag) &&
|
147 | c.bannedExternalImports &&
|
148 | c.bannedExternalImports.length);
|
149 | return depConstraints.find((constraint) => isConstraintBanningProject(target, constraint));
|
150 | }
|
151 | exports.hasBannedImport = hasBannedImport;
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 | function findTransitiveExternalDependencies(graph, source) {
|
159 | if (!graph.externalNodes) {
|
160 | return [];
|
161 | }
|
162 | const allReachableProjects = [];
|
163 | const allProjects = Object.keys(graph.nodes);
|
164 | for (let i = 0; i < allProjects.length; i++) {
|
165 | if ((0, graph_utils_1.pathExists)(graph, source.name, allProjects[i])) {
|
166 | allReachableProjects.push(allProjects[i]);
|
167 | }
|
168 | }
|
169 | const externalDependencies = [];
|
170 | for (let i = 0; i < allReachableProjects.length; i++) {
|
171 | const dependencies = graph.dependencies[allReachableProjects[i]];
|
172 | if (dependencies) {
|
173 | for (let d = 0; d < dependencies.length; d++) {
|
174 | const dependency = dependencies[d];
|
175 | if (graph.externalNodes[dependency.target]) {
|
176 | externalDependencies.push(dependency);
|
177 | }
|
178 | }
|
179 | }
|
180 | }
|
181 | return externalDependencies;
|
182 | }
|
183 | exports.findTransitiveExternalDependencies = findTransitiveExternalDependencies;
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 | function hasBannedDependencies(externalDependencies, graph, depConstraint) {
|
192 | return externalDependencies
|
193 | .filter((dependency) => isConstraintBanningProject(graph.externalNodes[dependency.target], depConstraint))
|
194 | .map((dep) => [
|
195 | graph.externalNodes[dep.target],
|
196 | graph.nodes[dep.source],
|
197 | depConstraint,
|
198 | ]);
|
199 | }
|
200 | exports.hasBannedDependencies = hasBannedDependencies;
|
201 | function isDirectDependency(target) {
|
202 | const fileName = 'package.json';
|
203 | const content = (0, file_utils_1.readFileIfExisting)((0, path_1.join)(app_root_1.workspaceRoot, fileName));
|
204 | if (content) {
|
205 | const { dependencies, devDependencies, peerDependencies } = (0, devkit_1.parseJson)(content);
|
206 | if (dependencies && dependencies[target.data.packageName]) {
|
207 | return true;
|
208 | }
|
209 | if (peerDependencies && peerDependencies[target.data.packageName]) {
|
210 | return true;
|
211 | }
|
212 | if (devDependencies && devDependencies[target.data.packageName]) {
|
213 | return true;
|
214 | }
|
215 | return false;
|
216 | }
|
217 | return true;
|
218 | }
|
219 | exports.isDirectDependency = isDirectDependency;
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 | function parseImportWildcards(importDefinition) {
|
226 | const mappedWildcards = importDefinition.split('*').join('.*');
|
227 | return new RegExp(`^${new RegExp(mappedWildcards).source}$`);
|
228 | }
|
229 |
|
230 |
|
231 |
|
232 |
|
233 | function hasBuildExecutor(projectGraph) {
|
234 | return (
|
235 |
|
236 | projectGraph.data.targets &&
|
237 | projectGraph.data.targets.build &&
|
238 | projectGraph.data.targets.build.executor !== '');
|
239 | }
|
240 | exports.hasBuildExecutor = hasBuildExecutor;
|
241 | function mapProjectGraphFiles(projectGraph) {
|
242 | if (!projectGraph) {
|
243 | return null;
|
244 | }
|
245 | const allFiles = {};
|
246 | Object.entries(projectGraph.nodes).forEach(([name, node]) => {
|
247 | node.data.files.forEach(({ file }) => {
|
248 | const fileName = removeExt(file);
|
249 | allFiles[fileName] = name;
|
250 | });
|
251 | });
|
252 | return Object.assign(Object.assign({}, projectGraph), { allFiles });
|
253 | }
|
254 | exports.mapProjectGraphFiles = mapProjectGraphFiles;
|
255 | const ESLINT_REGEX = /node_modules.*[\/\\]eslint$/;
|
256 | const NRWL_CLI_REGEX = /nx[\/\\]bin[\/\\]run-executor\.js$/;
|
257 | function isTerminalRun() {
|
258 | return (process.argv.length > 1 &&
|
259 | (!!process.argv[1].match(NRWL_CLI_REGEX) ||
|
260 | !!process.argv[1].match(ESLINT_REGEX)));
|
261 | }
|
262 | exports.isTerminalRun = isTerminalRun;
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 | function groupImports(importsToRemap) {
|
271 | const importsToRemapGrouped = importsToRemap.reduce((acc, curr) => {
|
272 | const existing = acc.find((i) => i.importPath === curr.importPath && i.member !== curr.member);
|
273 | if (existing) {
|
274 | if (existing.member) {
|
275 | existing.member += `, ${curr.member}`;
|
276 | }
|
277 | }
|
278 | else {
|
279 | acc.push({
|
280 | importPath: curr.importPath,
|
281 | member: curr.member,
|
282 | });
|
283 | }
|
284 | return acc;
|
285 | }, []);
|
286 | return importsToRemapGrouped
|
287 | .map((entry) => `import { ${entry.member} } from '${entry.importPath}';`)
|
288 | .join('\n');
|
289 | }
|
290 | exports.groupImports = groupImports;
|
291 |
|
292 |
|
293 |
|
294 |
|
295 |
|
296 |
|
297 | function isAngularSecondaryEntrypoint(targetProjectLocator, importExpr) {
|
298 | const targetFiles = targetProjectLocator.findPaths(importExpr);
|
299 | return (targetFiles &&
|
300 | targetFiles.some((file) =>
|
301 |
|
302 |
|
303 | (file.endsWith('src/public_api.ts') || file.endsWith('src/index.ts')) &&
|
304 | (0, fs_1.existsSync)((0, devkit_1.joinPathFragments)(file, '../../', 'ng-package.json'))));
|
305 | }
|
306 | exports.isAngularSecondaryEntrypoint = isAngularSecondaryEntrypoint;
|
307 |
|
\ | No newline at end of file |