@adonisjs/assembler 8.0.0-next.5 → 8.0.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -59
- package/build/chunk-25Q3N5JR.js +392 -0
- package/build/chunk-PORDZS62.js +391 -0
- package/build/chunk-TIKQQRMX.js +116 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +825 -430
- package/build/src/bundler.d.ts +44 -3
- package/build/src/code_scanners/routes_scanner/main.d.ts +49 -9
- package/build/src/code_scanners/routes_scanner/main.js +445 -0
- package/build/src/code_scanners/routes_scanner/validator_extractor.d.ts +12 -4
- package/build/src/code_transformer/main.d.ts +44 -43
- package/build/src/code_transformer/main.js +123 -101
- package/build/src/code_transformer/rc_file_transformer.d.ts +56 -4
- package/build/src/debug.d.ts +12 -0
- package/build/src/dev_server.d.ts +38 -9
- package/build/src/file_buffer.d.ts +67 -0
- package/build/src/file_system.d.ts +45 -7
- package/build/src/helpers.d.ts +79 -4
- package/build/src/helpers.js +16 -0
- package/build/src/hooks.d.ts +224 -0
- package/build/src/index_generator/main.d.ts +64 -0
- package/build/src/index_generator/main.js +7 -0
- package/build/src/index_generator/source.d.ts +60 -0
- package/build/src/paths_resolver.d.ts +27 -2
- package/build/src/shortcuts_manager.d.ts +42 -4
- package/build/src/test_runner.d.ts +56 -10
- package/build/src/types/code_scanners.d.ts +138 -24
- package/build/src/types/code_transformer.d.ts +61 -19
- package/build/src/types/common.d.ts +199 -55
- package/build/src/types/hooks.d.ts +235 -22
- package/build/src/types/main.d.ts +13 -0
- package/build/src/utils.d.ts +88 -13
- package/build/src/virtual_file_system.d.ts +112 -0
- package/package.json +9 -3
- package/build/chunk-RR4HCA4M.js +0 -7
- package/build/src/ast_file_system.d.ts +0 -17
package/README.md
CHANGED
|
@@ -420,83 +420,111 @@ export const policies = {
|
|
|
420
420
|
}
|
|
421
421
|
```
|
|
422
422
|
|
|
423
|
-
|
|
424
|
-
|
|
423
|
+
## Index generator
|
|
424
|
+
|
|
425
|
+
The `IndexGenerator` is a core concept in Assembler that is used to watch the filesystem and create barrel files or types from a source directory.
|
|
426
|
+
|
|
427
|
+
For example, the core of the framework uses the following config to generate controllers, events, and listeners barrel file.
|
|
425
428
|
|
|
426
429
|
```ts
|
|
427
|
-
|
|
430
|
+
import hooks from '@adonisjs/assembler/hooks'
|
|
431
|
+
|
|
432
|
+
export default hooks.init((type, parent, indexGenerator) => {
|
|
433
|
+
indexGenerator.add('controllers', {
|
|
434
|
+
source: './app/controllers',
|
|
435
|
+
importAlias: '#controllers',
|
|
436
|
+
as: 'barrelFile',
|
|
437
|
+
exportName: 'controllers',
|
|
438
|
+
removeSuffix: 'controllers',
|
|
439
|
+
output: './.adonisjs/server/controllers.ts',
|
|
440
|
+
})
|
|
428
441
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
})
|
|
442
|
+
indexGenerator.add('events', {
|
|
443
|
+
source: './app/events',
|
|
444
|
+
importAlias: '#events',
|
|
445
|
+
as: 'barrelFile',
|
|
446
|
+
exportName: 'events',
|
|
447
|
+
output: './.adonisjs/server/events.ts',
|
|
448
|
+
})
|
|
436
449
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
450
|
+
indexGenerator.add('listeners', {
|
|
451
|
+
source: './app/listeners',
|
|
452
|
+
importAlias: '#listeners',
|
|
453
|
+
as: 'barrelFile',
|
|
454
|
+
exportName: 'listeners',
|
|
455
|
+
removeSuffix: 'listener',
|
|
456
|
+
output: './.adonisjs/server/listeners.ts',
|
|
457
|
+
})
|
|
458
|
+
})
|
|
445
459
|
```
|
|
446
460
|
|
|
447
|
-
|
|
461
|
+
Once the configurations have been registered with the `IndexGenerator`, it will scan the needed directories and generate the output files. Additionally, the file watchers will re-trigger the index generation when a file is added or removed from the source directory.
|
|
448
462
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
463
|
+
### Barrel file generation
|
|
464
|
+
|
|
465
|
+
Barrel files provide a single entry point by exporting a collection of lazily imported entities, recursively gathered from a source directory. The `IndexGenerator` automates this process by scanning nested directories and generating import mappings that mirror the file structure.
|
|
466
|
+
|
|
467
|
+
For example, given the following `controllers` directory structure:
|
|
468
|
+
|
|
469
|
+
```sh
|
|
470
|
+
app/controllers/
|
|
471
|
+
├── auth/
|
|
472
|
+
│ ├── login_controller.ts
|
|
473
|
+
│ └── register_controller.ts
|
|
474
|
+
├── blog/
|
|
475
|
+
│ ├── posts_controller.ts
|
|
476
|
+
│ └── post_comments_controller.ts
|
|
477
|
+
└── users_controller.ts
|
|
458
478
|
```
|
|
459
479
|
|
|
460
|
-
|
|
480
|
+
When processed with the controllers configuration, the `IndexGenerator` produces a barrel file that reflects the directory hierarchy as nested objects, using capitalized file names as property keys.
|
|
461
481
|
|
|
462
482
|
```ts
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
importAlias: '#controllers'
|
|
468
|
-
}, {
|
|
469
|
-
destination: '.adonisjs/backend/controllers',
|
|
470
|
-
exportName: 'controllers',
|
|
471
|
-
computeBaseName(filePath, sourcePath) {
|
|
472
|
-
const baseName = relative(sourcePath, filePath)
|
|
473
|
-
return new StringBuilder(baseName).toUnixSlash().removeExtension().removeSuffix('Controller').toString()
|
|
483
|
+
export const controllers = {
|
|
484
|
+
auth: {
|
|
485
|
+
Login: () => import('#controllers/auth/login_controller'),
|
|
486
|
+
Register: () => import('#controllers/auth/register_controller'),
|
|
474
487
|
},
|
|
475
|
-
|
|
488
|
+
blog: {
|
|
489
|
+
Posts: () => import('#controllers/blog/posts_controller'),
|
|
490
|
+
PostComments: () => import('#controllers/blog/post_comments_controller'),
|
|
491
|
+
},
|
|
492
|
+
Users: () => import('#controllers/users_controller'),
|
|
493
|
+
}
|
|
476
494
|
```
|
|
477
495
|
|
|
478
|
-
|
|
479
|
-
|
|
496
|
+
### Types generation
|
|
497
|
+
|
|
498
|
+
To generate a types file, register a custom callback that takes an instance of the `VirtualFileSystem` and updates the output string via the `buffer` object.
|
|
499
|
+
|
|
500
|
+
The collection is represented as key–value pairs:
|
|
501
|
+
|
|
502
|
+
- **Key** — the relative path (without extension) from the root of the source directory.
|
|
503
|
+
- **Value** — an object containing the file's `importPath`, `relativePath`, and `absolutePath`.
|
|
480
504
|
|
|
481
505
|
```ts
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
506
|
+
import hooks from '@adonisjs/assembler/hooks'
|
|
507
|
+
|
|
508
|
+
export default hooks.init((type, parent, indexGenerator) => {
|
|
509
|
+
indexGenerator.add('inertiaPages', {
|
|
510
|
+
source: './inertia/pages',
|
|
511
|
+
as: (vfs, buffer) => {
|
|
512
|
+
buffer.write(`declare module '@adonisjs/inertia' {`).indent()
|
|
513
|
+
buffer.write(`export interface Pages {`).indent()
|
|
514
|
+
|
|
515
|
+
const files = vfs.asList()
|
|
516
|
+
Object.keys(files).forEach((filePath) => {
|
|
517
|
+
buffer.write(
|
|
518
|
+
`'${filePath}': InferPageProps<typeof import('${file.importPath}').default>`
|
|
494
519
|
)
|
|
495
|
-
|
|
496
|
-
|
|
520
|
+
})
|
|
521
|
+
|
|
522
|
+
buffer.dedent().write('}')
|
|
523
|
+
buffer.dedent().write('}')
|
|
497
524
|
},
|
|
498
|
-
|
|
499
|
-
)
|
|
525
|
+
output: './.adonisjs/server/inertia_pages.d.ts',
|
|
526
|
+
})
|
|
527
|
+
})
|
|
500
528
|
```
|
|
501
529
|
|
|
502
530
|
## Contributing
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import {
|
|
2
|
+
VirtualFileSystem,
|
|
3
|
+
debug_default,
|
|
4
|
+
removeExtension,
|
|
5
|
+
throttle
|
|
6
|
+
} from "./chunk-PORDZS62.js";
|
|
7
|
+
|
|
8
|
+
// src/index_generator/source.ts
|
|
9
|
+
import string from "@poppinss/utils/string";
|
|
10
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
11
|
+
import { dirname, join, relative } from "path/posix";
|
|
12
|
+
import StringBuilder from "@poppinss/utils/string_builder";
|
|
13
|
+
|
|
14
|
+
// src/file_buffer.ts
|
|
15
|
+
var FileBuffer = class _FileBuffer {
|
|
16
|
+
/**
|
|
17
|
+
* Collected lines
|
|
18
|
+
*/
|
|
19
|
+
#buffer = [];
|
|
20
|
+
/**
|
|
21
|
+
* Current indentation size. Each call to indent will increment
|
|
22
|
+
* it by 2
|
|
23
|
+
*/
|
|
24
|
+
#identationSize = 0;
|
|
25
|
+
/**
|
|
26
|
+
* Cached compiled output. Once this value is set, the `flush`
|
|
27
|
+
* method will become a noop
|
|
28
|
+
*/
|
|
29
|
+
#compiledOutput;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new child buffer instance
|
|
32
|
+
*
|
|
33
|
+
* @returns A new FileBuffer instance
|
|
34
|
+
*/
|
|
35
|
+
create() {
|
|
36
|
+
return new _FileBuffer();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Returns the size of buffer text
|
|
40
|
+
*
|
|
41
|
+
* @returns The number of lines in the buffer
|
|
42
|
+
*/
|
|
43
|
+
get size() {
|
|
44
|
+
return this.#buffer.length;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Write a new line to the output with current indentation
|
|
48
|
+
*
|
|
49
|
+
* @param text - The text to write as a new line
|
|
50
|
+
* @returns This FileBuffer instance for method chaining
|
|
51
|
+
*/
|
|
52
|
+
writeLine(text) {
|
|
53
|
+
this.#buffer.push(`${" ".repeat(this.#identationSize)}${text}
|
|
54
|
+
`);
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Write text to the output without adding a new line
|
|
59
|
+
*
|
|
60
|
+
* @param text - The text to write without a newline
|
|
61
|
+
* @returns This FileBuffer instance for method chaining
|
|
62
|
+
*/
|
|
63
|
+
write(text) {
|
|
64
|
+
this.#buffer.push(`${" ".repeat(this.#identationSize)}${text}`);
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Increase indentation by 2 spaces
|
|
69
|
+
*
|
|
70
|
+
* @returns This FileBuffer instance for method chaining
|
|
71
|
+
*/
|
|
72
|
+
indent() {
|
|
73
|
+
this.#identationSize += 2;
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Decrease indentation by 2 spaces (minimum of 0)
|
|
78
|
+
*
|
|
79
|
+
* @returns This FileBuffer instance for method chaining
|
|
80
|
+
*/
|
|
81
|
+
dedent() {
|
|
82
|
+
this.#identationSize -= 2;
|
|
83
|
+
if (this.#identationSize < 0) {
|
|
84
|
+
this.#identationSize = 0;
|
|
85
|
+
}
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Return template as a string, joining all buffer lines
|
|
90
|
+
*
|
|
91
|
+
* Once called, the output is cached and subsequent calls return the same result.
|
|
92
|
+
* The flush method becomes a no-op after the first call.
|
|
93
|
+
*
|
|
94
|
+
* @returns The complete buffer content as a string
|
|
95
|
+
*/
|
|
96
|
+
flush() {
|
|
97
|
+
if (this.#compiledOutput !== void 0) {
|
|
98
|
+
return this.#compiledOutput;
|
|
99
|
+
}
|
|
100
|
+
this.#compiledOutput = this.#buffer.join("\n");
|
|
101
|
+
return this.#compiledOutput;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// src/index_generator/source.ts
|
|
106
|
+
var IndexGeneratorSource = class {
|
|
107
|
+
/**
|
|
108
|
+
* The application root directory path
|
|
109
|
+
*/
|
|
110
|
+
#appRoot;
|
|
111
|
+
/**
|
|
112
|
+
* The absolute path to the output file
|
|
113
|
+
*/
|
|
114
|
+
#output;
|
|
115
|
+
/**
|
|
116
|
+
* The absolute path to the source directory
|
|
117
|
+
*/
|
|
118
|
+
#source;
|
|
119
|
+
/**
|
|
120
|
+
* The directory containing the output file
|
|
121
|
+
*/
|
|
122
|
+
#outputDirname;
|
|
123
|
+
/**
|
|
124
|
+
* Virtual file system for scanning source files
|
|
125
|
+
*/
|
|
126
|
+
#vfs;
|
|
127
|
+
/**
|
|
128
|
+
* Configuration for this index generator source
|
|
129
|
+
*/
|
|
130
|
+
#config;
|
|
131
|
+
/**
|
|
132
|
+
* CLI logger instance for output messages
|
|
133
|
+
*/
|
|
134
|
+
#cliLogger;
|
|
135
|
+
/**
|
|
136
|
+
* Generate the output content and write it to the output file
|
|
137
|
+
*
|
|
138
|
+
* This method creates the file buffer, populates it with the generated
|
|
139
|
+
* content based on configuration, and writes it to disk.
|
|
140
|
+
*/
|
|
141
|
+
#generateOutput = throttle(async () => {
|
|
142
|
+
const buffer = new FileBuffer();
|
|
143
|
+
if (this.#config.as === "barrelFile") {
|
|
144
|
+
this.#asBarrelFile(this.#vfs, buffer, this.#config.exportName);
|
|
145
|
+
} else {
|
|
146
|
+
this.#config.as(this.#vfs, buffer, this.#config);
|
|
147
|
+
}
|
|
148
|
+
await mkdir(dirname(this.#output), { recursive: true });
|
|
149
|
+
await writeFile(this.#output, buffer.flush());
|
|
150
|
+
});
|
|
151
|
+
/**
|
|
152
|
+
* Unique name for this index generator source
|
|
153
|
+
*/
|
|
154
|
+
name;
|
|
155
|
+
/**
|
|
156
|
+
* Create a new IndexGeneratorSource instance
|
|
157
|
+
*
|
|
158
|
+
* @param name - Unique name for this index generator source
|
|
159
|
+
* @param appRoot - The application root directory path
|
|
160
|
+
* @param cliLogger - Logger instance for CLI output
|
|
161
|
+
* @param config - Configuration for this index generator source
|
|
162
|
+
*/
|
|
163
|
+
constructor(name, appRoot, cliLogger, config) {
|
|
164
|
+
this.name = name;
|
|
165
|
+
this.#config = config;
|
|
166
|
+
this.#appRoot = appRoot;
|
|
167
|
+
this.#cliLogger = cliLogger;
|
|
168
|
+
this.#source = join(this.#appRoot, this.#config.source);
|
|
169
|
+
this.#output = join(this.#appRoot, this.#config.output);
|
|
170
|
+
this.#outputDirname = dirname(this.#output);
|
|
171
|
+
this.#vfs = new VirtualFileSystem(this.#source, {
|
|
172
|
+
glob: this.#config.glob
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Converts a recursive file tree to a string representation
|
|
177
|
+
*
|
|
178
|
+
* This method recursively processes a file tree structure and writes
|
|
179
|
+
* it as JavaScript object notation to the provided buffer.
|
|
180
|
+
*
|
|
181
|
+
* @param input - The recursive file tree to convert
|
|
182
|
+
* @param buffer - The file buffer to write the output to
|
|
183
|
+
*/
|
|
184
|
+
#treeToString(input, buffer) {
|
|
185
|
+
Object.keys(input).forEach((key) => {
|
|
186
|
+
const value = input[key];
|
|
187
|
+
if (typeof value === "string") {
|
|
188
|
+
buffer.write(`'${key}': ${value},`);
|
|
189
|
+
} else {
|
|
190
|
+
buffer.write(`'${key}': {`).indent();
|
|
191
|
+
this.#treeToString(value, buffer);
|
|
192
|
+
buffer.dedent().write(`},`);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Transforms the barrel file index key. Converts basename to PascalCase
|
|
198
|
+
* and all other paths to camelCase
|
|
199
|
+
*
|
|
200
|
+
* @param config - Configuration containing suffix removal options
|
|
201
|
+
* @returns Function that transforms file paths to appropriate keys
|
|
202
|
+
*/
|
|
203
|
+
#createBarrelFileKeyGenerator(config) {
|
|
204
|
+
return function(key) {
|
|
205
|
+
const paths = key.split("/");
|
|
206
|
+
const baseName = new StringBuilder(paths.pop()).removeSuffix(config.removeSuffix ?? "").pascalCase().toString();
|
|
207
|
+
return [...paths.map((p) => string.camelCase(p)), baseName].join("/");
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Converts the file path to a lazy import. In case of an alias, the source
|
|
212
|
+
* path is replaced with the alias, otherwise a relative import is created
|
|
213
|
+
* from the output dirname.
|
|
214
|
+
*
|
|
215
|
+
* @param source - The source directory path
|
|
216
|
+
* @param outputDirname - The output directory path
|
|
217
|
+
* @param config - Configuration containing import alias options
|
|
218
|
+
* @returns Function that converts file paths to import statements
|
|
219
|
+
*/
|
|
220
|
+
#createBarrelFileImportGenerator(source, outputDirname, config) {
|
|
221
|
+
return function(filePath) {
|
|
222
|
+
if (config.importAlias) {
|
|
223
|
+
debug_default('converting "%s" to import alias, source "%s"', filePath, source);
|
|
224
|
+
return `() => import('${removeExtension(filePath.replace(source, config.importAlias))}')`;
|
|
225
|
+
}
|
|
226
|
+
debug_default('converting "%s" to relative import, source "%s"', filePath, outputDirname);
|
|
227
|
+
return `() => import('${relative(outputDirname, filePath)}')`;
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Generate a barrel file export structure
|
|
232
|
+
*
|
|
233
|
+
* This method creates a nested object structure that represents all
|
|
234
|
+
* discovered files as lazy imports, organized by directory structure.
|
|
235
|
+
*
|
|
236
|
+
* @param vfs - Virtual file system containing the scanned files
|
|
237
|
+
* @param buffer - File buffer to write the barrel exports to
|
|
238
|
+
* @param exportName - Name for the main export object
|
|
239
|
+
*/
|
|
240
|
+
#asBarrelFile(vfs, buffer, exportName) {
|
|
241
|
+
const keyGenerator = this.#createBarrelFileKeyGenerator(this.#config);
|
|
242
|
+
const importGenerator = this.#createBarrelFileImportGenerator(
|
|
243
|
+
this.#source,
|
|
244
|
+
this.#outputDirname,
|
|
245
|
+
this.#config
|
|
246
|
+
);
|
|
247
|
+
const tree = vfs.asTree({
|
|
248
|
+
transformKey: keyGenerator,
|
|
249
|
+
transformValue: importGenerator
|
|
250
|
+
});
|
|
251
|
+
buffer.write(`export const ${exportName} = {`).indent();
|
|
252
|
+
this.#treeToString(tree, buffer);
|
|
253
|
+
buffer.dedent().write(`}`);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Create a log action for tracking file generation progress
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* const action = this.#createLogAction()
|
|
260
|
+
* // ... perform operations
|
|
261
|
+
* action.displayDuration().succeeded()
|
|
262
|
+
*/
|
|
263
|
+
#createLogAction() {
|
|
264
|
+
return this.#cliLogger.action(`create ${this.#config.output}`);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Add a file to the virtual file system and regenerate index if needed
|
|
268
|
+
*
|
|
269
|
+
* If the file matches the configured glob patterns, it will be added
|
|
270
|
+
* to the virtual file system and the index file will be regenerated.
|
|
271
|
+
*
|
|
272
|
+
* @param filePath - Absolute path of the file to add
|
|
273
|
+
*/
|
|
274
|
+
async addFile(filePath) {
|
|
275
|
+
const added = this.#vfs.add(filePath);
|
|
276
|
+
if (added) {
|
|
277
|
+
debug_default('file added, re-generating "%s" index', this.name);
|
|
278
|
+
const action = this.#createLogAction();
|
|
279
|
+
await this.#generateOutput();
|
|
280
|
+
action.displayDuration().succeeded();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Remove a file from the virtual file system and regenerate index if needed
|
|
285
|
+
*
|
|
286
|
+
* If the file was previously tracked, it will be removed from the
|
|
287
|
+
* virtual file system and the index file will be regenerated.
|
|
288
|
+
*
|
|
289
|
+
* @param filePath - Absolute path of the file to remove
|
|
290
|
+
*/
|
|
291
|
+
async removeFile(filePath) {
|
|
292
|
+
const removed = this.#vfs.remove(filePath);
|
|
293
|
+
if (removed) {
|
|
294
|
+
debug_default('file removed, re-generating "%s" index', this.name);
|
|
295
|
+
const action = this.#createLogAction();
|
|
296
|
+
await this.#generateOutput();
|
|
297
|
+
action.displayDuration().succeeded();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Generate the index file
|
|
302
|
+
*
|
|
303
|
+
* This method scans the source directory, processes files according to
|
|
304
|
+
* the configuration, and writes the generated index file to disk.
|
|
305
|
+
*/
|
|
306
|
+
async generate() {
|
|
307
|
+
const action = this.#createLogAction();
|
|
308
|
+
await this.#vfs.scan();
|
|
309
|
+
await this.#generateOutput();
|
|
310
|
+
action.displayDuration().succeeded();
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// src/index_generator/main.ts
|
|
315
|
+
var IndexGenerator = class {
|
|
316
|
+
/**
|
|
317
|
+
* The application root directory path
|
|
318
|
+
*/
|
|
319
|
+
#appRoot;
|
|
320
|
+
/**
|
|
321
|
+
* Collection of registered index generator sources
|
|
322
|
+
*/
|
|
323
|
+
#sources = {};
|
|
324
|
+
#cliLogger;
|
|
325
|
+
/**
|
|
326
|
+
* Create a new IndexGenerator instance
|
|
327
|
+
*
|
|
328
|
+
* @param appRoot - The application root directory path
|
|
329
|
+
* @param cliLogger - Logger instance for CLI output
|
|
330
|
+
*/
|
|
331
|
+
constructor(appRoot, cliLogger) {
|
|
332
|
+
this.#appRoot = appRoot;
|
|
333
|
+
this.#cliLogger = cliLogger;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Add a new index generator source
|
|
337
|
+
*
|
|
338
|
+
* @param name - Unique name for the source
|
|
339
|
+
* @param config - Configuration for the index generator source
|
|
340
|
+
* @returns This IndexGenerator instance for method chaining
|
|
341
|
+
*/
|
|
342
|
+
add(name, config) {
|
|
343
|
+
this.#sources[name] = new IndexGeneratorSource(name, this.#appRoot, this.#cliLogger, config);
|
|
344
|
+
return this;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Add a file to all registered index generator sources
|
|
348
|
+
*
|
|
349
|
+
* This method propagates the file addition to all registered sources,
|
|
350
|
+
* allowing them to regenerate their index files if the new file matches
|
|
351
|
+
* their glob patterns.
|
|
352
|
+
*
|
|
353
|
+
* @param filePath - Absolute path of the file to add
|
|
354
|
+
*/
|
|
355
|
+
async addFile(filePath) {
|
|
356
|
+
const sources = Object.values(this.#sources);
|
|
357
|
+
for (let source of sources) {
|
|
358
|
+
await source.addFile(filePath);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Remove a file from all registered index generator sources
|
|
363
|
+
*
|
|
364
|
+
* This method propagates the file removal to all registered sources,
|
|
365
|
+
* allowing them to regenerate their index files if the removed file
|
|
366
|
+
* was previously tracked.
|
|
367
|
+
*
|
|
368
|
+
* @param filePath - Absolute path of the file to remove
|
|
369
|
+
*/
|
|
370
|
+
async removeFile(filePath) {
|
|
371
|
+
const sources = Object.values(this.#sources);
|
|
372
|
+
for (let source of sources) {
|
|
373
|
+
await source.removeFile(filePath);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Generate all registered index files
|
|
378
|
+
*
|
|
379
|
+
* Iterates through all registered sources and generates their
|
|
380
|
+
* corresponding index files.
|
|
381
|
+
*/
|
|
382
|
+
async generate() {
|
|
383
|
+
const sources = Object.values(this.#sources);
|
|
384
|
+
for (let source of sources) {
|
|
385
|
+
await source.generate();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
export {
|
|
391
|
+
IndexGenerator
|
|
392
|
+
};
|