hale-commenting-system 2.1.1 → 2.2.0
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/bin/generators.d.ts +10 -8
- package/bin/generators.js +86 -7
- package/bin/onboarding.js +141 -95
- package/dist/cli/generators.d.ts +10 -8
- package/dist/cli/generators.js +86 -7
- package/dist/cli/onboarding.js +141 -95
- package/package.json +1 -1
package/bin/generators.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
interface GitHubConfig {
|
|
2
|
-
clientId
|
|
3
|
-
clientSecret
|
|
4
|
-
owner
|
|
5
|
-
repo
|
|
2
|
+
clientId?: string;
|
|
3
|
+
clientSecret?: string;
|
|
4
|
+
owner?: string;
|
|
5
|
+
repo?: string;
|
|
6
6
|
}
|
|
7
7
|
interface JiraConfig {
|
|
8
|
-
baseUrl
|
|
9
|
-
apiToken
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
apiToken?: string;
|
|
10
10
|
email?: string;
|
|
11
11
|
}
|
|
12
12
|
interface Config {
|
|
13
|
-
github: GitHubConfig;
|
|
14
|
-
jira: JiraConfig;
|
|
13
|
+
github: GitHubConfig | null;
|
|
14
|
+
jira: JiraConfig | null;
|
|
15
|
+
owner: string;
|
|
16
|
+
repo: string;
|
|
15
17
|
}
|
|
16
18
|
export declare function generateFiles(config: Config): Promise<void>;
|
|
17
19
|
export declare function integrateIntoProject(): Promise<void>;
|
package/bin/generators.js
CHANGED
|
@@ -41,16 +41,50 @@ async function generateFiles(config) {
|
|
|
41
41
|
const cwd = process.cwd();
|
|
42
42
|
// Generate .env file (client-safe)
|
|
43
43
|
const envPath = path.join(cwd, '.env');
|
|
44
|
-
|
|
44
|
+
let envContent = `# Hale Commenting System Configuration
|
|
45
|
+
# Client-safe environment variables (these are exposed to the browser)
|
|
46
|
+
|
|
47
|
+
`;
|
|
48
|
+
if (config.github && config.github.clientId) {
|
|
49
|
+
envContent += `# GitHub OAuth (client-side; safe to expose)
|
|
50
|
+
# Get your Client ID from: https://github.com/settings/developers
|
|
51
|
+
# 1. Click "New OAuth App"
|
|
52
|
+
# 2. Fill in the form (Homepage: http://localhost:9000, Callback: http://localhost:9000/api/github-oauth-callback)
|
|
53
|
+
# 3. Copy the Client ID
|
|
45
54
|
VITE_GITHUB_CLIENT_ID=${config.github.clientId}
|
|
46
55
|
|
|
47
56
|
# Target repo for Issues/Comments
|
|
48
|
-
VITE_GITHUB_OWNER=${config.github.owner}
|
|
49
|
-
VITE_GITHUB_REPO=${config.github.repo}
|
|
57
|
+
VITE_GITHUB_OWNER=${config.github.owner || config.owner}
|
|
58
|
+
VITE_GITHUB_REPO=${config.github.repo || config.repo}
|
|
59
|
+
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
envContent += `# GitHub OAuth (client-side; safe to expose)
|
|
64
|
+
# Get your Client ID from: https://github.com/settings/developers
|
|
65
|
+
# 1. Click "New OAuth App"
|
|
66
|
+
# 2. Fill in the form (Homepage: http://localhost:9000, Callback: http://localhost:9000/api/github-oauth-callback)
|
|
67
|
+
# 3. Copy the Client ID
|
|
68
|
+
VITE_GITHUB_CLIENT_ID=
|
|
69
|
+
|
|
70
|
+
# Target repo for Issues/Comments
|
|
71
|
+
VITE_GITHUB_OWNER=${config.owner}
|
|
72
|
+
VITE_GITHUB_REPO=${config.repo}
|
|
50
73
|
|
|
51
|
-
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
if (config.jira && config.jira.baseUrl) {
|
|
77
|
+
envContent += `# Jira Base URL
|
|
78
|
+
# For Red Hat Jira, use: https://issues.redhat.com
|
|
52
79
|
VITE_JIRA_BASE_URL=${config.jira.baseUrl}
|
|
53
80
|
`;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
envContent += `# Jira Base URL
|
|
84
|
+
# For Red Hat Jira, use: https://issues.redhat.com
|
|
85
|
+
VITE_JIRA_BASE_URL=
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
54
88
|
// Check if .env exists and append or create
|
|
55
89
|
if (fs.existsSync(envPath)) {
|
|
56
90
|
const existing = fs.readFileSync(envPath, 'utf-8');
|
|
@@ -67,15 +101,56 @@ VITE_JIRA_BASE_URL=${config.jira.baseUrl}
|
|
|
67
101
|
fs.writeFileSync(envPath, envContent);
|
|
68
102
|
console.log(' ✅ Created .env file');
|
|
69
103
|
}
|
|
104
|
+
// Note about empty values
|
|
105
|
+
if (!config.github || !config.jira) {
|
|
106
|
+
console.log(' ℹ️ Some values are empty - see comments in .env for setup instructions');
|
|
107
|
+
}
|
|
70
108
|
// Generate .env.server file (secrets)
|
|
71
109
|
const envServerPath = path.join(cwd, '.env.server');
|
|
72
|
-
let envServerContent = `#
|
|
110
|
+
let envServerContent = `# Hale Commenting System - Server Secrets
|
|
111
|
+
# ⚠️ DO NOT COMMIT THIS FILE - It contains sensitive credentials
|
|
112
|
+
# This file is automatically added to .gitignore
|
|
113
|
+
|
|
114
|
+
`;
|
|
115
|
+
if (config.github && config.github.clientSecret) {
|
|
116
|
+
envServerContent += `# GitHub OAuth Client Secret (server-only)
|
|
117
|
+
# Get this from your GitHub OAuth App settings: https://github.com/settings/developers
|
|
118
|
+
# Click on your OAuth App, then "Generate a new client secret"
|
|
73
119
|
GITHUB_CLIENT_SECRET=${config.github.clientSecret}
|
|
74
120
|
|
|
75
|
-
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
envServerContent += `# GitHub OAuth Client Secret (server-only)
|
|
125
|
+
# Get this from your GitHub OAuth App settings: https://github.com/settings/developers
|
|
126
|
+
# Click on your OAuth App, then "Generate a new client secret"
|
|
127
|
+
GITHUB_CLIENT_SECRET=
|
|
128
|
+
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
if (config.jira && config.jira.apiToken) {
|
|
132
|
+
envServerContent += `# Jira API Token (server-only)
|
|
133
|
+
# For Red Hat Jira, generate a Personal Access Token:
|
|
134
|
+
# 1. Visit: https://issues.redhat.com/secure/ViewProfile.jspa
|
|
135
|
+
# 2. Click "Personal Access Tokens" in the left sidebar
|
|
136
|
+
# 3. Click "Create token"
|
|
137
|
+
# 4. Give it a name and remove expiration
|
|
138
|
+
# 5. Copy the token
|
|
76
139
|
JIRA_API_TOKEN=${config.jira.apiToken}
|
|
77
140
|
`;
|
|
78
|
-
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
envServerContent += `# Jira API Token (server-only)
|
|
144
|
+
# For Red Hat Jira, generate a Personal Access Token:
|
|
145
|
+
# 1. Visit: https://issues.redhat.com/secure/ViewProfile.jspa
|
|
146
|
+
# 2. Click "Personal Access Tokens" in the left sidebar
|
|
147
|
+
# 3. Click "Create token"
|
|
148
|
+
# 4. Give it a name and remove expiration
|
|
149
|
+
# 5. Copy the token
|
|
150
|
+
JIRA_API_TOKEN=
|
|
151
|
+
`;
|
|
152
|
+
}
|
|
153
|
+
if (config.jira && config.jira.email) {
|
|
79
154
|
envServerContent += `JIRA_EMAIL=${config.jira.email}\n`;
|
|
80
155
|
}
|
|
81
156
|
if (fs.existsSync(envServerPath)) {
|
|
@@ -92,6 +167,10 @@ JIRA_API_TOKEN=${config.jira.apiToken}
|
|
|
92
167
|
fs.writeFileSync(envServerPath, envServerContent);
|
|
93
168
|
console.log(' ✅ Created .env.server file');
|
|
94
169
|
}
|
|
170
|
+
// Note about empty values
|
|
171
|
+
if (!config.github || !config.jira) {
|
|
172
|
+
console.log(' ℹ️ Some values are empty - see comments in .env.server for setup instructions');
|
|
173
|
+
}
|
|
95
174
|
// Ensure .env.server is in .gitignore
|
|
96
175
|
const gitignorePath = path.join(cwd, '.gitignore');
|
|
97
176
|
if (fs.existsSync(gitignorePath)) {
|
package/bin/onboarding.js
CHANGED
|
@@ -228,115 +228,151 @@ async function runOnboarding() {
|
|
|
228
228
|
repo = repoAnswers.repo;
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
|
-
// Step 2: GitHub OAuth Setup
|
|
232
|
-
console.log('\n📦 Step 2: GitHub
|
|
233
|
-
console.log('
|
|
234
|
-
console.log('
|
|
235
|
-
|
|
236
|
-
console.log('1. Visit: https://github.com/settings/developers');
|
|
237
|
-
console.log('2. Click "New OAuth App"');
|
|
238
|
-
console.log('3. Fill in the form:');
|
|
239
|
-
console.log(' - Application name: Your app name (e.g., "My Design Comments")');
|
|
240
|
-
console.log(' - Homepage URL: http://localhost:9000 (or your dev server URL)');
|
|
241
|
-
console.log(' - Authorization callback URL: http://localhost:9000/api/github-oauth-callback');
|
|
242
|
-
console.log('4. Click "Register application"');
|
|
243
|
-
console.log('5. Copy the Client ID and generate a Client Secret\n');
|
|
244
|
-
const githubAnswers = await inquirer_1.default.prompt([
|
|
231
|
+
// Step 2: GitHub OAuth Setup (Optional)
|
|
232
|
+
console.log('\n📦 Step 2: GitHub Integration (Optional)\n');
|
|
233
|
+
console.log('GitHub integration allows comments to sync with GitHub Issues.');
|
|
234
|
+
console.log('You can set this up now or add it later.\n');
|
|
235
|
+
const setupGitHub = await inquirer_1.default.prompt([
|
|
245
236
|
{
|
|
246
|
-
type: '
|
|
247
|
-
name: '
|
|
248
|
-
message: 'GitHub
|
|
249
|
-
|
|
250
|
-
if (!input.trim())
|
|
251
|
-
return 'Client ID is required';
|
|
252
|
-
return true;
|
|
253
|
-
}
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
type: 'password',
|
|
257
|
-
name: 'clientSecret',
|
|
258
|
-
message: 'GitHub OAuth Client Secret:',
|
|
259
|
-
mask: '*',
|
|
260
|
-
validate: (input) => {
|
|
261
|
-
if (!input.trim())
|
|
262
|
-
return 'Client Secret is required';
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
237
|
+
type: 'confirm',
|
|
238
|
+
name: 'setup',
|
|
239
|
+
message: 'Do you want to set up GitHub integration now?',
|
|
240
|
+
default: true
|
|
265
241
|
}
|
|
266
242
|
]);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
console.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
type: 'input',
|
|
290
|
-
name: 'baseUrl',
|
|
291
|
-
message: 'Jira Base URL (press Enter for Red Hat Jira):',
|
|
292
|
-
default: 'https://issues.redhat.com',
|
|
293
|
-
validate: (input) => {
|
|
294
|
-
if (!input.trim())
|
|
295
|
-
return 'Base URL is required';
|
|
296
|
-
try {
|
|
297
|
-
new URL(input);
|
|
243
|
+
let githubConfig = null;
|
|
244
|
+
let githubValid = false;
|
|
245
|
+
if (setupGitHub.setup) {
|
|
246
|
+
console.log('\nTo sync comments with GitHub Issues, we need to authenticate with GitHub.');
|
|
247
|
+
console.log('This requires creating a GitHub OAuth App.\n');
|
|
248
|
+
console.log('Instructions:');
|
|
249
|
+
console.log('1. Visit: https://github.com/settings/developers');
|
|
250
|
+
console.log('2. Click "New OAuth App"');
|
|
251
|
+
console.log('3. Fill in the form:');
|
|
252
|
+
console.log(' - Application name: Your app name (e.g., "My Design Comments")');
|
|
253
|
+
console.log(' - Homepage URL: http://localhost:9000 (or your dev server URL)');
|
|
254
|
+
console.log(' - Authorization callback URL: http://localhost:9000/api/github-oauth-callback');
|
|
255
|
+
console.log('4. Click "Register application"');
|
|
256
|
+
console.log('5. Copy the Client ID and generate a Client Secret\n');
|
|
257
|
+
const githubAnswers = await inquirer_1.default.prompt([
|
|
258
|
+
{
|
|
259
|
+
type: 'input',
|
|
260
|
+
name: 'clientId',
|
|
261
|
+
message: 'GitHub OAuth Client ID:',
|
|
262
|
+
validate: (input) => {
|
|
263
|
+
if (!input.trim())
|
|
264
|
+
return 'Client ID is required';
|
|
298
265
|
return true;
|
|
299
266
|
}
|
|
300
|
-
|
|
301
|
-
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
type: 'password',
|
|
270
|
+
name: 'clientSecret',
|
|
271
|
+
message: 'GitHub OAuth Client Secret:',
|
|
272
|
+
mask: '*',
|
|
273
|
+
validate: (input) => {
|
|
274
|
+
if (!input.trim())
|
|
275
|
+
return 'Client Secret is required';
|
|
276
|
+
return true;
|
|
302
277
|
}
|
|
303
278
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (!input.trim())
|
|
312
|
-
return 'API Token is required';
|
|
313
|
-
return true;
|
|
314
|
-
}
|
|
279
|
+
]);
|
|
280
|
+
// Validate GitHub credentials
|
|
281
|
+
console.log('\n🔍 Validating GitHub credentials...');
|
|
282
|
+
githubValid = await validators.validateGitHubCredentials(githubAnswers.clientId, githubAnswers.clientSecret, owner, repo);
|
|
283
|
+
if (!githubValid) {
|
|
284
|
+
console.error('❌ GitHub validation failed. Please check your credentials and try again.');
|
|
285
|
+
process.exit(1);
|
|
315
286
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
console.log('\n🔍 Validating Jira credentials...');
|
|
319
|
-
const jiraValid = await validators.validateJiraCredentials(jiraAnswers.baseUrl, jiraAnswers.apiToken, undefined // No email for Bearer token
|
|
320
|
-
);
|
|
321
|
-
if (!jiraValid) {
|
|
322
|
-
console.error('❌ Jira validation failed. Please check your credentials and try again.');
|
|
323
|
-
process.exit(1);
|
|
324
|
-
}
|
|
325
|
-
console.log('✅ Jira credentials validated!\n');
|
|
326
|
-
// Step 4: Generate files
|
|
327
|
-
console.log('📝 Step 4: Generating configuration files...\n');
|
|
328
|
-
await generators.generateFiles({
|
|
329
|
-
github: {
|
|
287
|
+
console.log('✅ GitHub credentials validated!\n');
|
|
288
|
+
githubConfig = {
|
|
330
289
|
clientId: githubAnswers.clientId,
|
|
331
290
|
clientSecret: githubAnswers.clientSecret,
|
|
332
291
|
owner: owner,
|
|
333
292
|
repo: repo
|
|
334
|
-
}
|
|
335
|
-
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
console.log('\n⏭️ Skipping GitHub setup. You can add it later by editing .env and .env.server files.\n');
|
|
297
|
+
}
|
|
298
|
+
// Step 3: Jira Setup (Optional)
|
|
299
|
+
console.log('🎫 Step 3: Jira Integration (Optional)\n');
|
|
300
|
+
console.log('Jira integration allows you to link Jira tickets to pages in your design.');
|
|
301
|
+
console.log('You can set this up now or add it later.\n');
|
|
302
|
+
const setupJira = await inquirer_1.default.prompt([
|
|
303
|
+
{
|
|
304
|
+
type: 'confirm',
|
|
305
|
+
name: 'setup',
|
|
306
|
+
message: 'Do you want to set up Jira integration now?',
|
|
307
|
+
default: true
|
|
308
|
+
}
|
|
309
|
+
]);
|
|
310
|
+
let jiraConfig = null;
|
|
311
|
+
let jiraValid = false;
|
|
312
|
+
if (setupJira.setup) {
|
|
313
|
+
console.log('\nFor Red Hat Jira, generate a Personal Access Token:');
|
|
314
|
+
console.log('1. Visit: https://issues.redhat.com/secure/ViewProfile.jspa');
|
|
315
|
+
console.log('2. Click "Personal Access Tokens" in the left sidebar');
|
|
316
|
+
console.log('3. Click "Create token"');
|
|
317
|
+
console.log('4. Give it a name (e.g., "Hale Commenting System")');
|
|
318
|
+
console.log('5. Remove expiration (or set a long expiration)');
|
|
319
|
+
console.log('6. Click "Create" and copy the token\n');
|
|
320
|
+
console.log('Note: We use Bearer token authentication (no email required for Red Hat Jira).\n');
|
|
321
|
+
const jiraAnswers = await inquirer_1.default.prompt([
|
|
322
|
+
{
|
|
323
|
+
type: 'input',
|
|
324
|
+
name: 'baseUrl',
|
|
325
|
+
message: 'Jira Base URL (press Enter for Red Hat Jira):',
|
|
326
|
+
default: 'https://issues.redhat.com',
|
|
327
|
+
validate: (input) => {
|
|
328
|
+
if (!input.trim())
|
|
329
|
+
return 'Base URL is required';
|
|
330
|
+
try {
|
|
331
|
+
new URL(input);
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return 'Please enter a valid URL';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
type: 'password',
|
|
341
|
+
name: 'apiToken',
|
|
342
|
+
message: 'Jira API Token:',
|
|
343
|
+
mask: '*',
|
|
344
|
+
validate: (input) => {
|
|
345
|
+
if (!input.trim())
|
|
346
|
+
return 'API Token is required';
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
]);
|
|
351
|
+
// Validate Jira credentials
|
|
352
|
+
console.log('\n🔍 Validating Jira credentials...');
|
|
353
|
+
jiraValid = await validators.validateJiraCredentials(jiraAnswers.baseUrl, jiraAnswers.apiToken, undefined // No email for Bearer token
|
|
354
|
+
);
|
|
355
|
+
if (!jiraValid) {
|
|
356
|
+
console.error('❌ Jira validation failed. Please check your credentials and try again.');
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
console.log('✅ Jira credentials validated!\n');
|
|
360
|
+
jiraConfig = {
|
|
336
361
|
baseUrl: jiraAnswers.baseUrl,
|
|
337
362
|
apiToken: jiraAnswers.apiToken,
|
|
338
|
-
email: undefined
|
|
339
|
-
}
|
|
363
|
+
email: undefined
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
console.log('\n⏭️ Skipping Jira setup. You can add it later by editing .env and .env.server files.\n');
|
|
368
|
+
}
|
|
369
|
+
// Step 4: Generate files
|
|
370
|
+
console.log('📝 Step 4: Generating configuration files...\n');
|
|
371
|
+
await generators.generateFiles({
|
|
372
|
+
github: githubConfig,
|
|
373
|
+
jira: jiraConfig,
|
|
374
|
+
owner: owner,
|
|
375
|
+
repo: repo
|
|
340
376
|
});
|
|
341
377
|
// Step 5: Integrate into project
|
|
342
378
|
console.log('🔧 Step 5: Integrating into PatternFly Seed project...\n');
|
|
@@ -346,4 +382,14 @@ async function runOnboarding() {
|
|
|
346
382
|
console.log('1. Start your dev server: npm run start:dev');
|
|
347
383
|
console.log(' (If it\'s already running, restart it to load the new configuration)');
|
|
348
384
|
console.log('2. The commenting system will be available in your app!\n');
|
|
385
|
+
if (!githubConfig || !jiraConfig) {
|
|
386
|
+
console.log('📝 To add integrations later:');
|
|
387
|
+
if (!githubConfig) {
|
|
388
|
+
console.log(' • GitHub: Edit .env and .env.server files (see comments in files for instructions)');
|
|
389
|
+
}
|
|
390
|
+
if (!jiraConfig) {
|
|
391
|
+
console.log(' • Jira: Edit .env and .env.server files (see comments in files for instructions)');
|
|
392
|
+
}
|
|
393
|
+
console.log(' • Then restart your dev server\n');
|
|
394
|
+
}
|
|
349
395
|
}
|
package/dist/cli/generators.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
interface GitHubConfig {
|
|
2
|
-
clientId
|
|
3
|
-
clientSecret
|
|
4
|
-
owner
|
|
5
|
-
repo
|
|
2
|
+
clientId?: string;
|
|
3
|
+
clientSecret?: string;
|
|
4
|
+
owner?: string;
|
|
5
|
+
repo?: string;
|
|
6
6
|
}
|
|
7
7
|
interface JiraConfig {
|
|
8
|
-
baseUrl
|
|
9
|
-
apiToken
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
apiToken?: string;
|
|
10
10
|
email?: string;
|
|
11
11
|
}
|
|
12
12
|
interface Config {
|
|
13
|
-
github: GitHubConfig;
|
|
14
|
-
jira: JiraConfig;
|
|
13
|
+
github: GitHubConfig | null;
|
|
14
|
+
jira: JiraConfig | null;
|
|
15
|
+
owner: string;
|
|
16
|
+
repo: string;
|
|
15
17
|
}
|
|
16
18
|
export declare function generateFiles(config: Config): Promise<void>;
|
|
17
19
|
export declare function integrateIntoProject(): Promise<void>;
|
package/dist/cli/generators.js
CHANGED
|
@@ -41,16 +41,50 @@ async function generateFiles(config) {
|
|
|
41
41
|
const cwd = process.cwd();
|
|
42
42
|
// Generate .env file (client-safe)
|
|
43
43
|
const envPath = path.join(cwd, '.env');
|
|
44
|
-
|
|
44
|
+
let envContent = `# Hale Commenting System Configuration
|
|
45
|
+
# Client-safe environment variables (these are exposed to the browser)
|
|
46
|
+
|
|
47
|
+
`;
|
|
48
|
+
if (config.github && config.github.clientId) {
|
|
49
|
+
envContent += `# GitHub OAuth (client-side; safe to expose)
|
|
50
|
+
# Get your Client ID from: https://github.com/settings/developers
|
|
51
|
+
# 1. Click "New OAuth App"
|
|
52
|
+
# 2. Fill in the form (Homepage: http://localhost:9000, Callback: http://localhost:9000/api/github-oauth-callback)
|
|
53
|
+
# 3. Copy the Client ID
|
|
45
54
|
VITE_GITHUB_CLIENT_ID=${config.github.clientId}
|
|
46
55
|
|
|
47
56
|
# Target repo for Issues/Comments
|
|
48
|
-
VITE_GITHUB_OWNER=${config.github.owner}
|
|
49
|
-
VITE_GITHUB_REPO=${config.github.repo}
|
|
57
|
+
VITE_GITHUB_OWNER=${config.github.owner || config.owner}
|
|
58
|
+
VITE_GITHUB_REPO=${config.github.repo || config.repo}
|
|
59
|
+
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
envContent += `# GitHub OAuth (client-side; safe to expose)
|
|
64
|
+
# Get your Client ID from: https://github.com/settings/developers
|
|
65
|
+
# 1. Click "New OAuth App"
|
|
66
|
+
# 2. Fill in the form (Homepage: http://localhost:9000, Callback: http://localhost:9000/api/github-oauth-callback)
|
|
67
|
+
# 3. Copy the Client ID
|
|
68
|
+
VITE_GITHUB_CLIENT_ID=
|
|
69
|
+
|
|
70
|
+
# Target repo for Issues/Comments
|
|
71
|
+
VITE_GITHUB_OWNER=${config.owner}
|
|
72
|
+
VITE_GITHUB_REPO=${config.repo}
|
|
50
73
|
|
|
51
|
-
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
if (config.jira && config.jira.baseUrl) {
|
|
77
|
+
envContent += `# Jira Base URL
|
|
78
|
+
# For Red Hat Jira, use: https://issues.redhat.com
|
|
52
79
|
VITE_JIRA_BASE_URL=${config.jira.baseUrl}
|
|
53
80
|
`;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
envContent += `# Jira Base URL
|
|
84
|
+
# For Red Hat Jira, use: https://issues.redhat.com
|
|
85
|
+
VITE_JIRA_BASE_URL=
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
54
88
|
// Check if .env exists and append or create
|
|
55
89
|
if (fs.existsSync(envPath)) {
|
|
56
90
|
const existing = fs.readFileSync(envPath, 'utf-8');
|
|
@@ -67,15 +101,56 @@ VITE_JIRA_BASE_URL=${config.jira.baseUrl}
|
|
|
67
101
|
fs.writeFileSync(envPath, envContent);
|
|
68
102
|
console.log(' ✅ Created .env file');
|
|
69
103
|
}
|
|
104
|
+
// Note about empty values
|
|
105
|
+
if (!config.github || !config.jira) {
|
|
106
|
+
console.log(' ℹ️ Some values are empty - see comments in .env for setup instructions');
|
|
107
|
+
}
|
|
70
108
|
// Generate .env.server file (secrets)
|
|
71
109
|
const envServerPath = path.join(cwd, '.env.server');
|
|
72
|
-
let envServerContent = `#
|
|
110
|
+
let envServerContent = `# Hale Commenting System - Server Secrets
|
|
111
|
+
# ⚠️ DO NOT COMMIT THIS FILE - It contains sensitive credentials
|
|
112
|
+
# This file is automatically added to .gitignore
|
|
113
|
+
|
|
114
|
+
`;
|
|
115
|
+
if (config.github && config.github.clientSecret) {
|
|
116
|
+
envServerContent += `# GitHub OAuth Client Secret (server-only)
|
|
117
|
+
# Get this from your GitHub OAuth App settings: https://github.com/settings/developers
|
|
118
|
+
# Click on your OAuth App, then "Generate a new client secret"
|
|
73
119
|
GITHUB_CLIENT_SECRET=${config.github.clientSecret}
|
|
74
120
|
|
|
75
|
-
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
envServerContent += `# GitHub OAuth Client Secret (server-only)
|
|
125
|
+
# Get this from your GitHub OAuth App settings: https://github.com/settings/developers
|
|
126
|
+
# Click on your OAuth App, then "Generate a new client secret"
|
|
127
|
+
GITHUB_CLIENT_SECRET=
|
|
128
|
+
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
if (config.jira && config.jira.apiToken) {
|
|
132
|
+
envServerContent += `# Jira API Token (server-only)
|
|
133
|
+
# For Red Hat Jira, generate a Personal Access Token:
|
|
134
|
+
# 1. Visit: https://issues.redhat.com/secure/ViewProfile.jspa
|
|
135
|
+
# 2. Click "Personal Access Tokens" in the left sidebar
|
|
136
|
+
# 3. Click "Create token"
|
|
137
|
+
# 4. Give it a name and remove expiration
|
|
138
|
+
# 5. Copy the token
|
|
76
139
|
JIRA_API_TOKEN=${config.jira.apiToken}
|
|
77
140
|
`;
|
|
78
|
-
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
envServerContent += `# Jira API Token (server-only)
|
|
144
|
+
# For Red Hat Jira, generate a Personal Access Token:
|
|
145
|
+
# 1. Visit: https://issues.redhat.com/secure/ViewProfile.jspa
|
|
146
|
+
# 2. Click "Personal Access Tokens" in the left sidebar
|
|
147
|
+
# 3. Click "Create token"
|
|
148
|
+
# 4. Give it a name and remove expiration
|
|
149
|
+
# 5. Copy the token
|
|
150
|
+
JIRA_API_TOKEN=
|
|
151
|
+
`;
|
|
152
|
+
}
|
|
153
|
+
if (config.jira && config.jira.email) {
|
|
79
154
|
envServerContent += `JIRA_EMAIL=${config.jira.email}\n`;
|
|
80
155
|
}
|
|
81
156
|
if (fs.existsSync(envServerPath)) {
|
|
@@ -92,6 +167,10 @@ JIRA_API_TOKEN=${config.jira.apiToken}
|
|
|
92
167
|
fs.writeFileSync(envServerPath, envServerContent);
|
|
93
168
|
console.log(' ✅ Created .env.server file');
|
|
94
169
|
}
|
|
170
|
+
// Note about empty values
|
|
171
|
+
if (!config.github || !config.jira) {
|
|
172
|
+
console.log(' ℹ️ Some values are empty - see comments in .env.server for setup instructions');
|
|
173
|
+
}
|
|
95
174
|
// Ensure .env.server is in .gitignore
|
|
96
175
|
const gitignorePath = path.join(cwd, '.gitignore');
|
|
97
176
|
if (fs.existsSync(gitignorePath)) {
|
package/dist/cli/onboarding.js
CHANGED
|
@@ -228,115 +228,151 @@ async function runOnboarding() {
|
|
|
228
228
|
repo = repoAnswers.repo;
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
|
-
// Step 2: GitHub OAuth Setup
|
|
232
|
-
console.log('\n📦 Step 2: GitHub
|
|
233
|
-
console.log('
|
|
234
|
-
console.log('
|
|
235
|
-
|
|
236
|
-
console.log('1. Visit: https://github.com/settings/developers');
|
|
237
|
-
console.log('2. Click "New OAuth App"');
|
|
238
|
-
console.log('3. Fill in the form:');
|
|
239
|
-
console.log(' - Application name: Your app name (e.g., "My Design Comments")');
|
|
240
|
-
console.log(' - Homepage URL: http://localhost:9000 (or your dev server URL)');
|
|
241
|
-
console.log(' - Authorization callback URL: http://localhost:9000/api/github-oauth-callback');
|
|
242
|
-
console.log('4. Click "Register application"');
|
|
243
|
-
console.log('5. Copy the Client ID and generate a Client Secret\n');
|
|
244
|
-
const githubAnswers = await inquirer_1.default.prompt([
|
|
231
|
+
// Step 2: GitHub OAuth Setup (Optional)
|
|
232
|
+
console.log('\n📦 Step 2: GitHub Integration (Optional)\n');
|
|
233
|
+
console.log('GitHub integration allows comments to sync with GitHub Issues.');
|
|
234
|
+
console.log('You can set this up now or add it later.\n');
|
|
235
|
+
const setupGitHub = await inquirer_1.default.prompt([
|
|
245
236
|
{
|
|
246
|
-
type: '
|
|
247
|
-
name: '
|
|
248
|
-
message: 'GitHub
|
|
249
|
-
|
|
250
|
-
if (!input.trim())
|
|
251
|
-
return 'Client ID is required';
|
|
252
|
-
return true;
|
|
253
|
-
}
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
type: 'password',
|
|
257
|
-
name: 'clientSecret',
|
|
258
|
-
message: 'GitHub OAuth Client Secret:',
|
|
259
|
-
mask: '*',
|
|
260
|
-
validate: (input) => {
|
|
261
|
-
if (!input.trim())
|
|
262
|
-
return 'Client Secret is required';
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
237
|
+
type: 'confirm',
|
|
238
|
+
name: 'setup',
|
|
239
|
+
message: 'Do you want to set up GitHub integration now?',
|
|
240
|
+
default: true
|
|
265
241
|
}
|
|
266
242
|
]);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
console.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
type: 'input',
|
|
290
|
-
name: 'baseUrl',
|
|
291
|
-
message: 'Jira Base URL (press Enter for Red Hat Jira):',
|
|
292
|
-
default: 'https://issues.redhat.com',
|
|
293
|
-
validate: (input) => {
|
|
294
|
-
if (!input.trim())
|
|
295
|
-
return 'Base URL is required';
|
|
296
|
-
try {
|
|
297
|
-
new URL(input);
|
|
243
|
+
let githubConfig = null;
|
|
244
|
+
let githubValid = false;
|
|
245
|
+
if (setupGitHub.setup) {
|
|
246
|
+
console.log('\nTo sync comments with GitHub Issues, we need to authenticate with GitHub.');
|
|
247
|
+
console.log('This requires creating a GitHub OAuth App.\n');
|
|
248
|
+
console.log('Instructions:');
|
|
249
|
+
console.log('1. Visit: https://github.com/settings/developers');
|
|
250
|
+
console.log('2. Click "New OAuth App"');
|
|
251
|
+
console.log('3. Fill in the form:');
|
|
252
|
+
console.log(' - Application name: Your app name (e.g., "My Design Comments")');
|
|
253
|
+
console.log(' - Homepage URL: http://localhost:9000 (or your dev server URL)');
|
|
254
|
+
console.log(' - Authorization callback URL: http://localhost:9000/api/github-oauth-callback');
|
|
255
|
+
console.log('4. Click "Register application"');
|
|
256
|
+
console.log('5. Copy the Client ID and generate a Client Secret\n');
|
|
257
|
+
const githubAnswers = await inquirer_1.default.prompt([
|
|
258
|
+
{
|
|
259
|
+
type: 'input',
|
|
260
|
+
name: 'clientId',
|
|
261
|
+
message: 'GitHub OAuth Client ID:',
|
|
262
|
+
validate: (input) => {
|
|
263
|
+
if (!input.trim())
|
|
264
|
+
return 'Client ID is required';
|
|
298
265
|
return true;
|
|
299
266
|
}
|
|
300
|
-
|
|
301
|
-
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
type: 'password',
|
|
270
|
+
name: 'clientSecret',
|
|
271
|
+
message: 'GitHub OAuth Client Secret:',
|
|
272
|
+
mask: '*',
|
|
273
|
+
validate: (input) => {
|
|
274
|
+
if (!input.trim())
|
|
275
|
+
return 'Client Secret is required';
|
|
276
|
+
return true;
|
|
302
277
|
}
|
|
303
278
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (!input.trim())
|
|
312
|
-
return 'API Token is required';
|
|
313
|
-
return true;
|
|
314
|
-
}
|
|
279
|
+
]);
|
|
280
|
+
// Validate GitHub credentials
|
|
281
|
+
console.log('\n🔍 Validating GitHub credentials...');
|
|
282
|
+
githubValid = await validators.validateGitHubCredentials(githubAnswers.clientId, githubAnswers.clientSecret, owner, repo);
|
|
283
|
+
if (!githubValid) {
|
|
284
|
+
console.error('❌ GitHub validation failed. Please check your credentials and try again.');
|
|
285
|
+
process.exit(1);
|
|
315
286
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
console.log('\n🔍 Validating Jira credentials...');
|
|
319
|
-
const jiraValid = await validators.validateJiraCredentials(jiraAnswers.baseUrl, jiraAnswers.apiToken, undefined // No email for Bearer token
|
|
320
|
-
);
|
|
321
|
-
if (!jiraValid) {
|
|
322
|
-
console.error('❌ Jira validation failed. Please check your credentials and try again.');
|
|
323
|
-
process.exit(1);
|
|
324
|
-
}
|
|
325
|
-
console.log('✅ Jira credentials validated!\n');
|
|
326
|
-
// Step 4: Generate files
|
|
327
|
-
console.log('📝 Step 4: Generating configuration files...\n');
|
|
328
|
-
await generators.generateFiles({
|
|
329
|
-
github: {
|
|
287
|
+
console.log('✅ GitHub credentials validated!\n');
|
|
288
|
+
githubConfig = {
|
|
330
289
|
clientId: githubAnswers.clientId,
|
|
331
290
|
clientSecret: githubAnswers.clientSecret,
|
|
332
291
|
owner: owner,
|
|
333
292
|
repo: repo
|
|
334
|
-
}
|
|
335
|
-
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
console.log('\n⏭️ Skipping GitHub setup. You can add it later by editing .env and .env.server files.\n');
|
|
297
|
+
}
|
|
298
|
+
// Step 3: Jira Setup (Optional)
|
|
299
|
+
console.log('🎫 Step 3: Jira Integration (Optional)\n');
|
|
300
|
+
console.log('Jira integration allows you to link Jira tickets to pages in your design.');
|
|
301
|
+
console.log('You can set this up now or add it later.\n');
|
|
302
|
+
const setupJira = await inquirer_1.default.prompt([
|
|
303
|
+
{
|
|
304
|
+
type: 'confirm',
|
|
305
|
+
name: 'setup',
|
|
306
|
+
message: 'Do you want to set up Jira integration now?',
|
|
307
|
+
default: true
|
|
308
|
+
}
|
|
309
|
+
]);
|
|
310
|
+
let jiraConfig = null;
|
|
311
|
+
let jiraValid = false;
|
|
312
|
+
if (setupJira.setup) {
|
|
313
|
+
console.log('\nFor Red Hat Jira, generate a Personal Access Token:');
|
|
314
|
+
console.log('1. Visit: https://issues.redhat.com/secure/ViewProfile.jspa');
|
|
315
|
+
console.log('2. Click "Personal Access Tokens" in the left sidebar');
|
|
316
|
+
console.log('3. Click "Create token"');
|
|
317
|
+
console.log('4. Give it a name (e.g., "Hale Commenting System")');
|
|
318
|
+
console.log('5. Remove expiration (or set a long expiration)');
|
|
319
|
+
console.log('6. Click "Create" and copy the token\n');
|
|
320
|
+
console.log('Note: We use Bearer token authentication (no email required for Red Hat Jira).\n');
|
|
321
|
+
const jiraAnswers = await inquirer_1.default.prompt([
|
|
322
|
+
{
|
|
323
|
+
type: 'input',
|
|
324
|
+
name: 'baseUrl',
|
|
325
|
+
message: 'Jira Base URL (press Enter for Red Hat Jira):',
|
|
326
|
+
default: 'https://issues.redhat.com',
|
|
327
|
+
validate: (input) => {
|
|
328
|
+
if (!input.trim())
|
|
329
|
+
return 'Base URL is required';
|
|
330
|
+
try {
|
|
331
|
+
new URL(input);
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return 'Please enter a valid URL';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
type: 'password',
|
|
341
|
+
name: 'apiToken',
|
|
342
|
+
message: 'Jira API Token:',
|
|
343
|
+
mask: '*',
|
|
344
|
+
validate: (input) => {
|
|
345
|
+
if (!input.trim())
|
|
346
|
+
return 'API Token is required';
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
]);
|
|
351
|
+
// Validate Jira credentials
|
|
352
|
+
console.log('\n🔍 Validating Jira credentials...');
|
|
353
|
+
jiraValid = await validators.validateJiraCredentials(jiraAnswers.baseUrl, jiraAnswers.apiToken, undefined // No email for Bearer token
|
|
354
|
+
);
|
|
355
|
+
if (!jiraValid) {
|
|
356
|
+
console.error('❌ Jira validation failed. Please check your credentials and try again.');
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
console.log('✅ Jira credentials validated!\n');
|
|
360
|
+
jiraConfig = {
|
|
336
361
|
baseUrl: jiraAnswers.baseUrl,
|
|
337
362
|
apiToken: jiraAnswers.apiToken,
|
|
338
|
-
email: undefined
|
|
339
|
-
}
|
|
363
|
+
email: undefined
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
console.log('\n⏭️ Skipping Jira setup. You can add it later by editing .env and .env.server files.\n');
|
|
368
|
+
}
|
|
369
|
+
// Step 4: Generate files
|
|
370
|
+
console.log('📝 Step 4: Generating configuration files...\n');
|
|
371
|
+
await generators.generateFiles({
|
|
372
|
+
github: githubConfig,
|
|
373
|
+
jira: jiraConfig,
|
|
374
|
+
owner: owner,
|
|
375
|
+
repo: repo
|
|
340
376
|
});
|
|
341
377
|
// Step 5: Integrate into project
|
|
342
378
|
console.log('🔧 Step 5: Integrating into PatternFly Seed project...\n');
|
|
@@ -346,4 +382,14 @@ async function runOnboarding() {
|
|
|
346
382
|
console.log('1. Start your dev server: npm run start:dev');
|
|
347
383
|
console.log(' (If it\'s already running, restart it to load the new configuration)');
|
|
348
384
|
console.log('2. The commenting system will be available in your app!\n');
|
|
385
|
+
if (!githubConfig || !jiraConfig) {
|
|
386
|
+
console.log('📝 To add integrations later:');
|
|
387
|
+
if (!githubConfig) {
|
|
388
|
+
console.log(' • GitHub: Edit .env and .env.server files (see comments in files for instructions)');
|
|
389
|
+
}
|
|
390
|
+
if (!jiraConfig) {
|
|
391
|
+
console.log(' • Jira: Edit .env and .env.server files (see comments in files for instructions)');
|
|
392
|
+
}
|
|
393
|
+
console.log(' • Then restart your dev server\n');
|
|
394
|
+
}
|
|
349
395
|
}
|