@ts-for-gir/cli 3.0.0-beta.6 → 3.0.0-beta.8

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 (71) hide show
  1. package/README.md +15 -6
  2. package/lib/commands/generate.d.ts +2 -0
  3. package/lib/commands/generate.js +3 -2
  4. package/lib/commands/generate.js.map +1 -1
  5. package/lib/config.d.ts +3 -18
  6. package/lib/config.js +55 -48
  7. package/lib/config.js.map +1 -1
  8. package/lib/template-processor.d.ts +33 -4
  9. package/lib/template-processor.js +68 -15
  10. package/lib/template-processor.js.map +1 -1
  11. package/lib/type-definition-generator.d.ts +0 -1
  12. package/lib/type-definition-generator.js +14 -13
  13. package/lib/type-definition-generator.js.map +1 -1
  14. package/lib/types/build-type.d.ts +1 -1
  15. package/lib/types/construct-name.d.ts +1 -1
  16. package/lib/types/environment.d.ts +1 -1
  17. package/lib/types/generate-config.d.ts +2 -0
  18. package/lib/types/gir-any-element.d.ts +1 -1
  19. package/lib/types/gir-boolean.d.ts +1 -1
  20. package/lib/types/gir-unparsed-number.d.ts +1 -1
  21. package/lib/types/injection-generic-parameter.d.ts +1 -1
  22. package/lib/types/injection-instance-parameter.d.ts +1 -1
  23. package/lib/types/injection-type.d.ts +1 -1
  24. package/lib/types/local-name-type.d.ts +1 -1
  25. package/lib/types/module-type.d.ts +1 -1
  26. package/lib/types/transformation-case.d.ts +1 -1
  27. package/lib/types/ts-method.d.ts +1 -1
  28. package/lib/types/ts-type-name.d.ts +1 -1
  29. package/lib/types/ts-type-separator.d.ts +1 -1
  30. package/lib/types/type-gir-alias.d.ts +1 -1
  31. package/lib/types/type-gir-class.d.ts +1 -1
  32. package/lib/types/type-gir-element.d.ts +1 -1
  33. package/lib/types/type-gir-enumeration-member.d.ts +1 -1
  34. package/lib/types/type-gir-enumeration.d.ts +1 -1
  35. package/lib/types/type-gir-function.d.ts +1 -1
  36. package/lib/types/type-gir-interface.d.ts +1 -1
  37. package/lib/types/type-gir-method.d.ts +1 -1
  38. package/lib/types/type-gir-parameter.d.ts +1 -1
  39. package/lib/types/type-gir-property.d.ts +1 -1
  40. package/lib/types/type-gir-variable.d.ts +1 -1
  41. package/lib/types/type-ts-element.d.ts +1 -1
  42. package/lib/types/type-ts-enumeration-member.d.ts +1 -1
  43. package/lib/types/type-ts-function.d.ts +1 -1
  44. package/lib/types/type-ts-property.d.ts +1 -1
  45. package/lib/types/user-config.d.ts +2 -0
  46. package/lib/utils.d.ts +11 -4
  47. package/lib/utils.js +6 -8
  48. package/lib/utils.js.map +1 -1
  49. package/package.json +34 -19
  50. package/src/commands/generate.ts +3 -2
  51. package/src/config.ts +76 -76
  52. package/src/template-processor.ts +78 -15
  53. package/src/type-definition-generator.ts +14 -14
  54. package/src/types/generate-config.ts +2 -0
  55. package/src/types/user-config.ts +2 -0
  56. package/src/utils.ts +7 -12
  57. package/templates/Gjs/Gjs.d.ts +3 -1
  58. package/templates/Gjs/GnomeShell.d.ts +122 -0
  59. package/templates/Gjs/GnomeShell.js +10 -0
  60. package/templates/Gjs/index.d.ts +7 -0
  61. package/templates/Gjs/misc/dbusUtils.d.ts +15 -0
  62. package/templates/Gjs/misc/dbusUtils.js +6 -0
  63. package/templates/Gjs/misc/extensionUtils.d.ts +99 -0
  64. package/templates/Gjs/misc/extensionUtils.js +6 -0
  65. package/templates/Gjs/misc/fileUtils.d.ts +49 -0
  66. package/templates/Gjs/misc/fileUtils.js +6 -0
  67. package/templates/Gjs/misc/gnomeSession.d.ts +72 -0
  68. package/templates/Gjs/misc/gnomeSession.js +6 -0
  69. package/templates/Gjs/ui/userWidget.d.ts +10 -0
  70. package/templates/Gjs/ui/userWidget.js +6 -0
  71. package/templates/Gjs/cast.ts +0 -52
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ts-for-gir/cli",
3
- "version": "3.0.0-beta.6",
3
+ "version": "3.0.0-beta.8",
4
4
  "description": "Typescript .d.ts generator from GIR for gjs and node-gtk",
