@ts-for-gir/cli 4.0.0-beta.9 → 4.0.0-rc.1

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.
Files changed (64) hide show
  1. package/README.md +295 -84
  2. package/bin/ts-for-gir +26569 -0
  3. package/bin/ts-for-gir-dev +43 -0
  4. package/package.json +39 -38
  5. package/src/commands/analyze.ts +344 -0
  6. package/src/commands/command-builder.ts +30 -0
  7. package/src/commands/copy.ts +71 -76
  8. package/src/commands/doc.ts +44 -47
  9. package/src/commands/generate.ts +35 -79
  10. package/src/commands/index.ts +6 -4
  11. package/src/commands/json.ts +43 -0
  12. package/src/commands/list.ts +71 -90
  13. package/src/commands/run-generation-command.ts +70 -0
  14. package/src/config/config-loader.ts +190 -0
  15. package/src/config/config-writer.ts +52 -0
  16. package/src/config/defaults.ts +66 -0
  17. package/src/config/index.ts +8 -0
  18. package/src/config/options.ts +315 -0
  19. package/src/config.ts +3 -456
  20. package/src/formatters/typescript-formatter.ts +24 -0
  21. package/src/generation-handler.ts +122 -67
  22. package/src/index.ts +4 -4
  23. package/src/module-loader/dependency-resolver.ts +100 -0
  24. package/src/module-loader/file-finder.ts +65 -0
  25. package/src/module-loader/index.ts +8 -0
  26. package/src/module-loader/module-grouper.ts +77 -0
  27. package/src/module-loader/prompt-handler.ts +111 -0
  28. package/src/module-loader.ts +289 -578
  29. package/src/start.ts +17 -14
  30. package/src/types/command-args.ts +118 -0
  31. package/src/types/command-definition.ts +17 -0
  32. package/src/types/commands.ts +30 -0
  33. package/src/types/index.ts +15 -0
  34. package/src/types/report-types.ts +34 -0
  35. package/lib/commands/copy.d.ts +0 -12
  36. package/lib/commands/copy.js +0 -80
  37. package/lib/commands/copy.js.map +0 -1
  38. package/lib/commands/doc.d.ts +0 -12
  39. package/lib/commands/doc.js +0 -40
  40. package/lib/commands/doc.js.map +0 -1
  41. package/lib/commands/generate.d.ts +0 -12
  42. package/lib/commands/generate.js +0 -71
  43. package/lib/commands/generate.js.map +0 -1
  44. package/lib/commands/index.d.ts +0 -4
  45. package/lib/commands/index.js +0 -5
  46. package/lib/commands/index.js.map +0 -1
  47. package/lib/commands/list.d.ts +0 -12
  48. package/lib/commands/list.js +0 -81
  49. package/lib/commands/list.js.map +0 -1
  50. package/lib/config.d.ts +0 -108
  51. package/lib/config.js +0 -410
  52. package/lib/config.js.map +0 -1
  53. package/lib/generation-handler.d.ts +0 -10
  54. package/lib/generation-handler.js +0 -48
  55. package/lib/generation-handler.js.map +0 -1
  56. package/lib/index.d.ts +0 -4
  57. package/lib/index.js +0 -5
  58. package/lib/index.js.map +0 -1
  59. package/lib/module-loader.d.ts +0 -148
  60. package/lib/module-loader.js +0 -468
  61. package/lib/module-loader.js.map +0 -1
  62. package/lib/start.d.ts +0 -2
  63. package/lib/start.js +0 -16
  64. package/lib/start.js.map +0 -1
package/src/config.ts CHANGED
@@ -1,460 +1,7 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2
1
  /**
3
2
  * Default values, parse the config file and handle CLI flags
3
+ *
4
+ * This file re-exports all config functionality from the config module
4
5
  */
5
- import { Options } from 'yargs'
6
- import { cosmiconfig, Options as ConfigSearchOptions } from 'cosmiconfig'
7
- import { join, extname, dirname, resolve } from 'path'
8
- import { writeFile } from 'fs/promises'
9
- import { existsSync } from 'fs'
10
- import { merge, isEqual, Logger, APP_NAME, APP_USAGE, ERROR_CONFIG_EXTENSION_UNSUPPORTED } from '@ts-for-gir/lib'
11
6
 
