@mnemonica/tactica 0.1.0
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/LICENSE +21 -0
- package/README.md +475 -0
- package/lib/analyzer.d.ts +75 -0
- package/lib/analyzer.js +478 -0
- package/lib/analyzer.js.map +1 -0
- package/lib/cli.d.ts +29 -0
- package/lib/cli.js +327 -0
- package/lib/cli.js.map +1 -0
- package/lib/generator.d.ts +42 -0
- package/lib/generator.js +187 -0
- package/lib/generator.js.map +1 -0
- package/lib/graph.d.ts +25 -0
- package/lib/graph.js +81 -0
- package/lib/graph.js.map +1 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.js +33 -0
- package/lib/index.js.map +1 -0
- package/lib/plugin.d.ts +8 -0
- package/lib/plugin.js +128 -0
- package/lib/plugin.js.map +1 -0
- package/lib/types.d.ts +72 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/lib/writer.d.ts +40 -0
- package/lib/writer.js +139 -0
- package/lib/writer.js.map +1 -0
- package/package.json +63 -0
package/lib/cli.js
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.main = main;
|
|
38
|
+
exports.run = run;
|
|
39
|
+
exports.watch = watch;
|
|
40
|
+
exports.parseArgs = parseArgs;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const ts = __importStar(require("typescript"));
|
|
44
|
+
const analyzer_1 = require("./analyzer");
|
|
45
|
+
const generator_1 = require("./generator");
|
|
46
|
+
const writer_1 = require("./writer");
|
|
47
|
+
/**
|
|
48
|
+
* Parse command line arguments
|
|
49
|
+
*/
|
|
50
|
+
function parseArgs(args) {
|
|
51
|
+
const options = {};
|
|
52
|
+
for (let i = 0; i < args.length; i++) {
|
|
53
|
+
const arg = args[i];
|
|
54
|
+
switch (arg) {
|
|
55
|
+
case '-w':
|
|
56
|
+
case '--watch':
|
|
57
|
+
options.watch = true;
|
|
58
|
+
break;
|
|
59
|
+
case '-p':
|
|
60
|
+
case '--project':
|
|
61
|
+
options.project = args[++i];
|
|
62
|
+
break;
|
|
63
|
+
case '-o':
|
|
64
|
+
case '--output':
|
|
65
|
+
options.outputDir = args[++i];
|
|
66
|
+
break;
|
|
67
|
+
case '-i':
|
|
68
|
+
case '--include':
|
|
69
|
+
options.include = (options.include || []).concat(args[++i].split(','));
|
|
70
|
+
break;
|
|
71
|
+
case '-e':
|
|
72
|
+
case '--exclude':
|
|
73
|
+
options.exclude = (options.exclude || []).concat(args[++i].split(','));
|
|
74
|
+
break;
|
|
75
|
+
case '-m':
|
|
76
|
+
case '--module-augmentation':
|
|
77
|
+
options.globalAugmentation = false;
|
|
78
|
+
break;
|
|
79
|
+
case '-v':
|
|
80
|
+
case '--verbose':
|
|
81
|
+
options.verbose = true;
|
|
82
|
+
break;
|
|
83
|
+
case '-h':
|
|
84
|
+
case '--help':
|
|
85
|
+
options.help = true;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return options;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Print help message
|
|
93
|
+
*/
|
|
94
|
+
function printHelp() {
|
|
95
|
+
console.log(`
|
|
96
|
+
Tactica - TypeScript Language Service Plugin for Mnemonica
|
|
97
|
+
|
|
98
|
+
Usage: tactica [options]
|
|
99
|
+
|
|
100
|
+
Options:
|
|
101
|
+
-w, --watch Watch for file changes and regenerate types
|
|
102
|
+
-p, --project Path to tsconfig.json (default: ./tsconfig.json)
|
|
103
|
+
-o, --output Output directory for generated types (default: .tactica)
|
|
104
|
+
-i, --include Comma-separated list of file patterns to include
|
|
105
|
+
-e, --exclude Comma-separated list of file patterns to exclude
|
|
106
|
+
-m, --module-augmentation Use module augmentation instead of global (legacy mode)
|
|
107
|
+
-v, --verbose Enable verbose logging
|
|
108
|
+
-h, --help Show this help message
|
|
109
|
+
|
|
110
|
+
Examples:
|
|
111
|
+
tactica # Generate types with global augmentation (default)
|
|
112
|
+
tactica --watch # Watch mode
|
|
113
|
+
tactica --module-augmentation # Use legacy module augmentation mode
|
|
114
|
+
tactica --project ./src/tsconfig.json # Custom tsconfig path
|
|
115
|
+
tactica --output ./types/mnemonica # Custom output directory
|
|
116
|
+
`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Find tsconfig.json
|
|
120
|
+
*/
|
|
121
|
+
function findTsConfig(projectPath) {
|
|
122
|
+
if (projectPath) {
|
|
123
|
+
if (fs.existsSync(projectPath)) {
|
|
124
|
+
return projectPath;
|
|
125
|
+
}
|
|
126
|
+
throw new Error(`Project file not found: ${projectPath}`);
|
|
127
|
+
}
|
|
128
|
+
// Look for tsconfig.json in current directory and parent directories
|
|
129
|
+
let currentDir = process.cwd();
|
|
130
|
+
while (currentDir !== path.dirname(currentDir)) {
|
|
131
|
+
const tsconfigPath = path.join(currentDir, 'tsconfig.json');
|
|
132
|
+
if (fs.existsSync(tsconfigPath)) {
|
|
133
|
+
return tsconfigPath;
|
|
134
|
+
}
|
|
135
|
+
currentDir = path.dirname(currentDir);
|
|
136
|
+
}
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Load TypeScript program from tsconfig
|
|
141
|
+
*/
|
|
142
|
+
function loadProgram(tsconfigPath) {
|
|
143
|
+
const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
|
|
144
|
+
if (configFile.error) {
|
|
145
|
+
throw new Error(`Error reading tsconfig: ${ts.flattenDiagnosticMessageText(configFile.error.messageText, '\n')}`);
|
|
146
|
+
}
|
|
147
|
+
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(tsconfigPath));
|
|
148
|
+
if (parsedConfig.errors.length > 0) {
|
|
149
|
+
const errorMessages = parsedConfig.errors.map(e => ts.flattenDiagnosticMessageText(e.messageText, '\n'));
|
|
150
|
+
throw new Error(`Error parsing tsconfig: ${errorMessages.join('\n')}`);
|
|
151
|
+
}
|
|
152
|
+
const program = ts.createProgram({
|
|
153
|
+
rootNames: parsedConfig.fileNames,
|
|
154
|
+
options: parsedConfig.options,
|
|
155
|
+
});
|
|
156
|
+
return program;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Print type hierarchy as a tree
|
|
160
|
+
*/
|
|
161
|
+
function printTypeHierarchy(graph) {
|
|
162
|
+
console.log('\nType Hierarchy (Trie):');
|
|
163
|
+
function printNode(node, prefix = '', isLast = true) {
|
|
164
|
+
const connector = isLast ? '└── ' : '├── ';
|
|
165
|
+
const instanceName = `${node.name}Instance`;
|
|
166
|
+
console.log(`${prefix}${connector}${instanceName}`);
|
|
167
|
+
const children = Array.from(node.children.values());
|
|
168
|
+
const newPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
169
|
+
for (let i = 0; i < children.length; i++) {
|
|
170
|
+
printNode(children[i], newPrefix, i === children.length - 1);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const roots = Array.from(graph.roots.values());
|
|
174
|
+
for (let i = 0; i < roots.length; i++) {
|
|
175
|
+
printNode(roots[i], '', i === roots.length - 1);
|
|
176
|
+
}
|
|
177
|
+
console.log(); // Empty line at end
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Run type generation
|
|
181
|
+
*/
|
|
182
|
+
function run(options) {
|
|
183
|
+
const tsconfigPath = findTsConfig(options.project);
|
|
184
|
+
if (!tsconfigPath) {
|
|
185
|
+
console.error('Error: Could not find tsconfig.json');
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
if (options.verbose) {
|
|
189
|
+
console.log(`Using tsconfig: ${tsconfigPath}`);
|
|
190
|
+
}
|
|
191
|
+
// Load TypeScript program
|
|
192
|
+
const program = loadProgram(tsconfigPath);
|
|
193
|
+
// Create analyzer
|
|
194
|
+
const analyzer = new analyzer_1.MnemonicaAnalyzer(program);
|
|
195
|
+
// Determine output directory for exclusion
|
|
196
|
+
const outputDir = options.outputDir || '.tactica';
|
|
197
|
+
const outputDirPath = path.resolve(process.cwd(), outputDir);
|
|
198
|
+
// Analyze all source files
|
|
199
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
200
|
+
if (sourceFile.isDeclarationFile) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
// Always exclude the output directory to avoid analyzing generated files
|
|
204
|
+
if (sourceFile.fileName.startsWith(outputDirPath + path.sep)) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
// Check exclude patterns
|
|
208
|
+
if (options.exclude) {
|
|
209
|
+
const shouldExclude = options.exclude.some(pattern => sourceFile.fileName.includes(pattern.replace(/\*/g, '')));
|
|
210
|
+
if (shouldExclude) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// Check include patterns
|
|
215
|
+
if (options.include && options.include.length > 0) {
|
|
216
|
+
const shouldInclude = options.include.some(pattern => sourceFile.fileName.includes(pattern.replace(/\*/g, '')));
|
|
217
|
+
if (!shouldInclude) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (options.verbose) {
|
|
222
|
+
console.log(`Analyzing: ${sourceFile.fileName}`);
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
analyzer.analyzeFile(sourceFile);
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
console.error(`Error analyzing ${sourceFile.fileName}:`, err);
|
|
229
|
+
throw err;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Generate types
|
|
233
|
+
const graph = analyzer.getGraph();
|
|
234
|
+
const generator = new generator_1.TypesGenerator(graph);
|
|
235
|
+
// Check if module augmentation mode is requested (legacy)
|
|
236
|
+
const useModuleAugmentation = options.globalAugmentation === false;
|
|
237
|
+
// Generate types based on mode
|
|
238
|
+
let generatedTypes;
|
|
239
|
+
let outputPath;
|
|
240
|
+
const writer = new writer_1.TypesWriter(options.outputDir);
|
|
241
|
+
if (useModuleAugmentation) {
|
|
242
|
+
// Legacy mode: generate global augmentation file (index.d.ts)
|
|
243
|
+
generatedTypes = generator.generateGlobalAugmentation();
|
|
244
|
+
outputPath = writer.writeGlobalAugmentation(generatedTypes);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
// Default mode: generate only types.ts for manual imports
|
|
248
|
+
generatedTypes = generator.generateTypesFile();
|
|
249
|
+
outputPath = writer.writeTypesFile(generatedTypes);
|
|
250
|
+
}
|
|
251
|
+
if (options.verbose) {
|
|
252
|
+
console.log(`Generated types at: ${outputPath}`);
|
|
253
|
+
console.log(`Mode: ${useModuleAugmentation ? 'global augmentation (legacy)' : 'types file (default)'}`);
|
|
254
|
+
console.log(`Found ${generatedTypes.types.length} types:`);
|
|
255
|
+
printTypeHierarchy(graph);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
console.log(`Generated ${generatedTypes.types.length} types at ${options.outputDir || '.tactica'}`);
|
|
259
|
+
if (useModuleAugmentation) {
|
|
260
|
+
console.log('Using global augmentation mode (legacy, use default mode for types.ts only)');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Watch mode
|
|
266
|
+
*/
|
|
267
|
+
function watch(options) {
|
|
268
|
+
console.log('Starting watch mode...');
|
|
269
|
+
// Initial run
|
|
270
|
+
run(options);
|
|
271
|
+
// Set up file watching
|
|
272
|
+
const chokidar = require('chokidar');
|
|
273
|
+
const tsconfigPath = findTsConfig(options.project);
|
|
274
|
+
if (!tsconfigPath) {
|
|
275
|
+
console.error('Error: Could not find tsconfig.json');
|
|
276
|
+
process.exit(1);
|
|
277
|
+
}
|
|
278
|
+
const projectDir = path.dirname(tsconfigPath);
|
|
279
|
+
const watchPaths = options.include || ['**/*.ts'];
|
|
280
|
+
const ignorePaths = options.exclude || ['**/*.d.ts', 'node_modules/**', '.tactica/**'];
|
|
281
|
+
const watcher = chokidar.watch(watchPaths, {
|
|
282
|
+
cwd: projectDir,
|
|
283
|
+
ignored: ignorePaths,
|
|
284
|
+
persistent: true,
|
|
285
|
+
});
|
|
286
|
+
watcher.on('change', (filePath) => {
|
|
287
|
+
if (options.verbose) {
|
|
288
|
+
console.log(`File changed: ${filePath}`);
|
|
289
|
+
}
|
|
290
|
+
run(options);
|
|
291
|
+
});
|
|
292
|
+
watcher.on('add', (filePath) => {
|
|
293
|
+
if (options.verbose) {
|
|
294
|
+
console.log(`File added: ${filePath}`);
|
|
295
|
+
}
|
|
296
|
+
run(options);
|
|
297
|
+
});
|
|
298
|
+
console.log('Watching for changes... (Press Ctrl+C to stop)');
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Main entry point
|
|
302
|
+
*/
|
|
303
|
+
function main() {
|
|
304
|
+
const args = process.argv.slice(2);
|
|
305
|
+
const options = parseArgs(args);
|
|
306
|
+
if (options.help) {
|
|
307
|
+
printHelp();
|
|
308
|
+
process.exit(0);
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
if (options.watch) {
|
|
312
|
+
watch(options);
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
run(options);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
320
|
+
process.exit(1);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Run if executed directly
|
|
324
|
+
if (require.main === module) {
|
|
325
|
+
main();
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=cli.js.map
|
package/lib/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { TypeNode, GeneratedTypes } from './types';
|
|
2
|
+
import { TypeGraphImpl } from './graph';
|
|
3
|
+
/**
|
|
4
|
+
* TypeScript declaration file generator
|
|
5
|
+
*/
|
|
6
|
+
export declare class TypesGenerator {
|
|
7
|
+
private graph;
|
|
8
|
+
constructor(graph: TypeGraphImpl);
|
|
9
|
+
/**
|
|
10
|
+
* Generate global augmentation file that augments user classes directly
|
|
11
|
+
* This allows using decorated classes without manual type casting
|
|
12
|
+
*
|
|
13
|
+
* All types are placed in the global scope via declare global, which allows
|
|
14
|
+
* them to be accessed from any module without imports. Interfaces declared
|
|
15
|
+
* in the global scope will merge with classes of the same name in user modules.
|
|
16
|
+
*/
|
|
17
|
+
generateGlobalAugmentation(): GeneratedTypes;
|
|
18
|
+
/**
|
|
19
|
+
* Generate instance type alias (describes what the instance IS)
|
|
20
|
+
* Uses intersection types for inheritance (types can't extend)
|
|
21
|
+
*/
|
|
22
|
+
private generateInstanceType;
|
|
23
|
+
/**
|
|
24
|
+
* Generate class interface for TypeScript declaration merging
|
|
25
|
+
* This merges with the actual class to provide proper typing
|
|
26
|
+
*/
|
|
27
|
+
private generateClassInterface;
|
|
28
|
+
/**
|
|
29
|
+
* Generate a types.ts file with complete instance interfaces
|
|
30
|
+
* This includes all properties extracted from the constructors
|
|
31
|
+
*/
|
|
32
|
+
generateTypesFile(): GeneratedTypes;
|
|
33
|
+
/**
|
|
34
|
+
* Generate a complete instance type alias with all properties
|
|
35
|
+
* This is for the types.ts file that users import from
|
|
36
|
+
*/
|
|
37
|
+
private generateCompleteInstanceInterface;
|
|
38
|
+
/**
|
|
39
|
+
* Generate a simple type declaration for a single type
|
|
40
|
+
*/
|
|
41
|
+
generateSingleType(node: TypeNode): string;
|
|
42
|
+
}
|
package/lib/generator.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TypesGenerator = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* TypeScript declaration file generator
|
|
6
|
+
*/
|
|
7
|
+
class TypesGenerator {
|
|
8
|
+
constructor(graph) {
|
|
9
|
+
this.graph = graph;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generate global augmentation file that augments user classes directly
|
|
13
|
+
* This allows using decorated classes without manual type casting
|
|
14
|
+
*
|
|
15
|
+
* All types are placed in the global scope via declare global, which allows
|
|
16
|
+
* them to be accessed from any module without imports. Interfaces declared
|
|
17
|
+
* in the global scope will merge with classes of the same name in user modules.
|
|
18
|
+
*/
|
|
19
|
+
generateGlobalAugmentation() {
|
|
20
|
+
const lines = [];
|
|
21
|
+
const generatedTypes = [];
|
|
22
|
+
// Header - make this a module so we can use declare global
|
|
23
|
+
lines.push('// Generated by @mnemonica/tactica - DO NOT EDIT');
|
|
24
|
+
lines.push('// This file provides automatic type augmentation for decorated classes');
|
|
25
|
+
lines.push('');
|
|
26
|
+
lines.push('/* eslint-disable @typescript-eslint/no-empty-object-type */');
|
|
27
|
+
lines.push('/* eslint-disable @typescript-eslint/no-empty-interface */');
|
|
28
|
+
lines.push('');
|
|
29
|
+
// Make this a module so we can use declare global
|
|
30
|
+
lines.push('export {};');
|
|
31
|
+
lines.push('');
|
|
32
|
+
// All types go inside declare global so they are globally accessible
|
|
33
|
+
lines.push('declare global {');
|
|
34
|
+
lines.push('');
|
|
35
|
+
// Helper type - in global scope
|
|
36
|
+
lines.push(' // Helper type for nested type constructors');
|
|
37
|
+
lines.push(' type TypeConstructor<T> = {');
|
|
38
|
+
lines.push(' new (...args: unknown[]): T;');
|
|
39
|
+
lines.push(' (...args: unknown[]): T;');
|
|
40
|
+
lines.push(' };');
|
|
41
|
+
lines.push('');
|
|
42
|
+
// Generate instance types for all types - in global scope
|
|
43
|
+
for (const root of this.graph.roots.values()) {
|
|
44
|
+
for (const node of this.graph.dfs(root)) {
|
|
45
|
+
const instanceName = `${node.name}Instance`;
|
|
46
|
+
generatedTypes.push(instanceName);
|
|
47
|
+
this.generateInstanceType(node, lines, 1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Generate class interfaces - in global scope for declaration merging
|
|
51
|
+
// These interfaces will merge with classes of the same name in user modules
|
|
52
|
+
lines.push(' // Class interfaces for declaration merging');
|
|
53
|
+
lines.push(' // These merge with @decorate() classes to provide proper typing');
|
|
54
|
+
lines.push('');
|
|
55
|
+
for (const root of this.graph.roots.values()) {
|
|
56
|
+
for (const node of this.graph.dfs(root)) {
|
|
57
|
+
this.generateClassInterface(node, lines, 1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
lines.push('}');
|
|
61
|
+
return {
|
|
62
|
+
content: lines.join('\n'),
|
|
63
|
+
types: generatedTypes,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Generate instance type alias (describes what the instance IS)
|
|
68
|
+
* Uses intersection types for inheritance (types can't extend)
|
|
69
|
+
*/
|
|
70
|
+
generateInstanceType(node, lines, indent) {
|
|
71
|
+
const indentStr = '\t'.repeat(indent);
|
|
72
|
+
const instanceName = `${node.name}Instance`;
|
|
73
|
+
// Build intersection with parent instance
|
|
74
|
+
const parentType = node.parent ? `${node.parent.name}Instance & ` : '';
|
|
75
|
+
// Instance is a type describing the data structure
|
|
76
|
+
lines.push(`${indentStr}type ${instanceName} = ${parentType}{`);
|
|
77
|
+
// Add instance properties
|
|
78
|
+
for (const [propName, propInfo] of node.properties.entries()) {
|
|
79
|
+
const optional = propInfo.optional ? '?' : '';
|
|
80
|
+
lines.push(`${indentStr}\t${propName}${optional}: ${propInfo.type};`);
|
|
81
|
+
}
|
|
82
|
+
// Add nested constructor properties (mnemonica subtypes)
|
|
83
|
+
for (const child of node.children.values()) {
|
|
84
|
+
const childInstanceType = `${child.name}Instance`;
|
|
85
|
+
lines.push(`${indentStr}\t${child.name}: TypeConstructor<${childInstanceType}>;`);
|
|
86
|
+
}
|
|
87
|
+
lines.push(`${indentStr}}`);
|
|
88
|
+
// Add empty line after each type
|
|
89
|
+
lines.push('');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Generate class interface for TypeScript declaration merging
|
|
93
|
+
* This merges with the actual class to provide proper typing
|
|
94
|
+
*/
|
|
95
|
+
generateClassInterface(node, lines, indent) {
|
|
96
|
+
const indentStr = '\t'.repeat(indent);
|
|
97
|
+
// Build extends clause
|
|
98
|
+
const extendsTypes = [];
|
|
99
|
+
if (node.parent) {
|
|
100
|
+
extendsTypes.push(node.parent.name);
|
|
101
|
+
}
|
|
102
|
+
const extendsClause = extendsTypes.length > 0
|
|
103
|
+
? ` extends ${extendsTypes.join(', ')}`
|
|
104
|
+
: '';
|
|
105
|
+
// Interface with same name as class - TypeScript merges these
|
|
106
|
+
lines.push(`${indentStr}interface ${node.name}${extendsClause} {`);
|
|
107
|
+
// Add all instance properties (for type merging)
|
|
108
|
+
for (const [propName, propInfo] of node.properties.entries()) {
|
|
109
|
+
const optional = propInfo.optional ? '?' : '';
|
|
110
|
+
lines.push(`${indentStr}\t${propName}${optional}: ${propInfo.type};`);
|
|
111
|
+
}
|
|
112
|
+
// Add subtype constructors (non-optional so they're accessible)
|
|
113
|
+
for (const child of node.children.values()) {
|
|
114
|
+
const childInstanceType = `${child.name}Instance`;
|
|
115
|
+
lines.push(`${indentStr}\t${child.name}: TypeConstructor<${childInstanceType}>;`);
|
|
116
|
+
}
|
|
117
|
+
lines.push(`${indentStr}}`);
|
|
118
|
+
lines.push('');
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Generate a types.ts file with complete instance interfaces
|
|
122
|
+
* This includes all properties extracted from the constructors
|
|
123
|
+
*/
|
|
124
|
+
generateTypesFile() {
|
|
125
|
+
const lines = [];
|
|
126
|
+
const generatedTypes = [];
|
|
127
|
+
// Header
|
|
128
|
+
lines.push('// Generated by @mnemonica/tactica - DO NOT EDIT');
|
|
129
|
+
lines.push('// This file provides complete TypeScript interfaces for Mnemonica types');
|
|
130
|
+
lines.push('');
|
|
131
|
+
lines.push('/* eslint-disable @typescript-eslint/no-empty-object-type */');
|
|
132
|
+
lines.push('/* eslint-disable @typescript-eslint/no-empty-interface */');
|
|
133
|
+
lines.push('');
|
|
134
|
+
// Define a helper type for nested constructors (since IDefinitorInstance is internal)
|
|
135
|
+
lines.push('// Helper type for nested type constructors');
|
|
136
|
+
lines.push('type TypeConstructor<T> = {');
|
|
137
|
+
lines.push('\tnew (...args: unknown[]): T;');
|
|
138
|
+
lines.push('\t(...args: unknown[]): T;');
|
|
139
|
+
lines.push('};');
|
|
140
|
+
lines.push('');
|
|
141
|
+
// Generate complete instance interfaces
|
|
142
|
+
for (const root of this.graph.roots.values()) {
|
|
143
|
+
for (const node of this.graph.dfs(root)) {
|
|
144
|
+
const interfaceName = `${node.name}Instance`;
|
|
145
|
+
generatedTypes.push(interfaceName);
|
|
146
|
+
this.generateCompleteInstanceInterface(node, lines);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
content: lines.join('\n'),
|
|
151
|
+
types: generatedTypes,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Generate a complete instance type alias with all properties
|
|
156
|
+
* This is for the types.ts file that users import from
|
|
157
|
+
*/
|
|
158
|
+
generateCompleteInstanceInterface(node, lines) {
|
|
159
|
+
const typeName = `${node.name}Instance`;
|
|
160
|
+
// Build intersection with parent type
|
|
161
|
+
const parentType = node.parent ? `${node.parent.name}Instance & ` : '';
|
|
162
|
+
// Export the type alias
|
|
163
|
+
lines.push(`export type ${typeName} = ${parentType}{`);
|
|
164
|
+
// Add instance properties extracted from the constructor
|
|
165
|
+
for (const [propName, propInfo] of node.properties.entries()) {
|
|
166
|
+
const optional = propInfo.optional ? '?' : '';
|
|
167
|
+
lines.push(`\t${propName}${optional}: ${propInfo.type};`);
|
|
168
|
+
}
|
|
169
|
+
// Add nested constructor properties
|
|
170
|
+
for (const child of node.children.values()) {
|
|
171
|
+
const childInstanceType = `${child.name}Instance`;
|
|
172
|
+
lines.push(`\t${child.name}: TypeConstructor<${childInstanceType}>;`);
|
|
173
|
+
}
|
|
174
|
+
lines.push('}');
|
|
175
|
+
lines.push('');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Generate a simple type declaration for a single type
|
|
179
|
+
*/
|
|
180
|
+
generateSingleType(node) {
|
|
181
|
+
const lines = [];
|
|
182
|
+
this.generateCompleteInstanceInterface(node, lines);
|
|
183
|
+
return lines.join('\n');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.TypesGenerator = TypesGenerator;
|
|
187
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
|
package/lib/graph.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TypeNode, TypeGraph } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Trie-based type graph for storing Mnemonica type hierarchy
|
|
4
|
+
*/
|
|
5
|
+
export declare class TypeGraphImpl implements TypeGraph {
|
|
6
|
+
roots: Map<string, TypeNode>;
|
|
7
|
+
allTypes: Map<string, TypeNode>;
|
|
8
|
+
addRoot(node: TypeNode): void;
|
|
9
|
+
addChild(parent: TypeNode, child: TypeNode): void;
|
|
10
|
+
findType(fullPath: string): TypeNode | undefined;
|
|
11
|
+
getAllTypes(): TypeNode[];
|
|
12
|
+
clear(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Create a new TypeNode
|
|
15
|
+
*/
|
|
16
|
+
static createNode(name: string, parent: TypeNode | undefined, sourceFile: string, line: number, column: number): TypeNode;
|
|
17
|
+
/**
|
|
18
|
+
* Traverse the graph in breadth-first order
|
|
19
|
+
*/
|
|
20
|
+
bfs(): Generator<TypeNode>;
|
|
21
|
+
/**
|
|
22
|
+
* Traverse the graph in depth-first order
|
|
23
|
+
*/
|
|
24
|
+
dfs(node?: TypeNode, visited?: Set<string>): Generator<TypeNode>;
|
|
25
|
+
}
|