Skip to content

Commit 370fd89

Browse files
committed
cleanup
1 parent eb002ac commit 370fd89

File tree

1 file changed

+123
-103
lines changed

1 file changed

+123
-103
lines changed

src/services/DockerSourceFinder.ts

+123-103
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,142 @@
1-
const Docker = require('dockerode');
2-
const https = require('https');
3-
import * as http from 'http';
1+
const Docker = require("dockerode");
2+
const https = require("https");
3+
import * as http from "http";
44

5-
interface HttpRequestOptions {
6-
method?: string;
7-
headers?: { [key: string]: string };
8-
}
5+
export default class DockerSourceFinder {
6+
public static docker = new Docker();
97

10-
interface HttpResponse {
11-
ok: boolean;
12-
status: number;
13-
statusText: string;
14-
json(): Promise<any>;
15-
}
8+
constructor() {
9+
DockerSourceFinder.docker = new Docker();
10+
}
1611

17-
export default class DockerSourceFinder {
18-
public static docker = new Docker();
12+
async getImageLabels(imageName: string) {
13+
try {
14+
const image = await DockerSourceFinder.docker.getImage(imageName);
15+
const inspect = await image.inspect();
16+
return inspect.Config.Labels;
17+
} catch (error: unknown) {
18+
console.error(
19+
`Error accessing image ${imageName}:`,
20+
error instanceof Error ? error.message : String(error)
21+
);
22+
return null;
23+
}
24+
}
1925

20-
constructor() {
21-
DockerSourceFinder.docker = new Docker();
26+
parseGithubUrl(url: string) {
27+
const parsed = new URL(url);
28+
if (parsed.hostname === "github.com") {
29+
const pathParts = parsed.pathname.split("/").filter((p) => p);
30+
if (pathParts.length >= 2) {
31+
return `github.com/${pathParts[0]}/${pathParts[1]}`;
32+
}
2233
}
34+
return null;
35+
}
2336

24-
async getImageLabels(imageName: string) {
25-
try {
26-
const image = await DockerSourceFinder.docker.getImage(imageName);
27-
const inspect = await image.inspect();
28-
return inspect.Config.Labels;
29-
} catch (error: unknown) {
30-
console.error(`Error accessing image ${imageName}:`,
31-
error instanceof Error ? error.message : String(error));
32-
return null;
33-
}
37+
async findSourceRepo(imageName: string) {
38+
// Try method 1: Check Docker labels
39+
const labels = await this.getImageLabels(imageName);
40+
if (labels && labels["org.opencontainers.image.source"]) {
41+
return labels["org.opencontainers.image.source"];
3442
}
3543

36-
parseGithubUrl(url: string) {
37-
const parsed = new URL(url);
38-
if (parsed.hostname === 'github.com') {
39-
const pathParts = parsed.pathname.split('/').filter(p => p);
40-
if (pathParts.length >= 2) {
41-
return `github.com/${pathParts[0]}/${pathParts[1]}`;
42-
}
44+
// Try method 2: Check Docker Hub API
45+
try {
46+
const dockerHubUrl = `https://hub.docker.com/v2/repositories/${imageName}`;
47+
const response = await this.makeHttpsRequest(dockerHubUrl);
48+
if (response.ok) {
49+
const data = await response.json();
50+
const fullDescription = data.full_description || "";
51+
if (fullDescription.toLowerCase().includes("[github]")) {
52+
const startIndex = fullDescription.indexOf("[github");
53+
const endIndex = fullDescription.indexOf("]", startIndex);
54+
if (startIndex !== -1 && endIndex !== -1) {
55+
const githubUrl = fullDescription
56+
.slice(startIndex, endIndex)
57+
.replace("[github]", "");
58+
return this.parseGithubUrl(githubUrl);
59+
}
4360
}
44-
return null;
61+
}
62+
} catch (error: unknown) {
63+
console.error(
64+
`Error checking Docker Hub API:`,
65+
error instanceof Error ? error.message : String(error)
66+
);
4567
}
4668

47-
async findSourceRepo(imageName: string) {
48-
// Try method 1: Check Docker labels
49-
const labels = await this.getImageLabels(imageName);
50-
if (labels && labels['org.opencontainers.image.source']) {
51-
return labels['org.opencontainers.image.source'];
52-
}
69+
// Try method 3: URL pattern matching
70+
const repoParts = imageName.split("/");
71+
if (repoParts.length >= 2) {
72+
const username = repoParts[0];
73+
const repoName = repoParts[repoParts.length - 1].split(":")[0];
74+
const potentialRepo = `github.com/${username}/${repoName}`;
5375

54-
// Try method 2: Check Docker Hub API
55-
try {
56-
const dockerHubUrl = `https://hub.docker.com/v2/repositories/${imageName}`;
57-
const response = await this.makeHttpsRequest(dockerHubUrl);
58-
if (response.ok) {
59-
const data = await response.json();
60-
const fullDescription = data.full_description || '';
61-
if (fullDescription.toLowerCase().includes('[github]')) {
62-
const startIndex = fullDescription.indexOf('[github');
63-
const endIndex = fullDescription.indexOf(']', startIndex);
64-
if (startIndex !== -1 && endIndex !== -1) {
65-
const githubUrl = fullDescription.slice(startIndex, endIndex).replace('[github]', '');
66-
return this.parseGithubUrl(githubUrl);
67-
}
68-
}
69-
}
70-
} catch (error: unknown) {
71-
console.error(`Error checking Docker Hub API:`,
72-
error instanceof Error ? error.message : String(error));
73-
}
76+
const response = await this.makeHttpsRequest(`https://${potentialRepo}`, {
77+
method: "HEAD",
78+
});
79+
if (response.ok) {
80+
return potentialRepo;
81+
}
82+
}
7483

75-
// Try method 3: URL pattern matching
76-
const repoParts = imageName.split('/');
77-
if (repoParts.length >= 2) {
78-
const username = repoParts[0];
79-
const repoName = repoParts[repoParts.length - 1].split(':')[0];
80-
const potentialRepo = `github.com/${username}/${repoName}`;
84+
return null;
85+
}
8186

82-
const response = await this.makeHttpsRequest(`https://${potentialRepo}`, { method: 'HEAD' });
83-
if (response.ok) {
84-
return potentialRepo;
87+
private makeHttpsRequest(
88+
url: string,
89+
options: { method?: string; headers?: { [key: string]: string } } = {}
90+
): Promise<{
91+
ok: boolean;
92+
status: number;
93+
statusText: string;
94+
json: () => Promise<any>;
95+
}> {
96+
return new Promise((resolve, reject) => {
97+
const req = https.request(
98+
url,
99+
{
100+
method: options.method || "GET",
101+
headers: options.headers || {},
102+
},
103+
(res: http.IncomingMessage) => {
104+
let body = "";
105+
res.on("data", (chunk: Buffer) => (body += chunk));
106+
res.on("end", () => {
107+
try {
108+
// Create response object with non-nullable properties
109+
const response = {
110+
ok: (res.statusCode || 0) >= 200 && (res.statusCode || 0) < 300,
111+
status: res.statusCode || 0,
112+
statusText: res.statusMessage || "Unknown Status",
113+
json: () => Promise.resolve(JSON.parse(body)),
114+
};
115+
resolve(response);
116+
} catch (err: unknown) {
117+
reject(
118+
new Error(
119+
`Failed to parse response: ${
120+
err instanceof Error ? err.message : String(err)
121+
}`
122+
)
123+
);
85124
}
125+
});
86126
}
127+
);
87128

88-
return null;
89-
}
90-
91-
private makeHttpsRequest(url: string, options: HttpRequestOptions = {}): Promise<HttpResponse> {
92-
return new Promise((resolve, reject) => {
93-
const req = https.request(url, {
94-
method: options.method || 'GET',
95-
headers: options.headers || {}
96-
}, (res: http.IncomingMessage) => {
97-
let body = '';
98-
res.on('data', (chunk: Buffer) => body += chunk);
99-
res.on('end', () => {
100-
try {
101-
// Create response object with non-nullable properties
102-
const response: HttpResponse = {
103-
ok: (res.statusCode || 0) >= 200 && (res.statusCode || 0) < 300,
104-
status: res.statusCode || 0,
105-
statusText: res.statusMessage || 'Unknown Status',
106-
json: () => Promise.resolve(JSON.parse(body))
107-
};
108-
resolve(response);
109-
} catch (err: unknown) {
110-
reject(new Error(`Failed to parse response: ${err instanceof Error ? err.message : String(err)}`));
111-
}
112-
});
113-
});
129+
req.on("error", (err: unknown) => {
130+
reject(
131+
new Error(
132+
`Request failed: ${
133+
err instanceof Error ? err.message : String(err)
134+
}`
135+
)
136+
);
137+
});
114138

115-
req.on('error', (err: unknown) => {
116-
reject(new Error(`Request failed: ${err instanceof Error ? err.message : String(err)}`));
117-
});
118-
119-
req.end();
120-
});
121-
}
139+
req.end();
140+
});
141+
}
122142
}

0 commit comments

Comments
 (0)