@ceon-oy/monitor-sdk 1.0.14 → 1.0.16
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/dist/index.d.mts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +71 -6
- package/dist/index.mjs +71 -6
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -43,11 +43,16 @@ interface MonitorClientConfig {
|
|
|
43
43
|
auditPaths?: AuditPath[];
|
|
44
44
|
/** Include devDependencies when tracking dependencies (default: false) */
|
|
45
45
|
includeDevDependencies?: boolean;
|
|
46
|
+
/** Enable fetching latest versions from npm registry (default: true) */
|
|
47
|
+
versionCheckEnabled?: boolean;
|
|
48
|
+
/** Timeout for npm audit command in ms (default: 60000, max: 300000) */
|
|
49
|
+
auditTimeoutMs?: number;
|
|
46
50
|
}
|
|
47
51
|
interface TechnologyItem {
|
|
48
52
|
name: string;
|
|
49
53
|
version: string;
|
|
50
54
|
type?: TechnologyType;
|
|
55
|
+
latestVersion?: string;
|
|
51
56
|
}
|
|
52
57
|
interface ErrorContext {
|
|
53
58
|
severity?: Severity;
|
|
@@ -178,6 +183,8 @@ declare class MonitorClient {
|
|
|
178
183
|
private lastScanTime;
|
|
179
184
|
private lastKnownScanRequestedAt;
|
|
180
185
|
private lastKnownTechScanRequestedAt;
|
|
186
|
+
private versionCheckEnabled;
|
|
187
|
+
private auditTimeoutMs;
|
|
181
188
|
constructor(config: MonitorClientConfig);
|
|
182
189
|
/**
|
|
183
190
|
* Security: Validate and sanitize metadata to prevent oversized payloads
|
|
@@ -229,10 +236,24 @@ declare class MonitorClient {
|
|
|
229
236
|
private startFlushTimer;
|
|
230
237
|
private stopFlushTimer;
|
|
231
238
|
syncDependencies(): Promise<void>;
|
|
239
|
+
/**
|
|
240
|
+
* Enrich technologies with latest version information from npm registry.
|
|
241
|
+
* Only runs if versionCheckEnabled is true.
|
|
242
|
+
*/
|
|
243
|
+
private enrichWithLatestVersions;
|
|
232
244
|
syncTechnologies(technologies: TechnologyItem[]): Promise<void>;
|
|
233
245
|
private readPackageJson;
|
|
234
246
|
private readPackageJsonFromPath;
|
|
235
247
|
private shouldExclude;
|
|
248
|
+
/**
|
|
249
|
+
* Fetch the latest version of a package from npm registry.
|
|
250
|
+
* Returns null if the package cannot be found or the request fails.
|
|
251
|
+
*/
|
|
252
|
+
private fetchLatestVersion;
|
|
253
|
+
/**
|
|
254
|
+
* Fetch latest versions for multiple packages in parallel with concurrency limit.
|
|
255
|
+
*/
|
|
256
|
+
private fetchLatestVersions;
|
|
236
257
|
private sendTechnologies;
|
|
237
258
|
private sendTechnologiesWithEnvironment;
|
|
238
259
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -43,11 +43,16 @@ interface MonitorClientConfig {
|
|
|
43
43
|
auditPaths?: AuditPath[];
|
|
44
44
|
/** Include devDependencies when tracking dependencies (default: false) */
|
|
45
45
|
includeDevDependencies?: boolean;
|
|
46
|
+
/** Enable fetching latest versions from npm registry (default: true) */
|
|
47
|
+
versionCheckEnabled?: boolean;
|
|
48
|
+
/** Timeout for npm audit command in ms (default: 60000, max: 300000) */
|
|
49
|
+
auditTimeoutMs?: number;
|
|
46
50
|
}
|
|
47
51
|
interface TechnologyItem {
|
|
48
52
|
name: string;
|
|
49
53
|
version: string;
|
|
50
54
|
type?: TechnologyType;
|
|
55
|
+
latestVersion?: string;
|
|
51
56
|
}
|
|
52
57
|
interface ErrorContext {
|
|
53
58
|
severity?: Severity;
|
|
@@ -178,6 +183,8 @@ declare class MonitorClient {
|
|
|
178
183
|
private lastScanTime;
|
|
179
184
|
private lastKnownScanRequestedAt;
|
|
180
185
|
private lastKnownTechScanRequestedAt;
|
|
186
|
+
private versionCheckEnabled;
|
|
187
|
+
private auditTimeoutMs;
|
|
181
188
|
constructor(config: MonitorClientConfig);
|
|
182
189
|
/**
|
|
183
190
|
* Security: Validate and sanitize metadata to prevent oversized payloads
|
|
@@ -229,10 +236,24 @@ declare class MonitorClient {
|
|
|
229
236
|
private startFlushTimer;
|
|
230
237
|
private stopFlushTimer;
|
|
231
238
|
syncDependencies(): Promise<void>;
|
|
239
|
+
/**
|
|
240
|
+
* Enrich technologies with latest version information from npm registry.
|
|
241
|
+
* Only runs if versionCheckEnabled is true.
|
|
242
|
+
*/
|
|
243
|
+
private enrichWithLatestVersions;
|
|
232
244
|
syncTechnologies(technologies: TechnologyItem[]): Promise<void>;
|
|
233
245
|
private readPackageJson;
|
|
234
246
|
private readPackageJsonFromPath;
|
|
235
247
|
private shouldExclude;
|
|
248
|
+
/**
|
|
249
|
+
* Fetch the latest version of a package from npm registry.
|
|
250
|
+
* Returns null if the package cannot be found or the request fails.
|
|
251
|
+
*/
|
|
252
|
+
private fetchLatestVersion;
|
|
253
|
+
/**
|
|
254
|
+
* Fetch latest versions for multiple packages in parallel with concurrency limit.
|
|
255
|
+
*/
|
|
256
|
+
private fetchLatestVersions;
|
|
236
257
|
private sendTechnologies;
|
|
237
258
|
private sendTechnologiesWithEnvironment;
|
|
238
259
|
/**
|
package/dist/index.js
CHANGED
|
@@ -50,7 +50,9 @@ var CONFIG_LIMITS = {
|
|
|
50
50
|
AUDIT_MAX_BUFFER: 10 * 1024 * 1024,
|
|
51
51
|
// 10MB
|
|
52
52
|
AUDIT_TIMEOUT_MS: 6e4,
|
|
53
|
-
// 60 seconds
|
|
53
|
+
// 60 seconds (default)
|
|
54
|
+
MAX_AUDIT_TIMEOUT_MS: 3e5,
|
|
55
|
+
// 5 minutes (max configurable)
|
|
54
56
|
SETTINGS_POLL_INTERVAL_MS: 5 * 60 * 1e3
|
|
55
57
|
// 5 minutes
|
|
56
58
|
};
|
|
@@ -117,6 +119,8 @@ var MonitorClient = class {
|
|
|
117
119
|
this.autoAudit = config.autoAudit || false;
|
|
118
120
|
this.auditPaths = config.auditPaths;
|
|
119
121
|
this.includeDevDependencies = config.includeDevDependencies ?? false;
|
|
122
|
+
this.versionCheckEnabled = config.versionCheckEnabled ?? true;
|
|
123
|
+
this.auditTimeoutMs = Math.min(CONFIG_LIMITS.MAX_AUDIT_TIMEOUT_MS, Math.max(1e3, config.auditTimeoutMs || CONFIG_LIMITS.AUDIT_TIMEOUT_MS));
|
|
120
124
|
this.startFlushTimer();
|
|
121
125
|
if (this.trackDependencies) {
|
|
122
126
|
this.syncDependencies().catch((err) => {
|
|
@@ -437,17 +441,40 @@ var MonitorClient = class {
|
|
|
437
441
|
for (const source of this.dependencySources) {
|
|
438
442
|
const technologies = await this.readPackageJsonFromPath(source.path);
|
|
439
443
|
if (technologies.length === 0) continue;
|
|
440
|
-
await this.
|
|
444
|
+
const enrichedTechnologies = await this.enrichWithLatestVersions(technologies);
|
|
445
|
+
await this.sendTechnologiesWithEnvironment(enrichedTechnologies, source.environment);
|
|
441
446
|
}
|
|
442
447
|
} else {
|
|
443
448
|
const technologies = await this.readPackageJson();
|
|
444
449
|
if (technologies.length === 0) return;
|
|
445
|
-
await this.
|
|
450
|
+
const enrichedTechnologies = await this.enrichWithLatestVersions(technologies);
|
|
451
|
+
await this.sendTechnologies(enrichedTechnologies);
|
|
446
452
|
}
|
|
447
453
|
} catch (err) {
|
|
448
454
|
console.error("[MonitorClient] Failed to sync dependencies:", err);
|
|
449
455
|
}
|
|
450
456
|
}
|
|
457
|
+
/**
|
|
458
|
+
* Enrich technologies with latest version information from npm registry.
|
|
459
|
+
* Only runs if versionCheckEnabled is true.
|
|
460
|
+
*/
|
|
461
|
+
async enrichWithLatestVersions(technologies) {
|
|
462
|
+
if (!this.versionCheckEnabled) {
|
|
463
|
+
return technologies;
|
|
464
|
+
}
|
|
465
|
+
try {
|
|
466
|
+
console.log(`[MonitorClient] Fetching latest versions for ${technologies.length} packages...`);
|
|
467
|
+
const packageNames = technologies.map((t) => t.name);
|
|
468
|
+
const latestVersions = await this.fetchLatestVersions(packageNames);
|
|
469
|
+
return technologies.map((tech) => ({
|
|
470
|
+
...tech,
|
|
471
|
+
latestVersion: latestVersions.get(tech.name) || void 0
|
|
472
|
+
}));
|
|
473
|
+
} catch (err) {
|
|
474
|
+
console.warn("[MonitorClient] Failed to fetch latest versions, continuing without:", err instanceof Error ? err.message : String(err));
|
|
475
|
+
return technologies;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
451
478
|
async syncTechnologies(technologies) {
|
|
452
479
|
await this.sendTechnologies(technologies);
|
|
453
480
|
}
|
|
@@ -514,6 +541,44 @@ var MonitorClient = class {
|
|
|
514
541
|
}
|
|
515
542
|
return false;
|
|
516
543
|
}
|
|
544
|
+
/**
|
|
545
|
+
* Fetch the latest version of a package from npm registry.
|
|
546
|
+
* Returns null if the package cannot be found or the request fails.
|
|
547
|
+
*/
|
|
548
|
+
async fetchLatestVersion(packageName) {
|
|
549
|
+
try {
|
|
550
|
+
const encodedName = encodeURIComponent(packageName).replace("%40", "@");
|
|
551
|
+
const response = await fetch(`https://registry.npmjs.org/${encodedName}`, {
|
|
552
|
+
headers: { "Accept": "application/json" },
|
|
553
|
+
signal: AbortSignal.timeout(5e3)
|
|
554
|
+
});
|
|
555
|
+
if (!response.ok) return null;
|
|
556
|
+
const data = await response.json();
|
|
557
|
+
return data["dist-tags"]?.latest || null;
|
|
558
|
+
} catch {
|
|
559
|
+
return null;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Fetch latest versions for multiple packages in parallel with concurrency limit.
|
|
564
|
+
*/
|
|
565
|
+
async fetchLatestVersions(packageNames) {
|
|
566
|
+
const results = /* @__PURE__ */ new Map();
|
|
567
|
+
const concurrencyLimit = 5;
|
|
568
|
+
for (let i = 0; i < packageNames.length; i += concurrencyLimit) {
|
|
569
|
+
const batch = packageNames.slice(i, i + concurrencyLimit);
|
|
570
|
+
const batchResults = await Promise.all(
|
|
571
|
+
batch.map(async (name) => ({
|
|
572
|
+
name,
|
|
573
|
+
version: await this.fetchLatestVersion(name)
|
|
574
|
+
}))
|
|
575
|
+
);
|
|
576
|
+
for (const { name, version } of batchResults) {
|
|
577
|
+
results.set(name, version);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return results;
|
|
581
|
+
}
|
|
517
582
|
async sendTechnologies(technologies) {
|
|
518
583
|
await this.sendTechnologiesWithEnvironment(technologies, this.environment);
|
|
519
584
|
}
|
|
@@ -708,7 +773,7 @@ var MonitorClient = class {
|
|
|
708
773
|
encoding: "utf-8",
|
|
709
774
|
stdio: ["pipe", "pipe", "pipe"],
|
|
710
775
|
maxBuffer: CONFIG_LIMITS.AUDIT_MAX_BUFFER,
|
|
711
|
-
timeout:
|
|
776
|
+
timeout: this.auditTimeoutMs
|
|
712
777
|
});
|
|
713
778
|
} catch (err) {
|
|
714
779
|
const execError = err;
|
|
@@ -742,7 +807,7 @@ var MonitorClient = class {
|
|
|
742
807
|
encoding: "utf-8",
|
|
743
808
|
stdio: ["pipe", "pipe", "pipe"],
|
|
744
809
|
maxBuffer: CONFIG_LIMITS.AUDIT_MAX_BUFFER,
|
|
745
|
-
timeout:
|
|
810
|
+
timeout: this.auditTimeoutMs
|
|
746
811
|
});
|
|
747
812
|
} catch (err) {
|
|
748
813
|
const execError = err;
|
|
@@ -766,7 +831,7 @@ var MonitorClient = class {
|
|
|
766
831
|
encoding: "utf-8",
|
|
767
832
|
stdio: ["pipe", "pipe", "pipe"],
|
|
768
833
|
maxBuffer: CONFIG_LIMITS.AUDIT_MAX_BUFFER,
|
|
769
|
-
timeout:
|
|
834
|
+
timeout: this.auditTimeoutMs
|
|
770
835
|
});
|
|
771
836
|
} catch (err) {
|
|
772
837
|
const execError = err;
|
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,9 @@ var CONFIG_LIMITS = {
|
|
|
14
14
|
AUDIT_MAX_BUFFER: 10 * 1024 * 1024,
|
|
15
15
|
// 10MB
|
|
16
16
|
AUDIT_TIMEOUT_MS: 6e4,
|
|
17
|
-
// 60 seconds
|
|
17
|
+
// 60 seconds (default)
|
|
18
|
+
MAX_AUDIT_TIMEOUT_MS: 3e5,
|
|
19
|
+
// 5 minutes (max configurable)
|
|
18
20
|
SETTINGS_POLL_INTERVAL_MS: 5 * 60 * 1e3
|
|
19
21
|
// 5 minutes
|
|
20
22
|
};
|
|
@@ -81,6 +83,8 @@ var MonitorClient = class {
|
|
|
81
83
|
this.autoAudit = config.autoAudit || false;
|
|
82
84
|
this.auditPaths = config.auditPaths;
|
|
83
85
|
this.includeDevDependencies = config.includeDevDependencies ?? false;
|
|
86
|
+
this.versionCheckEnabled = config.versionCheckEnabled ?? true;
|
|
87
|
+
this.auditTimeoutMs = Math.min(CONFIG_LIMITS.MAX_AUDIT_TIMEOUT_MS, Math.max(1e3, config.auditTimeoutMs || CONFIG_LIMITS.AUDIT_TIMEOUT_MS));
|
|
84
88
|
this.startFlushTimer();
|
|
85
89
|
if (this.trackDependencies) {
|
|
86
90
|
this.syncDependencies().catch((err) => {
|
|
@@ -401,17 +405,40 @@ var MonitorClient = class {
|
|
|
401
405
|
for (const source of this.dependencySources) {
|
|
402
406
|
const technologies = await this.readPackageJsonFromPath(source.path);
|
|
403
407
|
if (technologies.length === 0) continue;
|
|
404
|
-
await this.
|
|
408
|
+
const enrichedTechnologies = await this.enrichWithLatestVersions(technologies);
|
|
409
|
+
await this.sendTechnologiesWithEnvironment(enrichedTechnologies, source.environment);
|
|
405
410
|
}
|
|
406
411
|
} else {
|
|
407
412
|
const technologies = await this.readPackageJson();
|
|
408
413
|
if (technologies.length === 0) return;
|
|
409
|
-
await this.
|
|
414
|
+
const enrichedTechnologies = await this.enrichWithLatestVersions(technologies);
|
|
415
|
+
await this.sendTechnologies(enrichedTechnologies);
|
|
410
416
|
}
|
|
411
417
|
} catch (err) {
|
|
412
418
|
console.error("[MonitorClient] Failed to sync dependencies:", err);
|
|
413
419
|
}
|
|
414
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* Enrich technologies with latest version information from npm registry.
|
|
423
|
+
* Only runs if versionCheckEnabled is true.
|
|
424
|
+
*/
|
|
425
|
+
async enrichWithLatestVersions(technologies) {
|
|
426
|
+
if (!this.versionCheckEnabled) {
|
|
427
|
+
return technologies;
|
|
428
|
+
}
|
|
429
|
+
try {
|
|
430
|
+
console.log(`[MonitorClient] Fetching latest versions for ${technologies.length} packages...`);
|
|
431
|
+
const packageNames = technologies.map((t) => t.name);
|
|
432
|
+
const latestVersions = await this.fetchLatestVersions(packageNames);
|
|
433
|
+
return technologies.map((tech) => ({
|
|
434
|
+
...tech,
|
|
435
|
+
latestVersion: latestVersions.get(tech.name) || void 0
|
|
436
|
+
}));
|
|
437
|
+
} catch (err) {
|
|
438
|
+
console.warn("[MonitorClient] Failed to fetch latest versions, continuing without:", err instanceof Error ? err.message : String(err));
|
|
439
|
+
return technologies;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
415
442
|
async syncTechnologies(technologies) {
|
|
416
443
|
await this.sendTechnologies(technologies);
|
|
417
444
|
}
|
|
@@ -478,6 +505,44 @@ var MonitorClient = class {
|
|
|
478
505
|
}
|
|
479
506
|
return false;
|
|
480
507
|
}
|
|
508
|
+
/**
|
|
509
|
+
* Fetch the latest version of a package from npm registry.
|
|
510
|
+
* Returns null if the package cannot be found or the request fails.
|
|
511
|
+
*/
|
|
512
|
+
async fetchLatestVersion(packageName) {
|
|
513
|
+
try {
|
|
514
|
+
const encodedName = encodeURIComponent(packageName).replace("%40", "@");
|
|
515
|
+
const response = await fetch(`https://registry.npmjs.org/${encodedName}`, {
|
|
516
|
+
headers: { "Accept": "application/json" },
|
|
517
|
+
signal: AbortSignal.timeout(5e3)
|
|
518
|
+
});
|
|
519
|
+
if (!response.ok) return null;
|
|
520
|
+
const data = await response.json();
|
|
521
|
+
return data["dist-tags"]?.latest || null;
|
|
522
|
+
} catch {
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Fetch latest versions for multiple packages in parallel with concurrency limit.
|
|
528
|
+
*/
|
|
529
|
+
async fetchLatestVersions(packageNames) {
|
|
530
|
+
const results = /* @__PURE__ */ new Map();
|
|
531
|
+
const concurrencyLimit = 5;
|
|
532
|
+
for (let i = 0; i < packageNames.length; i += concurrencyLimit) {
|
|
533
|
+
const batch = packageNames.slice(i, i + concurrencyLimit);
|
|
534
|
+
const batchResults = await Promise.all(
|
|
535
|
+
batch.map(async (name) => ({
|
|
536
|
+
name,
|
|
537
|
+
version: await this.fetchLatestVersion(name)
|
|
538
|
+
}))
|
|
539
|
+
);
|
|
540
|
+
for (const { name, version } of batchResults) {
|
|
541
|
+
results.set(name, version);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return results;
|
|
545
|
+
}
|
|
481
546
|
async sendTechnologies(technologies) {
|
|
482
547
|
await this.sendTechnologiesWithEnvironment(technologies, this.environment);
|
|
483
548
|
}
|
|
@@ -672,7 +737,7 @@ var MonitorClient = class {
|
|
|
672
737
|
encoding: "utf-8",
|
|
673
738
|
stdio: ["pipe", "pipe", "pipe"],
|
|
674
739
|
maxBuffer: CONFIG_LIMITS.AUDIT_MAX_BUFFER,
|
|
675
|
-
timeout:
|
|
740
|
+
timeout: this.auditTimeoutMs
|
|
676
741
|
});
|
|
677
742
|
} catch (err) {
|
|
678
743
|
const execError = err;
|
|
@@ -706,7 +771,7 @@ var MonitorClient = class {
|
|
|
706
771
|
encoding: "utf-8",
|
|
707
772
|
stdio: ["pipe", "pipe", "pipe"],
|
|
708
773
|
maxBuffer: CONFIG_LIMITS.AUDIT_MAX_BUFFER,
|
|
709
|
-
timeout:
|
|
774
|
+
timeout: this.auditTimeoutMs
|
|
710
775
|
});
|
|
711
776
|
} catch (err) {
|
|
712
777
|
const execError = err;
|
|
@@ -730,7 +795,7 @@ var MonitorClient = class {
|
|
|
730
795
|
encoding: "utf-8",
|
|
731
796
|
stdio: ["pipe", "pipe", "pipe"],
|
|
732
797
|
maxBuffer: CONFIG_LIMITS.AUDIT_MAX_BUFFER,
|
|
733
|
-
timeout:
|
|
798
|
+
timeout: this.auditTimeoutMs
|
|
734
799
|
});
|
|
735
800
|
} catch (err) {
|
|
736
801
|
const execError = err;
|
package/package.json
CHANGED