5
5
  "module": "lib/index.js",
6
6
  "type": "module",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "scripts": {
14
14
  "start": "yarn node --max_old_space_size=9216 lib/start.js",
15
- "build": "yarn run clear:build && yarn run lint && yarn run build:ts && yarn run chmod",
15
+ "build": "yarn run lint && yarn run build:ts && yarn run chmod",
16
16
  "chmod": "chmod +x ./lib/start.js",
17
17
  "build:ts": "tsc",
18
18
  "clear": "yarn run clear:build",
@@ -36,37 +36,52 @@
36
36
  "url": "https://github.com/sammydre/ts-for-gjs/issues"
37
37
  },
38
38
  "homepage": "https://github.com/sammydre/ts-for-gjs#readme",
39
+ "keywords": [
40
+ "gjs",
41
+ "typescript",
42
+ "generate",
43
+ "node-gtk",
44
+ "gir",
45
+ "gobject-introspection",
46
+ "gnome",
47
+ "gtk",
48
+ "glib",
49
+ "gobject",
50
+ "dts",
51
+ "type definitions"
52
+ ],
39
53
  "devDependencies": {
40
54
  "@types/change-case": "^2.3.1",
41
55
  "@types/columnify": "^1.5.1",
42
56
  "@types/ejs": "^3.1.1",
43
- "@types/eslint": "8.4.6",
44
- "@types/inquirer": "^9.0.1",
45
- "@types/lodash": "^4.14.185",
46
- "@types/node": "^18.7.21",
47
- "@types/prettier": "^2.7.1",
57
+ "@types/eslint": "8.4.10",
58
+ "@types/inquirer": "^9.0.3",
59
+ "@types/lodash": "^4.14.191",
60
+ "@types/node": "^18.11.18",
61
+ "@types/prettier": "^2.7.2",
48
62
  "@types/xml2js": "^0.4.11",
49
- "@types/yargs": "^17.0.13",
50
- "@typescript-eslint/eslint-plugin": "^5.38.0",
51
- "@typescript-eslint/parser": "^5.38.0",
52
- "eslint": "^8.24.0",
53
- "eslint-config-prettier": "^8.5.0",
63
+ "@types/yargs": "^17.0.19",
64
+ "@typescript-eslint/eslint-plugin": "^5.48.2",
65
+ "@typescript-eslint/parser": "^5.48.2",
66
+ "eslint": "^8.32.0",
67
+ "eslint-config-prettier": "^8.6.0",
54
68
  "eslint-plugin-prettier": "^4.2.1",
55
- "rimraf": "^3.0.2"
69
+ "rimraf": "^4.1.0",
70
+ "typescript": "^4.9.4"
56
71
  },
57
72
  "dependencies": {
58
73
  "colorette": "^2.0.19",
59
74
  "columnify": "^1.6.0",
60
- "cosmiconfig": "^7.0.1",
75
+ "cosmiconfig": "^8.0.0",
61
76
  "ejs": "^3.1.8",
62
77
  "events": "^3.3.0",
63
- "globby": "^13.1.2",
64
- "inquirer": "^9.1.2",
78
+ "get-tsconfig": "^4.3.0",
79
+ "globby": "^13.1.3",
80
+ "inquirer": "^9.1.4",
65
81
  "lodash": "^4.17.21",
66
- "prettier": "^2.7.1",
82
+ "prettier": "^2.8.3",
67
83
  "tiny-glob": "^0.2.9",
68
- "typescript": "^4.8.3",
69
84
  "xml2js": "^0.4.23",
70
- "yargs": "^17.5.1"
85
+ "yargs": "^17.6.2"
71
86
  }
