@@ -63,11 +63,13 @@ function addPluginToConfig(configPath: string, packageName: string): void {
6363 let content = readConfigText ( configPath ) ;
6464
6565 // Derive a variable name from the package name
66- // e.g. "@objectstack/plugin-auth" → "pluginAuth "
66+ // e.g. "@objectstack/plugin-auth" → "authPlugin "
6767 const shortName = packageName
6868 . replace ( / ^ @ [ ^ / ] + \/ / , '' ) // strip scope
69- . replace ( / ^ p l u g i n - / , '' ) ; // strip "plugin-" prefix
70- const varName = shortName . replace ( / - ( [ a - z ] ) / g, ( _ , c ) => c . toUpperCase ( ) ) + 'Plugin' ;
69+ . replace ( / ^ p l u g i n - / , '' ) // strip "plugin-" prefix
70+ . replace ( / - + / g, '-' ) // collapse consecutive hyphens
71+ . replace ( / ^ - | - $ / g, '' ) ; // trim leading/trailing hyphens
72+ const varName = shortName . replace ( / - ( [ a - z ] ) / g, ( _ , c : string ) => c . toUpperCase ( ) ) + 'Plugin' ;
7173
7274 // 1. Add import
7375 const importLine = `import ${ varName } from '${ packageName } ';\n` ;
@@ -90,12 +92,17 @@ function addPluginToConfig(configPath: string, packageName: string): void {
9092 content = importLine + '\n' + content ;
9193 }
9294
93- // 2. Add to plugins array
95+ // 2. Add to plugins array (target only the first plugins: [ within defineStack)
9496 if ( / p l u g i n s \s * : \s * \[ / . test ( content ) ) {
95- // plugins array exists — append to it
97+ // plugins array exists — append to it (first occurrence only)
98+ let replaced = false ;
9699 content = content . replace (
97100 / ( p l u g i n s \s * : \s * \[ ) / ,
98- `$1\n ${ varName } ,`
101+ ( match ) => {
102+ if ( replaced ) return match ;
103+ replaced = true ;
104+ return `${ match } \n ${ varName } ,` ;
105+ }
99106 ) ;
100107 } else {
101108 // No plugins array — add one before the closing of defineStack({...})
@@ -117,16 +124,20 @@ function addPluginToConfig(configPath: string, packageName: string): void {
117124function removePluginFromConfig ( configPath : string , pluginName : string ) : void {
118125 let content = readConfigText ( configPath ) ;
119126
120- // Remove the import line that references this plugin (by package name or variable )
121- const importRegex = new RegExp ( `^import .+['"]${ escapeRegex ( pluginName ) } ['"]. *$\\n?` , 'gm' ) ;
127+ // Remove the import line that references this plugin (exact package name match )
128+ const importRegex = new RegExp ( `^import .+['"]${ escapeRegex ( pluginName ) } ['"]\\s*;?\\s *$\\n?` , 'gm' ) ;
122129 const hadImport = importRegex . test ( content ) ;
130+ // Reset regex lastIndex after test()
131+ importRegex . lastIndex = 0 ;
123132 content = content . replace ( importRegex , '' ) ;
124133
125134 // Also try to remove by a derived variable name
126135 const shortName = pluginName
127136 . replace ( / ^ @ [ ^ / ] + \/ / , '' )
128- . replace ( / ^ p l u g i n - / , '' ) ;
129- const varName = shortName . replace ( / - ( [ a - z ] ) / g, ( _ , c ) => c . toUpperCase ( ) ) + 'Plugin' ;
137+ . replace ( / ^ p l u g i n - / , '' )
138+ . replace ( / - + / g, '-' )
139+ . replace ( / ^ - | - $ / g, '' ) ;
140+ const varName = shortName . replace ( / - ( [ a - z ] ) / g, ( _ , c : string ) => c . toUpperCase ( ) ) + 'Plugin' ;
130141
131142 // Remove import by variable name if it wasn't caught above
132143 if ( ! hadImport ) {
0 commit comments