@ts-for-gir/generator-typescript 4.0.0-beta.9 → 4.0.0-rc.2

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 (72) hide show
  1. package/README.md +19 -2
  2. package/package.json +15 -29
  3. package/src/generators/index.ts +2 -0
  4. package/src/generators/module-exporter.ts +88 -0
  5. package/src/generators/signal-generator.ts +264 -0
  6. package/src/index.ts +4 -0
  7. package/src/module-generator-example.ts +68 -0
  8. package/src/module-generator.ts +2093 -0
  9. package/src/npm-package.ts +115 -0
  10. package/src/overrides/glib.ts +13 -0
  11. package/src/overrides/gobject.ts +52 -0
  12. package/src/template-processor.ts +216 -0
  13. package/src/type-definition-generator.ts +171 -0
  14. package/src/utils.ts +7 -0
  15. package/lib/index.d.ts +0 -3
  16. package/lib/index.js +0 -4
  17. package/lib/index.js.map +0 -1
  18. package/lib/module-generator.d.ts +0 -134
  19. package/lib/module-generator.js +0 -1224
  20. package/lib/module-generator.js.map +0 -1
  21. package/lib/npm-package.d.ts +0 -15
  22. package/lib/npm-package.js +0 -76
  23. package/lib/npm-package.js.map +0 -1
  24. package/lib/package-data-parser.d.ts +0 -13
  25. package/lib/package-data-parser.js +0 -67
  26. package/lib/package-data-parser.js.map +0 -1
  27. package/lib/template-processor.d.ts +0 -103
  28. package/lib/template-processor.js +0 -246
  29. package/lib/template-processor.js.map +0 -1
  30. package/lib/type-definition-generator.d.ts +0 -20
  31. package/lib/type-definition-generator.js +0 -102
  32. package/lib/type-definition-generator.js.map +0 -1
  33. package/lib/utils.d.ts +0 -1
  34. package/lib/utils.js +0 -7
  35. package/lib/utils.js.map +0 -1
  36. package/packages.xml +0 -1213
  37. package/templates/README-GJS.md +0 -133
  38. package/templates/README.md +0 -92
  39. package/templates/cogl-2-0.d.ts +0 -0
  40. package/templates/gi.d.ts +0 -7
  41. package/templates/gio-2.0.d.ts +0 -36
  42. package/templates/gjs/cairo-1.0.d.ts +0 -9
  43. package/templates/gjs/cairo.d.ts +0 -12
  44. package/templates/gjs/cairo.js +0 -4
  45. package/templates/gjs/dom.d.ts +0 -322
  46. package/templates/gjs/dom.js +0 -1
  47. package/templates/gjs/gettext.d.ts +0 -48
  48. package/templates/gjs/gettext.js +0 -4
  49. package/templates/gjs/gjs-ambient.d.ts +0 -19
  50. package/templates/gjs/gjs-ambient.js +0 -1
  51. package/templates/gjs/gjs.d.ts +0 -630
  52. package/templates/gjs/gjs.js +0 -4
  53. package/templates/gjs/system.d.ts +0 -187
  54. package/templates/gjs/system.js +0 -4
  55. package/templates/gobject-2.0.d.ts +0 -227
  56. package/templates/granite-1.0.d.ts +0 -7
  57. package/templates/granite-7.0.d.ts +0 -7
  58. package/templates/gstbase-0.10.d.ts +0 -5
  59. package/templates/index-locally.d.ts +0 -7
  60. package/templates/index.d.ts +0 -17
  61. package/templates/index.js +0 -4
  62. package/templates/module-ambient.d.ts +0 -17
  63. package/templates/module-ambient.js +0 -1
  64. package/templates/module-import.d.ts +0 -16
  65. package/templates/module-import.js +0 -2
  66. package/templates/module.append.d.ts +0 -17
  67. package/templates/module.d.ts +0 -45
  68. package/templates/module.js +0 -4
  69. package/templates/package.json +0 -95
  70. package/templates/rygelserver-2.6.d.ts +0 -3
  71. package/templates/tsconfig.json +0 -30
  72. package/templates/typedoc.json +0 -26