72
87
  }
@@ -35,6 +35,7 @@ const builder = (yargs: Argv) => {
35
35
  .option('noCheck', Config.generateOptions.noCheck)
36
36
  .option('noDOMLib', Config.generateOptions.noDOMLib)
37
37
  .option('fixConflicts', Config.generateOptions.fixConflicts)
38
+ .option('gnomeShellTypes', Config.generateOptions.gnomeShellTypes)
38
39
  .example(examples)
39
40
  }
40
41
 
@@ -73,8 +74,8 @@ const examples: ReadonlyArray<[string, string?]> = [
73
74
  [`${Config.appName} generate '*' -e node`, 'Generate .d.ts. files only for node'],
74
75
  [`${Config.appName} generate --configName='.ts-for-gir.gtk4.rc.js`, 'Use a special config file'],
75
76
  [
76
- `${Config.appName} generate --ignore=Gtk-3.0 xrandr-1.3`,
77
- 'Generate .d.ts. files but not for Gtk-3.0 and xrandr-1.3',
77
+ `${Config.appName} generate --ignore=Gtk-4.0 xrandr-1.3`,
78
+ 'Generate .d.ts. files but not for Gtk-4.0 and xrandr-1.3',
78
79
  ],
79
80
  ]
80
81
 
package/src/config.ts CHANGED
@@ -35,7 +35,7 @@ export class Config {
35
35
  girDirectories: OS.platform() === 'darwin' ? ['/usr/local/share/gir-1.0'] : ['/usr/share/gir-1.0'],
36
36
  modules: ['*'],
37
37
  ignore: [],
38
- verbose: true,
38
+ verbose: false,
39
39
  ignoreVersionConflicts: false,
40
40
  useNamespace: false,
41
41
  buildType: 'lib',
@@ -45,6 +45,7 @@ export class Config {
45
45
  noCheck: false,
46
46
  fixConflicts: true,
47
47
  noDOMLib: false,
48
+ gnomeShellTypes: false,
48
49
  }
49
50
 
50
51
  static configFilePath = Path.join(process.cwd(), Config.defaults.configName)
@@ -52,13 +53,13 @@ export class Config {
52
53
  /**
53
54
  * CLI options used in commands/generate.ts and commands/list.ts
54
55
  */
55
- static options = {
56
+ static options: { [name: string]: Options } = {
56
57
  modules: {
57
58
  description: "GIR modules to load, e.g. 'Gio-2.0'. Accepts multiple modules",
58
59
  array: true,
59
60
  default: Config.defaults.modules,
60
61
  normalize: true,
61
- } as Options,
62
+ },
62
63
  girDirectories: {
63
64
  type: 'string',
64
65
  alias: 'g',
@@ -66,14 +67,14 @@ export class Config {
66
67
  array: true,
67
68
  default: Config.defaults.girDirectories,
68
69
  normalize: true,
69
- } as Options,
70
+ },
70
71
  outdir: {
71
72
  type: 'string',
72
73
  alias: 'o',
73
74
  description: 'Directory to output to',
74
75
  default: Config.defaults.outdir,
75
76
  normalize: true,
76
- } as Options,
77
+ },
77
78
  environments: {
78
79
  type: 'string',
79
80
  alias: 'e',
@@ -82,7 +83,7 @@ export class Config {
82
83
  choices: ['gjs', 'node'],
83
84
  default: Config.defaults.environments,
84
85
  normalize: true,
85
- } as Options,
86
+ },
86
87
  ignore: {
87
88
  type: 'string',
88
89
  alias: 'i',
@@ -90,7 +91,7 @@ export class Config {
90
91
  array: true,
91
92
  default: Config.defaults.ignore,
92
93
  normalize: true,
93
- } as Options,
94
+ },
94
95
  buildType: {
95
96
  type: 'string',
96
97
  alias: 'b',
@@ -99,7 +100,7 @@ export class Config {
99
100
  choices: ['lib', 'types'],
100
101
  default: Config.defaults.buildType,
101
102
  normalize: true,
102
- } as Options,
103
+ },
103
104
  moduleType: {
104
105
  type: 'string',
105
106
  alias: 't',
@@ -107,77 +108,83 @@ export class Config {
107
108
  choices: ['esm', 'commonjs'],
108
109
  default: Config.defaults.moduleType,
109
110
  normalize: true,
110
- } as Options,
111
+ },
111
112
  pretty: {
112
113
  type: 'boolean',
113
114
  description: 'Prettifies the generated .d.ts files',
114
115
  default: Config.defaults.pretty,
115
116
  normalize: true,
116
- } as Options,
117
+ },
117
118
  verbose: {
118
119
  type: 'boolean',
119
120
  alias: 'v',
120
121
  description: 'Switch on/off the verbose mode',
121
122
  default: Config.defaults.verbose,
122
123
  normalize: true,
123
- } as Options,
124
+ },
124
125
  ignoreVersionConflicts: {
125
126
  type: 'boolean',
126
127
  description: 'Do not ask for package versions if multiple versions are found',
127
128
  default: Config.defaults.ignoreVersionConflicts,
128
129
  normalize: true,
129
- } as Options,
130
+ },
130
131
  print: {
131
132
  type: 'boolean',
132
133
  alias: 'p',
133
134
  description: 'Print the output to console and create no files',
134
135
  default: Config.defaults.print,
135
136
  normalize: true,
136
- } as Options,
137
+ },
137
138
  configName: {
138
139
  type: 'string',
139
140
  description: 'Name of the config if you want to use a different name',
140
141
  default: Config.defaults.configName,
141
142
  normalize: true,
142
- } as Options,
143
+ },
143
144
  useNamespace: {
144
145
  type: 'boolean',
145
146
  alias: 'd',
146
147
  description: 'Export all symbols for each module as a namespace',
147
148
  default: Config.defaults.useNamespace,
148
149
  normalize: true,
149
- } as Options,
150
+ },
150
151
  noComments: {
151
152
  type: 'boolean',
152
153
  alias: 'n',
153
154
  description: 'Do not generate documentation comments',
154
155
  default: Config.defaults.noComments,
155
156
  normalize: true,
156
- } as Options,
157
+ },
157
158
  noDebugComments: {
158
159
  type: 'boolean',
159
160
  description: 'Do not generate debugging inline comments',
160
161
  default: Config.defaults.noDebugComments,
161
162
  normalize: true,
162
- } as Options,
163
+ },
163
164
  noCheck: {
164
165
  type: 'boolean',
165
166
  description: 'Disable typescript semantic checks using @ts-nocheck',
166
167
  default: Config.defaults.noCheck,
167
168
  normalize: true,
168
- } as Options,
169
+ },
169
170
  fixConflicts: {
170
171
  type: 'boolean',
171
172
  description: 'Fix Inheritance and implementation type conflicts',
172
173
  default: Config.defaults.fixConflicts,
173
174
  normalize: true,
174
- } as Options,
175
+ },
175
176
  noDOMLib: {
176
177
  type: 'boolean',
177
178
  description: 'Disables the generation of types that are in conflict with the DOM types',
178
179
  default: Config.defaults.noDOMLib,
179
180
  normalize: true,
180
- } as Options,
181
+ },
182
+ gnomeShellTypes: {
183
+ type: 'boolean',
184
+ description: 'Generate types for GNOME Shell',
185
+ default: Config.defaults.gnomeShellTypes,
186
+ normalize: true,
187
+ },
181
188
  }