12
- import type { UserConfig, ConfigFlags, UserConfigLoadResult, OptionsGeneration } from '@ts-for-gir/lib'
13
-
14
- export class Config {
15
- static appName = APP_NAME
16
-
17
- static usage = APP_USAGE
18
-
19
- /**
20
- * Default cli flag and argument values
21
- */
22
- static defaults = {
23
- print: false,
24
- configName: '.ts-for-girrc.js',
25
- root: process.cwd(),
26
- outdir: './@types',
27
- girDirectories: getDefaultGirDirectories(),
28
- modules: ['*'],
29
- ignore: [],
30
- verbose: false,
31
- ignoreVersionConflicts: false,
32
- noNamespace: false,
33
- noComments: false,
34
- promisify: true,
35
- npmScope: '@girs',
36
- workspace: false,
37
- onlyVersionPrefix: false,
38
- noPrettyPrint: false,
39
- // Disabled by default because advanced variants are complicated,
40
- // it does impact performance (especially on older typescript versions)
41
- // and we'd need to test it works with the updated bindings
42
- noAdvancedVariants: true,
43
- package: false,
44
- }
45
-
46
- static configFilePath = join(process.cwd(), Config.defaults.configName)
47
-
48
- /**
49
- * CLI options used in commands/generate.ts and commands/list.ts
50
- */
51
- static options: { [name: string]: Options } = {
52
- modules: {
53
- description: "GIR modules to load, e.g. 'Gio-2.0'. Accepts multiple modules",
54
- array: true,
55
- default: Config.defaults.modules,
56
- normalize: true,
57
- },
58
- girDirectories: {
59
- type: 'string',
60
- alias: 'g',
61
- description: 'GIR directories',
62
- array: true,
63
- default: Config.defaults.girDirectories,
64
- normalize: true,
65
- },
66
- root: {
67
- type: 'string',
68
- description: 'Root directory of your project',
69
- default: Config.defaults.root,
70
- normalize: true,
71
- },
72
- outdir: {
73
- type: 'string',
74
- alias: 'o',
75
- description: 'Directory to output to',
76
- default: Config.defaults.outdir,
77
- normalize: true,
78
- },
79
- ignore: {
80
- type: 'string',
81
- alias: 'i',
82
- description: 'Modules that should be ignored',
83
- array: true,
84
- default: Config.defaults.ignore,
85
- normalize: true,
86
- },
87
- verbose: {
88
- type: 'boolean',
89
- alias: 'v',
90
- description: 'Switch on/off the verbose mode',
91
- default: Config.defaults.verbose,
92
- normalize: true,
93
- },
94
- ignoreVersionConflicts: {
95
- type: 'boolean',
96
- description: 'Skip prompts for library version selection when multiple versions are detected',
97
- default: Config.defaults.ignoreVersionConflicts,
98
- normalize: true,
99
- },
100
- print: {
101
- type: 'boolean',
102
- alias: 'p',
103
- description: 'Print the output to console and create no files',
104
- default: Config.defaults.print,
105
- normalize: true,
106
- },
107
- configName: {
108
- type: 'string',
109
- description: 'Specify a custom name for the configuration file',
110
- default: Config.defaults.configName,
111
- normalize: true,
112
- },
113
- noNamespace: {
114
- type: 'boolean',
115
- alias: 'd',
116
- description: 'Do not export all symbols for each module as a namespace',
117
- default: Config.defaults.noNamespace,
118
- normalize: true,
119
- },
120
- noComments: {
121
- type: 'boolean',
122
- alias: 'n',
123
- description: 'Do not generate documentation comments',
124
- default: Config.defaults.noComments,
125
- normalize: true,
126
- },
127
- promisify: {
128
- type: 'boolean',
129
- description: 'Generate promisified functions for async/finish calls',
130
- default: Config.defaults.promisify,
131
- normalize: true,
132
- },
133
- npmScope: {
134
- type: 'string',
135
- description: 'Scope of the generated NPM packages',
136
- default: Config.defaults.npmScope,
137
- normalize: true,
138
- },
139
- workspace: {
140
- type: 'boolean',
141
- description:
142
- 'Uses the workspace protocol for the generated packages which can be used with package managers like Yarn and PNPM',
143
- default: Config.defaults.workspace,
144
- normalize: true,
145
- },
146
- onlyVersionPrefix: {
147
- type: 'boolean',
148
- description:
149
- 'Only use the version prefix for the ambient module exports. This is useful if, for whatever reason, you want to use different library versions of the same library in your project.',
150
- default: Config.defaults.onlyVersionPrefix,
151
- normalize: true,
152
- },
153
- noPrettyPrint: {
154
- type: 'boolean',
155
- description: 'Do not prettify the generated types',
156
- default: Config.defaults.noPrettyPrint,
157
- normalize: true,
158
- },
159
- noAdvancedVariants: {
160
- type: 'boolean',
161
- description: 'Disable GLib.Variant class with string parsing',
162
- default: Config.defaults.noAdvancedVariants,
163
- normalize: true,
164
- },
165
- package: {
166
- type: 'boolean',
167
- description: 'Generate the typescript types with package.json support',
168
- default: Config.defaults.package,
169
- normalize: true,
170
- },
171
- }
172
-
173
- /**
174
- * CLI flags used in commands/generate.ts
175
- */
176
- static generateOptions = {
177
- modules: this.options.modules,
178
- girDirectories: this.options.girDirectories,
179
- root: this.options.root,
180
- outdir: this.options.outdir,
181
- ignore: this.options.ignore,
182
- verbose: this.options.verbose,
183
- ignoreVersionConflicts: this.options.ignoreVersionConflicts,
184
- print: this.options.print,
185
- configName: this.options.configName,
186
- noNamespace: this.options.noNamespace,
187
- noComments: this.options.noComments,
188
- promisify: this.options.promisify,
189
- npmScope: this.options.npmScope,
190
- workspace: this.options.workspace,
191
- onlyVersionPrefix: this.options.onlyVersionPrefix,
192
- noPrettyPrint: this.options.noPrettyPrint,
193
- noAdvancedVariants: this.options.noAdvancedVariants,
194
- package: this.options.package,
195
- }
196
-
197
- static listOptions = {
198
- modules: this.options.modules,
199
- girDirectories: Config.options.girDirectories,
200
- root: this.options.root,
201
- ignore: Config.options.ignore,
202
- configName: Config.options.configName,
203
- verbose: Config.options.verbose,
204
- }
205
-
206
- static copyOptions = {
207
- modules: this.options.modules,
208
- girDirectories: Config.options.girDirectories,
209
- root: this.options.root,
210
- outdir: Config.options.outdir,
211
- ignore: Config.options.ignore,
212
- configName: Config.options.configName,
213
- verbose: Config.options.verbose,
214
- }
215
-
216
- static docOptions = {
217
- modules: this.options.modules,
218
- girDirectories: Config.options.girDirectories,
219
- root: this.options.root,
220
- outdir: Config.options.outdir,
221
- ignore: Config.options.ignore,
222
- verbose: Config.options.verbose,
223
- ignoreVersionConflicts: Config.options.ignoreVersionConflicts,
224
- configName: Config.options.configName,
225
- }
226
-
227
- /**
228
- * Overwrites values in the user config file
229
- * @param configsToAdd
230
- */
231
- public static async addToConfig(configsToAdd: Partial<UserConfig>, configName?: string): Promise<void> {
232
- const userConfig = await this.loadConfigFile(configName)
233
- const path = userConfig?.filepath || this.configFilePath
234
- const configToStore = {}
235
- merge(configToStore, userConfig?.config || {}, configsToAdd)
236
- const fileExtension = extname(path)
237
- let writeConfigString = ''
238
- switch (fileExtension) {
239
- case '.js':
240
- writeConfigString = `export default ${JSON.stringify(configToStore, null, 4)}`
241
- break
242
- case '.json':
243
- writeConfigString = `${JSON.stringify(configToStore, null, 4)}`
244
- break
245
- default:
246
- Logger.error(ERROR_CONFIG_EXTENSION_UNSUPPORTED)
247
- break
248
- }
249
- if (writeConfigString && path) {
250
- return writeFile(path, writeConfigString)
251
- }
252
- }
253
-
254
- /**
255
- * The user can create a `.ts-for-girrc` file for his default configs,
256
- * this method load this config file an returns the user configuration
257
- * @param configName If the user uses a custom config file name
258
- */
259
- private static async loadConfigFile(configName?: string): Promise<UserConfigLoadResult | null> {
260
- const configSearchOptions: Partial<ConfigSearchOptions> = {
261
- loaders: {
262
- // ESM loader
263
- '.js': async (filepath) => {
264
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
265
- const file = await import(filepath)
266
-
267
- // Files with `exports.default = { ... }`
268
- if (file?.default?.default) {
269
- return file.default.default as Partial<UserConfig>
270
- }
271
- // Files with `export default { ... }`
272
- if (file?.default) {
273
- return file.default as Partial<UserConfig>
274
- }
275
- // Files with `export { ... }`
276
- return file as Partial<UserConfig>
277
- },
278
- },
279
- }
280
- if (configName) {
281
- configSearchOptions.searchPlaces = [configName]
282
- }
283
- const configFile: UserConfigLoadResult | null = await cosmiconfig(Config.appName, configSearchOptions).search()
284
- if (configFile?.filepath) {
285
- Config.configFilePath = configFile.filepath
286
- }
287
-
288
- return configFile
289
- }
290
-
291
- public static getOptionsGeneration(config: UserConfig): OptionsGeneration {
292
- const generateConfig: OptionsGeneration = {
293
- ...config,
294
- }
295
- return generateConfig
296
- }
297
-
298
- public static validate(config: UserConfig): UserConfig {
299
- return config
300
- }
301
-
302
- /**
303
- * Loads the values of the config file and concatenate them with passed cli flags / arguments.
304
- * The values from config file are preferred if the cli flag value is the default (and so not set / overwritten)
305
- * @param options
306
- */
307
- public static async load(options: ConfigFlags): Promise<UserConfig> {
308
- const configFile = await this.loadConfigFile(options.configName)
309
- const configFileData = configFile?.config || {}
310
-
311
- const config: UserConfig = {
312
- ...options,
313
- }
314
-
315
- if (configFileData) {
316
- // verbose
317
- if (config.verbose === Config.options.verbose.default && typeof configFileData.verbose === 'boolean') {
318
- config.verbose = configFileData.verbose
319
- }
320
- // ignoreVersionConflicts
321
- if (
322
- config.ignoreVersionConflicts === Config.options.ignoreVersionConflicts.default &&
323
- typeof configFileData.ignoreVersionConflicts === 'boolean'
324
- ) {
325
- config.ignoreVersionConflicts = configFileData.ignoreVersionConflicts
326
- }
327
- // print
328
- if (config.print === Config.options.print.default && typeof configFileData.print === 'boolean') {
329
- config.print = configFileData.print
330
- }
331
- // root
332
- if (config.root === Config.options.root.default && (configFileData.root || configFile?.filepath)) {
333
- // Use the config file path as the root path if no root path is set
334
- config.root =
335
- configFileData.root ||
336
- (configFile?.filepath ? dirname(configFile.filepath) : (Config.options.root.default as string))
337
- }
338
- // outdir
339
- if (config.outdir === Config.options.outdir.default && configFileData.outdir) {
340
- config.outdir = config.print ? null : configFileData.outdir
341
- }
342
- // girDirectories
343
- if (config.girDirectories === Config.options.girDirectories.default && configFileData.girDirectories) {
344
- config.girDirectories = configFileData.girDirectories
345
- }
346
- // ignore
347
- if (
348
- (!config.ignore || config.ignore.length <= 0 || isEqual(config.ignore, Config.defaults.ignore)) &&
349
- configFileData.ignore
350
- ) {
351
- config.ignore = configFileData.ignore
352
- }
353
- // modules
354
- if (
355
- (config.modules.length <= 0 || isEqual(config.modules, Config.defaults.modules)) &&
356
- configFileData.modules
357
- ) {
358
- config.modules = configFileData.modules
359
- }
360
- // noNamespace
361
- if (
362
- config.noNamespace === Config.options.noNamespace.default &&
363
- typeof configFileData.noNamespace === 'boolean'
364
- ) {
365
- config.noNamespace = configFileData.noNamespace
366
- }
367
- // noComments
368
- if (
369
- config.noComments === Config.options.noComments.default &&
370
- typeof configFileData.noComments === 'boolean'
371
- ) {
372
- config.noComments = configFileData.noComments
373
- }
374
- // promisify
375
- if (
376
- config.promisify === Config.options.promisify.default &&
377
- typeof configFileData.promisify === 'boolean'
378
- ) {
379
- config.promisify = configFileData.promisify
380
- }
381
- // npmScope
382
- if (config.npmScope === Config.options.npmScope.default && configFileData.npmScope) {
383
- config.npmScope = configFileData.npmScope
384
- }
385
- // workspace
386
- if (
387
- config.workspace === Config.options.workspace.default &&
388
- typeof configFileData.workspace === 'boolean'
389
- ) {
390
- config.workspace = configFileData.workspace
391
- }
392
- // onlyVersionPrefix
393
- if (
394
- config.onlyVersionPrefix === Config.options.onlyVersionPrefix.default &&
395
- typeof configFileData.onlyVersionPrefix === 'boolean'
396
- ) {
397
- config.onlyVersionPrefix = configFileData.onlyVersionPrefix
398
- }
399
- // noPrettyPrint
400
- if (
401
- config.noPrettyPrint === Config.options.noPrettyPrint.default &&
402
- typeof configFileData.noPrettyPrint === 'boolean'
403
- ) {
404
- config.noPrettyPrint = configFileData.noPrettyPrint
405
- }
406
- // noAdvancedVariants
407
- if (
408
- config.noAdvancedVariants === Config.options.noAdvancedVariants.default &&
409
- typeof configFileData.noAdvancedVariants === 'boolean'
410
- ) {
411
- config.noAdvancedVariants = configFileData.noAdvancedVariants
412
- }
413
- // package
414
- if (config.package === Config.options.package.default && typeof configFileData.package === 'boolean') {
415
- config.package = configFileData.package
416
- }
417
- }
418
-
419
- // If outdir is not absolute, make it absolute to the root path
420
- if (config.outdir && !config.outdir?.startsWith('/')) {
421
- config.outdir = resolve(config.root, config.outdir)
422
- }
423
-
424
- // Same for girDirectories
425
- if (config.girDirectories) {
426
- config.girDirectories = config.girDirectories.map((dir) => {
427
- if (!dir.startsWith('/')) {
428
- return resolve(config.root, dir)
429
- }
430
- return dir
431
- })
432
- }
433
-
434
- return this.validate(config)
435
- }
436
- }
437
-
438
- function getDefaultGirDirectories(): string[] {
439
- const girDirectories = [
440
- '/usr/local/share/gir-1.0',
441
- '/usr/share/gir-1.0',
442
- '/usr/share/*/gir-1.0',
443
- '/usr/share/gnome-shell',
444
- '/usr/share/gnome-shell/gir-1.0',
445
- '/usr/lib64/mutter-*',
446
- '/usr/lib/mutter-*',
447
- '/usr/lib/x86_64-linux-gnu/mutter-*',
448
- ]
449
- // NixOS and other distributions does not have a /usr/local/share directory.
450
- // Instead, the nix store paths with Gir files are set as XDG_DATA_DIRS.
451
- // See https://github.com/NixOS/nixpkgs/blob/96e18717904dfedcd884541e5a92bf9ff632cf39/pkgs/development/libraries/gobject-introspection/setup-hook.sh#L7-L10
452
- const dataDirs = process.env['XDG_DATA_DIRS']?.split(':') || []
453
- for (let dataDir of dataDirs) {
454
- dataDir = join(dataDir, 'gir-1.0')
455
- if (!girDirectories.includes(dataDir) && existsSync(dataDir)) {
456
- girDirectories.push(dataDir)
457
- }
458
- }
459
- return girDirectories
460
- }
7
+ export * from "./config/index.ts";
@@ -0,0 +1,24 @@
1
+ /**
2
+ * TypeScript formatter using Prettier
3
+ */
4
+
5
+ import { Formatter, Logger } from "@ts-for-gir/lib";
6
+ import prettier from "prettier";
7
+
8
+ const logger = new Logger(false, "TypeScriptFormatter");
9
+
10
+ export class TypeScriptFormatter extends Formatter {
11
+ format(input: string): Promise<string> {
12
+ try {
13
+ return prettier.format(input, {
14
+ singleQuote: true,
15
+ parser: "typescript",
16
+ printWidth: 120,
17
+ tabWidth: 4,
18
+ });
19
+ } catch (error) {
20
+ logger.warn("Failed to format with prettier, returning original input", error);
21
+ return Promise.resolve(input);
22
+ }
23
+ }
24
+ }
@@ -1,71 +1,126 @@
1
- import { mkdir } from 'fs/promises'
1
+ import { mkdir } from "node:fs/promises";
2
+ import { type Generator, GeneratorType } from "@ts-for-gir/generator-base";
3
+ import { HtmlDocGenerator } from "@ts-for-gir/generator-html-doc";
4
+ import { JsonDefinitionGenerator } from "@ts-for-gir/generator-json";
5
+ import { TypeDefinitionGenerator } from "@ts-for-gir/generator-typescript";
2
6
  import {
3
- GirModule,
4
- Logger,
5
- START_MODULE,
6
- FILE_PARSING_DONE,
7
- TSDATA_PARSING_DONE,
8
- GENERATING_TYPES_DONE,
9
- ERROR_NO_MODULE_SPECIFIED,
10
- } from '@ts-for-gir/lib'
11
- import { GeneratorType, Generator } from '@ts-for-gir/generator-base'
12
- import { TypeDefinitionGenerator } from '@ts-for-gir/generator-typescript'
13
- import { HtmlDocGenerator } from '@ts-for-gir/generator-html-doc'
14
-
15
- import type { OptionsGeneration, NSRegistry } from '@ts-for-gir/lib'
7
+ conflictsReporter,
8
+ ERROR_NO_MODULE_SPECIFIED,
9
+ FILE_PARSING_DONE,
10
+ GENERATING_TYPES_DONE,
11
+ type GirModule,
12
+ girParsingReporter,
13
+ type NSRegistry,
14
+ type OptionsGeneration,
15
+ Reporter,
16
+ ReporterService,
17
+ START_MODULE,
18
+ TSDATA_PARSING_DONE,
19
+ TypeIdentifier,
20
+ } from "@ts-for-gir/lib";
16
21
 
