@groma/scanner-angular 0.2.2 → 0.2.3
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 +1 -1
- package/dist/index.js +45 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ bun plugins/scanners/angular/build.ts
|
|
|
16
16
|
From the project being scanned:
|
|
17
17
|
|
|
18
18
|
```sh
|
|
19
|
-
groma
|
|
19
|
+
groma plugin add /absolute/path/to/groma/plugins/scanners/angular/dist/package
|
|
20
20
|
groma scan
|
|
21
21
|
```
|
|
22
22
|
|
package/dist/index.js
CHANGED
|
@@ -254,31 +254,33 @@ function configOwners(wanted, configs) {
|
|
|
254
254
|
}
|
|
255
255
|
return owners;
|
|
256
256
|
}
|
|
257
|
+
function programWithOwnedSources(program, paths) {
|
|
258
|
+
return { program, owned: new Set(paths.map((file) => program.getSourceFile(file))) };
|
|
259
|
+
}
|
|
257
260
|
function angularPrograms(root, files, configs) {
|
|
258
261
|
const wanted = new Set(files.map((file) => path3.resolve(root, file)));
|
|
259
262
|
const owners = configOwners(wanted, configs);
|
|
260
263
|
const groups = new Map;
|
|
261
264
|
for (const [file, owner] of owners)
|
|
262
265
|
groups.set(owner, [...groups.get(owner) ?? [], file]);
|
|
263
|
-
const programs = [...groups].map(([owner, rootNames]) => ({
|
|
264
|
-
program: ts.createProgram(rootNames, { ...owner.config.options, noEmit: true }),
|
|
265
|
-
files: new Set(rootNames)
|
|
266
|
-
}));
|
|
266
|
+
const programs = [...groups].map(([owner, rootNames]) => programWithOwnedSources(ts.createProgram(rootNames, { ...owner.config.options, noEmit: true }), rootNames));
|
|
267
267
|
const loose = [];
|
|
268
268
|
for (const file of wanted) {
|
|
269
269
|
if (owners.has(file))
|
|
270
270
|
continue;
|
|
271
|
-
const
|
|
271
|
+
const readers = programs.filter(({ program }) => program.getSourceFile(file) !== undefined);
|
|
272
|
+
if (readers.some(({ program, owned }) => owned.has(program.getSourceFile(file))))
|
|
273
|
+
continue;
|
|
274
|
+
const [importer] = readers;
|
|
272
275
|
if (importer)
|
|
273
|
-
importer.
|
|
276
|
+
importer.owned.add(importer.program.getSourceFile(file));
|
|
274
277
|
else
|
|
275
278
|
loose.push(file);
|
|
276
279
|
}
|
|
277
280
|
if (loose.length)
|
|
278
|
-
programs.push(
|
|
279
|
-
return programs.map(({ program,
|
|
280
|
-
|
|
281
|
-
failDiagnostics(owned.flatMap((source) => program.getSyntacticDiagnostics(source)));
|
|
281
|
+
programs.push(programWithOwnedSources(ts.createProgram(loose, { noEmit: true }), loose));
|
|
282
|
+
return programs.map(({ program, owned }) => {
|
|
283
|
+
failDiagnostics([...owned].flatMap((source) => program.getSyntacticDiagnostics(source)));
|
|
282
284
|
return { program, owned, sources: program.getSourceFiles().filter((source) => inRepository(root, source)) };
|
|
283
285
|
});
|
|
284
286
|
}
|
|
@@ -28710,20 +28712,32 @@ function reachedFiles(entry, compiled, imports, packages, units) {
|
|
|
28710
28712
|
}
|
|
28711
28713
|
async function declaredEntries(root, declarations, packages, workspaces) {
|
|
28712
28714
|
const entries = [];
|
|
28715
|
+
const diagnostics = [];
|
|
28713
28716
|
for (const file of declarations) {
|
|
28714
28717
|
const text = await readFile3(path5.join(root, file), "utf8");
|
|
28715
28718
|
const name = path5.posix.basename(file);
|
|
28716
|
-
|
|
28717
|
-
|
|
28718
|
-
|
|
28719
|
-
|
|
28720
|
-
|
|
28721
|
-
|
|
28722
|
-
|
|
28723
|
-
|
|
28724
|
-
|
|
28719
|
+
try {
|
|
28720
|
+
if (name === "package.json") {
|
|
28721
|
+
const manifest = JSON.parse(text);
|
|
28722
|
+
entries.push(...declaredBins(file, manifest), ...declaredScripts(file, manifest.scripts));
|
|
28723
|
+
} else if (name === "angular.json")
|
|
28724
|
+
entries.push(...angularEntries(file, text));
|
|
28725
|
+
else if (name === "project.json")
|
|
28726
|
+
entries.push(...nxEntries(file, text, workspaces));
|
|
28727
|
+
else if (file.endsWith(".html"))
|
|
28728
|
+
entries.push(...browserEntries(file, text, packages));
|
|
28729
|
+
} catch (error) {
|
|
28730
|
+
if (!(error instanceof SyntaxError))
|
|
28731
|
+
throw error;
|
|
28732
|
+
diagnostics.push({
|
|
28733
|
+
severity: "warning",
|
|
28734
|
+
code: "JAVASCRIPT_MANIFEST_INVALID",
|
|
28735
|
+
file,
|
|
28736
|
+
message: `The file is not valid JSON; the entry points it declares are not read. ${error.message}`
|
|
28737
|
+
});
|
|
28738
|
+
}
|
|
28725
28739
|
}
|
|
28726
|
-
return entries;
|
|
28740
|
+
return { entries, diagnostics };
|
|
28727
28741
|
}
|
|
28728
28742
|
function sourced(entry, files, outputs = []) {
|
|
28729
28743
|
const file = sourceOf(entry.file, outputs, files);
|
|
@@ -28737,7 +28751,8 @@ async function withJavaScriptEntries(root, observation, inputs, files) {
|
|
|
28737
28751
|
const packages = new Set(inventory.filter((file) => path5.posix.basename(file) === "package.json").map((file) => path5.posix.dirname(file)));
|
|
28738
28752
|
const active = new Set(observation.files.map((file) => packageFor(file.file, packages)));
|
|
28739
28753
|
const declarations = inventory.filter((file) => path5.posix.basename(file) !== "nx.json" && active.has(packageFor(file, packages)));
|
|
28740
|
-
const
|
|
28754
|
+
const declared = await declaredEntries(root, declarations, packages, workspaces);
|
|
28755
|
+
const entries = [...inputs.entries, ...declared.entries];
|
|
28741
28756
|
const inventoryFiles = [...observation.files];
|
|
28742
28757
|
const visible = new Set(inventoryFiles.map((file) => file.file));
|
|
28743
28758
|
const readable = new Set(files);
|
|
@@ -28754,7 +28769,12 @@ async function withJavaScriptEntries(root, observation, inputs, files) {
|
|
|
28754
28769
|
}
|
|
28755
28770
|
return [{ ...entry, files: [...new Set([entry.file, ...members.map((file) => file.file)])] }];
|
|
28756
28771
|
});
|
|
28757
|
-
return createScanObservation({
|
|
28772
|
+
return createScanObservation({
|
|
28773
|
+
...observation,
|
|
28774
|
+
files: inventoryFiles,
|
|
28775
|
+
entryPoints,
|
|
28776
|
+
diagnostics: [...observation.diagnostics, ...declared.diagnostics]
|
|
28777
|
+
});
|
|
28758
28778
|
}
|
|
28759
28779
|
|
|
28760
28780
|
// plugins/scanners/entry-points/source.ts
|
|
@@ -30039,17 +30059,16 @@ async function scanProject(root, directory, programs, inputs, readable) {
|
|
|
30039
30059
|
const httpRequests = [];
|
|
30040
30060
|
for (const { program, owned, sources } of programs) {
|
|
30041
30061
|
const checker = program.getTypeChecker();
|
|
30042
|
-
const mine = new Set(owned);
|
|
30043
30062
|
const directives = sources.filter((source) => readable.has(relative(root, source.fileName))).flatMap((source) => source.statements.filter(ts6.isClassDeclaration).flatMap((node) => sourceDirective(node, checker) ?? []));
|
|
30044
|
-
for (const component of directives.filter((directive) => directive.view &&
|
|
30063
|
+
for (const component of directives.filter((directive) => directive.view && owned.has(directive.declaration.getSourceFile()))) {
|
|
30045
30064
|
templates.bindOutputs(component, directives, checker);
|
|
30046
30065
|
sourceUnits.push(templates.unit(component));
|
|
30047
30066
|
}
|
|
30048
30067
|
httpRequests.push(...await angularHttpRequests(sources, checker, (node) => {
|
|
30049
|
-
const caller =
|
|
30068
|
+
const caller = owned.has(node.getSourceFile()) ? enclosingOperation(node) : undefined;
|
|
30050
30069
|
return caller && evidence.operationId(caller);
|
|
30051
30070
|
}));
|
|
30052
|
-
files.push(...owned.map((source) => ({
|
|
30071
|
+
files.push(...[...owned].map((source) => ({
|
|
30053
30072
|
file: relative(root, source.fileName),
|
|
30054
30073
|
symbols: source.statements.filter(ts6.isClassDeclaration).map((node) => ({
|
|
30055
30074
|
id: `${relative(root, source.fileName)}#${node.getStart()}`,
|