0
# Generator Utilities
1
2
Core utilities for generator development including project management, plop integration, and workspace operations.
3
4
## Capabilities
5
6
### Project Management
7
8
Utilities for working with Turborepo project instances and configuration.
9
10
#### Project Instance
11
12
```typescript { .api }
13
/**
14
* Get Turborepo project instance from repository root
15
* @param args - Project configuration
16
* @returns Promise with Project instance for the repository
17
*/
18
function getProject(args: { root?: string }): Promise<Project>;
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import { getProject } from "@turbo/gen/dist/utils/getProject";
25
26
// Get project from current directory
27
const project = await getProject({});
28
29
// Get project from specific root
30
const project = await getProject({
31
root: "/path/to/turborepo"
32
});
33
```
34
35
### Update Notifications
36
37
Check for package updates and notify users.
38
39
```typescript { .api }
40
/**
41
* Check for package updates and display notification
42
* @returns Promise that resolves when update check is complete
43
*/
44
function notifyUpdate(): Promise<void>;
45
```
46
47
**Usage Examples:**
48
49
```typescript
50
import { notifyUpdate } from "@turbo/gen/dist/utils/notifyUpdate";
51
52
// Check for updates (typically called after command completion)
53
await notifyUpdate();
54
```
55
56
### Error Handling
57
58
Specialized error types for generator operations.
59
60
```typescript { .api }
61
/**
62
* Custom error class for generator operations
63
*/
64
class GeneratorError extends Error {
65
public type: GenerateErrorType;
66
67
constructor(message: string, opts?: GeneratorErrorOptions);
68
}
69
70
type GenerateErrorType =
71
| "plop_error_running_generator"
72
| "plop_unable_to_load_config"
73
| "plop_generator_not_found"
74
| "plop_no_config"
75
| "config_directory_already_exists"
76
| "unknown";
77
78
interface GeneratorErrorOptions {
79
type?: GenerateErrorType;
80
}
81
```
82
83
**Usage Examples:**
84
85
```typescript
86
import { GeneratorError } from "@turbo/gen/dist/utils/error";
87
88
// Throw specific error type
89
throw new GeneratorError("Generator not found", {
90
type: "plop_generator_not_found"
91
});
92
93
// Catch and handle generator errors
94
try {
95
await runCustomGenerator(args);
96
} catch (error) {
97
if (error instanceof GeneratorError) {
98
console.error(`Generator error (${error.type}): ${error.message}`);
99
}
100
}
101
```
102
103
## Plop Integration Utilities
104
105
Advanced utilities for working with node-plop and custom generators.
106
107
### Plop API Access
108
109
```typescript { .api }
110
/**
111
* Get NodePlopAPI instance for direct plop operations
112
* @param args - Plop configuration
113
* @returns NodePlopAPI instance or undefined if config not found
114
*/
115
function getPlop(args: {
116
project: Project;
117
configPath?: string;
118
}): NodePlopAPI | undefined;
119
```
120
121
### Generator Management
122
123
```typescript { .api }
124
/**
125
* Get list of all available custom generators
126
* @param args - Generator discovery configuration
127
* @returns Array of generators or separators for UI display
128
*/
129
function getCustomGenerators(args: {
130
project: Project;
131
configPath?: string;
132
}): Array<Generator | Separator>;
133
134
/**
135
* Get specific generator by name
136
* @param args - Generator lookup configuration
137
* @returns Generator name or undefined if not found
138
*/
139
function getCustomGenerator(args: {
140
project: Project;
141
generator: string;
142
configPath?: string;
143
}): string | undefined;
144
145
/**
146
* Execute a custom generator with optional bypass arguments
147
* @param args - Generator execution configuration
148
* @returns Promise that resolves when generator completes
149
*/
150
function runCustomGenerator(args: {
151
project: Project;
152
generator: string;
153
bypassArgs?: Array<string>;
154
configPath?: string;
155
}): Promise<void>;
156
157
type Generator = PlopGenerator & {
158
basePath: string;
159
name: string;
160
};
161
```
162
163
**Usage Examples:**
164
165
```typescript
166
import {
167
getPlop,
168
getCustomGenerators,
169
getCustomGenerator,
170
runCustomGenerator
171
} from "@turbo/gen/dist/utils/plop";
172
173
const project = await getProject({});
174
175
// Get plop instance for advanced operations
176
const plop = getPlop({
177
project,
178
configPath: "./turbo/generators/config.js"
179
});
180
181
if (plop) {
182
// Access plop directly for custom operations
183
const generator = plop.getGenerator("component");
184
await plop.runGenerator(generator, { name: "MyComponent" });
185
}
186
187
// List available generators
188
const generators = getCustomGenerators({
189
project,
190
configPath: "./turbo/generators/config.js"
191
});
192
193
// Check if specific generator exists
194
const componentGenerator = getCustomGenerator({
195
project,
196
generator: "component",
197
configPath: "./turbo/generators/config.js"
198
});
199
200
if (componentGenerator) {
201
// Run the generator
202
await runCustomGenerator({
203
project,
204
generator: "component",
205
bypassArgs: ["Button", "ui/components"]
206
});
207
}
208
```
209
210
## Workspace Utilities
211
212
Utilities for analyzing and working with workspace structures in monorepos.
213
214
### Workspace Analysis
215
216
```typescript { .api }
217
/**
218
* Analyze workspace structure in the monorepo
219
* @param args - Project instance
220
* @returns Detailed workspace structure information
221
*/
222
function getWorkspaceStructure(args: {
223
project: Project;
224
}): WorkspaceStructure;
225
226
interface WorkspaceStructure {
227
hasRootApps: boolean;
228
hasRootPackages: boolean;
229
workspacesByGroup: Record<string, Array<Workspace>>;
230
nonAppWorkspaces: Array<Workspace>;
231
}
232
233
/**
234
* Get group name for a workspace based on its location
235
* @param args - Project and workspace
236
* @returns Group name for the workspace
237
*/
238
function getGroupFromWorkspace(args: {
239
project: Project;
240
workspace: Workspace;
241
}): string;
242
```
243
244
### Workspace Listing
245
246
```typescript { .api }
247
/**
248
* Get filtered list of workspaces for selection or processing
249
* @param args - Project and filtering options
250
* @returns Array of workspaces or separators for UI
251
*/
252
function getWorkspaceList(args: {
253
project: Project;
254
type: WorkspaceType;
255
showAllDependencies?: boolean;
256
}): Array<Workspace | Separator>;
257
258
type WorkspaceType = "app" | "package";
259
```
260
261
### Workspace Roots
262
263
```typescript { .api }
264
/**
265
* Get workspace root directories from project configuration
266
* @param args - Project instance
267
* @returns Array of workspace root directory paths
268
*/
269
function getWorkspaceRoots(args: {
270
project: Project;
271
}): Array<string>;
272
```
273
274
**Usage Examples:**
275
276
```typescript
277
import {
278
getWorkspaceStructure,
279
getGroupFromWorkspace,
280
getWorkspaceList,
281
getWorkspaceRoots
282
} from "@turbo/gen/dist/utils";
283
284
const project = await getProject({});
285
286
// Analyze workspace structure
287
const structure = getWorkspaceStructure({ project });
288
console.log("Has root apps:", structure.hasRootApps);
289
console.log("Workspaces by group:", structure.workspacesByGroup);
290
291
// Get group for specific workspace
292
const workspace = structure.workspacesByGroup["packages"][0];
293
const group = getGroupFromWorkspace({ project, workspace });
294
console.log("Workspace group:", group);
295
296
// Get filtered workspace list
297
const packages = getWorkspaceList({
298
project,
299
type: "package",
300
showAllDependencies: false
301
});
302
303
// Get workspace roots
304
const roots = getWorkspaceRoots({ project });
305
console.log("Workspace roots:", roots); // ["apps", "packages", "tools"]
306
```
307
308
## Template and Setup Utilities
309
310
Utilities for generator template setup and configuration.
311
312
### Template Setup
313
314
```typescript { .api }
315
/**
316
* Set up generator configuration from built-in templates
317
* @param args - Template setup configuration
318
* @returns Promise that resolves when template is set up
319
*/
320
function setupFromTemplate(args: {
321
project: Project;
322
template: "ts" | "js";
323
}): Promise<void>;
324
```
325
326
**Usage Examples:**
327
328
```typescript
329
import { setupFromTemplate } from "@turbo/gen/dist/utils/setupFromTemplate";
330
331
const project = await getProject({});
332
333
// Set up TypeScript generator template
334
await setupFromTemplate({
335
project,
336
template: "ts"
337
});
338
339
// This creates:
340
// - turbo/generators/ directory
341
// - turbo/generators/config.ts
342
// - turbo/generators/templates/
343
// - turbo/generators/package.json
344
```
345
346
### Requirement Gathering
347
348
```typescript { .api }
349
/**
350
* Gather all requirements for workspace creation including interactive prompts
351
* @param args - Generator arguments
352
* @returns Promise with collected workspace requirements
353
*/
354
function gatherAddRequirements(args: TurboGeneratorArguments): Promise<{
355
type: WorkspaceType;
356
name: string;
357
location: { absolute: string; relative: string };
358
source: Workspace | undefined;
359
dependencies: DependencyGroups;
360
}>;
361
362
interface TurboGeneratorArguments {
363
project: Project;
364
opts: TurboGeneratorOptions;
365
}
366
367
interface DependencyGroups {
368
dependencies: string[];
369
devDependencies: string[];
370
peerDependencies: string[];
371
}
372
```
373
374
**Usage Examples:**
375
376
```typescript
377
import { gatherAddRequirements } from "@turbo/gen/dist/utils/gatherAddRequirements";
378
379
const project = await getProject({});
380
381
const requirements = await gatherAddRequirements({
382
project,
383
opts: {
384
name: "my-package",
385
type: "package",
386
method: "empty",
387
copy: { type: "internal", source: "" },
388
showAllDependencies: false
389
}
390
});
391
392
console.log("Workspace name:", requirements.name);
393
console.log("Location:", requirements.location);
394
console.log("Dependencies:", requirements.dependencies);
395
```
396
397
## Advanced Usage Patterns
398
399
### Custom Generator Development
400
401
```typescript
402
import {
403
getProject,
404
getPlop,
405
setupFromTemplate
406
} from "@turbo/gen/dist/utils";
407
408
// Set up a new generator project
409
const project = await getProject({});
410
411
// Initialize generator template
412
await setupFromTemplate({
413
project,
414
template: "ts"
415
});
416
417
// Get plop instance for custom generator registration
418
const plop = getPlop({
419
project,
420
configPath: "./turbo/generators/config.ts"
421
});
422
423
if (plop) {
424
// Register custom helper
425
plop.setHelper("capitalize", (text: string) =>
426
text.charAt(0).toUpperCase() + text.slice(1)
427
);
428
429
// Add custom action type
430
plop.setActionType("custom-action", (answers, config) => {
431
// Custom action implementation
432
return "Custom action completed";
433
});
434
}
435
```
436
437
### Workspace Operations
438
439
```typescript
440
import {
441
getProject,
442
getWorkspaceStructure,
443
getWorkspaceList,
444
generate
445
} from "@turbo/gen/dist/utils";
446
447
const project = await getProject({});
448
449
// Analyze current workspace structure
450
const structure = getWorkspaceStructure({ project });
451
452
// Find available packages to copy from
453
const availablePackages = getWorkspaceList({
454
project,
455
type: "package",
456
showAllDependencies: false
457
});
458
459
// Create new workspace based on existing one
460
if (availablePackages.length > 0) {
461
const sourceWorkspace = availablePackages[0];
462
463
await generate({
464
project,
465
opts: {
466
name: "new-package",
467
type: "package",
468
method: "copy",
469
copy: {
470
type: "internal",
471
source: sourceWorkspace.name
472
},
473
showAllDependencies: false
474
}
475
});
476
}
477
```
478
479
### Error Handling Best Practices
480
481
```typescript
482
import { GeneratorError } from "@turbo/gen/dist/utils/error";
483
import { runCustomGenerator } from "@turbo/gen/dist/utils/plop";
484
485
async function safeGeneratorExecution() {
486
try {
487
const project = await getProject({});
488
489
await runCustomGenerator({
490
project,
491
generator: "component",
492
configPath: "./turbo/generators/config.js"
493
});
494
495
} catch (error) {
496
if (error instanceof GeneratorError) {
497
switch (error.type) {
498
case "plop_generator_not_found":
499
console.error("Generator not found. Check your config file.");
500
break;
501
case "plop_unable_to_load_config":
502
console.error("Unable to load generator config. Check file path and syntax.");
503
break;
504
case "plop_error_running_generator":
505
console.error("Error during generator execution:", error.message);
506
break;
507
default:
508
console.error("Unknown generator error:", error.message);
509
}
510
} else {
511
console.error("Unexpected error:", error);
512
}
513
}
514
}
515
```