17
22
  export class GenerationHandler {
18
- log: Logger
19
- generator: Generator
20
-
21
- constructor(
22
- private readonly config: OptionsGeneration,
23
- type: GeneratorType,
24
- ) {
25
- this.log = new Logger(config.verbose, 'GenerationHandler')
26
-
27
- switch (type) {
28
- case GeneratorType.TYPES:
29
- this.generator = new TypeDefinitionGenerator(config)
30
- break
31
- case GeneratorType.HTML_DOC:
32
- this.generator = new HtmlDocGenerator(config)
33
- break
34
- default:
35
- throw new Error('Unknown Generator')
36
- }
37
- }
38
-
39
- public async start(girModules: GirModule[], registry: NSRegistry): Promise<void> {
40
- this.log.info(START_MODULE)
41
-
42
- if (girModules.length == 0) {
43
- this.log.error(ERROR_NO_MODULE_SPECIFIED)
44
- }
45
-
46
- this.log.info(FILE_PARSING_DONE)
47
-
48
- this.log.info(TSDATA_PARSING_DONE)
49
-
50
- if (this.config.outdir) {
51
- await mkdir(this.config.outdir, { recursive: true })
52
- }
53
-
54
- // TODO: Put this somewhere that makes sense
55
- registry.transform({
56
- inferGenerics: true,
57
- verbose: this.config.verbose,
58
- })
59
-
60
- await this.generator.start(registry)
61
-
62
- for (const girModule of girModules) {
63
- this.log.log(` - ${girModule.packageName} ...`)
64
- await this.generator.generate(registry, girModule)
65
- }
66
-
67
- await this.generator.finish(registry, girModules)
68
-
69
- this.log.success(GENERATING_TYPES_DONE)
70
- }
23
+ log: Reporter;
24
+ generator: Generator;
25
+ protected readonly config: OptionsGeneration;
26
+ protected readonly registry: NSRegistry;
27
+ private readonly reporterService: ReporterService;
28
+
29
+ constructor(config: OptionsGeneration, type: GeneratorType, registry: NSRegistry) {
30
+ this.registry = registry;
31
+ this.config = config;
32
+ this.log = new Reporter(config.verbose, "GenerationHandler", config.reporter, config.reporterOutput);
33
+ this.reporterService = ReporterService.getInstance();
34
+
35
+ // Configure the reporter service
36
+ this.reporterService.configure(config.reporter, config.reporterOutput);
37
+
38
+ // Configure reporters globally
39
+ TypeIdentifier.configureReporter(config.reporter, config.reporterOutput);
40
+ conflictsReporter.configure(config.reporter, config.reporterOutput);
41
+ girParsingReporter.configure(config.reporter, config.reporterOutput);
42
+
43
+ // Register the main handler reporter
44
+ if (config.reporter) {
45
+ this.reporterService.registerReporter("GenerationHandler", this.log);
46
+ }
47
+
48
+ switch (type) {
49
+ case GeneratorType.TYPES:
50
+ this.generator = new TypeDefinitionGenerator(config, this.registry);
51
+ break;
52
+ case GeneratorType.HTML_DOC:
53
+ this.generator = new HtmlDocGenerator(config, this.registry);
54
+ break;
55
+ case GeneratorType.JSON:
56
+ this.generator = new JsonDefinitionGenerator(config, this.registry);
57
+ break;
58
+ default:
59
+ throw new Error("Unknown Generator");
60
+ }
61
+ }
62
+
63
+ public async start(girModules: GirModule[]): Promise<void> {
64
+ this.log.info(START_MODULE);
65
+
66
+ if (girModules.length === 0) {
67
+ this.log.error(ERROR_NO_MODULE_SPECIFIED);
68
+ }
69
+
70
+ this.log.info(FILE_PARSING_DONE);
71
+
72
+ this.log.info(TSDATA_PARSING_DONE);
73
+
74
+ try {
75
+ if (this.config.outdir) {
76
+ await mkdir(this.config.outdir, { recursive: true });
77
+ }
78
+
79
+ // TODO: Put this somewhere that makes sense
80
+ this.registry.transform({
81
+ inferGenerics: true,
82
+ verbose: this.config.verbose,
83
+ reporter: this.config.reporter,
84
+ reporterOutput: this.config.reporterOutput,
85
+ });
86
+
87
+ await this.generator.start();
88
+
89
+ for (const girModule of girModules) {
90
+ this.log.log(` - ${girModule.packageName} ...`);
91
+ await this.generator.generate(girModule);
92
+ }
93
+
94
+ await this.generator.finish(girModules);
95
+
96
+ this.log.success(GENERATING_TYPES_DONE);
97
+ } finally {
98
+ // Generate comprehensive report if reporter is enabled
99
+ // This will run even if there's an error
100
+ if (this.config.reporter) {
101
+ await this.generateComprehensiveReport();
102
+ }
103
+ }
104
+ }
105
+
106
+ private async generateComprehensiveReport(): Promise<void> {
107
+ try {
108
+ // Generate report once, pass to print and save
109
+ const report = this.reporterService.generateComprehensiveReport();
110
+
111
+ this.reporterService.printComprehensiveSummary(report);
112
+ await this.reporterService.saveComprehensiveReport(undefined, report);
113
+
114
+ const totalProblems = report.statistics.totalProblems;
115
+ const modulesProcessed = this.reporterService.getReporters().size;
116
+
117
+ if (totalProblems > 0) {
118
+ this.log.info(`📊 Generated comprehensive report: ${totalProblems} issues across ${modulesProcessed} modules`);
119
+ } else {
120
+ this.log.success("🎉 Generation completed without any reported issues across all modules!");
121
+ }
122
+ } catch (error) {
123
+ this.log.danger(`Failed to generate comprehensive report: ${error}`);
124
+ }
125
+ }
71
126
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './commands/index.js'
2
- export * from './config.js'
3
- export * from './generation-handler.js'
4
- export * from './module-loader.js'
1
+ export * from "./commands/index.ts";
2
+ export * from "./config.ts";
3
+ export * from "./generation-handler.ts";
4
+ export * from "./module-loader.ts";