hale-commenting-system 3.8.1 → 3.8.4
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/package.json +5 -1
- package/scripts/integrate.js +215 -81
- package/scripts/remove.js +32 -7
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hale-commenting-system",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.4",
|
|
4
4
|
"description": "A commenting system for PatternFly React applications that allows designers and developers to add comments directly on design pages, sync with GitHub Issues, and link Jira tickets.",
|
|
5
5
|
"homepage": "https://www.npmjs.com/package/hale-commenting-system",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://gitlab.cee.redhat.com/juhale/hale-commenting-system.git"
|
|
9
|
+
},
|
|
6
10
|
"license": "MIT",
|
|
7
11
|
"main": "src/app/commenting-system/index.ts",
|
|
8
12
|
"types": "src/app/commenting-system/index.ts",
|
package/scripts/integrate.js
CHANGED
|
@@ -170,6 +170,36 @@ function findFile(filename, startDir = process.cwd()) {
|
|
|
170
170
|
// Detection Functions
|
|
171
171
|
// ============================================================================
|
|
172
172
|
|
|
173
|
+
function getDevServerPort() {
|
|
174
|
+
// Check environment variable first
|
|
175
|
+
if (process.env.PORT) {
|
|
176
|
+
return process.env.PORT;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Try to read from webpack.dev.js
|
|
180
|
+
try {
|
|
181
|
+
const webpackDevPath = path.join(process.cwd(), 'webpack.dev.js');
|
|
182
|
+
if (fs.existsSync(webpackDevPath)) {
|
|
183
|
+
const content = fs.readFileSync(webpackDevPath, 'utf8');
|
|
184
|
+
// Check for PORT env var pattern: process.env.PORT || '9000'
|
|
185
|
+
const envPortMatch = content.match(/process\.env\.PORT\s*\|\|\s*['"]?(\d+)['"]?/);
|
|
186
|
+
if (envPortMatch) {
|
|
187
|
+
return envPortMatch[1];
|
|
188
|
+
}
|
|
189
|
+
// Check for direct port assignment: port: PORT or port: '9000'
|
|
190
|
+
const portMatch = content.match(/port:\s*(?:PORT|['"]?(\d+)['"]?)/);
|
|
191
|
+
if (portMatch && portMatch[1]) {
|
|
192
|
+
return portMatch[1];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} catch {
|
|
196
|
+
// Ignore errors
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Default fallback
|
|
200
|
+
return '9000';
|
|
201
|
+
}
|
|
202
|
+
|
|
173
203
|
function detectPatternFlySeed() {
|
|
174
204
|
const cwd = process.cwd();
|
|
175
205
|
|
|
@@ -188,7 +218,11 @@ function detectPatternFlySeed() {
|
|
|
188
218
|
const packageJsonPath = path.join(cwd, 'package.json');
|
|
189
219
|
if (fs.existsSync(packageJsonPath)) {
|
|
190
220
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
191
|
-
const deps = {
|
|
221
|
+
const deps = {
|
|
222
|
+
...packageJson.dependencies,
|
|
223
|
+
...packageJson.devDependencies,
|
|
224
|
+
...packageJson.peerDependencies
|
|
225
|
+
};
|
|
192
226
|
hasPatternFly = !!(
|
|
193
227
|
deps['@patternfly/react-core'] ||
|
|
194
228
|
deps['@patternfly/react-icons']
|
|
@@ -927,6 +961,82 @@ devServer.app.use(express.json());
|
|
|
927
961
|
}
|
|
928
962
|
}
|
|
929
963
|
|
|
964
|
+
function fixWebpackCssLoader() {
|
|
965
|
+
const cwd = process.cwd();
|
|
966
|
+
const webpackDevPath = path.join(cwd, 'webpack.dev.js');
|
|
967
|
+
const webpackCommonPath = path.join(cwd, 'webpack.common.js');
|
|
968
|
+
|
|
969
|
+
// Try to fix CSS loader in webpack.dev.js or webpack.common.js
|
|
970
|
+
const filesToCheck = [webpackDevPath, webpackCommonPath].filter(f => fs.existsSync(f));
|
|
971
|
+
|
|
972
|
+
for (const filePath of filesToCheck) {
|
|
973
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
974
|
+
|
|
975
|
+
// Check if CSS loader already has exclude for nested node_modules
|
|
976
|
+
if (content.includes('exclude') && content.includes('node_modules') && content.includes('node_modules')) {
|
|
977
|
+
// Already has exclude pattern, skip
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// Look for CSS loader rule patterns
|
|
982
|
+
const cssLoaderPatterns = [
|
|
983
|
+
// Pattern 1: test: /\.css$/
|
|
984
|
+
/(test:\s*\/\\\.css\\\$\/[,\s]*)/,
|
|
985
|
+
// Pattern 2: test: /\.css$/i
|
|
986
|
+
/(test:\s*\/\\\.css\\\$\/i[,\s]*)/,
|
|
987
|
+
// Pattern 3: test: /\.css$/, with include
|
|
988
|
+
/(test:\s*\/\\\.css\\\$\/[,\s]*\n\s*include:)/,
|
|
989
|
+
];
|
|
990
|
+
|
|
991
|
+
let modified = false;
|
|
992
|
+
for (const pattern of cssLoaderPatterns) {
|
|
993
|
+
const match = content.match(pattern);
|
|
994
|
+
if (match) {
|
|
995
|
+
// Add exclude after the test pattern
|
|
996
|
+
const excludePattern = match[1] + '\n exclude: /node_modules\\/.*\\/node_modules\\//,';
|
|
997
|
+
content = content.replace(pattern, excludePattern);
|
|
998
|
+
modified = true;
|
|
999
|
+
break;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
// Also try to find CSS rules in module.rules array
|
|
1004
|
+
if (!modified) {
|
|
1005
|
+
// Look for CSS rules that use stylePaths or include patterns
|
|
1006
|
+
// Pattern: test: /\.css$/, followed by include: [...stylePaths]
|
|
1007
|
+
// Match: test: /\.css$/, (with optional comma and whitespace)
|
|
1008
|
+
// newline and indentation
|
|
1009
|
+
// include: [...stylePaths]
|
|
1010
|
+
const cssRuleWithIncludePattern = /(test:\s*\/\\?\.css\$\/,?\s*\n\s*)(include:\s*\[.*?stylePaths)/s;
|
|
1011
|
+
const match = content.match(cssRuleWithIncludePattern);
|
|
1012
|
+
if (match) {
|
|
1013
|
+
// Add exclude between test and include
|
|
1014
|
+
const excludeLine = ' exclude: /node_modules\\/.*\\/node_modules\\//,\n';
|
|
1015
|
+
content = content.replace(cssRuleWithIncludePattern, match[1] + excludeLine + match[2]);
|
|
1016
|
+
modified = true;
|
|
1017
|
+
} else {
|
|
1018
|
+
// Try a more flexible pattern - look for any CSS rule with include
|
|
1019
|
+
// Match test: /\.css$/ (with or without backslash escape) followed by include:
|
|
1020
|
+
const flexiblePattern = /(test:\s*\/\\?\.css\$\/,?\s*\n\s*)(include:)/;
|
|
1021
|
+
const flexibleMatch = content.match(flexiblePattern);
|
|
1022
|
+
if (flexibleMatch) {
|
|
1023
|
+
const excludeLine = ' exclude: /node_modules\\/.*\\/node_modules\\//,\n';
|
|
1024
|
+
content = content.replace(flexiblePattern, flexibleMatch[1] + excludeLine + flexibleMatch[2]);
|
|
1025
|
+
modified = true;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
if (modified) {
|
|
1031
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
1032
|
+
console.log(` ✅ Updated CSS loader in ${path.basename(filePath)} to exclude nested node_modules`);
|
|
1033
|
+
return true;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
return false;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
930
1040
|
function getPackageVersion() {
|
|
931
1041
|
try {
|
|
932
1042
|
// Get the script's directory and find package.json relative to it
|
|
@@ -954,8 +1064,8 @@ function getPackageVersion() {
|
|
|
954
1064
|
function modifyIndexTsx(filePath) {
|
|
955
1065
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
956
1066
|
|
|
957
|
-
// Check if already integrated
|
|
958
|
-
if (content.includes('CommentProvider') && content.includes('GitHubAuthProvider')) {
|
|
1067
|
+
// Check if already integrated (look for ProviderAuthProvider or GitHubAuthProvider for backward compat)
|
|
1068
|
+
if (content.includes('CommentProvider') && (content.includes('ProviderAuthProvider') || content.includes('GitHubAuthProvider'))) {
|
|
959
1069
|
console.log(' ⚠️ Already integrated (providers found)');
|
|
960
1070
|
return false;
|
|
961
1071
|
}
|
|
@@ -967,8 +1077,9 @@ function modifyIndexTsx(filePath) {
|
|
|
967
1077
|
});
|
|
968
1078
|
|
|
969
1079
|
let hasCommentProvider = false;
|
|
970
|
-
let
|
|
1080
|
+
let hasProviderAuthProvider = false;
|
|
971
1081
|
let hasCommentImport = false;
|
|
1082
|
+
let importSource = 'hale-commenting-system'; // Default import path
|
|
972
1083
|
let routerElement = null;
|
|
973
1084
|
|
|
974
1085
|
// Check existing imports and find Router element
|
|
@@ -977,13 +1088,21 @@ function modifyIndexTsx(filePath) {
|
|
|
977
1088
|
const source = path.node.source.value;
|
|
978
1089
|
if (source.includes('commenting-system') || source.includes('@app/commenting-system') || source.includes('hale-commenting-system')) {
|
|
979
1090
|
hasCommentImport = true;
|
|
1091
|
+
// Detect the import path being used
|
|
1092
|
+
// Always prefer 'hale-commenting-system' over '@app/commenting-system'
|
|
1093
|
+
if (source.includes('hale-commenting-system')) {
|
|
1094
|
+
importSource = 'hale-commenting-system';
|
|
1095
|
+
} else if (source.includes('@app/commenting-system')) {
|
|
1096
|
+
// If old @app/ path is found, we'll update it to hale-commenting-system
|
|
1097
|
+
importSource = 'hale-commenting-system';
|
|
1098
|
+
}
|
|
980
1099
|
// Check if providers are imported
|
|
981
1100
|
path.node.specifiers.forEach(spec => {
|
|
982
1101
|
if (spec.imported && spec.imported.name === 'CommentProvider') {
|
|
983
1102
|
hasCommentProvider = true;
|
|
984
1103
|
}
|
|
985
|
-
if (spec.imported && spec.imported.name === 'GitHubAuthProvider') {
|
|
986
|
-
|
|
1104
|
+
if (spec.imported && (spec.imported.name === 'ProviderAuthProvider' || spec.imported.name === 'GitHubAuthProvider')) {
|
|
1105
|
+
hasProviderAuthProvider = true;
|
|
987
1106
|
}
|
|
988
1107
|
});
|
|
989
1108
|
}
|
|
@@ -995,6 +1114,11 @@ function modifyIndexTsx(filePath) {
|
|
|
995
1114
|
}
|
|
996
1115
|
});
|
|
997
1116
|
|
|
1117
|
+
// Always use 'hale-commenting-system' as the package name
|
|
1118
|
+
// Don't use @app/ alias even if it exists in the file - the package
|
|
1119
|
+
// should be imported by its npm package name, not a path alias
|
|
1120
|
+
importSource = 'hale-commenting-system';
|
|
1121
|
+
|
|
998
1122
|
// Add imports if missing
|
|
999
1123
|
if (!hasCommentImport) {
|
|
1000
1124
|
// Find last import declaration
|
|
@@ -1010,24 +1134,28 @@ function modifyIndexTsx(filePath) {
|
|
|
1010
1134
|
const providerImports = types.importDeclaration(
|
|
1011
1135
|
[
|
|
1012
1136
|
types.importSpecifier(types.identifier('CommentProvider'), types.identifier('CommentProvider')),
|
|
1013
|
-
types.importSpecifier(types.identifier('
|
|
1137
|
+
types.importSpecifier(types.identifier('ProviderAuthProvider'), types.identifier('ProviderAuthProvider'))
|
|
1014
1138
|
],
|
|
1015
|
-
types.stringLiteral(
|
|
1139
|
+
types.stringLiteral(importSource)
|
|
1016
1140
|
);
|
|
1017
1141
|
|
|
1018
1142
|
ast.program.body.splice(importIndex, 0, providerImports);
|
|
1019
|
-
} else if (!hasCommentProvider || !
|
|
1020
|
-
// Update existing import
|
|
1143
|
+
} else if (!hasCommentProvider || !hasProviderAuthProvider) {
|
|
1144
|
+
// Update existing import - also fix @app/commenting-system to hale-commenting-system
|
|
1021
1145
|
traverse(ast, {
|
|
1022
1146
|
ImportDeclaration(path) {
|
|
1023
1147
|
const source = path.node.source.value;
|
|
1024
1148
|
if (source.includes('commenting-system') || source.includes('@app/commenting-system') || source.includes('hale-commenting-system')) {
|
|
1149
|
+
// Update import source to use hale-commenting-system if it's using @app/ path
|
|
1150
|
+
if (source.includes('@app/commenting-system')) {
|
|
1151
|
+
path.node.source.value = 'hale-commenting-system';
|
|
1152
|
+
}
|
|
1025
1153
|
const specifiers = path.node.specifiers || [];
|
|
1026
1154
|
if (!hasCommentProvider) {
|
|
1027
1155
|
specifiers.push(types.importSpecifier(types.identifier('CommentProvider'), types.identifier('CommentProvider')));
|
|
1028
1156
|
}
|
|
1029
|
-
if (!
|
|
1030
|
-
specifiers.push(types.importSpecifier(types.identifier('
|
|
1157
|
+
if (!hasProviderAuthProvider) {
|
|
1158
|
+
specifiers.push(types.importSpecifier(types.identifier('ProviderAuthProvider'), types.identifier('ProviderAuthProvider')));
|
|
1031
1159
|
}
|
|
1032
1160
|
path.node.specifiers = specifiers;
|
|
1033
1161
|
}
|
|
@@ -1039,28 +1167,30 @@ function modifyIndexTsx(filePath) {
|
|
|
1039
1167
|
if (routerElement) {
|
|
1040
1168
|
const routerChildren = routerElement.node.children;
|
|
1041
1169
|
|
|
1042
|
-
// Check if already wrapped
|
|
1170
|
+
// Check if already wrapped (check for ProviderAuthProvider or GitHubAuthProvider)
|
|
1043
1171
|
if (routerChildren.length > 0 &&
|
|
1044
|
-
routerChildren[0].type === 'JSXElement'
|
|
1045
|
-
|
|
1172
|
+
routerChildren[0].type === 'JSXElement') {
|
|
1173
|
+
const firstChildName = routerChildren[0].openingElement.name.name;
|
|
1174
|
+
if (firstChildName === 'ProviderAuthProvider' || firstChildName === 'GitHubAuthProvider') {
|
|
1046
1175
|
console.log(' ⚠️ Already integrated (providers found in JSX)');
|
|
1047
1176
|
return false;
|
|
1177
|
+
}
|
|
1048
1178
|
}
|
|
1049
1179
|
|
|
1050
|
-
// Create provider wrappers
|
|
1180
|
+
// Create provider wrappers in correct order: ProviderAuthProvider -> CommentProvider -> content
|
|
1051
1181
|
const commentProvider = types.jsxElement(
|
|
1052
1182
|
types.jsxOpeningElement(types.jsxIdentifier('CommentProvider'), []),
|
|
1053
1183
|
types.jsxClosingElement(types.jsxIdentifier('CommentProvider')),
|
|
1054
1184
|
routerChildren
|
|
1055
1185
|
);
|
|
1056
1186
|
|
|
1057
|
-
const
|
|
1058
|
-
types.jsxOpeningElement(types.jsxIdentifier('
|
|
1059
|
-
types.jsxClosingElement(types.jsxIdentifier('
|
|
1187
|
+
const providerAuthProvider = types.jsxElement(
|
|
1188
|
+
types.jsxOpeningElement(types.jsxIdentifier('ProviderAuthProvider'), []),
|
|
1189
|
+
types.jsxClosingElement(types.jsxIdentifier('ProviderAuthProvider')),
|
|
1060
1190
|
[commentProvider]
|
|
1061
1191
|
);
|
|
1062
1192
|
|
|
1063
|
-
routerElement.node.children = [
|
|
1193
|
+
routerElement.node.children = [providerAuthProvider];
|
|
1064
1194
|
}
|
|
1065
1195
|
|
|
1066
1196
|
const output = generate(ast, {
|
|
@@ -1198,7 +1328,7 @@ async function main() {
|
|
|
1198
1328
|
console.log(' • Sync comments with GitLab Issues (or GitHub)');
|
|
1199
1329
|
console.log(' • Link Jira tickets to pages');
|
|
1200
1330
|
console.log(' • Store design goals and context\n');
|
|
1201
|
-
|
|
1331
|
+
|
|
1202
1332
|
console.log('Why GitLab?');
|
|
1203
1333
|
console.log(' We use GitLab Issues to store and sync all comments. When you add a comment');
|
|
1204
1334
|
console.log(' on a page, it creates a GitLab Issue. This allows comments to persist, sync');
|
|
@@ -1247,6 +1377,21 @@ async function main() {
|
|
|
1247
1377
|
process.exit(1);
|
|
1248
1378
|
}
|
|
1249
1379
|
|
|
1380
|
+
// Check if the package is installed
|
|
1381
|
+
const cwd = process.cwd();
|
|
1382
|
+
const packageJsonPath = path.join(cwd, 'package.json');
|
|
1383
|
+
const nodeModulesPath = path.join(cwd, 'node_modules', 'hale-commenting-system');
|
|
1384
|
+
|
|
1385
|
+
if (!fs.existsSync(nodeModulesPath)) {
|
|
1386
|
+
console.error('\n❌ Error: hale-commenting-system is not installed.');
|
|
1387
|
+
console.error('Please install it first:');
|
|
1388
|
+
console.error(' npm install hale-commenting-system');
|
|
1389
|
+
console.error('Then run this command again:');
|
|
1390
|
+
console.error(' npx hale-commenting-system init\n');
|
|
1391
|
+
rl.close();
|
|
1392
|
+
process.exit(1);
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1250
1395
|
// Detect project setup type
|
|
1251
1396
|
const gitInfo = detectGitRemote();
|
|
1252
1397
|
const setupType = detectProjectSetup();
|
|
@@ -1263,7 +1408,7 @@ async function main() {
|
|
|
1263
1408
|
name: 'setupType',
|
|
1264
1409
|
message: 'How did you set up your PatternFly Seed project?',
|
|
1265
1410
|
choices: [
|
|
1266
|
-
{ name: 'I forked the PatternFly Seed repo
|
|
1411
|
+
{ name: 'I forked the PatternFly Seed repo', value: 'forked' },
|
|
1267
1412
|
{ name: 'I cloned the PatternFly Seed repo locally', value: 'cloned' },
|
|
1268
1413
|
{ name: 'I\'m not sure', value: 'unknown' }
|
|
1269
1414
|
]
|
|
@@ -1306,53 +1451,12 @@ async function main() {
|
|
|
1306
1451
|
console.log(`\n✅ Detected repository: ${owner}/${repo}\n`);
|
|
1307
1452
|
}
|
|
1308
1453
|
} else if (projectSetup === 'cloned') {
|
|
1309
|
-
console.log('\n📝 Since you cloned the repo, you can create your own
|
|
1310
|
-
console.log('Note: This is optional! You can test the system locally first and add
|
|
1311
|
-
|
|
1312
|
-
console.log('1. Create a new repository on GitHub');
|
|
1313
|
-
console.log('2. Add it as a remote: git remote add origin <your-repo-url>');
|
|
1314
|
-
console.log('3. Push your code: git push -u origin main\n');
|
|
1315
|
-
|
|
1316
|
-
const hasCreated = await prompt([
|
|
1317
|
-
{
|
|
1318
|
-
type: 'confirm',
|
|
1319
|
-
name: 'created',
|
|
1320
|
-
message: 'Have you created and pushed to your GitHub repository?',
|
|
1321
|
-
default: false
|
|
1322
|
-
}
|
|
1323
|
-
]);
|
|
1324
|
-
|
|
1325
|
-
if (!hasCreated.created) {
|
|
1326
|
-
console.log('\n⏭️ No problem! You can set up the GitHub repository later.');
|
|
1327
|
-
console.log(' The system will still work locally for testing.\n');
|
|
1454
|
+
console.log('\n📝 Since you cloned the repo, you can create your own repository to store comments.\n');
|
|
1455
|
+
console.log('Note: This is optional! You can test the system locally first and add integration later.\n');
|
|
1456
|
+
// Don't ask about repository here - wait until issue tracking selection
|
|
1328
1457
|
// Set placeholder values that can be updated later
|
|
1329
|
-
|
|
1458
|
+
owner = 'YOUR_USERNAME';
|
|
1330
1459
|
repo = 'YOUR_REPO_NAME';
|
|
1331
|
-
} else {
|
|
1332
|
-
// Ask for owner/repo
|
|
1333
|
-
const repoAnswers = await prompt([
|
|
1334
|
-
{
|
|
1335
|
-
type: 'input',
|
|
1336
|
-
name: 'owner',
|
|
1337
|
-
message: 'What is your GitHub username or organization name?',
|
|
1338
|
-
validate: (input) => {
|
|
1339
|
-
if (!input.trim()) return 'Owner is required';
|
|
1340
|
-
return true;
|
|
1341
|
-
}
|
|
1342
|
-
},
|
|
1343
|
-
{
|
|
1344
|
-
type: 'input',
|
|
1345
|
-
name: 'repo',
|
|
1346
|
-
message: 'What is the name of your GitHub repository?',
|
|
1347
|
-
validate: (input) => {
|
|
1348
|
-
if (!input.trim()) return 'Repository name is required';
|
|
1349
|
-
return true;
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
]);
|
|
1353
|
-
owner = repoAnswers.owner;
|
|
1354
|
-
repo = repoAnswers.repo;
|
|
1355
|
-
}
|
|
1356
1460
|
} else if (projectSetup === 'unknown') {
|
|
1357
1461
|
// Try to detect from git
|
|
1358
1462
|
if (gitInfo && gitInfo.owner && gitInfo.repo) {
|
|
@@ -1394,7 +1498,7 @@ async function main() {
|
|
|
1394
1498
|
console.log(' • GitHub - Sync with GitHub Issues');
|
|
1395
1499
|
console.log(' • GitLab - Sync with GitLab Issues (supports self-hosted)');
|
|
1396
1500
|
console.log(' • Skip - Set up later (you can still use local comments)\n');
|
|
1397
|
-
|
|
1501
|
+
|
|
1398
1502
|
const platformChoice = await prompt([
|
|
1399
1503
|
{
|
|
1400
1504
|
type: 'list',
|
|
@@ -1422,8 +1526,9 @@ async function main() {
|
|
|
1422
1526
|
console.log('2. Click "New OAuth App"');
|
|
1423
1527
|
console.log('3. Fill in the form:');
|
|
1424
1528
|
console.log(' - Application name: Your app name (e.g., "My Design Comments")');
|
|
1425
|
-
|
|
1426
|
-
console.log(
|
|
1529
|
+
const devPort = getDevServerPort();
|
|
1530
|
+
console.log(` - Homepage URL: http://localhost:${devPort} (or your dev server URL)`);
|
|
1531
|
+
console.log(` - Authorization callback URL: http://localhost:${devPort}/api/github-oauth-callback`);
|
|
1427
1532
|
console.log('4. Click "Register application"');
|
|
1428
1533
|
console.log('5. Copy the Client ID and generate a Client Secret\n');
|
|
1429
1534
|
|
|
@@ -1697,7 +1802,8 @@ async function main() {
|
|
|
1697
1802
|
console.log('2. Click "Add new application"');
|
|
1698
1803
|
console.log('3. Fill in the form:');
|
|
1699
1804
|
console.log(' - Name: Your app name (e.g., "My Design Comments")');
|
|
1700
|
-
|
|
1805
|
+
const devPort = getDevServerPort();
|
|
1806
|
+
console.log(` - Redirect URI: http://localhost:${devPort}/api/gitlab-oauth-callback`);
|
|
1701
1807
|
console.log(' - Confidential: ✓ (checked)');
|
|
1702
1808
|
console.log(' - Scopes: ✓ api (full API access)');
|
|
1703
1809
|
console.log('4. Click "Save application"');
|
|
@@ -1728,25 +1834,46 @@ async function main() {
|
|
|
1728
1834
|
// Prompt for project path
|
|
1729
1835
|
console.log('\nWhere do you want to store comments as GitLab Issues?');
|
|
1730
1836
|
console.log('This should be a project you have maintainer/owner access to.');
|
|
1731
|
-
console.log('Format: group/project or namespace/group/project');
|
|
1732
1837
|
console.log('');
|
|
1733
|
-
console.log('
|
|
1734
|
-
console.log(` ${baseUrl}/uxd/prototypes/rhoai`);
|
|
1735
|
-
console.log('
|
|
1838
|
+
console.log('You can paste the full URL or just the path:');
|
|
1839
|
+
console.log(` • Full URL: ${baseUrl}/uxd/prototypes/rhoai`);
|
|
1840
|
+
console.log(' • Path only: uxd/prototypes/rhoai\n');
|
|
1736
1841
|
|
|
1737
1842
|
const projectPathAnswer = await prompt([
|
|
1738
1843
|
{
|
|
1739
1844
|
type: 'input',
|
|
1740
1845
|
name: 'projectPath',
|
|
1741
|
-
message: 'GitLab project path
|
|
1846
|
+
message: 'GitLab project path or full URL:',
|
|
1742
1847
|
validate: (input) => {
|
|
1743
1848
|
if (!input.trim()) return 'Project path is required';
|
|
1744
|
-
if (input.includes('http://') || input.includes('https://')) {
|
|
1745
|
-
return 'Do not include the URL - just the project path (e.g., uxd/prototypes/rhoai)';
|
|
1746
|
-
}
|
|
1747
|
-
if (!input.includes('/')) return 'Project path must include at least one slash (e.g., group/project)';
|
|
1748
|
-
if (input.includes('/-/')) return 'Do not include "/-/tree/" or other GitLab UI paths - just the project path';
|
|
1749
1849
|
return true;
|
|
1850
|
+
},
|
|
1851
|
+
filter: (input) => {
|
|
1852
|
+
// If user pasted full URL, extract the path
|
|
1853
|
+
const trimmed = input.trim();
|
|
1854
|
+
|
|
1855
|
+
// Check if it's a full URL
|
|
1856
|
+
if (trimmed.includes('http://') || trimmed.includes('https://')) {
|
|
1857
|
+
try {
|
|
1858
|
+
const url = new URL(trimmed);
|
|
1859
|
+
// Extract path after domain, remove leading/trailing slashes
|
|
1860
|
+
let path = url.pathname.replace(/^\/+|\/+$/g, '');
|
|
1861
|
+
// Remove common GitLab UI paths like /-/tree/main, /-/settings, etc.
|
|
1862
|
+
path = path.replace(/\/-\/.*$/, '');
|
|
1863
|
+
// Remove .git suffix if present
|
|
1864
|
+
path = path.replace(/\.git$/, '');
|
|
1865
|
+
return path;
|
|
1866
|
+
} catch {
|
|
1867
|
+
// If URL parsing fails, try manual extraction
|
|
1868
|
+
const match = trimmed.match(/gitlab[^/]+\/(.+?)(?:\.git|\/-\/|$)/);
|
|
1869
|
+
if (match) {
|
|
1870
|
+
return match[1].replace(/\/-\/.*$/, '').replace(/\.git$/, '');
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
// If it's already a path, clean it up
|
|
1876
|
+
return trimmed.replace(/^\/+|\/+$/, '').replace(/\/-\/.*$/, '').replace(/\.git$/, '');
|
|
1750
1877
|
}
|
|
1751
1878
|
}
|
|
1752
1879
|
]);
|
|
@@ -1905,6 +2032,13 @@ async function main() {
|
|
|
1905
2032
|
// Integrate webpack middleware
|
|
1906
2033
|
console.log('\n📝 webpack.dev.js');
|
|
1907
2034
|
integrateWebpackMiddleware();
|
|
2035
|
+
|
|
2036
|
+
// Fix CSS loader to exclude nested node_modules
|
|
2037
|
+
console.log('\n📝 Fixing CSS loader configuration...');
|
|
2038
|
+
if (!fixWebpackCssLoader()) {
|
|
2039
|
+
console.log(' ⚠️ Could not auto-fix CSS loader. You may need to manually exclude nested node_modules.');
|
|
2040
|
+
console.log(' Add this to your CSS loader rule: exclude: /node_modules\\/.*\\/node_modules\\//');
|
|
2041
|
+
}
|
|
1908
2042
|
|
|
1909
2043
|
console.log('\n╔══════════════════════════════════════════════════════════╗');
|
|
1910
2044
|
console.log('║ ✅ Integration Complete! ║');
|
package/scripts/remove.js
CHANGED
|
@@ -70,12 +70,25 @@ async function main() {
|
|
|
70
70
|
let content = fs.readFileSync(indexPath, 'utf8');
|
|
71
71
|
const originalContent = content;
|
|
72
72
|
|
|
73
|
-
// Remove
|
|
74
|
-
|
|
73
|
+
// Remove imports - handle both old (GitHubAuthProvider) and new (ProviderAuthProvider) names
|
|
74
|
+
// Also handle both @app/commenting-system and hale-commenting-system import paths
|
|
75
|
+
const importPatterns = [
|
|
76
|
+
// Pattern 1: Both providers together (any order)
|
|
77
|
+
/import\s*{\s*[^}]*CommentProvider[^}]*,\s*(?:GitHubAuthProvider|ProviderAuthProvider)[^}]*}\s*from\s*["'](?:@app\/commenting-system|hale-commenting-system)["'];?\s*\n?/g,
|
|
78
|
+
/import\s*{\s*(?:GitHubAuthProvider|ProviderAuthProvider)[^}]*,\s*[^}]*CommentProvider[^}]*}\s*from\s*["'](?:@app\/commenting-system|hale-commenting-system)["'];?\s*\n?/g,
|
|
79
|
+
// Pattern 2: Single CommentProvider
|
|
80
|
+
/import\s*{\s*CommentProvider\s*}\s*from\s*["'](?:@app\/commenting-system|hale-commenting-system)["'];?\s*\n?/g,
|
|
81
|
+
// Pattern 3: Single auth provider (old or new)
|
|
82
|
+
/import\s*{\s*(?:GitHubAuthProvider|ProviderAuthProvider)\s*}\s*from\s*["'](?:@app\/commenting-system|hale-commenting-system)["'];?\s*\n?/g,
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
for (const pattern of importPatterns) {
|
|
86
|
+
content = content.replace(pattern, '');
|
|
87
|
+
}
|
|
75
88
|
|
|
76
|
-
// Remove the providers from JSX
|
|
77
|
-
content = content.replace(/<GitHubAuthProvider>\s*/g, '');
|
|
78
|
-
content = content.replace(/<\/GitHubAuthProvider>/g, '');
|
|
89
|
+
// Remove the providers from JSX - handle both old and new provider names
|
|
90
|
+
content = content.replace(/<(?:GitHubAuthProvider|ProviderAuthProvider)>\s*/g, '');
|
|
91
|
+
content = content.replace(/<\/(?:GitHubAuthProvider|ProviderAuthProvider)>/g, '');
|
|
79
92
|
content = content.replace(/<CommentProvider>\s*/g, '');
|
|
80
93
|
content = content.replace(/<\/CommentProvider>/g, '');
|
|
81
94
|
|
|
@@ -92,13 +105,25 @@ async function main() {
|
|
|
92
105
|
let content = fs.readFileSync(appLayoutPath, 'utf8');
|
|
93
106
|
const originalContent = content;
|
|
94
107
|
|
|
95
|
-
// Remove the import
|
|
96
|
-
|
|
108
|
+
// Remove the import - handle both import paths
|
|
109
|
+
const importPatterns = [
|
|
110
|
+
// Both components together
|
|
111
|
+
/import\s*{\s*CommentPanel\s*,\s*CommentOverlay\s*}\s*from\s*["'](?:@app\/commenting-system|hale-commenting-system)["'];?\s*\n?/g,
|
|
112
|
+
// Single CommentPanel
|
|
113
|
+
/import\s*{\s*CommentPanel\s*}\s*from\s*["'](?:@app\/commenting-system|hale-commenting-system)["'];?\s*\n?/g,
|
|
114
|
+
// Single CommentOverlay
|
|
115
|
+
/import\s*{\s*CommentOverlay\s*}\s*from\s*["'](?:@app\/commenting-system|hale-commenting-system)["'];?\s*\n?/g,
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
for (const pattern of importPatterns) {
|
|
119
|
+
content = content.replace(pattern, '');
|
|
120
|
+
}
|
|
97
121
|
|
|
98
122
|
// Remove the components from JSX
|
|
99
123
|
content = content.replace(/<CommentPanel>\s*/g, '');
|
|
100
124
|
content = content.replace(/<\/CommentPanel>/g, '');
|
|
101
125
|
content = content.replace(/<CommentOverlay\s*\/>\s*/g, '');
|
|
126
|
+
content = content.replace(/<CommentOverlay\s+[^>]*\/>\s*/g, '');
|
|
102
127
|
|
|
103
128
|
if (content !== originalContent) {
|
|
104
129
|
fs.writeFileSync(appLayoutPath, content, 'utf8');
|