hale-commenting-system 2.2.0 → 2.2.2
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/.claude/settings.local.json +7 -0
- package/.editorconfig +17 -0
- package/.eslintrc.js +75 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +23 -0
- package/.github/workflows/ci.yaml +51 -0
- package/.prettierignore +1 -0
- package/.prettierrc +4 -0
- package/GITHUB_OAUTH_ENV_TEMPLATE.md +53 -0
- package/LICENSE +21 -0
- package/README.md +92 -21
- package/package.json +74 -50
- package/scripts/README.md +42 -0
- package/scripts/integrate.js +472 -0
- package/src/app/AppLayout/AppLayout.tsx +248 -0
- package/src/app/Comments/Comments.tsx +273 -0
- package/src/app/Dashboard/Dashboard.tsx +10 -0
- package/src/app/NotFound/NotFound.tsx +35 -0
- package/src/app/Settings/General/GeneralSettings.tsx +16 -0
- package/src/app/Settings/Profile/ProfileSettings.tsx +18 -0
- package/src/app/Support/Support.tsx +50 -0
- package/src/app/__snapshots__/app.test.tsx.snap +524 -0
- package/src/app/app.css +11 -0
- package/src/app/app.test.tsx +55 -0
- package/src/app/bgimages/Patternfly-Logo.svg +28 -0
- package/src/app/commenting-system/components/CommentOverlay.tsx +93 -0
- package/src/app/commenting-system/components/CommentPanel.tsx +534 -0
- package/src/app/commenting-system/components/CommentPin.tsx +60 -0
- package/src/app/commenting-system/components/DetailsTab.tsx +516 -0
- package/src/app/commenting-system/components/FloatingWidget.tsx +130 -0
- package/src/app/commenting-system/components/JiraTab.tsx +696 -0
- package/src/app/commenting-system/contexts/CommentContext.tsx +1033 -0
- package/src/app/commenting-system/contexts/GitHubAuthContext.tsx +84 -0
- package/{dist/index.d.ts → src/app/commenting-system/index.ts} +5 -4
- package/src/app/commenting-system/services/githubAdapter.ts +359 -0
- package/src/app/commenting-system/types/index.ts +27 -0
- package/src/app/commenting-system/utils/version.ts +19 -0
- package/src/app/index.tsx +22 -0
- package/src/app/routes.tsx +81 -0
- package/src/app/utils/useDocumentTitle.ts +13 -0
- package/src/favicon.png +0 -0
- package/src/index.html +18 -0
- package/src/index.tsx +25 -0
- package/src/test/setup.ts +33 -0
- package/src/typings.d.ts +12 -0
- package/stylePaths.js +14 -0
- package/tsconfig.json +34 -0
- package/vitest.config.ts +19 -0
- package/webpack.common.js +139 -0
- package/webpack.dev.js +318 -0
- package/webpack.prod.js +38 -0
- package/bin/detect.d.ts +0 -10
- package/bin/detect.js +0 -134
- package/bin/generators.d.ts +0 -20
- package/bin/generators.js +0 -272
- package/bin/hale-commenting.js +0 -4
- package/bin/index.d.ts +0 -2
- package/bin/index.js +0 -61
- package/bin/onboarding.d.ts +0 -1
- package/bin/onboarding.js +0 -395
- package/bin/postinstall.d.ts +0 -2
- package/bin/postinstall.js +0 -65
- package/bin/validators.d.ts +0 -2
- package/bin/validators.js +0 -66
- package/dist/cli/detect.d.ts +0 -10
- package/dist/cli/detect.js +0 -134
- package/dist/cli/generators.d.ts +0 -20
- package/dist/cli/generators.js +0 -272
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js +0 -61
- package/dist/cli/onboarding.d.ts +0 -1
- package/dist/cli/onboarding.js +0 -395
- package/dist/cli/postinstall.d.ts +0 -2
- package/dist/cli/postinstall.js +0 -65
- package/dist/cli/validators.d.ts +0 -2
- package/dist/cli/validators.js +0 -66
- package/dist/components/CommentOverlay.d.ts +0 -2
- package/dist/components/CommentOverlay.js +0 -101
- package/dist/components/CommentPanel.d.ts +0 -6
- package/dist/components/CommentPanel.js +0 -334
- package/dist/components/CommentPin.d.ts +0 -11
- package/dist/components/CommentPin.js +0 -64
- package/dist/components/DetailsTab.d.ts +0 -2
- package/dist/components/DetailsTab.js +0 -380
- package/dist/components/FloatingWidget.d.ts +0 -8
- package/dist/components/FloatingWidget.js +0 -128
- package/dist/components/JiraTab.d.ts +0 -2
- package/dist/components/JiraTab.js +0 -507
- package/dist/contexts/CommentContext.d.ts +0 -30
- package/dist/contexts/CommentContext.js +0 -891
- package/dist/contexts/GitHubAuthContext.d.ts +0 -13
- package/dist/contexts/GitHubAuthContext.js +0 -96
- package/dist/index.js +0 -27
- package/dist/services/githubAdapter.d.ts +0 -56
- package/dist/services/githubAdapter.js +0 -321
- package/dist/types/index.d.ts +0 -25
- package/dist/types/index.js +0 -2
- package/dist/utils/version.d.ts +0 -1
- package/dist/utils/version.js +0 -23
- package/templates/webpack-middleware.js +0 -226
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
// Hale Commenting System - Webpack Dev Server Middleware
|
|
2
|
-
// Add this code to your webpack.dev.js inside setupMiddlewares function
|
|
3
|
-
|
|
4
|
-
// Load env vars for local OAuth/token exchange without bundling secrets into the client.
|
|
5
|
-
try {
|
|
6
|
-
const dotenv = require('dotenv');
|
|
7
|
-
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
|
8
|
-
dotenv.config({ path: path.resolve(__dirname, '.env.server'), override: true });
|
|
9
|
-
} catch (e) {
|
|
10
|
-
// no-op
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const express = require('express');
|
|
14
|
-
devServer.app.use(express.json());
|
|
15
|
-
|
|
16
|
-
// GitHub OAuth Callback
|
|
17
|
-
devServer.app.get('/api/github-oauth-callback', async (req, res) => {
|
|
18
|
-
try {
|
|
19
|
-
const code = req.query.code;
|
|
20
|
-
if (!code) {
|
|
21
|
-
return res.status(400).send('Missing ?code from GitHub OAuth callback.');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const clientId = process.env.VITE_GITHUB_CLIENT_ID;
|
|
25
|
-
const clientSecret = process.env.GITHUB_CLIENT_SECRET;
|
|
26
|
-
|
|
27
|
-
if (!clientId || !clientSecret) {
|
|
28
|
-
return res.status(500).send('Missing GitHub OAuth credentials.');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const tokenResp = await fetch('https://github.com/login/oauth/access_token', {
|
|
32
|
-
method: 'POST',
|
|
33
|
-
headers: {
|
|
34
|
-
'Accept': 'application/json',
|
|
35
|
-
'Content-Type': 'application/json',
|
|
36
|
-
},
|
|
37
|
-
body: JSON.stringify({
|
|
38
|
-
client_id: clientId,
|
|
39
|
-
client_secret: clientSecret,
|
|
40
|
-
code,
|
|
41
|
-
}),
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const tokenData = await tokenResp.json();
|
|
45
|
-
if (!tokenResp.ok || tokenData.error) {
|
|
46
|
-
return res.status(500).send(`OAuth token exchange failed: ${tokenData.error || tokenResp.statusText}`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const accessToken = tokenData.access_token;
|
|
50
|
-
if (!accessToken) {
|
|
51
|
-
return res.status(500).send('OAuth token exchange did not return an access_token.');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const userResp = await fetch('https://api.github.com/user', {
|
|
55
|
-
headers: {
|
|
56
|
-
'Accept': 'application/vnd.github+json',
|
|
57
|
-
'Authorization': `token ${accessToken}`,
|
|
58
|
-
'User-Agent': 'hale-commenting-system',
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
const user = await userResp.json();
|
|
62
|
-
if (!userResp.ok) {
|
|
63
|
-
return res.status(500).send(`Failed to fetch GitHub user: ${user.message || userResp.statusText}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const login = encodeURIComponent(user.login || '');
|
|
67
|
-
const avatar = encodeURIComponent(user.avatar_url || '');
|
|
68
|
-
const token = encodeURIComponent(accessToken);
|
|
69
|
-
|
|
70
|
-
return res.redirect(`/#/auth-callback?token=${token}&login=${login}&avatar=${avatar}`);
|
|
71
|
-
} catch (err) {
|
|
72
|
-
console.error(err);
|
|
73
|
-
return res.status(500).send('Unhandled OAuth callback error. See dev server logs.');
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
// GitHub API Proxy
|
|
78
|
-
devServer.app.post('/api/github-api', async (req, res) => {
|
|
79
|
-
try {
|
|
80
|
-
const { token, method, endpoint, data } = req.body || {};
|
|
81
|
-
if (!token) return res.status(401).json({ message: 'Missing token' });
|
|
82
|
-
if (!method || !endpoint) return res.status(400).json({ message: 'Missing method or endpoint' });
|
|
83
|
-
|
|
84
|
-
const url = `https://api.github.com${endpoint}`;
|
|
85
|
-
const resp = await fetch(url, {
|
|
86
|
-
method,
|
|
87
|
-
headers: {
|
|
88
|
-
'Accept': 'application/vnd.github+json',
|
|
89
|
-
'Authorization': `token ${token}`,
|
|
90
|
-
'User-Agent': 'hale-commenting-system',
|
|
91
|
-
...(data ? { 'Content-Type': 'application/json' } : {}),
|
|
92
|
-
},
|
|
93
|
-
body: data ? JSON.stringify(data) : undefined,
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const text = await resp.text();
|
|
97
|
-
const maybeJson = (() => {
|
|
98
|
-
try {
|
|
99
|
-
return JSON.parse(text);
|
|
100
|
-
} catch {
|
|
101
|
-
return text;
|
|
102
|
-
}
|
|
103
|
-
})();
|
|
104
|
-
|
|
105
|
-
return res.status(resp.status).json(maybeJson);
|
|
106
|
-
} catch (err) {
|
|
107
|
-
console.error(err);
|
|
108
|
-
return res.status(500).json({ message: 'Unhandled github-api proxy error. See dev server logs.' });
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
// Jira Issue Proxy
|
|
113
|
-
devServer.app.get('/api/jira-issue', async (req, res) => {
|
|
114
|
-
try {
|
|
115
|
-
const key = String(req.query.key || '').trim();
|
|
116
|
-
if (!key) return res.status(400).json({ message: 'Missing ?key (e.g. ABC-123)' });
|
|
117
|
-
|
|
118
|
-
const baseUrl = (process.env.VITE_JIRA_BASE_URL || 'https://issues.redhat.com').replace(/\/+$/, '');
|
|
119
|
-
const email = process.env.JIRA_EMAIL;
|
|
120
|
-
const token = process.env.JIRA_API_TOKEN;
|
|
121
|
-
|
|
122
|
-
if (!token) {
|
|
123
|
-
return res.status(500).json({
|
|
124
|
-
message: 'Missing JIRA_API_TOKEN. For local dev, put it in .env.server (gitignored).',
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const authHeader = email
|
|
129
|
-
? `Basic ${Buffer.from(`${email}:${token}`).toString('base64')}`
|
|
130
|
-
: `Bearer ${token}`;
|
|
131
|
-
|
|
132
|
-
const buildUrl = (apiVersion) =>
|
|
133
|
-
`${baseUrl}/rest/api/${apiVersion}/issue/${encodeURIComponent(key)}?fields=summary,status,assignee,issuetype,priority,created,updated,description&expand=renderedFields`;
|
|
134
|
-
|
|
135
|
-
const commonHeaders = {
|
|
136
|
-
'Accept': 'application/json',
|
|
137
|
-
'Authorization': authHeader,
|
|
138
|
-
'User-Agent': 'hale-commenting-system',
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
const fetchOnce = async (apiVersion) => {
|
|
142
|
-
const r = await fetch(buildUrl(apiVersion), { headers: commonHeaders, redirect: 'manual' });
|
|
143
|
-
const text = await r.text();
|
|
144
|
-
const contentType = String(r.headers.get('content-type') || '');
|
|
145
|
-
const looksLikeHtml =
|
|
146
|
-
contentType.includes('text/html') ||
|
|
147
|
-
String(text || '').trim().startsWith('<');
|
|
148
|
-
return { r, text, contentType, looksLikeHtml };
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const preferV2 = baseUrl.includes('issues.redhat.com');
|
|
152
|
-
const firstVersion = preferV2 ? '2' : '3';
|
|
153
|
-
const secondVersion = preferV2 ? '3' : '2';
|
|
154
|
-
|
|
155
|
-
let attempt = await fetchOnce(firstVersion);
|
|
156
|
-
if (
|
|
157
|
-
attempt.r.status === 404 ||
|
|
158
|
-
attempt.r.status === 302 ||
|
|
159
|
-
attempt.looksLikeHtml ||
|
|
160
|
-
attempt.r.status === 401 ||
|
|
161
|
-
attempt.r.status === 403
|
|
162
|
-
) {
|
|
163
|
-
const fallback = await fetchOnce(secondVersion);
|
|
164
|
-
if (fallback.r.ok || attempt.looksLikeHtml || attempt.r.status === 302) {
|
|
165
|
-
attempt = fallback;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const resp = attempt.r;
|
|
170
|
-
const payloadText = attempt.text;
|
|
171
|
-
const contentType = attempt.contentType;
|
|
172
|
-
|
|
173
|
-
const payload = (() => {
|
|
174
|
-
try {
|
|
175
|
-
return JSON.parse(payloadText);
|
|
176
|
-
} catch {
|
|
177
|
-
return { message: payloadText };
|
|
178
|
-
}
|
|
179
|
-
})();
|
|
180
|
-
|
|
181
|
-
if (!resp.ok) {
|
|
182
|
-
const looksLikeHtml =
|
|
183
|
-
contentType.includes('text/html') ||
|
|
184
|
-
String(payloadText || '').trim().startsWith('<');
|
|
185
|
-
|
|
186
|
-
if (looksLikeHtml) {
|
|
187
|
-
return res.status(resp.status).json({
|
|
188
|
-
message:
|
|
189
|
-
resp.status === 401 || resp.status === 403
|
|
190
|
-
? 'Unauthorized to Jira. Your token/auth scheme may be incorrect for this Jira instance.'
|
|
191
|
-
: `Jira request failed (${resp.status}).`,
|
|
192
|
-
hint: email
|
|
193
|
-
? 'You are using Basic auth (JIRA_EMAIL + JIRA_API_TOKEN). If this Jira uses PAT/Bearer tokens, remove JIRA_EMAIL and set only JIRA_API_TOKEN.'
|
|
194
|
-
: baseUrl.includes('issues.redhat.com')
|
|
195
|
-
? 'You are using Bearer auth (JIRA_API_TOKEN). For issues.redhat.com, ensure you are using a PAT that works with REST API v2 and that JIRA_EMAIL is NOT set.'
|
|
196
|
-
: 'You are using Bearer auth (JIRA_API_TOKEN). If this Jira uses Jira Cloud API tokens, set JIRA_EMAIL as well.',
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return res.status(resp.status).json({
|
|
201
|
-
message: payload?.message || `Jira request failed (${resp.status}).`,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const issue = payload;
|
|
206
|
-
const fields = issue.fields || {};
|
|
207
|
-
const renderedFields = issue.renderedFields || {};
|
|
208
|
-
|
|
209
|
-
return res.json({
|
|
210
|
-
key: issue.key,
|
|
211
|
-
url: `${baseUrl}/browse/${issue.key}`,
|
|
212
|
-
summary: fields.summary || '',
|
|
213
|
-
status: fields.status?.name || '',
|
|
214
|
-
assignee: fields.assignee?.displayName || '',
|
|
215
|
-
issueType: fields.issuetype?.name || '',
|
|
216
|
-
priority: fields.priority?.name || '',
|
|
217
|
-
created: fields.created || '',
|
|
218
|
-
updated: fields.updated || '',
|
|
219
|
-
description: renderedFields.description || fields.description || '',
|
|
220
|
-
});
|
|
221
|
-
} catch (err) {
|
|
222
|
-
console.error(err);
|
|
223
|
-
return res.status(500).json({ message: 'Unhandled jira-issue proxy error. See dev server logs.' });
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
|