package/README.md CHANGED
@@ -16,5 +16,22 @@
16
16
  <img src="https://raw.githubusercontent.com/gjsify/ts-for-gir/main/.github/feeling.gif" />
17
17
  </p>
18
18
 
19
- # Generator base
20
- TypeScript type definition generator for ts-for-gir.
19
+ # TypeScript Generator
20
+
21
+ TypeScript-specific generator for `ts-for-gir`. This package implements the actual generation of TypeScript declaration files (.d.ts) from the processed GIR data. It transforms the intermediate representation of GObject types into TypeScript type definitions.
22
+
23
+ ## Features
24
+
25
+ - Generation of TypeScript declaration files (.d.ts) from GIR data
26
+ - Support for generating NPM packages with proper package.json configuration
27
+ - Template-based code generation using EJS templates
28
+ - Complete handling of complex type transformations:
29
+ - Classes, interfaces, and records
30
+ - Functions, methods, and constructors
31
+ - Properties, fields, and constants
32
+ - Enums and callbacks
33
+ - Signals and their event handlers
34
+ - Generation of proper JSDoc comments from GIR documentation
35
+ - Support for GJS-specific module formats and ambient type declarations
36
+
37
+ This package is responsible for the final output of the `ts-for-gir` toolchain, producing TypeScript definition files that can be used in GJS projects.
package/package.json CHANGED
@@ -1,36 +1,26 @@
1
1
  {
2
2
  "name": "@ts-for-gir/generator-typescript",
3
- "version": "4.0.0-beta.9",
3
+ "version": "4.0.0-rc.2",
4
4
  "description": "TypeScript type definition generator for ts-for-gir",
5
- "module": "lib/index.js",
6
- "main": "lib/index.js",
5
+ "main": "src/index.ts",
6
+ "module": "src/index.ts",
7
7
  "type": "module",
8
8
  "engines": {
9
9
  "node": ">=18"
10
10
  },
11
11
  "exports": {
12
- ".": {
13
- "types": "./lib/index.d.ts",
14
- "import": "./lib/index.js"
15
- }
12
+ ".": "./src/index.ts"
16
13
  },
17
14
  "scripts": {
18
- "build": "yarn lint && yarn build:ts",
19
- "build:ts": "tsc",
20
- "clear": "yarn clear:build",
21
- "clear:build": "rimraf ./lib",
22
- "watch": "yarn build:ts --watch",
23
- "lint": "eslint . --ext .ts,.tsx --fix"
15
+ "check": "tsc --noEmit"
24
16
  },
25
17
  "repository": {
26
18
  "type": "git",
27
19
  "url": "git+https://github.com/gjsify/ts-for-gir.git"
28
20
  },
29
- "author": "Pascal Garber <pascal@artandcode.studio>",
21
+ "author": "Pascal Garber <pascal@mailfreun.de>",
30
22
  "files": [
31
- "lib",
32
- "templates",
33
- "packages.xml"
23
+ "src"
34
24
  ],
35
25
  "license": "Apache-2.0",
36
26
  "bugs": {
@@ -41,22 +31,18 @@
41
31
  "generator"
42
32
  ],
43
33
  "devDependencies": {
34
+ "@ts-for-gir/tsconfig": "^4.0.0-rc.2",
44
35
  "@types/ejs": "^3.1.5",
45
- "@types/node": "^20.14.11",
36
+ "@types/node": "^24.12.2",
46
37
  "@types/xml2js": "^0.4.14",
47
- "@typescript-eslint/eslint-plugin": "^7.16.1",
48
- "@typescript-eslint/parser": "^7.16.1",
49
- "eslint": "^8.57.0",
50
- "eslint-config-prettier": "^9.1.0",
51
- "eslint-plugin-prettier": "^5.2.1",
52
- "prettier": "^3.3.3",
53
- "rimraf": "^6.0.1",
54
- "typescript": "^5.5.3"
38
+ "typescript": "^6.0.2"
55
39
  },
56
40
  "dependencies": {
57
- "@ts-for-gir/generator-base": "^4.0.0-beta.9",
58
- "@ts-for-gir/lib": "^4.0.0-beta.9",
59
- "ejs": "^3.1.10",
41
+ "@gi.ts/parser": "^4.0.0-rc.2",
42
+ "@ts-for-gir/generator-base": "^4.0.0-rc.2",
43
+ "@ts-for-gir/lib": "^4.0.0-rc.2",
44
+ "@ts-for-gir/templates": "^4.0.0-rc.2",
45
+ "ejs": "^5.0.1",
60
46
  "xml2js": "^0.6.2"
61
47
  }
62
48
  }