182
189
 
183
190
  /**
@@ -202,6 +209,7 @@ export class Config {
202
209
  noCheck: this.options.noCheck,
203
210
  noDOMLib: this.options.noDOMLib,
204
211
  fixConflicts: this.options.fixConflicts,
212
+ gnomeShellTypes: this.options.gnomeShellTypes,
205
213
  }
206
214
 
207
215
  static listOptions = {
@@ -290,28 +298,18 @@ export class Config {
290
298
  noCheck: config.noCheck,
291
299
  fixConflicts: config.fixConflicts,
292
300
  noDOMLib: config.noDOMLib,
301
+ gnomeShellTypes: config.gnomeShellTypes,
293
302
  }
294
303
  return generateConfig
295
304
  }
296
305
 
297
306
  protected static async validateTsConfig(config: UserConfig): Promise<UserConfig> {
298
- const tsConfig = config.outdir ? readTsJsConfig(config.outdir) : null
299
-
300
- const tsCompilerOptions = (
301
- tsConfig &&
302
- 'compilerOptions' in tsConfig &&
303
- typeof tsConfig.compilerOptions === 'object' &&
304
- tsConfig.compilerOptions != null
305
- ? tsConfig.compilerOptions
306
- : {}
307
- ) as Record<PropertyKey, unknown>
308
-
309
- const tsConfigHasDOMLib =
310
- 'noLib' in tsCompilerOptions && tsCompilerOptions.noLib
311
- ? false // NoLib makes typescript to ignore the lib property
312
- : 'lib' in tsCompilerOptions && Array.isArray(tsCompilerOptions.lib)
313
- ? tsCompilerOptions.lib.some((lib) => String(lib).toLowerCase().startsWith('dom'))
314
- : true // Typescript icludes DOM lib by default
307
+ const tsCompilerOptions = (config.outdir && readTsJsConfig(config.outdir)?.compilerOptions) || {}
308
+ const tsConfigHasDOMLib = tsCompilerOptions.noLib
309
+ ? false // NoLib makes typescript to ignore the lib property
310
+ : Array.isArray(tsCompilerOptions.lib)
311
+ ? tsCompilerOptions.lib.some((lib) => lib.toLowerCase().startsWith('dom'))
312
+ : true // Typescript icludes DOM lib by default
315
313
 
316
314
  if (config.environments.includes('gjs') && tsConfigHasDOMLib && !config.noDOMLib) {
317
315
  const answer = (
@@ -358,7 +356,7 @@ export class Config {
358
356
  * @param options
359
357
  */
