@dependabit/manifest 0.1.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/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +43 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +191 -0
- package/dist/manifest.js.map +1 -0
- package/dist/schema.d.ts +488 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +213 -0
- package/dist/schema.js.map +1 -0
- package/dist/size-check.d.ts +39 -0
- package/dist/size-check.d.ts.map +1 -0
- package/dist/size-check.js +84 -0
- package/dist/size-check.js.map +1 -0
- package/dist/validator.d.ts +53 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +110 -0
- package/dist/validator.js.map +1 -0
- package/package.json +38 -0
- package/src/config.test.ts +266 -0
- package/src/config.ts +96 -0
- package/src/index.ts +16 -0
- package/src/manifest.test.ts +400 -0
- package/src/manifest.ts +261 -0
- package/src/schema.test.ts +293 -0
- package/src/schema.ts +265 -0
- package/src/size-check.test.ts +246 -0
- package/src/size-check.ts +124 -0
- package/src/validator.test.ts +161 -0
- package/src/validator.ts +131 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-present Pradeep Mouli
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# @dependabit/manifest
|
|
2
|
+
|
|
3
|
+
Manifest schema and validation for dependency tracking.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides the core schema definitions and validation logic for the dependency manifest format used by dependabit.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Zod-based schema validation
|
|
12
|
+
- Manifest CRUD operations
|
|
13
|
+
- Config file parsing and validation
|
|
14
|
+
- Type-safe manifest handling
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add @dependabit/manifest
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { DependencyManifestSchema } from '@dependabit/manifest';
|
|
26
|
+
|
|
27
|
+
// Coming soon in Phase 2
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## License
|
|
31
|
+
|
|
32
|
+
MIT
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type DependabitConfig } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse and validate a YAML configuration file
|
|
4
|
+
*/
|
|
5
|
+
export declare function readConfig(path: string): Promise<DependabitConfig>;
|
|
6
|
+
/**
|
|
7
|
+
* Parse YAML string to config
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseConfig(yaml: string): DependabitConfig;
|
|
10
|
+
/**
|
|
11
|
+
* Convert config to YAML string
|
|
12
|
+
*/
|
|
13
|
+
export declare function stringifyConfig(config: DependabitConfig): string;
|
|
14
|
+
/**
|
|
15
|
+
* Get effective monitoring rules for a dependency
|
|
16
|
+
* Merges global config with dependency-specific overrides
|
|
17
|
+
*/
|
|
18
|
+
export declare function getEffectiveMonitoringRules(config: DependabitConfig, dependencyUrl: string): {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
checkFrequency: 'hourly' | 'daily' | 'weekly' | 'monthly';
|
|
21
|
+
ignoreChanges: boolean;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Check if a URL should be ignored based on config
|
|
25
|
+
*/
|
|
26
|
+
export declare function shouldIgnoreUrl(config: DependabitConfig, url: string): boolean;
|
|
27
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAIxE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAG1D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAIhE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,gBAAgB,EACxB,aAAa,EAAE,MAAM,GACpB;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC1D,aAAa,EAAE,OAAO,CAAC;CACxB,CAsBA;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CA0B9E"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import YAML from 'yaml';
|
|
3
|
+
import {} from './schema.js';
|
|
4
|
+
import { validateConfig } from './validator.js';
|
|
5
|
+
/**
|
|
6
|
+
* Parse and validate a YAML configuration file
|
|
7
|
+
*/
|
|
8
|
+
export async function readConfig(path) {
|
|
9
|
+
const content = await readFile(path, 'utf-8');
|
|
10
|
+
const data = YAML.parse(content);
|
|
11
|
+
return validateConfig(data);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Parse YAML string to config
|
|
15
|
+
*/
|
|
16
|
+
export function parseConfig(yaml) {
|
|
17
|
+
const data = YAML.parse(yaml);
|
|
18
|
+
return validateConfig(data);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert config to YAML string
|
|
22
|
+
*/
|
|
23
|
+
export function stringifyConfig(config) {
|
|
24
|
+
// Validate before stringifying
|
|
25
|
+
validateConfig(config);
|
|
26
|
+
return YAML.stringify(config);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get effective monitoring rules for a dependency
|
|
30
|
+
* Merges global config with dependency-specific overrides
|
|
31
|
+
*/
|
|
32
|
+
export function getEffectiveMonitoringRules(config, dependencyUrl) {
|
|
33
|
+
// Start with global defaults
|
|
34
|
+
const globalEnabled = config.monitoring?.enabled ?? true;
|
|
35
|
+
const globalCheckFrequency = config.schedule?.interval ?? 'daily';
|
|
36
|
+
// Find dependency-specific override
|
|
37
|
+
const override = config.dependencies?.find((dep) => dep.url === dependencyUrl);
|
|
38
|
+
if (override?.monitoring) {
|
|
39
|
+
return {
|
|
40
|
+
enabled: override.monitoring.enabled ?? globalEnabled,
|
|
41
|
+
checkFrequency: override.monitoring.checkFrequency ?? override.schedule?.interval ?? globalCheckFrequency,
|
|
42
|
+
ignoreChanges: override.monitoring.ignoreChanges ?? false
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
enabled: globalEnabled,
|
|
47
|
+
checkFrequency: globalCheckFrequency,
|
|
48
|
+
ignoreChanges: false
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check if a URL should be ignored based on config
|
|
53
|
+
*/
|
|
54
|
+
export function shouldIgnoreUrl(config, url) {
|
|
55
|
+
if (!config.ignore) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
// Check exact URL matches
|
|
59
|
+
if (config.ignore.urls?.includes(url)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
// Check regex patterns with error handling
|
|
63
|
+
if (config.ignore.patterns) {
|
|
64
|
+
for (const pattern of config.ignore.patterns) {
|
|
65
|
+
try {
|
|
66
|
+
const regex = new RegExp(pattern);
|
|
67
|
+
if (regex.test(url)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Invalid regex pattern - log warning but continue
|
|
73
|
+
console.warn(`Invalid regex pattern in config.ignore.patterns: ${pattern}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,aAAa,CAAC;AAG5B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,eAAe,CAAC;AAG9B,cAAc,aAAa,CAAC;AAG5B,cAAc,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Entry point for @dependabit/manifest
|
|
2
|
+
// Export schemas and types
|
|
3
|
+
export * from './schema.js';
|
|
4
|
+
// Export validators
|
|
5
|
+
export * from './validator.js';
|
|
6
|
+
// Export manifest operations
|
|
7
|
+
export * from './manifest.js';
|
|
8
|
+
// Export config operations
|
|
9
|
+
export * from './config.js';
|
|
10
|
+
// Export size checking
|
|
11
|
+
export * from './size-check.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAEvC,2BAA2B;AAC3B,cAAc,aAAa,CAAC;AAE5B,oBAAoB;AACpB,cAAc,gBAAgB,CAAC;AAE/B,6BAA6B;AAC7B,cAAc,eAAe,CAAC;AAE9B,2BAA2B;AAC3B,cAAc,aAAa,CAAC;AAE5B,uBAAuB;AACvB,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type DependencyManifest, type DependencyEntry } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read and parse a manifest file
|
|
4
|
+
*/
|
|
5
|
+
export declare function readManifest(path: string): Promise<DependencyManifest>;
|
|
6
|
+
/**
|
|
7
|
+
* Write a manifest to file
|
|
8
|
+
*/
|
|
9
|
+
export declare function writeManifest(path: string, manifest: DependencyManifest): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Update a dependency entry in the manifest
|
|
12
|
+
*/
|
|
13
|
+
export declare function updateDependency(path: string, dependencyId: string, updates: Partial<DependencyEntry>): Promise<DependencyManifest>;
|
|
14
|
+
/**
|
|
15
|
+
* Add a new dependency to the manifest
|
|
16
|
+
*/
|
|
17
|
+
export declare function addDependency(path: string, dependency: DependencyEntry): Promise<DependencyManifest>;
|
|
18
|
+
/**
|
|
19
|
+
* Remove a dependency from the manifest
|
|
20
|
+
*/
|
|
21
|
+
export declare function removeDependency(path: string, dependencyId: string): Promise<DependencyManifest>;
|
|
22
|
+
/**
|
|
23
|
+
* Merge two manifests, preserving manual entries
|
|
24
|
+
* Manual entries are those with detectionMethod === 'manual'
|
|
25
|
+
*/
|
|
26
|
+
export declare function mergeManifests(existing: DependencyManifest, updated: DependencyManifest, options?: {
|
|
27
|
+
preserveManual?: boolean;
|
|
28
|
+
preserveHistory?: boolean;
|
|
29
|
+
}): DependencyManifest;
|
|
30
|
+
/**
|
|
31
|
+
* Create an empty manifest template
|
|
32
|
+
*/
|
|
33
|
+
export declare function createEmptyManifest(options: {
|
|
34
|
+
owner: string;
|
|
35
|
+
name: string;
|
|
36
|
+
branch: string;
|
|
37
|
+
commit: string;
|
|
38
|
+
action?: string;
|
|
39
|
+
version?: string;
|
|
40
|
+
llmProvider?: string;
|
|
41
|
+
llmModel?: string;
|
|
42
|
+
}): DependencyManifest;
|
|
43
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAG5E;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAI5E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAU7F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAqB7B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,eAAe,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CAyB7B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAkB7B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,kBAAkB,EAC3B,OAAO,GAAE;IACP,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;CACtB,GACL,kBAAkB,CAqDpB;AAyCD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,kBAAkB,CAyBrB"}
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import {} from './schema.js';
|
|
4
|
+
import { validateManifest, validateDependencyEntry } from './validator.js';
|
|
5
|
+
/**
|
|
6
|
+
* Read and parse a manifest file
|
|
7
|
+
*/
|
|
8
|
+
export async function readManifest(path) {
|
|
9
|
+
const content = await readFile(path, 'utf-8');
|
|
10
|
+
const data = JSON.parse(content);
|
|
11
|
+
return validateManifest(data);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Write a manifest to file
|
|
15
|
+
*/
|
|
16
|
+
export async function writeManifest(path, manifest) {
|
|
17
|
+
// Validate before writing
|
|
18
|
+
validateManifest(manifest);
|
|
19
|
+
// Ensure directory exists
|
|
20
|
+
await mkdir(dirname(path), { recursive: true });
|
|
21
|
+
// Write formatted JSON
|
|
22
|
+
const content = JSON.stringify(manifest, null, 2);
|
|
23
|
+
await writeFile(path, content, 'utf-8');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Update a dependency entry in the manifest
|
|
27
|
+
*/
|
|
28
|
+
export async function updateDependency(path, dependencyId, updates) {
|
|
29
|
+
const manifest = await readManifest(path);
|
|
30
|
+
const dep = manifest.dependencies.find((d) => d.id === dependencyId);
|
|
31
|
+
if (!dep) {
|
|
32
|
+
throw new Error(`Dependency with id ${dependencyId} not found`);
|
|
33
|
+
}
|
|
34
|
+
// Update the dependency in place
|
|
35
|
+
Object.assign(dep, updates);
|
|
36
|
+
// Validate the merged dependency
|
|
37
|
+
validateDependencyEntry(dep);
|
|
38
|
+
// Update statistics
|
|
39
|
+
manifest.statistics = calculateStatistics(manifest.dependencies);
|
|
40
|
+
// Write back
|
|
41
|
+
await writeManifest(path, manifest);
|
|
42
|
+
return manifest;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Add a new dependency to the manifest
|
|
46
|
+
*/
|
|
47
|
+
export async function addDependency(path, dependency) {
|
|
48
|
+
const manifest = await readManifest(path);
|
|
49
|
+
// Check for duplicates by ID or URL
|
|
50
|
+
const existingById = manifest.dependencies.find((dep) => dep.id === dependency.id);
|
|
51
|
+
const existingByUrl = manifest.dependencies.find((dep) => dep.url === dependency.url);
|
|
52
|
+
if (existingById) {
|
|
53
|
+
throw new Error(`Dependency with id ${dependency.id} already exists`);
|
|
54
|
+
}
|
|
55
|
+
if (existingByUrl) {
|
|
56
|
+
throw new Error(`Dependency with url ${dependency.url} already exists`);
|
|
57
|
+
}
|
|
58
|
+
// Add dependency
|
|
59
|
+
manifest.dependencies.push(dependency);
|
|
60
|
+
// Update statistics
|
|
61
|
+
manifest.statistics = calculateStatistics(manifest.dependencies);
|
|
62
|
+
// Write back
|
|
63
|
+
await writeManifest(path, manifest);
|
|
64
|
+
return manifest;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Remove a dependency from the manifest
|
|
68
|
+
*/
|
|
69
|
+
export async function removeDependency(path, dependencyId) {
|
|
70
|
+
const manifest = await readManifest(path);
|
|
71
|
+
const index = manifest.dependencies.findIndex((dep) => dep.id === dependencyId);
|
|
72
|
+
if (index === -1) {
|
|
73
|
+
throw new Error(`Dependency with id ${dependencyId} not found`);
|
|
74
|
+
}
|
|
75
|
+
// Remove dependency
|
|
76
|
+
manifest.dependencies.splice(index, 1);
|
|
77
|
+
// Update statistics
|
|
78
|
+
manifest.statistics = calculateStatistics(manifest.dependencies);
|
|
79
|
+
// Write back
|
|
80
|
+
await writeManifest(path, manifest);
|
|
81
|
+
return manifest;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Merge two manifests, preserving manual entries
|
|
85
|
+
* Manual entries are those with detectionMethod === 'manual'
|
|
86
|
+
*/
|
|
87
|
+
export function mergeManifests(existing, updated, options = {}) {
|
|
88
|
+
const { preserveManual = true, preserveHistory = true } = options;
|
|
89
|
+
// Create a deep copy of the updated manifest to avoid mutations
|
|
90
|
+
const merged = {
|
|
91
|
+
...updated,
|
|
92
|
+
dependencies: updated.dependencies.map((dep) => ({
|
|
93
|
+
...dep,
|
|
94
|
+
changeHistory: dep.changeHistory ? [...dep.changeHistory] : [],
|
|
95
|
+
referencedIn: dep.referencedIn ? [...dep.referencedIn] : []
|
|
96
|
+
}))
|
|
97
|
+
};
|
|
98
|
+
if (preserveManual) {
|
|
99
|
+
// Find manual entries in existing manifest
|
|
100
|
+
const manualEntries = existing.dependencies.filter((dep) => dep.detectionMethod === 'manual');
|
|
101
|
+
// Add manual entries that aren't in the updated manifest
|
|
102
|
+
for (const manualEntry of manualEntries) {
|
|
103
|
+
const existsInUpdated = merged.dependencies.some((dep) => dep.id === manualEntry.id || dep.url === manualEntry.url);
|
|
104
|
+
if (!existsInUpdated) {
|
|
105
|
+
merged.dependencies.push({
|
|
106
|
+
...manualEntry,
|
|
107
|
+
changeHistory: manualEntry.changeHistory ? [...manualEntry.changeHistory] : [],
|
|
108
|
+
referencedIn: manualEntry.referencedIn ? [...manualEntry.referencedIn] : []
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (preserveHistory) {
|
|
114
|
+
// Preserve change history for matching dependencies
|
|
115
|
+
merged.dependencies = merged.dependencies.map((dep) => {
|
|
116
|
+
const existingDep = existing.dependencies.find((d) => d.id === dep.id || d.url === dep.url);
|
|
117
|
+
if (existingDep && existingDep.changeHistory && existingDep.changeHistory.length > 0) {
|
|
118
|
+
return {
|
|
119
|
+
...dep,
|
|
120
|
+
changeHistory: [...existingDep.changeHistory, ...(dep.changeHistory || [])]
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return dep;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// Recalculate statistics
|
|
127
|
+
merged.statistics = calculateStatistics(merged.dependencies);
|
|
128
|
+
return merged;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Calculate statistics for a list of dependencies
|
|
132
|
+
*/
|
|
133
|
+
function calculateStatistics(dependencies) {
|
|
134
|
+
const byType = {};
|
|
135
|
+
const byAccessMethod = {};
|
|
136
|
+
const byDetectionMethod = {};
|
|
137
|
+
let totalConfidence = 0;
|
|
138
|
+
let falsePositiveCount = 0;
|
|
139
|
+
let totalChangeCount = 0;
|
|
140
|
+
for (const dep of dependencies) {
|
|
141
|
+
byType[dep.type] = (byType[dep.type] || 0) + 1;
|
|
142
|
+
byAccessMethod[dep.accessMethod] = (byAccessMethod[dep.accessMethod] || 0) + 1;
|
|
143
|
+
byDetectionMethod[dep.detectionMethod] = (byDetectionMethod[dep.detectionMethod] || 0) + 1;
|
|
144
|
+
totalConfidence += dep.detectionConfidence;
|
|
145
|
+
// Count false positives in change history
|
|
146
|
+
const changeHistory = dep.changeHistory || [];
|
|
147
|
+
const fpCount = changeHistory.filter((change) => change.falsePositive).length;
|
|
148
|
+
falsePositiveCount += fpCount;
|
|
149
|
+
totalChangeCount += changeHistory.length;
|
|
150
|
+
}
|
|
151
|
+
const averageConfidence = dependencies.length > 0 ? totalConfidence / dependencies.length : 0;
|
|
152
|
+
const falsePositiveRate = totalChangeCount > 0 ? falsePositiveCount / totalChangeCount : undefined;
|
|
153
|
+
return {
|
|
154
|
+
totalDependencies: dependencies.length,
|
|
155
|
+
byType,
|
|
156
|
+
byAccessMethod,
|
|
157
|
+
byDetectionMethod,
|
|
158
|
+
averageConfidence,
|
|
159
|
+
falsePositiveRate
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Create an empty manifest template
|
|
164
|
+
*/
|
|
165
|
+
export function createEmptyManifest(options) {
|
|
166
|
+
return {
|
|
167
|
+
version: '1.0.0',
|
|
168
|
+
generatedAt: new Date().toISOString(),
|
|
169
|
+
generatedBy: {
|
|
170
|
+
action: options.action || 'dependabit',
|
|
171
|
+
version: options.version || '0.1.0',
|
|
172
|
+
llmProvider: options.llmProvider || 'github-copilot',
|
|
173
|
+
llmModel: options.llmModel
|
|
174
|
+
},
|
|
175
|
+
repository: {
|
|
176
|
+
owner: options.owner,
|
|
177
|
+
name: options.name,
|
|
178
|
+
branch: options.branch,
|
|
179
|
+
commit: options.commit
|
|
180
|
+
},
|
|
181
|
+
dependencies: [],
|
|
182
|
+
statistics: {
|
|
183
|
+
totalDependencies: 0,
|
|
184
|
+
byType: {},
|
|
185
|
+
byAccessMethod: {},
|
|
186
|
+
byDetectionMethod: {},
|
|
187
|
+
averageConfidence: 0
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|