@cyclonedx/cdxgen 12.4.2 → 12.4.4
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 +6 -0
- package/bin/audit.js +7 -0
- package/bin/cdxgen.js +48 -2
- package/bin/evinse.js +7 -0
- package/lib/audit/index.js +165 -2
- package/lib/audit/index.poku.js +462 -0
- package/lib/cli/index.js +320 -172
- package/lib/cli/index.poku.js +81 -0
- package/lib/evinser/evinser.js +31 -9
- package/lib/helpers/analyzer.js +890 -0
- package/lib/helpers/analyzer.poku.js +341 -0
- package/lib/helpers/atomUtils.js +445 -0
- package/lib/helpers/atomUtils.poku.js +137 -0
- package/lib/helpers/bomUtils.js +71 -0
- package/lib/helpers/bomUtils.poku.js +45 -0
- package/lib/helpers/depsUtils.js +146 -0
- package/lib/helpers/depsUtils.poku.js +183 -0
- package/lib/helpers/display.js +12 -6
- package/lib/helpers/display.poku.js +38 -0
- package/lib/helpers/utils.js +653 -191
- package/lib/helpers/utils.poku.js +414 -4
- package/lib/managers/binary.js +18 -9
- package/lib/stages/postgen/postgen.js +215 -0
- package/lib/stages/postgen/postgen.poku.js +218 -3
- package/lib/validator/bomValidator.js +11 -2
- package/package.json +8 -8
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/helpers/analyzer.d.ts.map +1 -1
- package/types/lib/helpers/atomUtils.d.ts +18 -0
- package/types/lib/helpers/atomUtils.d.ts.map +1 -0
- package/types/lib/helpers/bomUtils.d.ts +10 -0
- package/types/lib/helpers/bomUtils.d.ts.map +1 -1
- package/types/lib/helpers/depsUtils.d.ts +9 -0
- package/types/lib/helpers/depsUtils.d.ts.map +1 -1
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/dosaiParsers.d.ts.map +1 -1
- package/types/lib/helpers/utils.d.ts +19 -0
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts +2 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
|
@@ -278,6 +278,347 @@ wasi.start(instance);
|
|
|
278
278
|
});
|
|
279
279
|
});
|
|
280
280
|
|
|
281
|
+
describe("findJSImportsExports() Angular occurrence evidence", () => {
|
|
282
|
+
it("captures Angular workspace builder, polyfill, style, script, plugin, and schematic package references", async () => {
|
|
283
|
+
const projectDir = createProjectFiles("angular-workspace-evidence", {
|
|
284
|
+
"angular.json": JSON.stringify({
|
|
285
|
+
projects: {
|
|
286
|
+
app: {
|
|
287
|
+
architect: {
|
|
288
|
+
build: {
|
|
289
|
+
builder: "@angular-devkit/build-angular:application",
|
|
290
|
+
options: {
|
|
291
|
+
polyfills: ["zone.js", "@angular/localize/init"],
|
|
292
|
+
scripts: ["node_modules/jquery/dist/jquery.js"],
|
|
293
|
+
styles: [
|
|
294
|
+
"src/styles.scss",
|
|
295
|
+
"node_modules/bootstrap/dist/css/bootstrap.css",
|
|
296
|
+
{
|
|
297
|
+
input:
|
|
298
|
+
"node_modules/@fortawesome/fontawesome-free/css/all.css",
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
serve: {
|
|
304
|
+
executor: "@nx/angular:dev-server",
|
|
305
|
+
},
|
|
306
|
+
test: {
|
|
307
|
+
builder: "@angular-devkit/build-angular:karma",
|
|
308
|
+
},
|
|
309
|
+
e2e: {
|
|
310
|
+
builder: "@angular-devkit/build-angular:protractor",
|
|
311
|
+
},
|
|
312
|
+
package: {
|
|
313
|
+
builder: "@angular-devkit/build-ng-packagr:build",
|
|
314
|
+
},
|
|
315
|
+
modernBuild: {
|
|
316
|
+
builder: "@angular/build:application",
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
schematics: {
|
|
320
|
+
"@schematics/angular:component": {
|
|
321
|
+
style: "scss",
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
plugins: ["@angular-eslint/builder"],
|
|
327
|
+
}),
|
|
328
|
+
"src/app/app.component.ts":
|
|
329
|
+
"import { Component } from '@angular/core';\n@Component({ template: '<router-outlet />' })\nexport class AppComponent {}\n",
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
const { allImports } = await findJSImportsExports(projectDir, false);
|
|
333
|
+
|
|
334
|
+
for (const expectedPackage of [
|
|
335
|
+
"@angular-devkit/build-angular",
|
|
336
|
+
"@angular-eslint/builder",
|
|
337
|
+
"@angular/build",
|
|
338
|
+
"@angular/compiler-cli",
|
|
339
|
+
"@angular/localize",
|
|
340
|
+
"@fortawesome/fontawesome-free",
|
|
341
|
+
"@nx/angular",
|
|
342
|
+
"@schematics/angular",
|
|
343
|
+
"bootstrap",
|
|
344
|
+
"jquery",
|
|
345
|
+
"karma",
|
|
346
|
+
"ng-packagr",
|
|
347
|
+
"protractor",
|
|
348
|
+
"typescript",
|
|
349
|
+
"zone.js",
|
|
350
|
+
]) {
|
|
351
|
+
assert.ok(
|
|
352
|
+
allImports[expectedPackage],
|
|
353
|
+
`expected ${expectedPackage} workspace evidence`,
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
assert.equal(allImports["src"], undefined);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it("captures Angular resource metadata and legacy external loadChildren strings", async () => {
|
|
360
|
+
const projectDir = createProjectFiles("angular-source-literal-evidence", {
|
|
361
|
+
"src/app/app.module.ts": `import { NgModule } from "@angular/core";
|
|
362
|
+
import { RouterModule } from "@angular/router";
|
|
363
|
+
|
|
364
|
+
@NgModule({
|
|
365
|
+
imports: [
|
|
366
|
+
RouterModule.forRoot([
|
|
367
|
+
{ path: "legacy", loadChildren: "@acme/legacy-feature#LegacyFeatureModule" },
|
|
368
|
+
{ path: "local", loadChildren: "./local/local.module#LocalModule" },
|
|
369
|
+
]),
|
|
370
|
+
],
|
|
371
|
+
})
|
|
372
|
+
export class AppModule {}
|
|
373
|
+
`,
|
|
374
|
+
"src/app/app.component.ts": `import { Component } from "@angular/core";
|
|
375
|
+
|
|
376
|
+
@Component({
|
|
377
|
+
selector: "app-root",
|
|
378
|
+
templateUrl: "./app.component.html",
|
|
379
|
+
styleUrls: ["./app.component.scss"],
|
|
380
|
+
})
|
|
381
|
+
export class AppComponent {}
|
|
382
|
+
`,
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
const { allImports } = await findJSImportsExports(projectDir, false);
|
|
386
|
+
|
|
387
|
+
assert.ok(allImports["@acme/legacy-feature"]);
|
|
388
|
+
assert.ok(
|
|
389
|
+
Object.keys(allImports).some((importName) =>
|
|
390
|
+
normalizePathForAssertion(importName).endsWith(
|
|
391
|
+
"src/app/local/local.module",
|
|
392
|
+
),
|
|
393
|
+
),
|
|
394
|
+
);
|
|
395
|
+
assert.ok(
|
|
396
|
+
Object.keys(allImports).some((importName) =>
|
|
397
|
+
normalizePathForAssertion(importName).endsWith(
|
|
398
|
+
"src/app/app.component.html",
|
|
399
|
+
),
|
|
400
|
+
),
|
|
401
|
+
);
|
|
402
|
+
assert.ok(
|
|
403
|
+
Object.keys(allImports).some((importName) =>
|
|
404
|
+
normalizePathForAssertion(importName).endsWith(
|
|
405
|
+
"src/app/app.component.scss",
|
|
406
|
+
),
|
|
407
|
+
),
|
|
408
|
+
);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it("captures Angular package script and test config package evidence", async () => {
|
|
412
|
+
const projectDir = createProjectFiles("angular-script-config-evidence", {
|
|
413
|
+
"package.json": JSON.stringify({
|
|
414
|
+
scripts: {
|
|
415
|
+
start: "ng serve",
|
|
416
|
+
test: "ng test",
|
|
417
|
+
e2e: "ng e2e",
|
|
418
|
+
"ng-lint": "ng lint",
|
|
419
|
+
compile: "tsc -p tsconfig.json && ngc -p tsconfig.app.json",
|
|
420
|
+
lint: "tslint --project tslint.json",
|
|
421
|
+
analyze: "webpack-bundle-analyzer dist/stats.json",
|
|
422
|
+
docs: "typedoc src/public-api.ts",
|
|
423
|
+
clean: "rimraf dist",
|
|
424
|
+
},
|
|
425
|
+
}),
|
|
426
|
+
"src/app/app.component.ts":
|
|
427
|
+
"import { Component } from '@angular/core';\n@Component({ template: '<router-outlet />' })\nexport class AppComponent {}\n",
|
|
428
|
+
"karma.conf.js": [
|
|
429
|
+
"module.exports = function(config) {",
|
|
430
|
+
"config.set({",
|
|
431
|
+
"frameworks: ['jasmine', '@angular-devkit/build-angular'],",
|
|
432
|
+
"browsers: ['ChromeHeadless'],",
|
|
433
|
+
"reporters: ['progress', 'coverage-istanbul', 'html'],",
|
|
434
|
+
"plugins: [require('karma-jasmine'), require('karma-chrome-launcher')],",
|
|
435
|
+
"});",
|
|
436
|
+
"};",
|
|
437
|
+
].join("\n"),
|
|
438
|
+
"protractor.conf.js": [
|
|
439
|
+
"require('ts-node/register');",
|
|
440
|
+
"exports.config = { framework: 'jasmine' };",
|
|
441
|
+
].join("\n"),
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
const { allImports } = await findJSImportsExports(projectDir, false);
|
|
445
|
+
|
|
446
|
+
for (const expectedPackage of [
|
|
447
|
+
"@angular/cli",
|
|
448
|
+
"@angular/compiler-cli",
|
|
449
|
+
"codelyzer",
|
|
450
|
+
"jasmine-core",
|
|
451
|
+
"jasminewd2",
|
|
452
|
+
"karma",
|
|
453
|
+
"karma-chrome-launcher",
|
|
454
|
+
"karma-coverage-istanbul-reporter",
|
|
455
|
+
"karma-jasmine",
|
|
456
|
+
"karma-jasmine-html-reporter",
|
|
457
|
+
"protractor",
|
|
458
|
+
"rimraf",
|
|
459
|
+
"ts-node",
|
|
460
|
+
"tslint",
|
|
461
|
+
"typedoc",
|
|
462
|
+
"typescript",
|
|
463
|
+
"webpack-bundle-analyzer",
|
|
464
|
+
]) {
|
|
465
|
+
assert.ok(
|
|
466
|
+
allImports[expectedPackage],
|
|
467
|
+
`expected ${expectedPackage} script/config evidence`,
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it("captures @angular/animations when platform-browser animations are imported", async () => {
|
|
473
|
+
const projectDir = createProjectFiles("angular-animations-evidence", {
|
|
474
|
+
"src/app/app.module.ts":
|
|
475
|
+
"import { BrowserAnimationsModule } from '@angular/platform-browser/animations';\nvoid BrowserAnimationsModule;\n",
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
const { allImports } = await findJSImportsExports(projectDir, false);
|
|
479
|
+
|
|
480
|
+
assert.ok(allImports["@angular/platform-browser/animations"]);
|
|
481
|
+
assert.ok(allImports["@angular/animations"]);
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it("captures AngularFire and platform-browser-dynamic implied package evidence", async () => {
|
|
485
|
+
const projectDir = createProjectFiles("angular-import-implied-evidence", {
|
|
486
|
+
"src/app/app.module.ts": [
|
|
487
|
+
"import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';",
|
|
488
|
+
"import { AngularFireModule } from '@angular/fire';",
|
|
489
|
+
"import { AngularFirestoreModule } from '@angular/fire/firestore';",
|
|
490
|
+
"void platformBrowserDynamic;",
|
|
491
|
+
"void AngularFireModule;",
|
|
492
|
+
"void AngularFirestoreModule;",
|
|
493
|
+
].join("\n"),
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
const { allImports } = await findJSImportsExports(projectDir, false);
|
|
497
|
+
|
|
498
|
+
assert.ok(allImports["@angular/compiler"]);
|
|
499
|
+
assert.ok(allImports.firebase);
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
it("captures Angular tsconfig helper, type, and transformer package evidence", async () => {
|
|
503
|
+
const projectDir = createProjectFiles("angular-tsconfig-evidence", {
|
|
504
|
+
"src/app/app.component.ts":
|
|
505
|
+
"import { Component } from '@angular/core';\n@Component({ template: '<router-outlet />' })\nexport class AppComponent {}\n",
|
|
506
|
+
"tsconfig.json": JSON.stringify({
|
|
507
|
+
compilerOptions: {
|
|
508
|
+
importHelpers: true,
|
|
509
|
+
plugins: [{ transform: "ts-transformer-keys/transformer" }],
|
|
510
|
+
types: ["jasmine", "node"],
|
|
511
|
+
},
|
|
512
|
+
}),
|
|
513
|
+
"tsconfig.spec.json": [
|
|
514
|
+
"{",
|
|
515
|
+
" // JSON with comments should still be parsed",
|
|
516
|
+
' "compilerOptions": { "types": ["jasminewd2"] }',
|
|
517
|
+
"}",
|
|
518
|
+
].join("\n"),
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
const { allImports } = await findJSImportsExports(projectDir, false);
|
|
522
|
+
|
|
523
|
+
for (const expectedPackage of [
|
|
524
|
+
"@types/jasmine",
|
|
525
|
+
"@types/jasminewd2",
|
|
526
|
+
"@types/node",
|
|
527
|
+
"ts-transformer-keys",
|
|
528
|
+
"tslib",
|
|
529
|
+
]) {
|
|
530
|
+
assert.ok(
|
|
531
|
+
allImports[expectedPackage],
|
|
532
|
+
`expected ${expectedPackage} tsconfig evidence`,
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
it("captures common Angular template selector package evidence", async () => {
|
|
538
|
+
const routerLinkAttr = "routerLink";
|
|
539
|
+
const ngIfAttr = "ngIf";
|
|
540
|
+
const formGroupAttr = "formGroup";
|
|
541
|
+
const formControlNameAttr = "formControlName";
|
|
542
|
+
const matButtonAttr = "mat-button";
|
|
543
|
+
const cdkDropListAttr = "cdkDropList";
|
|
544
|
+
const projectDir = createProjectFiles("angular-template-evidence", {
|
|
545
|
+
"src/app/app.component.ts":
|
|
546
|
+
"import { Component } from '@angular/core';\n@Component({ templateUrl: './app.component.html' })\nexport class AppComponent {}\n",
|
|
547
|
+
"src/app/app.component.html": [
|
|
548
|
+
"<router-outlet />",
|
|
549
|
+
`<a ${routerLinkAttr}="/home">Home</a>`,
|
|
550
|
+
[
|
|
551
|
+
"<section ",
|
|
552
|
+
"*",
|
|
553
|
+
ngIfAttr,
|
|
554
|
+
'="ready">{{ total | async }}</section>',
|
|
555
|
+
].join(""),
|
|
556
|
+
[
|
|
557
|
+
"<form ",
|
|
558
|
+
"[",
|
|
559
|
+
formGroupAttr,
|
|
560
|
+
']="profileForm"><input ',
|
|
561
|
+
formControlNameAttr,
|
|
562
|
+
'="name" /></form>',
|
|
563
|
+
].join(""),
|
|
564
|
+
`<button ${matButtonAttr}>Save</button>`,
|
|
565
|
+
`<div ${cdkDropListAttr}></div>`,
|
|
566
|
+
"<ion-button>Open</ion-button>",
|
|
567
|
+
'<fa-icon [icon]="icon"></fa-icon>',
|
|
568
|
+
"<ag-grid-angular></ag-grid-angular>",
|
|
569
|
+
"<ng-select></ng-select>",
|
|
570
|
+
"<ngx-charts-bar-vertical></ngx-charts-bar-vertical>",
|
|
571
|
+
].join("\n"),
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
const { allImports } = await findJSImportsExports(projectDir, false);
|
|
575
|
+
|
|
576
|
+
for (const expectedPackage of [
|
|
577
|
+
"@angular/cdk",
|
|
578
|
+
"@angular/common",
|
|
579
|
+
"@angular/forms",
|
|
580
|
+
"@angular/material",
|
|
581
|
+
"@angular/router",
|
|
582
|
+
"@fortawesome/angular-fontawesome",
|
|
583
|
+
"@ionic/angular",
|
|
584
|
+
"@ng-select/ng-select",
|
|
585
|
+
"@swimlane/ngx-charts",
|
|
586
|
+
"ag-grid-angular",
|
|
587
|
+
]) {
|
|
588
|
+
assert.ok(
|
|
589
|
+
allImports[expectedPackage],
|
|
590
|
+
`expected ${expectedPackage} template evidence`,
|
|
591
|
+
);
|
|
592
|
+
const occurrences = Array.from(allImports[expectedPackage]);
|
|
593
|
+
assert.ok(
|
|
594
|
+
occurrences.some((occurrence) =>
|
|
595
|
+
normalizePathForAssertion(occurrence.fileName).endsWith(
|
|
596
|
+
"src/app/app.component.html",
|
|
597
|
+
),
|
|
598
|
+
),
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
it("does not treat unrelated project.json files as Angular workspace evidence", async () => {
|
|
604
|
+
const projectDir = createProjectFiles("non-angular-project-json", {
|
|
605
|
+
"project.json": JSON.stringify({
|
|
606
|
+
targets: {
|
|
607
|
+
build: {
|
|
608
|
+
executor: "@nx/react:build",
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
}),
|
|
612
|
+
"src/index.ts": "import React from 'react';\nvoid React;\n",
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
const { allImports } = await findJSImportsExports(projectDir, false);
|
|
616
|
+
|
|
617
|
+
assert.ok(allImports.react);
|
|
618
|
+
assert.equal(allImports["@nx/react"], undefined);
|
|
619
|
+
});
|
|
620
|
+
});
|
|
621
|
+
|
|
281
622
|
describe("detectExtensionCapabilities()", () => {
|
|
282
623
|
it("should detect extension capability signals from source usage", () => {
|
|
283
624
|
const projectDir = createProject(
|