11const {
22 DECORATOR_PATHS ,
3+ DECORATOR_PATH_OVERRIDES ,
34 EMBER_DECORATOR_SPECIFIERS ,
45 get,
56 getFirstDeclaration,
@@ -170,11 +171,18 @@ function createNewImportDeclarations(
170171function getDecoratorPathSpecifiers ( j , root , decoratorsToImport = [ ] ) {
171172 // create a copy - we need to mutate the object later
172173 const edPathNameMap = Object . assign ( { } , EMBER_DECORATOR_SPECIFIERS ) ;
174+
175+ // Iterate over the existing imports
176+ // Extract and process the specifiers
177+ // Construct the map with path as key and value as list of specifiers to import from the path
173178 return getExistingDecoratorImports ( j , root ) . reduce (
174179 ( decoratorPathSpecifierMap , existingDecoratorImport ) => {
175180 const { importPropDecoratorMap, decoratorPath } = DECORATOR_PATHS [
176181 get ( existingDecoratorImport , "value.source.value" )
177182 ] ;
183+ // Decorators to be imported for the path
184+ // These are typically additional decorators which need to be imported for a path
185+ // For example - `@action` decorator
178186 const decoratorsForPath = edPathNameMap [ decoratorPath ] || [ ] ;
179187 // delete the visited path to avoid duplicate imports
180188 delete edPathNameMap [ decoratorPath ] ;
@@ -186,7 +194,6 @@ function getDecoratorPathSpecifiers(j, root, decoratorsToImport = []) {
186194 decoratorsForPath ,
187195 decoratorsToImport
188196 ) ;
189-
190197 const existingSpecifiers =
191198 get ( existingDecoratorImport , "value.specifiers" ) || [ ] ;
192199
@@ -200,15 +207,26 @@ function getDecoratorPathSpecifiers(j, root, decoratorsToImport = []) {
200207 // Update decorator local and imported names,
201208 // Needed in case of `observer` which need to be renamed to `@observes`
202209 setSpecifierNames ( existingSpecifier , importPropDecoratorMap ) ;
203- const isSpecifierPresent = decoratedSpecifiers . some ( specifier => {
204- return (
205- ! get ( specifier , "local.name" ) &&
206- get ( specifier , "imported.name" ) ===
207- get ( existingSpecifier , "imported.name" )
210+ // Check if the decorator import path is overridden
211+ // Needed in case of `observes` which need to be imported from `@ember-decorators/object`
212+ const overriddenPath =
213+ DECORATOR_PATH_OVERRIDES [ get ( existingSpecifier , "imported.name" ) ] ;
214+ if ( overriddenPath ) {
215+ decoratorPathSpecifierMap [ overriddenPath ] = [ ] . concat (
216+ decoratorPathSpecifierMap [ overriddenPath ] || [ ] ,
217+ existingSpecifier
208218 ) ;
209- } ) ;
210- if ( ! isSpecifierPresent ) {
211- decoratedSpecifiers . push ( existingSpecifier ) ;
219+ } else {
220+ const isSpecifierPresent = decoratedSpecifiers . some ( specifier => {
221+ return (
222+ ! get ( specifier , "local.name" ) &&
223+ get ( specifier , "imported.name" ) ===
224+ get ( existingSpecifier , "imported.name" )
225+ ) ;
226+ } ) ;
227+ if ( ! isSpecifierPresent ) {
228+ decoratedSpecifiers . push ( existingSpecifier ) ;
229+ }
212230 }
213231
214232 // Remove the specifier from the existing import
@@ -252,6 +270,7 @@ function createDecoratorImportDeclarations(j, root, decoratorsToImport = []) {
252270 root ,
253271 decoratorsToImport
254272 ) ;
273+
255274 const firstDeclaration = getFirstDeclaration ( j , root ) ;
256275 const decoratorPathsImported = Object . keys ( decoratorPathSpecifierMap ) ;
257276 // Create import statement replacing the existing ones with specifiers importing from ember-decorators namespace
0 commit comments