-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathContactExtractor.class.ts
More file actions
138 lines (112 loc) · 3.97 KB
/
Copy pathContactExtractor.class.ts
File metadata and controls
138 lines (112 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Import Third-party Dependencies
import type { Contact, PackumentVersion, Packument } from "@nodesecure/npm-types";
// Import Internal Dependencies
import {
UnlitContact,
type EnforcedContact,
type IlluminatedContact
} from "./UnlitContact.class.ts";
import { NsResolver } from "./NsResolver.class.ts";
import { toContactWithMetadata } from "./utils/index.ts";
import type { ContactWithMetadata } from "./types.ts";
export type {
IlluminatedContact,
EnforcedContact
};
export interface ContactExtractorPackageMetadata {
author?: Contact | null;
maintainers: Contact[];
}
type ContactPackageMetaData = Partial<ContactExtractorPackageMetadata>;
export interface ContactExtractorFromDependenciesResult {
illuminated: IlluminatedContact[];
/**
* List of email domains that are expired
*/
expired: string[];
}
export interface ContactExtractorOptions {
highlight: EnforcedContact[];
}
export class ContactExtractor {
private highlighted: EnforcedContact[] = [];
constructor(
options: ContactExtractorOptions
) {
const {
highlight
} = options;
this.highlighted = structuredClone(highlight);
}
async fromDependencies(
dependencies: Record<string, ContactExtractorPackageMetadata>
): Promise<ContactExtractorFromDependenciesResult> {
const unlitContacts = this.highlighted
.map((contact) => new UnlitContact(contact));
const resolver = new NsResolver();
for (const [packageName, metadata] of Object.entries(dependencies)) {
const extractedContacts = extractMetadataContacts(metadata);
extractedContacts.forEach((contact) => resolver.registerEmail(contact.email));
this.addDependencyToUnlitContacts(unlitContacts, extractedContacts, packageName);
}
return this.processIlluminatedAndExpired(unlitContacts, resolver);
}
async fromManifest(manifest: PackumentVersion) {
const resolver = new NsResolver();
const unlitContacts = this.highlighted
.map((contact) => new UnlitContact(contact));
const extractedContacts = extractMetadataContacts(manifest);
extractedContacts.forEach((contact) => resolver.registerEmail(contact.email));
this.addDependencyToUnlitContacts(unlitContacts, extractedContacts, manifest.name);
return this.processIlluminatedAndExpired(unlitContacts, resolver);
}
async fromPackument(packument: Packument) {
const resolver = new NsResolver();
const unlitContacts = this.highlighted
.map((contact) => new UnlitContact(contact));
const emails = new Set<string>();
for (const packumentVersion of Object.values(packument.versions)) {
const extractedContacts = extractMetadataContacts(packumentVersion);
extractedContacts.forEach(({ email }) => {
if (email) {
emails.add(email);
}
});
this.addDependencyToUnlitContacts(unlitContacts, extractedContacts, packumentVersion.name);
}
for (const email of emails) {
resolver.registerEmail(email);
}
return this.processIlluminatedAndExpired(unlitContacts, resolver);
}
private addDependencyToUnlitContacts(
unlitContacts: UnlitContact[],
contacts: ContactWithMetadata[],
packageName: string
) {
for (const unlit of unlitContacts) {
const isMaintainer = contacts.some((contact) => unlit.compareTo(contact));
if (isMaintainer) {
unlit.dependencies.add(packageName);
}
}
}
private async processIlluminatedAndExpired(unlitContacts: UnlitContact[], resolver: NsResolver) {
const expired = await resolver.getExpired();
const illuminated = unlitContacts.flatMap(
(unlit) => (unlit.dependencies.size > 0 ? [unlit.illuminate()] : [])
);
return {
expired,
illuminated
};
}
}
export function extractMetadataContacts(
metadata: ContactPackageMetaData
): ContactWithMetadata[] {
return [
...(metadata.author ? [toContactWithMetadata<Contact>(metadata.author)] : []),
...(metadata.maintainers ? metadata.maintainers.map(toContactWithMetadata) : [])
];
}