7
7
* file that was distributed with this source code.
8
8
*/
9
9
10
- import { join } from 'node:path'
11
10
import { fileURLToPath } from 'node:url'
11
+ import { basename , dirname , join , relative } from 'node:path'
12
+ import string from '@poppinss/utils/string'
13
+ import { isScriptFile } from '@poppinss/utils'
14
+ import { fsReadAll } from '@poppinss/utils/fs'
15
+ import { mkdir , writeFile } from 'node:fs/promises'
16
+ import { type OneOrMore } from '@poppinss/utils/types'
17
+ import StringBuilder from '@poppinss/utils/string_builder'
12
18
import { installPackage , detectPackageManager } from '@antfu/install-pkg'
13
19
import {
14
20
Node ,
@@ -26,6 +32,7 @@ import type {
26
32
EnvValidationNode ,
27
33
BouncerPolicyNode ,
28
34
} from '../types/code_transformer.ts'
35
+ import debug from '../debug.ts'
29
36
30
37
/**
31
38
* This class is responsible for updating
@@ -42,6 +49,7 @@ export class CodeTransformer {
42
49
* Directory of the adonisjs project
43
50
*/
44
51
#cwd: URL
52
+ #cwdPath: string
45
53
46
54
/**
47
55
* The TsMorph project
@@ -63,6 +71,7 @@ export class CodeTransformer {
63
71
64
72
constructor ( cwd : URL ) {
65
73
this . #cwd = cwd
74
+ this . #cwdPath = fileURLToPath ( this . #cwd)
66
75
this . project = new Project ( {
67
76
tsConfigFilePath : join ( fileURLToPath ( this . #cwd) , 'tsconfig.json' ) ,
68
77
manipulationSettings : { quoteKind : QuoteKind . Single } ,
@@ -235,7 +244,7 @@ export class CodeTransformer {
235
244
/**
236
245
* Get the `start/env.ts` source file
237
246
*/
238
- const kernelUrl = fileURLToPath ( new URL ( './start/env.ts' , this . #cwd ) )
247
+ const kernelUrl = join ( this . #cwdPath , './start/env.ts' )
239
248
const file = this . project . getSourceFileOrThrow ( kernelUrl )
240
249
241
250
/**
@@ -308,7 +317,7 @@ export class CodeTransformer {
308
317
/**
309
318
* Get the `start/kernel.ts` source file
310
319
*/
311
- const kernelUrl = fileURLToPath ( new URL ( './start/kernel.ts' , this . #cwd ) )
320
+ const kernelUrl = join ( this . #cwdPath , './start/kernel.ts' )
312
321
const file = this . project . getSourceFileOrThrow ( kernelUrl )
313
322
314
323
/**
@@ -345,7 +354,7 @@ export class CodeTransformer {
345
354
/**
346
355
* Get the `tests/bootstrap.ts` source file
347
356
*/
348
- const testBootstrapUrl = fileURLToPath ( new URL ( './tests/bootstrap.ts' , this . #cwd ) )
357
+ const testBootstrapUrl = join ( this . #cwdPath , './tests/bootstrap.ts' )
349
358
const file = this . project . getSourceFileOrThrow ( testBootstrapUrl )
350
359
351
360
/**
@@ -383,7 +392,7 @@ export class CodeTransformer {
383
392
/**
384
393
* Get the `vite.config.ts` source file
385
394
*/
386
- const viteConfigTsUrl = fileURLToPath ( new URL ( './vite.config.ts' , this . #cwd ) )
395
+ const viteConfigTsUrl = join ( this . #cwdPath , './vite.config.ts' )
387
396
388
397
const file = this . project . getSourceFile ( viteConfigTsUrl )
389
398
if ( ! file ) {
@@ -438,7 +447,7 @@ export class CodeTransformer {
438
447
/**
439
448
* Get the `app/policies/main.ts` source file
440
449
*/
441
- const kernelUrl = fileURLToPath ( new URL ( './app/policies/main.ts' , this . #cwd ) )
450
+ const kernelUrl = join ( this . #cwdPath , './app/policies/main.ts' )
442
451
const file = this . project . getSourceFileOrThrow ( kernelUrl )
443
452
444
453
/**
@@ -451,4 +460,87 @@ export class CodeTransformer {
451
460
file . formatText ( this . #editorSettings)
452
461
await file . save ( )
453
462
}
463
+
464
+ /**
465
+ * Creates an index file that exports an object in which the key is the PascalCase
466
+ * name of the entity and the value is a dynamic import.
467
+ *
468
+ * For example, in case of controllers, the index file will be the list of controller
469
+ * names pointing a dynamically imported controller file.
470
+ *
471
+ * ```ts
472
+ * export const controllers = {
473
+ * Login: () => import('#controllers/login_controller'),
474
+ * Login: () => import('#controllers/login_controller'),
475
+ * }
476
+ * ```
477
+ *
478
+ * @param source
479
+ * @param outputPath
480
+ * @param importAlias
481
+ */
482
+ async makeEntityIndex (
483
+ input : OneOrMore < { source : string ; importAlias ?: string } > ,
484
+ output : {
485
+ destination : string
486
+ exportName ?: string
487
+ transformName ?: ( name : string ) => string
488
+ transformImport ?: ( modulePath : string ) => string
489
+ }
490
+ ) {
491
+ const inputs = Array . isArray ( input ) ? input : [ input ]
492
+ const outputPath = join ( this . #cwdPath, output . destination )
493
+ const outputDir = dirname ( outputPath )
494
+ const exportName =
495
+ output . exportName ??
496
+ new StringBuilder ( basename ( output . destination ) ) . removeExtension ( ) . camelCase ( )
497
+
498
+ debug (
499
+ 'creating index for "%s" at destination "%s" using sources %O' ,
500
+ exportName ,
501
+ outputPath ,
502
+ inputs
503
+ )
504
+
505
+ const entries = await Promise . all (
506
+ inputs . map ( async ( { source, importAlias } ) => {
507
+ const sourcePath = join ( this . #cwdPath, source )
508
+ const filesList = await fsReadAll ( sourcePath , {
509
+ filter : isScriptFile ,
510
+ pathType : 'absolute' ,
511
+ } )
512
+
513
+ return filesList . map ( ( filePath ) => {
514
+ const name = new StringBuilder ( relative ( sourcePath , filePath ) )
515
+ . removeExtension ( )
516
+ . pascalCase ( )
517
+ . toString ( )
518
+
519
+ const importPath = importAlias
520
+ ? `${ importAlias } /${ new StringBuilder ( relative ( sourcePath , filePath ) ) . removeExtension ( ) . toString ( ) } `
521
+ : relative ( outputDir , filePath )
522
+
523
+ return {
524
+ name : output . transformName ?.( name ) ?? name ,
525
+ importPath : output . transformImport ?.( importPath ) ?? importPath ,
526
+ }
527
+ } )
528
+ } )
529
+ )
530
+
531
+ const outputContents = entries
532
+ . flat ( 2 )
533
+ . reduce < string [ ] > (
534
+ ( result , entry ) => {
535
+ debug ( 'adding "%O" to the index' , entry )
536
+ result . push ( ` ${ entry . name } : () => import('${ entry . importPath } '),` )
537
+ return result
538
+ } ,
539
+ [ `export const ${ exportName } = {` ]
540
+ )
541
+ . concat ( '}' )
542
+
543
+ await mkdir ( outputDir , { recursive : true } )
544
+ await writeFile ( outputPath , outputContents . join ( '\n' ) )
545
+ }
454
546
}
0 commit comments