@@ -26,7 +26,6 @@ async function findResourceFilePath(resourceId) {
26
26
throw new Error ( `Failed to read resources directory ${ resourcesDir } : ${ error . message } ` ) ;
27
27
}
28
28
29
- console . log ( chalk . dim ( `Found .ts files to scan: ${ tsFiles . join ( ', ' ) || 'None' } ` ) ) ;
30
29
31
30
for ( const file of tsFiles ) {
32
31
const filePath = path . resolve ( resourcesDir , file ) ;
@@ -94,6 +93,7 @@ export async function updateResourceConfig(resourceId, columnName, fieldType, co
94
93
console . log ( chalk . dim ( `Attempting to update resource config: ${ filePath } ` ) ) ;
95
94
96
95
let content ;
96
+ let injectionLine = null ;
97
97
try {
98
98
content = await fs . readFile ( filePath , 'utf-8' ) ;
99
99
} catch ( error ) {
@@ -176,11 +176,16 @@ export async function updateResourceConfig(resourceId, columnName, fieldType, co
176
176
const newComponentValue = b . stringLiteral ( componentPathForConfig ) ;
177
177
178
178
if ( fieldTypeProperty ) {
179
+ injectionLine = fieldTypeProperty . loc ?. start . line ?? null ;
179
180
fieldTypeProperty . value = newComponentValue ;
180
181
console . log ( chalk . dim ( `Updated '${ fieldType } ' component path in column '${ columnName } '.` ) ) ;
181
182
} else {
182
183
fieldTypeProperty = b . objectProperty ( b . identifier ( fieldType ) , newComponentValue ) ;
183
184
componentsObject . properties . push ( fieldTypeProperty ) ;
185
+ fieldTypeProperty = componentsObject . properties . find ( p =>
186
+ n . ObjectProperty . check ( p ) && n . Identifier . check ( p . key ) && p . key . name === fieldType
187
+ ) ;
188
+ injectionLine = fieldTypeProperty . loc ?. start . line ?? null ;
184
189
console . log ( chalk . dim ( `Added '${ fieldType } ' component path to column '${ columnName } '.` ) ) ;
185
190
}
186
191
@@ -197,7 +202,12 @@ export async function updateResourceConfig(resourceId, columnName, fieldType, co
197
202
const outputCode = recast . print ( ast ) . code ;
198
203
199
204
await fs . writeFile ( filePath , outputCode , 'utf-8' ) ;
200
- console . log ( chalk . dim ( `Successfully updated resource configuration file (preserving formatting): ${ filePath } ` ) ) ;
205
+ console . log (
206
+ chalk . green (
207
+ `✅ Successfully updated CRUD injection in resource file: ${ filePath } ` +
208
+ ( injectionLine !== null ? `:${ injectionLine } ` : '' )
209
+ )
210
+ ) ;
201
211
202
212
} catch ( error ) {
203
213
console . error ( chalk . red ( `❌ Error processing resource file: ${ filePath } ` ) ) ;
@@ -211,78 +221,106 @@ export async function injectLoginComponent(indexFilePath, componentPath) {
211
221
console . log ( chalk . dim ( `Reading file: ${ indexFilePath } ` ) ) ;
212
222
const content = await fs . readFile ( indexFilePath , 'utf-8' ) ;
213
223
const ast = recast . parse ( content , {
214
- parser : typescriptParser ,
224
+ parser : typescriptParser ,
215
225
} ) ;
216
-
226
+
217
227
let updated = false ;
218
-
228
+ let injectionLine = null ;
229
+
219
230
recast . visit ( ast , {
220
- visitNewExpression ( path ) {
221
- if (
222
- n . Identifier . check ( path . node . callee ) &&
223
- path . node . callee . name === 'AdminForth' &&
224
- path . node . arguments . length > 0 &&
225
- n . ObjectExpression . check ( path . node . arguments [ 0 ] )
226
- ) {
227
- const configObject = path . node . arguments [ 0 ] ;
228
-
229
- let customizationProp = configObject . properties . find (
230
- p => n . ObjectProperty . check ( p ) && n . Identifier . check ( p . key ) && p . key . name === 'customization'
231
- ) ;
232
-
233
- if ( ! customizationProp ) {
234
- const customizationObj = b . objectExpression ( [ ] ) ;
235
- customizationProp = b . objectProperty ( b . identifier ( 'customization' ) , customizationObj ) ;
236
- configObject . properties . push ( customizationProp ) ;
237
- console . log ( chalk . dim ( `Added missing 'customization' property.` ) ) ;
238
- }
239
-
240
- const customizationValue = customizationProp . value ;
241
- if ( ! n . ObjectExpression . check ( customizationValue ) ) return false ;
242
-
243
- let loginPageInjections = customizationValue . properties . find (
244
- p => n . ObjectProperty . check ( p ) && n . Identifier . check ( p . key ) && p . key . name === 'loginPageInjections'
245
- ) ;
246
-
247
- if ( ! loginPageInjections ) {
248
- const injectionsObj = b . objectExpression ( [ ] ) ;
249
- loginPageInjections = b . objectProperty ( b . identifier ( 'loginPageInjections' ) , injectionsObj ) ;
250
- customizationValue . properties . push ( loginPageInjections ) ;
251
- console . log ( chalk . dim ( `Added missing 'loginPageInjections'.` ) ) ;
252
- }
253
-
254
- const injectionsValue = loginPageInjections . value ;
255
- if ( ! n . ObjectExpression . check ( injectionsValue ) ) return false ;
256
-
257
- let underInputsProp = injectionsValue . properties . find (
258
- p => n . ObjectProperty . check ( p ) && n . Identifier . check ( p . key ) && p . key . name === 'underInputs'
259
- ) ;
260
-
261
- if ( underInputsProp ) {
262
- underInputsProp . value = b . stringLiteral ( componentPath ) ;
263
- console . log ( chalk . dim ( `Updated 'underInputs' to ${ componentPath } ` ) ) ;
264
- } else {
265
- injectionsValue . properties . push (
266
- b . objectProperty ( b . identifier ( 'underInputs' ) , b . stringLiteral ( componentPath ) )
267
- ) ;
268
- console . log ( chalk . dim ( `Added 'underInputs': ${ componentPath } ` ) ) ;
269
- }
270
-
271
- updated = true ;
272
- this . abort ( ) ;
231
+ visitNewExpression ( path ) {
232
+ if (
233
+ n . Identifier . check ( path . node . callee ) &&
234
+ path . node . callee . name === 'AdminForth' &&
235
+ path . node . arguments . length > 0 &&
236
+ n . ObjectExpression . check ( path . node . arguments [ 0 ] )
237
+ ) {
238
+ const configObject = path . node . arguments [ 0 ] ;
239
+
240
+ const getOrCreateProp = ( obj , name ) => {
241
+ let prop = obj . properties . find (
242
+ p => n . ObjectProperty . check ( p ) && n . Identifier . check ( p . key ) && p . key . name === name
243
+ ) ;
244
+ if ( ! prop ) {
245
+ const newObj = b . objectExpression ( [ ] ) ;
246
+ prop = b . objectProperty ( b . identifier ( name ) , newObj ) ;
247
+ obj . properties . push ( prop ) ;
248
+ console . log ( chalk . dim ( `Added missing '${ name } ' property.` ) ) ;
273
249
}
274
- return false ;
250
+ return prop . value ;
251
+ } ;
252
+
253
+ const customization = getOrCreateProp ( configObject , 'customization' ) ;
254
+ if ( ! n . ObjectExpression . check ( customization ) ) return false ;
255
+
256
+ const loginPageInjections = getOrCreateProp ( customization , 'loginPageInjections' ) ;
257
+ if ( ! n . ObjectExpression . check ( loginPageInjections ) ) return false ;
258
+
259
+ let underInputsProp = loginPageInjections . properties . find (
260
+ p => n . ObjectProperty . check ( p ) && n . Identifier . check ( p . key ) && p . key . name === 'underInputs'
261
+ ) ;
262
+
263
+ if ( underInputsProp ) {
264
+ const currentVal = underInputsProp . value ;
265
+ injectionLine = underInputsProp . loc ?. start . line ?? null ;
266
+ if ( n . StringLiteral . check ( currentVal ) ) {
267
+ if ( currentVal . value !== componentPath ) {
268
+ underInputsProp . value = b . arrayExpression ( [
269
+ b . stringLiteral ( currentVal . value ) ,
270
+ b . stringLiteral ( componentPath ) ,
271
+ ] ) ;
272
+ console . log ( chalk . dim ( `Converted 'underInputs' to array with existing + new path.` ) ) ;
273
+ } else {
274
+ console . log ( chalk . dim ( `Component path already present as string. Skipping.` ) ) ;
275
+ }
276
+ } else if ( n . ArrayExpression . check ( currentVal ) ) {
277
+ const exists = currentVal . elements . some (
278
+ el => n . StringLiteral . check ( el ) && el . value === componentPath
279
+ ) ;
280
+ if ( ! exists ) {
281
+ currentVal . elements . push ( b . stringLiteral ( componentPath ) ) ;
282
+ console . log ( chalk . dim ( `Appended new component path to existing 'underInputs' array.` ) ) ;
283
+ } else {
284
+ console . log ( chalk . dim ( `Component path already present in array. Skipping.` ) ) ;
285
+ }
286
+ } else {
287
+ console . warn ( chalk . yellow ( `⚠️ 'underInputs' is not a string or array. Skipping.` ) ) ;
288
+ return false ;
289
+ }
290
+ } else {
291
+ const newProperty = b . objectProperty (
292
+ b . identifier ( 'underInputs' ) ,
293
+ b . stringLiteral ( componentPath )
294
+ ) ;
295
+
296
+ if ( newProperty . loc ) {
297
+ console . log ( chalk . dim ( `Adding 'underInputs' at line: ${ newProperty . loc . start . line } ` ) ) ;
298
+ }
299
+
300
+ loginPageInjections . properties . push ( newProperty ) ;
301
+ console . log ( chalk . dim ( `Added 'underInputs': ${ componentPath } ` ) ) ;
302
+ }
303
+
304
+ updated = true ;
305
+ this . abort ( ) ;
275
306
}
307
+ return false ;
308
+ }
276
309
} ) ;
277
-
310
+
278
311
if ( ! updated ) {
279
- throw new Error ( `Could not find AdminForth configuration in file: ${ indexFilePath } ` ) ;
312
+ throw new Error ( `Could not find AdminForth configuration in file: ${ indexFilePath } ` ) ;
280
313
}
281
-
314
+
282
315
const outputCode = recast . print ( ast ) . code ;
283
316
await fs . writeFile ( indexFilePath , outputCode , 'utf-8' ) ;
284
- console . log ( chalk . green ( `✅ Successfully updated login injection in: ${ indexFilePath } ` ) ) ;
285
- }
317
+ console . log (
318
+ chalk . green (
319
+ `✅ Successfully updated CRUD injection in resource file: ${ indexFilePath } ` +
320
+ ( injectionLine !== null ? `:${ injectionLine } ` : '' )
321
+ )
322
+ ) ;
323
+ }
286
324
287
325
288
326
export async function injectGlobalComponent ( indexFilePath , injectionType , componentPath ) {
@@ -293,7 +331,7 @@ export async function injectGlobalComponent(indexFilePath, injectionType, compon
293
331
} ) ;
294
332
295
333
let updated = false ;
296
-
334
+ let injectionLine = null ;
297
335
console . log ( JSON . stringify ( injectionType ) ) ;
298
336
recast . visit ( ast , {
299
337
visitNewExpression ( path ) {
@@ -315,7 +353,7 @@ export async function injectGlobalComponent(indexFilePath, injectionType, compon
315
353
configObject . properties . push ( customizationProp ) ;
316
354
console . log ( chalk . dim ( `Added missing 'customization' property.` ) ) ;
317
355
}
318
-
356
+
319
357
const customizationValue = customizationProp . value ;
320
358
if ( ! n . ObjectExpression . check ( customizationValue ) ) return false ;
321
359
@@ -338,7 +376,7 @@ export async function injectGlobalComponent(indexFilePath, injectionType, compon
338
376
) ;
339
377
if ( injectionProp ) {
340
378
const currentValue = injectionProp . value ;
341
-
379
+ injectionLine = injectionProp . loc ?. start . line ?? null ;
342
380
if ( n . ArrayExpression . check ( currentValue ) ) {
343
381
currentValue . elements . push ( b . stringLiteral ( componentPath ) ) ;
344
382
console . log ( chalk . dim ( `Added '${ componentPath } ' to existing array in '${ injectionType } '` ) ) ;
@@ -374,14 +412,20 @@ export async function injectGlobalComponent(indexFilePath, injectionType, compon
374
412
375
413
const outputCode = recast . print ( ast ) . code ;
376
414
await fs . writeFile ( indexFilePath , outputCode , 'utf-8' ) ;
377
- console . log ( chalk . green ( `✅ Successfully updated global injection '${ injectionType } ' in: ${ indexFilePath } ` ) ) ;
415
+ console . log (
416
+ chalk . green (
417
+ `✅ Successfully updated CRUD injection in resource file: ${ indexFilePath } ` +
418
+ ( injectionLine !== null ? `:${ injectionLine } ` : '' )
419
+ )
420
+ ) ;
378
421
}
379
422
380
423
export async function updateCrudInjectionConfig ( resourceId , crudType , injectionPosition , componentPathForConfig , isThin ) {
381
424
const filePath = await findResourceFilePath ( resourceId ) ;
382
425
console . log ( chalk . dim ( `Attempting to update resource CRUD injection: ${ filePath } ` ) ) ;
383
426
384
427
let content ;
428
+ let injectionLine = null ;
385
429
try {
386
430
content = await fs . readFile ( filePath , 'utf-8' ) ;
387
431
} catch ( error ) {
@@ -439,7 +483,7 @@ export async function updateCrudInjectionConfig(resourceId, crudType, injectionP
439
483
) ;
440
484
pageInjections . properties . push ( crudProp ) ;
441
485
}
442
-
486
+ injectionLine = crudProp . loc ?. start . line ?? null ;
443
487
const crudValue = crudProp . value ;
444
488
if ( ! n . ObjectExpression . check ( crudValue ) ) return false ;
445
489
@@ -458,11 +502,23 @@ export async function updateCrudInjectionConfig(resourceId, crudType, injectionP
458
502
] ) ;
459
503
460
504
if ( injectionProp ) {
461
- injectionProp . value = newInjectionObject ;
462
- console . log ( chalk . dim ( `Updated '${ injectionPosition } ' injection for '${ crudType } '.` ) ) ;
505
+ if ( n . ArrayExpression . check ( injectionProp . value ) ) {
506
+ injectionProp . value . elements . push ( newInjectionObject ) ;
507
+ console . log ( chalk . dim ( `Appended new injection to array at '${ injectionPosition } ' for '${ crudType } '.` ) ) ;
508
+ }
509
+ else if ( n . ObjectExpression . check ( injectionProp . value ) ) {
510
+ injectionProp . value = b . arrayExpression ( [ injectionProp . value , newInjectionObject ] ) ;
511
+ console . log ( chalk . dim ( `Converted to array and added new injection at '${ injectionPosition } ' for '${ crudType } '.` ) ) ;
512
+ }
513
+ else {
514
+ injectionProp . value = b . arrayExpression ( [ newInjectionObject ] ) ;
515
+ console . log ( chalk . yellow ( `⚠️ Replaced invalid injection at '${ injectionPosition } ' with array.` ) ) ;
516
+ }
463
517
} else {
464
- crudValue . properties . push ( b . objectProperty ( b . identifier ( injectionPosition ) , newInjectionObject ) ) ;
465
- console . log ( chalk . dim ( `Added '${ injectionPosition } ' injection for '${ crudType } '.` ) ) ;
518
+ crudValue . properties . push (
519
+ b . objectProperty ( b . identifier ( injectionPosition ) , b . arrayExpression ( [ newInjectionObject ] ) )
520
+ ) ;
521
+ console . log ( chalk . dim ( `Added new array of injections at '${ injectionPosition } ' for '${ crudType } '.` ) ) ;
466
522
}
467
523
468
524
updateApplied = true ;
@@ -477,7 +533,12 @@ export async function updateCrudInjectionConfig(resourceId, crudType, injectionP
477
533
478
534
const outputCode = recast . print ( ast ) . code ;
479
535
await fs . writeFile ( filePath , outputCode , 'utf-8' ) ;
480
- console . log ( chalk . dim ( `✅ Successfully updated CRUD injection in resource file: ${ filePath } ` ) ) ;
536
+ console . log (
537
+ chalk . green (
538
+ `✅ Successfully updated CRUD injection in resource file: ${ filePath } ` +
539
+ ( injectionLine !== null ? `:${ injectionLine } ` : '' )
540
+ )
541
+ ) ;
481
542
482
543
} catch ( error ) {
483
544
console . error ( chalk . red ( `❌ Error processing resource file: ${ filePath } ` ) ) ;
0 commit comments