0
# Generator Management
1
2
Registration, instantiation, and execution of generators with metadata management and lifecycle control.
3
4
## Capabilities
5
6
### Generator Registration
7
8
Register generators with the environment by path, constructor, or module.
9
10
```typescript { .api }
11
/**
12
* Register a generator by path or constructor
13
* Available on Environment and EnvironmentBase instances
14
* @param pathOrStub - Generator path, constructor, or module
15
* @param meta - Optional metadata for the generator
16
* @returns Generator metadata object
17
*/
18
register(pathOrStub: unknown, meta?: Partial<BaseGeneratorMeta>): GeneratorMeta;
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import { createEnv } from "yeoman-environment";
25
26
const env = createEnv();
27
28
// Register by file path
29
const meta1 = env.register("./generators/app/index.js", {
30
namespace: "myapp:app"
31
});
32
33
// Register by module path
34
const meta2 = env.register("generator-webapp/generators/app", {
35
namespace: "webapp:app"
36
});
37
38
// Register with custom metadata
39
const meta3 = env.register(MyGeneratorClass, {
40
namespace: "custom:generator",
41
packagePath: "/path/to/package"
42
});
43
```
44
45
### Generator Retrieval
46
47
Get generator instances or constructors from the registry.
48
49
```typescript { .api }
50
/**
51
* Get generator instance by namespace or path
52
* @param namespaceOrPath - Generator namespace or Yeoman namespace object
53
* @returns Generator instance or undefined if not found
54
*/
55
get<C>(namespaceOrPath: string | YeomanNamespace): Promise<C | undefined>;
56
57
/**
58
* Find generator metadata by namespace or path
59
* @param namespaceOrPath - Generator namespace or Yeoman namespace object
60
* @returns Generator metadata or undefined if not found
61
*/
62
findMeta(namespaceOrPath: string | YeomanNamespace): Promise<GeneratorMeta | undefined>;
63
64
/**
65
* Require and return a generator constructor
66
* Available on Environment instances
67
* @param namespace - Generator namespace to require
68
* @returns Generator constructor or undefined
69
*/
70
requireGenerator(namespace: string): Promise<BaseGeneratorConstructor | undefined>;
71
72
/**
73
* Get generator metadata by namespace
74
* @param namespace - Generator namespace
75
* @returns Generator metadata or undefined
76
*/
77
getGeneratorMeta(namespace: string): GeneratorMeta | undefined;
78
```
79
80
**Usage Examples:**
81
82
```typescript
83
// Get generator instance
84
const generator = await env.get<MyGenerator>("webapp:app");
85
86
// Find metadata
87
const meta = await env.findMeta("webapp:app");
88
89
// Require constructor
90
const GeneratorClass = await env.requireGenerator("webapp:app");
91
92
// Get metadata directly
93
const storedMeta = env.getGeneratorMeta("webapp:app");
94
```
95
96
### Generator Creation
97
98
Create and instantiate generator instances with arguments.
99
100
```typescript { .api }
101
/**
102
* Create generator instance with arguments
103
* @param namespaceOrPath - Generator namespace, path, or constructor
104
* @param args - Arguments to pass to generator constructor
105
* @returns Generator instance
106
*/
107
create<G>(namespaceOrPath: string | GetGeneratorConstructor<G>, ...args: any[]): Promise<G>;
108
109
/**
110
* Instantiate generator from constructor
111
* @param generator - Generator constructor
112
* @param args - Arguments to pass to constructor
113
* @returns Generator instance
114
*/
115
instantiate<G>(generator: GetGeneratorConstructor<G>, ...args: any[]): Promise<G>;
116
117
/**
118
* Compose with another generator
119
* @param generator - Generator to compose with (namespace or constructor)
120
* @param args - Arguments for the generator
121
* @returns Composed generator instance
122
*/
123
composeWith<G>(generator: string | GetGeneratorConstructor<G>, ...args: any[]): Promise<G>;
124
```
125
126
**Usage Examples:**
127
128
```typescript
129
// Create generator with arguments
130
const generator = await env.create("webapp:app", ["MyApp"], {
131
skipInstall: true,
132
framework: "react"
133
});
134
135
// Instantiate from constructor
136
const GeneratorClass = await env.requireGenerator("webapp:app");
137
const instance = await env.instantiate(GeneratorClass, ["MyApp"]);
138
139
// Compose with another generator
140
const subGenerator = await env.composeWith("webapp:component", ["UserCard"], {
141
style: "css",
142
test: true
143
});
144
```
145
146
### Generator Execution
147
148
Execute generators with queue management and lifecycle control.
149
150
```typescript { .api }
151
/**
152
* Run a generator instance
153
* @param generator - Generator to run
154
*/
155
runGenerator(generator: BaseGenerator): Promise<void>;
156
157
/**
158
* Queue generator for execution
159
* @param generator - Generator to queue
160
* @param queueOptions - Queue options
161
* @returns Queued generator
162
*/
163
queueGenerator<G>(generator: G, queueOptions?: { schedule?: boolean }): Promise<G>;
164
165
/**
166
* Execute a generator by namespace with arguments
167
* Available on Environment instances
168
* @param generatorNamespace - Namespace of generator to run
169
* @param args - Arguments to pass to generator
170
*/
171
execute(generatorNamespace: string, args?: string[]): Promise<void>;
172
173
/**
174
* Main run method for executing generators
175
* Available on Environment instances
176
* @param args - Arguments for the generator
177
* @param options - Options for execution
178
*/
179
run(args?: string[], options?: any): Promise<void>;
180
```
181
182
**Usage Examples:**
183
184
```typescript
185
// Execute by namespace
186
await env.execute("webapp:app", ["MyApp", "--skip-install"]);
187
188
// Run with options
189
await env.run(["webapp:app", "MyApp"], {
190
skipInstall: true,
191
force: true
192
});
193
194
// Queue and run manually
195
const generator = await env.create("webapp:app", ["MyApp"]);
196
await env.queueGenerator(generator);
197
await env.runGenerator(generator);
198
```
199
200
### Registry Management
201
202
Manage the generator registry and get information about registered generators.
203
204
```typescript { .api }
205
/**
206
* Get all registered generator namespaces
207
* Available on Environment instances
208
* @returns Array of namespace strings
209
*/
210
namespaces(): string[];
211
212
/**
213
* Get metadata for all registered generators
214
* Available on Environment instances
215
* @returns Object mapping namespaces to generator metadata
216
*/
217
getGeneratorsMeta(): Record<string, GeneratorMeta>;
218
219
/**
220
* Get names of all registered generators
221
* Available on Environment instances
222
* @returns Array of generator names
223
*/
224
getGeneratorNames(): string[];
225
226
/**
227
* Check if package is registered
228
* @param packageNamespace - Package namespace to check
229
* @returns True if registered
230
*/
231
isPackageRegistered(packageNamespace: string): boolean;
232
233
/**
234
* Get all registered package namespaces
235
* @returns Array of registered package namespaces
236
*/
237
getRegisteredPackages(): string[];
238
239
/**
240
* Get package path for a namespace
241
* Available on Environment instances
242
* @param namespace - Generator namespace to look up
243
* @returns Package path or undefined if not found
244
*/
245
getPackagePath(namespace: string): string | undefined;
246
247
/**
248
* Get all package paths for a namespace
249
* Available on Environment instances
250
* @param namespace - Generator namespace to look up
251
* @returns Array of package paths
252
*/
253
getPackagePaths(namespace: string): string[];
254
```
255
256
**Usage Examples:**
257
258
```typescript
259
// Get all registered namespaces
260
const allNamespaces = env.namespaces();
261
console.log("Registered generators:", allNamespaces);
262
263
// Get all metadata
264
const allMeta = env.getGeneratorsMeta();
265
266
// Check if generator is registered
267
if (env.isPackageRegistered("webapp")) {
268
console.log("WebApp generator is available");
269
}
270
271
// Get package information
272
const packagePath = env.getPackagePath("webapp:app");
273
const allPaths = env.getPackagePaths("webapp");
274
```
275
276
### Namespace Management
277
278
Handle namespace resolution and aliasing.
279
280
```typescript { .api }
281
/**
282
* Convert filepath to namespace
283
* @param filepath - File path to convert
284
* @param lookups - Optional lookup paths
285
* @returns Generator namespace
286
*/
287
namespace(filepath: string, lookups?: string[]): string;
288
289
/**
290
* Set or get namespace aliases
291
* @param match - String or regex to match
292
* @param value - Replacement value (optional for getter)
293
* @returns Alias value or this for setter
294
*/
295
alias(match: string | RegExp, value?: string): string | this;
296
```
297
298
**Usage Examples:**
299
300
```typescript
301
// Convert path to namespace
302
const namespace = env.namespace("./generators/app/index.js");
303
console.log(namespace); // "myapp:app"
304
305
// Set alias
306
env.alias(/^webapp:(.*)/, "web:$1");
307
308
// Get resolved alias
309
const aliased = env.alias("webapp:app"); // Returns "web:app"
310
```
311
312
## Task Queue Management
313
314
Manage the execution queue and task priorities.
315
316
```typescript { .api }
317
/**
318
* Queue a task for execution at specified priority
319
* @param priority - Task priority/queue name
320
* @param task - Task function to execute
321
* @param options - Task options
322
*/
323
queueTask(priority: string, task: () => void | Promise<void>, options?: any): void;
324
325
/**
326
* Add custom priority to execution queue
327
* @param priority - Priority name
328
* @param before - Priority to insert before
329
*/
330
addPriority(priority: string, before?: string): void;
331
332
/**
333
* Get root generator instance
334
* @returns Root generator
335
*/
336
rootGenerator<G>(): G;
337
```
338
339
**Usage Examples:**
340
341
```typescript
342
// Queue custom task
343
env.queueTask("writing", async () => {
344
console.log("Custom writing task");
345
}, { once: true });
346
347
// Add custom priority
348
env.addPriority("custom-step", "writing");
349
350
// Get root generator
351
const root = env.rootGenerator();
352
```
353
354
### Version Management
355
356
Get version information for packages and the environment.
357
358
```typescript { .api }
359
/**
360
* Get version of a package or the environment itself
361
* @param packageName - Package name (optional, defaults to environment version)
362
* @returns Version string or undefined if not found
363
*/
364
getVersion(packageName?: string): string | undefined;
365
```
366
367
**Usage Examples:**
368
369
```typescript
370
// Get environment version
371
const envVersion = env.getVersion();
372
console.log("Environment version:", envVersion);
373
374
// Get package version
375
const reactVersion = env.getVersion("react");
376
```
377
378
### Feature Discovery
379
380
Find generators that support specific features.
381
382
```typescript { .api }
383
/**
384
* Find generators with a specific feature
385
* @param featureName - Feature name to search for
386
* @returns Array of generators supporting the feature
387
*/
388
findFeature(featureName: string): Array<{ generatorId: string; feature: any }>;
389
```
390
391
**Usage Examples:**
392
393
```typescript
394
// Find generators supporting TypeScript
395
const tsGenerators = env.findFeature("typescript");
396
console.log("TypeScript-enabled generators:", tsGenerators);
397
```
398
399
## Metadata Types
400
401
```typescript { .api }
402
interface BaseGeneratorMeta {
403
/** Generator namespace (e.g., 'angular:component') */
404
namespace: string;
405
/** Resolved path to generator file */
406
resolved?: string;
407
/** Path to package containing generator */
408
packagePath?: string;
409
}
410
411
interface GeneratorMeta extends BaseGeneratorMeta {
412
/** Create generator instance with arguments */
413
instantiate(...args: any[]): Promise<BaseGenerator>;
414
/** Create generator instance for help display */
415
instantiateHelp(): Promise<BaseGenerator>;
416
}
417
418
type YeomanNamespace = {
419
/** Package namespace portion */
420
packageNamespace: string;
421
/** Generator name portion */
422
generator?: string;
423
/** Scope prefix (e.g., @angular) */
424
scope?: string;
425
/** Instance identifier */
426
instanceId?: string;
427
};
428
429
interface GetGeneratorConstructor<T = BaseGenerator> {
430
new (...args: any[]): T;
431
}
432
433
interface BaseGenerator {
434
/** Generator arguments */
435
arguments: any[];
436
/** Generator options */
437
options: any;
438
/** Run the generator */
439
run(): Promise<void>;
440
}
441
```