360
358
  public static async load(options: ConfigFlags): Promise<UserConfig> {
361
- const configFile = await this.loadConfigFile(options.configName)
359
+ const configFile = (await this.loadConfigFile(options.configName))?.config || {}
362
360
 
363
361
  const config: UserConfig = {
364
362
  environments: options.environments,
@@ -378,100 +376,102 @@ export class Config {
378
376
  noCheck: options.noCheck,
379
377
  fixConflicts: options.fixConflicts,
380
378
  noDOMLib: options.noDOMLib,
379
+ gnomeShellTypes: options.gnomeShellTypes,
381
380
  }
382
381
 
383
382
  if (configFile) {
384
383
  // environments
385
- if (isEqual(config.environments, Config.defaults.environments) && configFile.config.environments) {
386
- config.environments = configFile.config.environments
384
+ if (isEqual(config.environments, Config.defaults.environments) && configFile.environments) {
385
+ config.environments = configFile.environments
387
386
  }
388
387
  // buildType
389
- if (config.buildType === Config.options.buildType.default && configFile.config.buildType) {
390
- config.buildType = configFile.config.buildType
388
+ if (config.buildType === Config.options.buildType.default && configFile.buildType) {
389
+ config.buildType = configFile.buildType
391
390
  }
392
391
  // moduleType
393
- if (config.moduleType === Config.options.moduleType.default && configFile.config.moduleType) {
394
- config.moduleType = configFile.config.moduleType
392
+ if (config.moduleType === Config.options.moduleType.default && configFile.moduleType) {
393
+ config.moduleType = configFile.moduleType
395
394
  }
396
395
  // verbose
397
- if (config.verbose === Config.options.verbose.default && typeof configFile.config.verbose === 'boolean') {
398
- config.verbose = configFile.config.verbose
396
+ if (config.verbose === Config.options.verbose.default && typeof configFile.verbose === 'boolean') {
397
+ config.verbose = configFile.verbose
399
398
  }
400
399
  // ignoreVersionConflicts
401
400
  if (
402
401
  config.ignoreVersionConflicts === Config.options.ignoreVersionConflicts.default &&
403
- typeof configFile.config.ignoreVersionConflicts === 'boolean'
402
+ typeof configFile.ignoreVersionConflicts === 'boolean'
404
403
  ) {
405
- config.ignoreVersionConflicts = configFile.config.ignoreVersionConflicts
404
+ config.ignoreVersionConflicts = configFile.ignoreVersionConflicts
406
405
  }
407
406
  // pretty
408
- if (config.pretty === Config.options.pretty.default && typeof configFile.config.pretty === 'boolean') {
409
- config.pretty = configFile.config.pretty
407
+ if (config.pretty === Config.options.pretty.default && typeof configFile.pretty === 'boolean') {
408
+ config.pretty = configFile.pretty
410
409
  }
411
410
  // print
412
- if (config.print === Config.options.print.default && typeof configFile.config.print === 'boolean') {
413
- config.print = configFile.config.print
411
+ if (config.print === Config.options.print.default && typeof configFile.print === 'boolean') {
412
+ config.print = configFile.print
414
413
  }
415
414
  // outdir
416
- if (config.outdir === Config.options.outdir.default && configFile.config.outdir) {
417
- config.outdir = config.print ? null : configFile.config.outdir
415
+ if (config.outdir === Config.options.outdir.default && configFile.outdir) {
416
+ config.outdir = config.print ? null : configFile.outdir
418
417
  }
419
418
  // girDirectories
420
- if (config.girDirectories === Config.options.girDirectories.default && configFile.config.girDirectories) {
421
- config.girDirectories = configFile.config.girDirectories
419
+ if (config.girDirectories === Config.options.girDirectories.default && configFile.girDirectories) {
420
+ config.girDirectories = configFile.girDirectories
422
421
  }
423
422
  // ignore
424
423
  if (
425
424
  (!config.ignore || config.ignore.length <= 0 || isEqual(config.ignore, Config.defaults.ignore)) &&
426
- configFile.config.ignore
425
+ configFile.ignore
427
426
  ) {
428
- config.ignore = configFile.config.ignore
427
+ config.ignore = configFile.ignore
429
428
  }
430
429
  // modules
431
430
  if (
432
431
  (config.modules.length <= 0 || isEqual(config.modules, Config.defaults.modules)) &&
433
- configFile.config.modules
432
+ configFile.modules
434
433
  ) {
435
- config.modules = configFile.config.modules
434
+ config.modules = configFile.modules
436
435
  }
437
436
  // useNamespace
438
437
  if (
439
438
  config.useNamespace === Config.options.useNamespace.default &&
440
- typeof configFile.config.useNamespace === 'boolean'
439
+ typeof configFile.useNamespace === 'boolean'
441
440
  ) {
442
- config.useNamespace = configFile.config.useNamespace
441
+ config.useNamespace = configFile.useNamespace
443
442
  }
444
443
  // noComments
445
- if (
446
- config.noComments === Config.options.noComments.default &&
447
- typeof configFile.config.noComments === 'boolean'
448
- ) {
449
- config.noComments = configFile.config.noComments
444
+ if (config.noComments === Config.options.noComments.default && typeof configFile.noComments === 'boolean') {
445
+ config.noComments = configFile.noComments
450
446
  }
451
447
  // noDebugComments
452
448
  if (
453
449
  config.noDebugComments === Config.options.noDebugComments.default &&
454
- typeof configFile.config.noDebugComments === 'boolean'
450
+ typeof configFile.noDebugComments === 'boolean'
455
451
  ) {
456
- config.noDebugComments = configFile.config.noDebugComments
452
+ config.noDebugComments = configFile.noDebugComments
457
453
  }
458
454
  // noCheck
459
- if (config.noCheck === Config.options.noCheck.default && typeof configFile.config.noCheck === 'boolean') {
460
- config.noCheck = configFile.config.noCheck
455
+ if (config.noCheck === Config.options.noCheck.default && typeof configFile.noCheck === 'boolean') {
456
+ config.noCheck = configFile.noCheck
461
457
  }
462
458
  // fixConflicts
463
459
  if (
464
460
  config.fixConflicts === Config.options.fixConflicts.default &&
465
- typeof configFile.config.fixConflicts === 'boolean'
461
+ typeof configFile.fixConflicts === 'boolean'
466
462
  ) {
467
- config.fixConflicts = configFile.config.fixConflicts
463
+ config.fixConflicts = configFile.fixConflicts
468
464
  }
469
465
  // noDOMLib
466
+ if (config.noDOMLib === Config.options.noDOMLib.default && typeof configFile.noDOMLib === 'boolean') {
467
+ config.noDOMLib = configFile.noDOMLib
468
+ }
469
+ // gnomeShellTypes
470
470
  if (
471
- config.noDOMLib === Config.options.noDOMLib.default &&
472
- typeof configFile.config.noDOMLib === 'boolean'
471
+ config.gnomeShellTypes === Config.options.gnomeShellTypes.default &&
472
+ typeof configFile.gnomeShellTypes === 'boolean'
473
473
  ) {
474
- config.noDOMLib = configFile.config.noDOMLib
474
+ config.gnomeShellTypes = configFile.gnomeShellTypes
475
475
  }
476
476
  }
477
477
 
@@ -3,7 +3,8 @@
3
3
  * For example, the signal methods are generated here
4
4
  */
5
5
 
6
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs'
6
+ import { existsSync } from 'fs'
7
+ import { readFile, writeFile, mkdir, readdir } from 'fs/promises'
7
8
  import Path from 'path'
8
9
  import ejs from 'ejs'
9
10
  import { Logger } from './logger.js'
@@ -34,7 +35,7 @@ export class TemplateProcessor {
34
35
  }
35
36
 
36
37
  /**
37
- * Loads and renders a template and gets the rendered string back
38
+ * Loads and renders a template and gets the rendered templates back
38
39
  * @param templateFilename
39
40
  */
40
41
  public async load(templateFilename: string): Promise<string> {
@@ -42,13 +43,25 @@ export class TemplateProcessor {
42
43
  return await this.render(fileContent)
43
44
  }
44
45
 
46
+ /**
47
+ * Loads and renders all templates in a directory and gets the rendered templates back
48
+ * @param templateDirname
49
+ */
50
+ public async loadAll(templateDirname: string, fileExtension: string): Promise<{ [path: string]: string }> {
51
+ const fileContents = await this.readAll(templateDirname, fileExtension)
52
+ for (const file of Object.keys(fileContents)) {
53
+ fileContents[file] = await this.render(fileContents[file])
54
+ }
55
+ return fileContents
56
+ }
57
+
45
58
  /**
46
59
  * Loads an template, render the template and write the template to the filesystem
47
60
  * @param templateFilename
48
61
  * @param outputDir
49
62
  * @param outputFilename
50
63
  * @param append
51
- * @return The rendered (and if possible prettified) code string
64
+ * @return The rendered (and if possible prettified) template string
52
65
  */
53
66
  public async create(
54
67
  templateFilename: string,
@@ -56,34 +69,60 @@ export class TemplateProcessor {
56
69
  outputFilename: string,
57
70
  append = '',
58
71
  ): Promise<string> {
59
- const fileContent = await this.load(templateFilename)
60
- const renderedCode = await this.render(fileContent)
72
+ const renderedTpl = await this.load(templateFilename)
61
73
  const destPath = getDestPath(this.config.environment, outputDir, outputFilename)
62
- const prettifiedCode = this.config.pretty ? this.prettifySource(renderedCode, destPath) : null
63
- const code = (prettifiedCode || renderedCode) + append
74
+ const prettifiedCode = this.config.pretty ? this.prettifySource(renderedTpl, destPath) : null
75
+ const code = (prettifiedCode || renderedTpl) + append
64
76
  await this.write(code, outputDir, outputFilename)
65
77
  return code
66
78
  }
67
79
 
80
+ /**
81
+ * Loads all templates with file extension in dir, render the templates and write the template to the filesystem
82
+ * @param fileExtension
83
+ * @param templateDirname
84
+ * @param outputDir
85
+ * @param outputDirname
86
+ * @return The rendered (and if possible prettified) templates
87
+ */
88
+ public async createAll(
89
+ fileExtension: string,
90
+ templateDirname: string,
91
+ outputDir: string,
92
+ outputDirname: string,
93
+ append = '',
94
+ ) {
95
+ const renderedTpls = await this.loadAll(templateDirname, fileExtension)
96
+ const result: { [path: string]: string } = {}
97
+ for (const filename of Object.keys(renderedTpls)) {
98
+ const destPath = getDestPath(this.config.environment, outputDir, outputDirname, filename)
99
+ const prettifiedCode = this.config.pretty ? this.prettifySource(renderedTpls[filename], destPath) : null
100
+ result[destPath] = (prettifiedCode || renderedTpls[filename]) + append
101
+ await this.write(result[destPath], outputDir, Path.join(outputDirname, filename))
102
+ }
103
+
104
+ return result
105
+ }
106
+
68
107
  protected async write(content: string, outputDir: string, outputFilename: string): Promise<string> {
69
108
  const destPath = getDestPath(this.config.environment, outputDir, outputFilename)
70
109
 
71
110
  // write template result file
72
- mkdirSync(outputDir, { recursive: true })
73
- writeFileSync(destPath, content, { encoding: 'utf8', flag: 'w' })
111
+ await mkdir(Path.dirname(destPath), { recursive: true })
112
+ await writeFile(destPath, content, { encoding: 'utf8', flag: 'w' })
74
113
 
75
114
  return Promise.resolve(destPath)
76
115
  }
77
116
 
78
117
  protected async render(templateString: string, additionalData: Partial<ejs.Options> = {}): Promise<string> {
79
118
  try {
80
- const renderedCode = ejs.render(templateString, {
119
+ const renderedTpl = ejs.render(templateString, {
81
120
  async: true,
82
121
  ...this.config,
83
122
  ...this.data,
84
123
  ...additionalData,
85
124
  })
86
- return Promise.resolve(renderedCode)
125
+ return Promise.resolve(renderedTpl)
87
126
  } catch (error) {
88
127
  this.log.error('Error on render', error)
89
128
  return ''
@@ -91,8 +130,8 @@ export class TemplateProcessor {
91
130
  }
92
131
 
93
132
  /**
94
- * Checks if the template file exists and returns the path if found
95
- * Tries first to load the file from the environment-specific template folder and otherwise looks for it in the general template folder
133
+ * Checks if the template file or directory exists and returns the path if found
134
+ * Tries first to load the file / directory from the environment-specific template folder and otherwise looks for it in the general template folder
96
135
  * @param templateFilename
97
136
  */
98
137
  public exists(templateFilename: string): string | null {
@@ -133,7 +172,7 @@ export class TemplateProcessor {
133
172
  const filename = Path.basename(path)
134
173
  this.log.info(` Prettify ${filename}...`)
135
174
  try {
136
- const source = readFileSync(Path.resolve('.', path), 'utf8')
175
+ const source = await readFile(Path.resolve('.', path), 'utf8')
137
176
  prettyCode = this.prettifySource(source, path)
138
177
  } catch (error) {
139
178
  this.log.warn('Error on prettify', error)
@@ -161,10 +200,34 @@ export class TemplateProcessor {
161
200
  protected async read(templateFilename: string) {
162
201
  const path = this.exists(templateFilename)
163
202
  if (path) {
164
- return Promise.resolve(readFileSync(path, 'utf8'))
203
+ return await readFile(path, 'utf8')
165
204
  }
166
205
  throw new Error(`Template '${templateFilename}' not found'`)
167
206
  }
207
+
208
+ /**
209
+ * Reads all template files from a directory and gets the raw strings back
210
+ * @param templateDirname
211
+ * @param fileExtension
212
+ * @return The raw template contents
213
+ * @throws Error if the template directory does not exist
214
+ * @throws Error if the template directory is empty
215
+ */
216
+ protected async readAll(templateDirname: string, fileExtension: string) {
217
+ const path = this.exists(templateDirname)
218
+ if (path) {
219
+ const files = (await readdir(path)).filter((file) => file.endsWith(fileExtension))
220
+ if (files.length === 0) {
221
+ throw new Error(`Template directory '${templateDirname}' is empty'`)
222
+ }
223
+ const results: { [path: string]: string } = {}
224
+ for (const file of files) {
225
+ results[file] = await readFile(Path.join(path, file), 'utf8')
226
+ }
227
+ return results
228
+ }
229
+ throw new Error(`Template directory '${templateDirname}' not found'`)
230
+ }
168
231
  }
169
232
 
170
233
  export default TemplateProcessor