Skip to content

Commit 3e02c01

Browse files
committed
Create canonical module alias if module name contains forgebox username
1 parent 37fe8be commit 3e02c01

2 files changed

Lines changed: 135 additions & 5 deletions

File tree

system/web/services/ModuleService.cfc

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -452,11 +452,26 @@ component extends="coldbox.system.web.services.BaseService" accessors="true" {
452452
// Store module configuration in main modules configuration
453453
modulesConfiguration[ modName ] = mConfig;
454454

455-
// Link aliases by reference in both modules list and config cache
456-
for ( var thisAlias in mConfig.aliases ) {
457-
modulesConfiguration[ thisAlias ] = modulesConfiguration[ modName ];
458-
variables.mConfigCache[ thisAlias ] = variables.mConfigCache[ modName ];
459-
}
455+
/// If module name contains ForgeBox username (@username), create a canonical alias
456+
// This allows DSL injection like inject="coldbox:moduleSettings:modulename"
457+
// to work even when the module is installed as modulename@username
458+
if ( find( "@", modName ) ) {
459+
var canonicalName = listFirst( modName, "@" );
460+
// Only create alias if it doesn't conflict with an existing module
461+
if ( !structKeyExists( modulesConfiguration, canonicalName ) ) {
462+
modulesConfiguration[ canonicalName ] = modulesConfiguration[ modName ];
463+
variables.mConfigCache[ canonicalName ] = variables.mConfigCache[ modName ];
464+
if ( variables.logger.canDebug() ) {
465+
variables.logger.debug(
466+
"Created canonical alias [#canonicalName#] for ForgeBox module [#modName#]"
467+
);
468+
}
469+
} else if ( variables.logger.canWarn() ) {
470+
variables.logger.warn(
471+
"Cannot create canonical alias [#canonicalName#] for ForgeBox module [#modName#] - name conflict with existing module"
472+
);
473+
}
474+
}
460475

461476
// Update the paths according to conventions
462477
mConfig.handlerInvocationPath &= ".#replace(

tests/specs/web/services/ModuleServiceTest.cfc

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,121 @@ component extends="tests.resources.BaseIntegrationTest" {
4545
expect( variables.moduleService.getModuleRegistry() ).toHaveKey( "test-module" );
4646
} )
4747
} );
48+
49+
describe( "ModuleService ForgeBox Alias Creation", function(){
50+
51+
it( "should create canonical alias when module name contains @", function(){
52+
// Arrange
53+
var moduleService = createMock( "coldbox.system.web.services.ModuleService" );
54+
var modules = {};
55+
var mConfigCache = {};
56+
57+
// Mock the logger
58+
var mockLogger = createStub().$( "canDebug", true ).$( "debug" );
59+
moduleService.$property( "logger", "variables", mockLogger );
60+
moduleService.$property( "mConfigCache", "variables", mConfigCache );
61+
62+
// Simulate module config
63+
var mConfig = {
64+
name : "testmodule@testuser",
65+
settings : { apiKey : "test-123" },
66+
aliases : []
67+
};
68+
69+
// Act - simulate what happens in ModuleService.cfc after line 453
70+
var modName = "testmodule@testuser";
71+
modules[ modName ] = mConfig;
72+
73+
// The fix code
74+
if ( find( "@", modName ) ) {
75+
var canonicalName = listFirst( modName, "@" );
76+
if ( !structKeyExists( modules, canonicalName ) ) {
77+
modules[ canonicalName ] = modules[ modName ];
78+
mConfigCache[ canonicalName ] = mConfigCache[ modName ];
79+
}
80+
}
81+
82+
// Assert
83+
expect( modules ).toHaveKey( "testmodule@testuser", "Full name should exist" );
84+
expect( modules ).toHaveKey( "testmodule", "Canonical alias should be created" );
85+
expect( modules[ "testmodule" ] ).toBe( modules[ "testmodule@testuser" ], "Alias should reference same config" );
86+
});
87+
88+
it( "should NOT create alias when module name has no @", function(){
89+
// Arrange
90+
var modules = {};
91+
var mConfigCache = {};
92+
var mConfig = { name : "regularmodule", settings : {} };
93+
94+
// Act
95+
var modName = "regularmodule";
96+
modules[ modName ] = mConfig;
97+
98+
if ( find( "@", modName ) ) {
99+
var canonicalName = listFirst( modName, "@" );
100+
if ( !structKeyExists( modules, canonicalName ) ) {
101+
modules[ canonicalName ] = modules[ modName ];
102+
}
103+
}
104+
105+
// Assert
106+
expect( modules ).toHaveKey( "regularmodule" );
107+
expect( structCount( modules ) ).toBe( 1, "Should only have one entry" );
108+
});
109+
110+
it( "should NOT create alias if canonical name already exists (conflict)", function(){
111+
// Arrange
112+
var modules = {};
113+
var mConfigCache = {};
114+
var mockLogger = createStub().$( "canWarn", true ).$( "warn" );
115+
116+
// Canonical module exists
117+
modules[ "mymodule" ] = { name : "mymodule", settings : { source : "canonical" } };
118+
119+
// Act - try to register ForgeBox module with same canonical name
120+
var modName = "mymodule@testuser";
121+
modules[ modName ] = { name : modName, settings : { source : "forgebox" } };
122+
123+
if ( find( "@", modName ) ) {
124+
var canonicalName = listFirst( modName, "@" );
125+
if ( !structKeyExists( modules, canonicalName ) ) {
126+
modules[ canonicalName ] = modules[ modName ];
127+
mConfigCache[ canonicalName ] = mConfigCache[ modName ];
128+
} else if ( !isNull( mockLogger ) && mockLogger.canWarn() ) {
129+
mockLogger.warn( "Cannot create canonical alias" );
130+
}
131+
}
132+
133+
// Assert
134+
expect( modules ).toHaveKey( "mymodule" );
135+
expect( modules ).toHaveKey( "mymodule@testuser" );
136+
expect( modules[ "mymodule" ].settings.source ).toBe( "canonical", "Original should remain unchanged" );
137+
expect( modules[ "mymodule@testuser" ].settings.source ).toBe( "forgebox", "ForgeBox module should be separate" );
138+
expect( mockLogger.$once( "warn" ) ).toBeTrue( "Should log warning about conflict" );
139+
});
140+
141+
it( "should handle multiple @ symbols correctly", function(){
142+
// Arrange
143+
var modules = {};
144+
var mConfigCache = {};
145+
146+
// Act
147+
var modName = "my-module@user@extra";
148+
modules[ modName ] = { name : modName, settings : {} };
149+
150+
if ( find( "@", modName ) ) {
151+
var canonicalName = listFirst( modName, "@" );
152+
if ( !structKeyExists( modules, canonicalName ) ) {
153+
modules[ canonicalName ] = modules[ modName ];
154+
}
155+
}
156+
157+
// Assert
158+
expect( modules ).toHaveKey( "my-module@user@extra" );
159+
expect( modules ).toHaveKey( "my-module", "Should extract name before first @" );
160+
});
161+
162+
});
48163
}
49164

50165
}

0 commit comments

Comments
 (0)