@@ -0,0 +1,2 @@
1
+ export { ModuleExporter } from "./module-exporter.ts";
2
+ export { SignalGenerator } from "./signal-generator.ts";
@@ -0,0 +1,88 @@
1
+ import type { DependencyManager, GirModule, NSRegistry, OptionsGeneration, Reporter } from "@ts-for-gir/lib";
2
+ import type { ModuleGenerator } from "../module-generator.ts";
3
+ import { NpmPackage } from "../npm-package.ts";
4
+ import type { TemplateProcessor } from "../template-processor.ts";
5
+
6
+ /** Handles exporting generated modules to files. */
7
+ export class ModuleExporter {
8
+ constructor(private readonly core: ModuleGenerator) {}
9
+
10
+ private get config(): OptionsGeneration {
11
+ return this.core.config;
12
+ }
13
+
14
+ private get log(): Reporter {
15
+ return this.core.log;
16
+ }
17
+
18
+ private get moduleTemplateProcessor(): TemplateProcessor {
19
+ return this.core.moduleTemplateProcessor;
20
+ }
21
+
22
+ private get dependencyManager(): DependencyManager {
23
+ return this.core.dependencyManager;
24
+ }
25
+
26
+ /** Export a template file to outdir or log its content. */
27
+ private async exportTemplate(template: string, target: string): Promise<void> {
28
+ if (this.config.outdir) {
29
+ await this.moduleTemplateProcessor.create(template, this.config.outdir, target);
30
+ } else {
31
+ const { append, prepend } = await this.moduleTemplateProcessor.load(template);
32
+ this.log.log(append + prepend);
33
+ }
34
+ }
35
+
36
+ async exportModuleTS(): Promise<void> {
37
+ const girModule = this.core.girNamespace;
38
+ const template = "module.d.ts";
39
+ const explicitTemplate = `${girModule.importName}.d.ts`;
40
+ const output = await this.core.generateModule(girModule);
41
+
42
+ if (!output) {
43
+ this.log.error("Failed to generate gir module");
44
+ return;
45
+ }
46
+
47
+ if (await this.moduleTemplateProcessor.exists(explicitTemplate)) {
48
+ const { append: appendExplicit, prepend: prependExplicit } =
49
+ await this.moduleTemplateProcessor.load(explicitTemplate);
50
+ output.unshift(prependExplicit);
51
+ output.push(appendExplicit);
52
+ }
53
+
54
+ const { append, prepend } = await this.moduleTemplateProcessor.load(template);
55
+ output.unshift(prepend);
56
+ output.push(append);
57
+
58
+ if (this.config.outdir) {
59
+ await this.moduleTemplateProcessor.write(output.join("\n"), this.config.outdir, explicitTemplate);
60
+ } else {
61
+ this.log.log(output.join("\n"));
62
+ }
63
+ }
64
+
65
+ async exportModule(registry: NSRegistry, girModule: GirModule): Promise<void> {
66
+ await this.exportModuleTS();
67
+
68
+ if (this.config.package) {
69
+ const name = girModule.importName;
70
+ await this.exportTemplate("module.js", `${name}.js`);
71
+ await this.exportTemplate("index.d.ts", "index.d.ts");
72
+ await this.exportTemplate("index.js", "index.js");
73
+ await this.exportTemplate("module-ambient.d.ts", `${name}-ambient.d.ts`);
74
+ await this.exportTemplate("module-ambient.js", `${name}-ambient.js`);
75
+ await this.exportTemplate("module-import.d.ts", `${name}-import.d.ts`);
76
+ await this.exportTemplate("module-import.js", `${name}-import.js`);
77
+
78
+ const pkg = new NpmPackage(
79
+ this.config,
80
+ this.dependencyManager,
81
+ registry,
82
+ girModule,
83
+ girModule.transitiveDependencies,
84
+ );
85
+ await pkg.exportNPMPackage();
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,264 @@
1
+ import { GirDirection } from "@gi.ts/parser";
2
+ import {
3
+ BinaryType,
4
+ BooleanType,
5
+ FilterBehavior,
6
+ filterConflicts,
7
+ type GirModule,
8
+ generateIndent,
9
+ type IntrospectedBaseClass,
10
+ IntrospectedClass,
11
+ IntrospectedClassFunction,
12
+ IntrospectedInterface,
13
+ type IntrospectedRecord,
14
+ mergeDescs,
15
+ NumberType,
16
+ type OptionsGeneration,
17
+ VoidType,
18
+ } from "@ts-for-gir/lib";
19
+ import type { ModuleGenerator } from "../module-generator.ts";
20
+
21
+ const SIGNAL_JSDOC = "/** @signal */";
22
+
23
+ /** Handles generation of GObject signal-related TypeScript definitions. */
24
+ export class SignalGenerator {
25
+ constructor(private readonly core: ModuleGenerator) {}
26
+
27
+ private get namespace(): GirModule {
28
+ return this.core.girNamespace;
29
+ }
30
+
31
+ private get config(): OptionsGeneration {
32
+ return this.core.config;
33
+ }
34
+
35
+ /**
36
+ * Generate SignalSignatures interface for type-safe signal handling.
37
+ *
38
+ * Creates a comprehensive mapping of signal names to their callback types,
39
+ * enabling TypeScript to provide proper type checking and IntelliSense for
40
+ * GObject signals using the centralized getAllSignals() method from the model.
41
+ */
42
+ generateClassSignalInterfaces(girClass: IntrospectedClass, indentCount = 0): string[] {
43
+ const def: string[] = [];
44
+ const indent = generateIndent(indentCount);
45
+
46
+ def.push(`${indent}// Signal signatures`);
47
+ def.push(`${indent}interface SignalSignatures`);
48
+
49
+ const parentSignatures: string[] = [];
50
+
51
+ // Inherit signal signatures from parent class
52
+ const parentResolution = girClass.resolveParents().extends();
53
+ if (parentResolution && parentResolution.node instanceof IntrospectedClass) {
54
+ const parentClass = parentResolution.node as IntrospectedClass;
55
+ const parentTypeIdentifier = parentResolution.identifier
56
+ .resolveIdentifier(this.namespace, this.config)
57
+ ?.print(this.namespace, this.config);
58
+
59
+ const hasSignalMethods = parentClass.signals?.length > 0;
60
+ const isNotTemplateWorkaround = !(
61
+ this.namespace.namespace === "Gimp" && ["ParamObject", "ParamItem", "ParamArray"].includes(parentClass.name)
62
+ );
63
+
64
+ if (parentTypeIdentifier && (hasSignalMethods || isNotTemplateWorkaround)) {
65
+ parentSignatures.push(`${parentTypeIdentifier}.SignalSignatures`);
66
+ }
67
+ }
68
+
69
+ // Inherit signal signatures from implemented interfaces
70
+ const interfaceSignatures = girClass
71
+ .resolveParents()
72
+ .implements()
73
+ .filter((iface) => iface.node instanceof IntrospectedInterface)
74
+ .filter((iface) => {
75
+ const node = iface.node as unknown as { signals?: unknown[] };
76
+ return node.signals && node.signals.length > 0;
77
+ })
78
+ .map((iface) => {
79
+ const interfaceTypeIdentifier = iface.identifier
80
+ .resolveIdentifier(this.namespace, this.config)
81
+ ?.print(this.namespace, this.config);
82
+ return interfaceTypeIdentifier ? `${interfaceTypeIdentifier}.SignalSignatures` : null;
83
+ })
84
+ .filter((sig): sig is string => !!sig);
85
+
86
+ parentSignatures.push(...interfaceSignatures);
87
+
88
+ if (parentSignatures.length > 0) {
89
+ def.push(` extends ${parentSignatures.join(", ")} {`);
90
+ } else {
91
+ const isGObjectObject = girClass.name === "Object" && girClass.namespace.namespace === "GObject";
92
+
93
+ if (isGObjectObject) {
94
+ def.push(" {");
95
+ } else {
96
+ const gobjectNamespace = this.namespace.assertInstalledImport("GObject");
97
+ const gobjectObjectClass = gobjectNamespace.assertClass("Object");
98
+ const gobjectRef = gobjectObjectClass
99
+ .getType()
100
+ .resolveIdentifier(this.namespace, this.config)
101
+ ?.print(this.namespace, this.config);
102
+
103
+ const fallbackRef = gobjectRef ? `${gobjectRef}.SignalSignatures` : "GObject.Object.SignalSignatures";
104
+ def.push(` extends ${fallbackRef} {`);
105
+ }
106
+ }
107
+
108
+ const allSignals = girClass.getAllSignals();
109
+
110
+ allSignals.forEach((signalInfo) => {
111
+ let cbType: string;
112
+
113
+ if (signalInfo.isNotifySignal) {
114
+ const gobjectRef = this.namespace.namespace === "GObject" ? "" : "GObject.";
115
+ cbType = `(pspec: ${gobjectRef}ParamSpec) => void`;
116
+ } else if (signalInfo.signal) {
117
+ // Signal handlers are invoked from C to JS: in-params come _out_ of C
118
+ // (so e.g. 64-bit ints arrive as `number`, not `bigint | number`), and
119
+ // the handler's return value goes _in_ to C.
120
+ const paramTypes = signalInfo.signal.parameters
121
+ .map((p, idx) => `arg${idx}: ${this.core.generateDirectedType(p.type, GirDirection.Out)}`)
122
+ .join(", ");
123
+
124
+ let returnType = signalInfo.signal.return_type;
125
+ if (signalInfo.signal.return_type.equals(BooleanType)) {
126
+ returnType = new BinaryType(BooleanType, VoidType);
127
+ }
128
+ const returnTypeStr = this.core.generateDirectedType(returnType, GirDirection.In);
129
+
130
+ cbType = `(${paramTypes}) => ${returnTypeStr}`;
131
+ } else {
132
+ const paramTypes = signalInfo.parameterTypes?.map((type, idx) => `arg${idx}: ${type}`) || [];
133
+ const returnTypeStr = signalInfo.returnType || "void";
134
+ cbType = `(${paramTypes.join(", ")}) => ${returnTypeStr}`;
135
+ }
136
+
137
+ // Template literal catch-all signals use index signature syntax
138
+ if (signalInfo.isTemplateLiteral) {
139
+ def.push(`${indent} [key: \`${signalInfo.name}\`]: ${cbType};`);
140
+ return;
141
+ }
142
+
143
+ const signalKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(signalInfo.name) ? signalInfo.name : `"${signalInfo.name}"`;
144
+
145
+ // Add signal doc comment with @signal tag and signal-specific modifier tags
146
+ if (!signalInfo.isNotifySignal && signalInfo.signal) {
147
+ const signalTags = [
148
+ { tagName: "signal", paramName: "", text: "" },
149
+ ...this.namespace.getTsDocMetadataTags(signalInfo.signal.metadata),
150
+ ];
151
+ if (signalInfo.signal.detailed) signalTags.push({ tagName: "detailed", paramName: "", text: "" });
152
+ if (signalInfo.signal.action) signalTags.push({ tagName: "action", paramName: "", text: "" });
153
+ if (signalInfo.signal.when)
154
+ signalTags.push({ tagName: `run-${signalInfo.signal.when}`, paramName: "", text: "" });
155
+ const comment = this.core.addGirDocComment(signalInfo.signal.doc, signalTags, indentCount + 1);
156
+ if (comment.length) {
157
+ def.push(...comment);
158
+ } else {
159
+ def.push(`${indent} /** @signal */`);
160
+ }
161
+ } else if (!signalInfo.isNotifySignal) {
162
+ def.push(`${indent} /** @signal */`);
163
+ }
164
+ def.push(`${indent} ${signalKey}: ${cbType};`);
165
+ });
166
+
167
+ def.push(`${indent}}`);
168
+ def.push("");
169
+
170
+ return def;
171
+ }
172
+
173
+ /**
174
+ * Generate signal methods section with header comment
175
+ */
176
+ generateClassSignals(girClass: IntrospectedClass): string[] {
177
+ return mergeDescs(this.generateSignalMethods(girClass), "Signals", 1);
178
+ }
179
+
180
+ /**
181
+ * Generate the $signals property for type-safe signal access
182
+ */
183
+ generateClassSignalsProperty(girClass: IntrospectedClass | IntrospectedRecord, indentCount = 1): string[] {
184
+ const isGObjectObject = girClass.name === "Object" && girClass.namespace.namespace === "GObject";
185
+ const hasGObjectParent =
186
+ isGObjectObject ||
187
+ girClass.someParent((p: IntrospectedBaseClass) => p.namespace.namespace === "GObject" && p.name === "Object");
188
+
189
+ if (!hasGObjectParent) return [];
190
+
191
+ const indent = generateIndent(indentCount);
192
+ return [
193
+ "",
194
+ `${indent}/**`,
195
+ `${indent} * Compile-time signal type information.`,
196
+ `${indent} *`,
197
+ `${indent} * This instance property is generated only for TypeScript type checking.`,
198
+ `${indent} * It is not defined at runtime and should not be accessed in JS code.`,
199
+ `${indent} * @internal`,
200
+ `${indent} */`,
201
+ `${indent}$signals: ${girClass.name}.SignalSignatures;`,
202
+ "",
203
+ ];
204
+ }
205
+
206
+ /**
207
+ * Generate type-safe connect/connect_after/emit signal methods
208
+ */
209
+ private generateSignalMethods(girClass: IntrospectedClass): string[] {
210
+ const signalFunctions = [
211
+ new IntrospectedClassFunction({
212
+ name: "connect",
213
+ parent: girClass,
214
+ parameters: [],
215
+ return_type: NumberType,
216
+ }),
217
+ new IntrospectedClassFunction({
218
+ name: "connect_after",
219
+ parent: girClass,
220
+ parameters: [],
221
+ return_type: NumberType,
222
+ }),
223
+ new IntrospectedClassFunction({
224
+ name: "emit",
225
+ parent: girClass,
226
+ parameters: [],
227
+ return_type: VoidType,
228
+ }),
229
+ ];
230
+
231
+ const filteredFunctions = filterConflicts(girClass.namespace, girClass, signalFunctions, FilterBehavior.DELETE);
232
+ const allowedNames = new Set(filteredFunctions.map((f) => f.name));
233
+
234
+ const gobjectRef = this.namespace.namespace === "GObject" ? "" : "GObject.";
235
+
236
+ const methods: string[] = [];
237
+
238
+ if (allowedNames.has("connect")) {
239
+ methods.push(
240
+ SIGNAL_JSDOC,
241
+ `connect<K extends keyof ${girClass.name}.SignalSignatures>(signal: K, callback: ${gobjectRef}SignalCallback<this, ${girClass.name}.SignalSignatures[K]>): number;`,
242
+ "connect(signal: string, callback: (...args: any[]) => any): number;",
243
+ );
244
+ }
245
+
246
+ if (allowedNames.has("connect_after")) {
247
+ methods.push(
248
+ SIGNAL_JSDOC,
249
+ `connect_after<K extends keyof ${girClass.name}.SignalSignatures>(signal: K, callback: ${gobjectRef}SignalCallback<this, ${girClass.name}.SignalSignatures[K]>): number;`,
250
+ "connect_after(signal: string, callback: (...args: any[]) => any): number;",
251
+ );
252
+ }
253
+
254
+ if (allowedNames.has("emit")) {
255
+ methods.push(
256
+ SIGNAL_JSDOC,
257
+ `emit<K extends keyof ${girClass.name}.SignalSignatures>(signal: K, ...args: ${gobjectRef}GjsParameters<${girClass.name}.SignalSignatures[K]> extends [any, ...infer Q] ? Q : never): void;`,
258
+ "emit(signal: string, ...args: any[]): void;",
259
+ );
260
+ }
261
+
262
+ return methods;
263
+ }
264
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { ModuleGenerator, ModuleGeneratorFormat } from "./module-generator.ts";
2
+ export { NpmPackage } from "./npm-package.ts";
3
+ export { TemplateProcessor } from "./template-processor.ts";
4
+ export { TypeDefinitionGenerator } from "./type-definition-generator.ts";
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Example usage of the refactored ModuleGenerator
3
+ *
4
+ * This demonstrates how the unified ModuleGenerator now incorporates
5
+ * functionality from DtsGenerator and DtsModuleGenerator
6
+ */
7
+
8
+ import type { GirModule, NSRegistry, OptionsGeneration } from "@ts-for-gir/lib";
9
+ import { ModuleGenerator } from "./module-generator.ts";
10
+
11
+ // Example: Using ModuleGenerator with different output formats
12
+ async function generateTypeDefinitions(girModule: GirModule, config: OptionsGeneration, registry: NSRegistry) {
13
+ // Create a ModuleGenerator instance
14
+ const generator = new ModuleGenerator(girModule, config, registry);
15
+
16
+ // 1. Generate as string array (default behavior)
17
+ const arrayOutput = await generator.generateModule(girModule);
18
+ console.log("String array output:", arrayOutput);
19
+
20
+ // 2. Generate as single string (DtsGenerator compatibility)
21
+ const stringOutput = await generator.generateModuleString(girModule);
22
+ console.log("String output:", stringOutput);
23
+
24
+ // 3. Generate as module declaration (DtsModuleGenerator compatibility)
25
+ const moduleDeclaration = await generator.generateModuleDeclaration(girModule);
26
+ console.log("Module declaration output:", moduleDeclaration);
27
+
28
+ // 4. Generate namespace as string
29
+ const namespaceString = await generator.generateNamespaceAsString(girModule);
30
+ console.log("Namespace string output:", namespaceString);
31
+
32
+ // 5. The AdvancedVariants feature is automatically applied
33
+ // when generating GLib or GObject modules (unless disabled with noAdvancedVariants option)
34
+ if (girModule.namespace === "GLib" && !config.noAdvancedVariants) {
35
+ console.log("GLib module will include advanced variant type definitions");
36
+ }
37
+ if (girModule.namespace === "GObject") {
38
+ console.log("GObject module will include registerClass overrides");
39
+ }
40
+ }
41
+
42
+ // Example: Migrating from DtsGenerator
43
+ function migrateFromDtsGenerator(girModule: GirModule, config: OptionsGeneration, registry: NSRegistry) {
44
+ // Before (using DtsGenerator):
45
+ // const generator = new DtsGenerator(girModule, config);
46
+ // const output = await generator.generateNamespace(girModule);
47
+
48
+ // After (using ModuleGenerator):
49
+ const generator = new ModuleGenerator(girModule, config, registry);
50
+ const output = generator.generateNamespaceAsString(girModule);
51
+
52
+ return output;
53
+ }
54
+
55
+ // Example: Migrating from DtsModuleGenerator
56
+ function migrateFromDtsModuleGenerator(girModule: GirModule, config: OptionsGeneration, registry: NSRegistry) {
57
+ // Before (using DtsModuleGenerator):
58
+ // const generator = new DtsModuleGenerator(girModule, config);
59
+ // const output = await generator.generateNamespace(girModule);
60
+
61
+ // After (using ModuleGenerator):
62
+ const generator = new ModuleGenerator(girModule, config, registry);
63
+ const output = generator.generateModuleDeclaration(girModule);
64
+
65
+ return output;
66
+ }
67
+
68
+ export { generateTypeDefinitions, migrateFromDtsGenerator, migrateFromDtsModuleGenerator };