0
# Utility Library
1
2
Comprehensive toolkit for TypeScript/JavaScript code manipulation, module management, and project structure operations. Provides AST parsers, file system helpers, and NestJS-specific utilities for programmatic code generation and modification.
3
4
## Capabilities
5
6
### Module Management
7
8
#### MetadataManager
9
10
Manages metadata entries within `@Module` decorators, allowing programmatic insertion of providers, controllers, imports, and exports.
11
12
```typescript { .api }
13
/**
14
* Manages metadata entries within @Module decorators
15
*/
16
class MetadataManager {
17
/**
18
* Insert metadata entry into a module decorator
19
* @param metadata - Type of metadata ('providers', 'controllers', 'imports', 'exports')
20
* @param symbol - Symbol name to insert
21
* @param staticOptions - Optional static configuration
22
* @returns Updated content or undefined if insertion failed
23
*/
24
insert(
25
metadata: string,
26
symbol: string,
27
staticOptions?: DeclarationOptions['staticOptions']
28
): string | undefined;
29
}
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { MetadataManager } from '@nestjs/schematics';
36
37
const manager = new MetadataManager();
38
39
// Insert provider into module
40
const updatedContent = manager.insert('providers', 'UserService');
41
42
// Insert with static options
43
const updatedContent2 = manager.insert('providers', 'ConfigService', {
44
name: 'CONFIG_OPTIONS',
45
value: 'configOptions'
46
});
47
```
48
49
#### ModuleDeclarator
50
51
Main orchestrator for module imports and metadata declarations, combining import and metadata operations.
52
53
```typescript { .api }
54
/**
55
* Main orchestrator for module imports and metadata declarations
56
*/
57
class ModuleDeclarator {
58
/**
59
* Declare module imports and metadata
60
* @param content - Source file content
61
* @param options - Declaration configuration
62
* @returns Updated file content
63
*/
64
declare(content: string, options: DeclarationOptions): string;
65
}
66
67
interface DeclarationOptions {
68
/** Metadata type to modify */
69
metadata: string;
70
/** Symbol to declare */
71
symbol: string;
72
/** Symbol type (class, function, etc.) */
73
type?: string;
74
/** Static options for configuration */
75
staticOptions?: {
76
name: string;
77
value: string;
78
};
79
}
80
```
81
82
**Usage Examples:**
83
84
```typescript
85
import { ModuleDeclarator } from '@nestjs/schematics';
86
87
const declarator = new ModuleDeclarator();
88
89
// Declare service in module
90
const updatedContent = declarator.declare(moduleContent, {
91
metadata: 'providers',
92
symbol: 'UserService',
93
type: 'class'
94
});
95
96
// Declare controller with import
97
const updatedContent2 = declarator.declare(moduleContent, {
98
metadata: 'controllers',
99
symbol: 'AuthController',
100
type: 'class'
101
});
102
```
103
104
#### ModuleImportDeclarator
105
106
Handles import statement declarations in TypeScript files.
107
108
```typescript { .api }
109
/**
110
* Declares module imports in TypeScript files
111
*/
112
class ModuleImportDeclarator {
113
/**
114
* Declare import statements in file content
115
* @param content - Source file content
116
* @param options - Import declaration options
117
* @returns Updated file content with imports
118
*/
119
declare(content: string, options: DeclarationOptions): string;
120
}
121
```
122
123
#### ModuleMetadataDeclarator
124
125
Handles metadata declarations within module decorators.
126
127
```typescript { .api }
128
/**
129
* Declares metadata in TypeScript files
130
*/
131
class ModuleMetadataDeclarator {
132
/**
133
* Declare metadata in module decorators
134
* @param content - Source file content
135
* @param options - Metadata declaration options
136
* @returns Updated file content with metadata
137
*/
138
declare(content: string, options: DeclarationOptions): string;
139
}
140
```
141
142
### File System Operations
143
144
#### ModuleFinder
145
146
Locates module files within directory structures, supporting various naming conventions and patterns.
147
148
```typescript { .api }
149
/**
150
* Finds module files in directory structures
151
*/
152
class ModuleFinder {
153
/**
154
* Find module file based on options
155
* @param options - Search configuration
156
* @returns Path to found module or null
157
*/
158
find(options: FindOptions): Path | null;
159
}
160
161
interface FindOptions {
162
/** Module name to search for */
163
name: string;
164
/** Base path to search in */
165
path: Path;
166
}
167
```
168
169
**Usage Examples:**
170
171
```typescript
172
import { ModuleFinder } from '@nestjs/schematics';
173
174
const finder = new ModuleFinder();
175
176
// Find app module
177
const appModulePath = finder.find({
178
name: 'app',
179
path: '/src' as Path
180
});
181
182
// Find specific module
183
const userModulePath = finder.find({
184
name: 'users',
185
path: '/src/users' as Path
186
});
187
```
188
189
#### PathSolver
190
191
Computes relative paths between different locations in the project structure.
192
193
```typescript { .api }
194
/**
195
* Computes relative paths between locations
196
*/
197
class PathSolver {
198
/**
199
* Calculate relative path between two locations
200
* @param from - Source path
201
* @param to - Target path
202
* @returns Relative path string
203
*/
204
relative(from: Path, to: Path): string;
205
}
206
```
207
208
**Usage Examples:**
209
210
```typescript
211
import { PathSolver } from '@nestjs/schematics';
212
213
const solver = new PathSolver();
214
215
// Calculate import path
216
const relativePath = solver.relative(
217
'/src/users/users.controller.ts' as Path,
218
'/src/users/users.service.ts' as Path
219
);
220
// Result: './users.service'
221
```
222
223
### Name and Path Processing
224
225
#### NameParser
226
227
Parses names and paths for schematics, handling various naming conventions and path structures.
228
229
```typescript { .api }
230
/**
231
* Parses names and paths for schematics
232
*/
233
class NameParser {
234
/**
235
* Parse name and path options into location structure
236
* @param options - Parsing configuration
237
* @returns Parsed location with name and path
238
*/
239
parse(options: ParseOptions): Location;
240
}
241
242
interface ParseOptions {
243
/** Component name (can include path) */
244
name: string;
245
/** Base path for generation */
246
path?: string;
247
}
248
249
interface Location {
250
/** Parsed component name */
251
name: string;
252
/** Resolved path */
253
path: Path;
254
}
255
```
256
257
**Usage Examples:**
258
259
```typescript
260
import { NameParser } from '@nestjs/schematics';
261
262
const parser = new NameParser();
263
264
// Parse simple name
265
const location1 = parser.parse({ name: 'user-service' });
266
// Result: { name: 'user-service', path: '.' }
267
268
// Parse name with path
269
const location2 = parser.parse({
270
name: 'auth/auth-service',
271
path: 'src/modules'
272
});
273
// Result: { name: 'auth-service', path: 'src/modules/auth' }
274
275
// Parse kebab-case to different formats
276
const location3 = parser.parse({ name: 'user-profile-service' });
277
// Handles conversion to UserProfileService, user-profile-service, etc.
278
```
279
280
### JSON File Operations
281
282
#### JSONFile
283
284
Advanced JSON file manipulation with AST parsing, supporting comments and complex modifications.
285
286
```typescript { .api }
287
/**
288
* JSON file manipulation with AST parsing
289
*/
290
class JSONFile {
291
/**
292
* Get value at JSON path
293
* @param jsonPath - Array representing path to value
294
* @returns Value at path or undefined
295
*/
296
get(jsonPath: JSONPath): unknown;
297
298
/**
299
* Modify value at JSON path
300
* @param jsonPath - Array representing path to value
301
* @param value - New value to set
302
* @param insertInOrder - Optional insertion order function
303
*/
304
modify(
305
jsonPath: JSONPath,
306
value: JsonValue | undefined,
307
insertInOrder?: InsertionIndex | false
308
): void;
309
310
/**
311
* Remove value at JSON path
312
* @param jsonPath - Array representing path to remove
313
*/
314
remove(jsonPath: JSONPath): void;
315
}
316
317
type JSONPath = (string | number)[];
318
type InsertionIndex = (properties: string[]) => number;
319
type JsonValue = string | number | boolean | null | JsonObject | JsonArray;
320
interface JsonObject { [key: string]: JsonValue; }
321
interface JsonArray extends Array<JsonValue> {}
322
```
323
324
**Usage Examples:**
325
326
```typescript
327
import { JSONFile } from '@nestjs/schematics';
328
329
// Create JSONFile instance from tree
330
const packageJson = new JSONFile(tree, 'package.json');
331
332
// Get dependency version
333
const nestVersion = packageJson.get(['dependencies', '@nestjs/core']);
334
335
// Add new dependency
336
packageJson.modify(['dependencies', 'lodash'], '^4.17.21');
337
338
// Add script with ordered insertion
339
packageJson.modify(['scripts', 'test:e2e'], 'jest --config ./test/jest-e2e.json',
340
(props) => props.sort().indexOf('test:e2e')
341
);
342
343
// Remove devDependency
344
packageJson.remove(['devDependencies', 'old-package']);
345
```
346
347
### String and Formatting Utilities
348
349
#### Formatting Functions
350
351
Various string formatting utilities for consistent naming conventions.
352
353
```typescript { .api }
354
/**
355
* Normalize string to kebab-case or snake_case
356
* @param str - Input string
357
* @returns Normalized string
358
*/
359
function normalizeToKebabOrSnakeCase(str: string): string;
360
```
361
362
**Usage Examples:**
363
364
```typescript
365
import { normalizeToKebabOrSnakeCase } from '@nestjs/schematics';
366
367
// Convert various formats
368
const kebab1 = normalizeToKebabOrSnakeCase('UserService'); // 'user-service'
369
const kebab2 = normalizeToKebabOrSnakeCase('user_profile'); // 'user-profile'
370
const kebab3 = normalizeToKebabOrSnakeCase('API_KEY'); // 'api-key'
371
```
372
373
### Object Manipulation
374
375
#### Object Sorting
376
377
Utilities for organizing object properties in consistent order.
378
379
```typescript { .api }
380
/**
381
* Sort object properties in place by keys
382
* @param object - Object to sort
383
* @returns Sorted object
384
*/
385
function inPlaceSortByKeys(object: Record<string, any>): Record<string, any>;
386
```
387
388
**Usage Examples:**
389
390
```typescript
391
import { inPlaceSortByKeys } from '@nestjs/schematics';
392
393
const config = {
394
providers: ['ServiceA'],
395
imports: ['ModuleB'],
396
controllers: ['ControllerC'],
397
exports: ['ServiceA']
398
};
399
400
// Sort for consistent output
401
const sortedConfig = inPlaceSortByKeys(config);
402
// Result: { controllers: [...], exports: [...], imports: [...], providers: [...] }
403
```
404
405
### Source Root Management
406
407
#### Source Root Helpers
408
409
Utilities for managing source root directories in projects.
410
411
```typescript { .api }
412
/**
413
* Check if generation is happening in root directory
414
* @param host - Virtual file system tree
415
* @param extraFiles - Additional files to check for
416
* @returns True if in root directory
417
*/
418
function isInRootDirectory(host: Tree, extraFiles?: string[]): boolean;
419
420
/**
421
* Merge source root configuration into options
422
* @param options - Schematic options
423
* @returns Rule for merging source root
424
*/
425
function mergeSourceRoot<T>(options: T): Rule;
426
```
427
428
**Usage Examples:**
429
430
```typescript
431
import { isInRootDirectory, mergeSourceRoot } from '@nestjs/schematics';
432
433
// Check if in root
434
const inRoot = isInRootDirectory(tree, ['nest-cli.json']);
435
436
// Apply source root merging
437
return chain([
438
mergeSourceRoot(options),
439
// ... other rules
440
]);
441
```
442
443
### Dependency Management
444
445
#### Dependencies Utilities
446
447
Functions for managing package.json dependencies programmatically.
448
449
```typescript { .api }
450
/**
451
* Add dependency to package.json
452
* @param tree - Virtual file system
453
* @param dependency - Dependency specification
454
* @param pkgJsonPath - Optional package.json path
455
*/
456
function addPackageJsonDependency(
457
tree: Tree,
458
dependency: NodeDependency,
459
pkgJsonPath?: string
460
): void;
461
462
/**
463
* Get dependency from package.json
464
* @param tree - Virtual file system
465
* @param name - Dependency name
466
* @param pkgJsonPath - Optional package.json path
467
* @returns Dependency specification or null
468
*/
469
function getPackageJsonDependency(
470
tree: Tree,
471
name: string,
472
pkgJsonPath?: string
473
): NodeDependency | null;
474
475
interface NodeDependency {
476
type: NodeDependencyType;
477
name: string;
478
version: string;
479
overwrite?: boolean;
480
}
481
482
enum NodeDependencyType {
483
Default = 'dependencies',
484
Dev = 'devDependencies',
485
Peer = 'peerDependencies',
486
Optional = 'optionalDependencies'
487
}
488
```
489
490
**Usage Examples:**
491
492
```typescript
493
import {
494
addPackageJsonDependency,
495
getPackageJsonDependency,
496
NodeDependencyType
497
} from '@nestjs/schematics';
498
499
// Add production dependency
500
addPackageJsonDependency(tree, {
501
type: NodeDependencyType.Default,
502
name: '@nestjs/jwt',
503
version: '^8.0.0'
504
});
505
506
// Add dev dependency
507
addPackageJsonDependency(tree, {
508
type: NodeDependencyType.Dev,
509
name: '@types/jest',
510
version: '^27.0.0',
511
overwrite: true
512
});
513
514
// Check existing dependency
515
const existing = getPackageJsonDependency(tree, '@nestjs/core');
516
if (existing) {
517
console.log(`Found ${existing.name}@${existing.version}`);
518
}
519
```
520
521
### File Reading System
522
523
#### Reader Interface
524
525
Abstract interface for file reading operations with sync and async support.
526
527
```typescript { .api }
528
/**
529
* Interface for file reading operations
530
*/
531
interface Reader {
532
/** List available files */
533
list(): string[] | Promise<string[]>;
534
535
/** Read file content (async) */
536
read(name: string): string | Promise<string>;
537
538
/** Read file content (sync) */
539
readSync(name: string): string;
540
541
/** Read any of the specified files (async) */
542
readAnyOf(filenames: string[]): string | Promise<string | undefined>;
543
544
/** Read any of the specified files (sync) */
545
readSyncAnyOf(filenames: string[]): string | undefined;
546
}
547
```
548
549
#### FileSystemReader
550
551
Concrete implementation of Reader for file system operations.
552
553
```typescript { .api }
554
/**
555
* File system implementation of Reader interface
556
*/
557
class FileSystemReader implements Reader {
558
/**
559
* Create file system reader
560
* @param directory - Base directory for file operations
561
*/
562
constructor(private readonly directory: string);
563
564
list(): string[];
565
read(name: string): string;
566
readSync(name: string): string;
567
readAnyOf(filenames: string[]): string | undefined;
568
readSyncAnyOf(filenames: string[]): string | undefined;
569
}
570
```
571
572
**Usage Examples:**
573
574
```typescript
575
import { FileSystemReader } from '@nestjs/schematics';
576
577
// Create reader for templates directory
578
const reader = new FileSystemReader('./templates');
579
580
// List available template files
581
const templates = reader.list();
582
583
// Read specific template
584
const controllerTemplate = reader.readSync('controller.template.ts');
585
586
// Read any available config file
587
const config = reader.readSyncAnyOf([
588
'nest-cli.json',
589
'angular.json',
590
'.nestcli.json'
591
]);
592
```
593
594
## Default Constants
595
596
Pre-configured values for consistent project generation.
597
598
```typescript { .api }
599
/** Default application author */
600
const DEFAULT_AUTHOR: string = '';
601
602
/** Default application description */
603
const DEFAULT_DESCRIPTION: string = '';
604
605
/** Default programming language */
606
const DEFAULT_LANGUAGE: string = 'ts';
607
608
/** Default application version */
609
const DEFAULT_VERSION: string = '0.0.1';
610
611
/** Default source path name */
612
const DEFAULT_PATH_NAME: string = 'src';
613
614
/** Default libraries path for monorepo */
615
const DEFAULT_LIB_PATH: string = 'libs';
616
617
/** Default applications path for monorepo */
618
const DEFAULT_APPS_PATH: string = 'apps';
619
620
/** Default application name */
621
const DEFAULT_APP_NAME: string = 'app';
622
623
/** Default directory entry for app */
624
const DEFAULT_DIR_ENTRY_APP: string = 'main';
625
626
/** Test environment identifier */
627
const TEST_ENV: string = 'test';
628
629
/** Project type constants */
630
const PROJECT_TYPE: {
631
readonly LIBRARY: 'library';
632
readonly APPLICATION: 'application';
633
};
634
```
635
636
## Integration with Angular DevKit
637
638
All utilities are designed to work seamlessly with Angular DevKit's schematic system:
639
640
```typescript { .api }
641
// Common Angular DevKit types used throughout utilities
642
type Tree = import('@angular-devkit/schematics').Tree;
643
type Rule = import('@angular-devkit/schematics').Rule;
644
type SchematicContext = import('@angular-devkit/schematics').SchematicContext;
645
type Path = import('@angular-devkit/core').Path;
646
```
647
648
These utilities provide the foundation for all NestJS schematics, enabling consistent and reliable code generation across the entire framework ecosystem.