0
# String & Path Utilities
1
2
Utility functions for string manipulation, path operations, and code transformations. These utilities provide consistent naming conventions, path handling, and string processing across different platforms and use cases.
3
4
## Capabilities
5
6
### Name Generation Utilities
7
8
Functions for generating consistent naming conventions from base strings.
9
10
```typescript { .api }
11
/**
12
* Generate various name formats from a base name
13
* @param name - Base name to transform
14
* @returns Object with different name formats
15
*/
16
function names(name: string): {
17
/** Original name as provided */
18
name: string;
19
/** PascalCase class name (e.g., "MyComponent") */
20
className: string;
21
/** camelCase property name (e.g., "myComponent") */
22
propertyName: string;
23
/** CONSTANT_CASE name (e.g., "MY_COMPONENT") */
24
constantName: string;
25
/** kebab-case file name (e.g., "my-component") */
26
fileName: string;
27
};
28
```
29
30
**Usage Examples:**
31
32
```typescript
33
import { names } from "@nrwl/devkit";
34
35
function generateNames() {
36
const nameVariants = names('my-awesome-feature');
37
38
console.log(nameVariants);
39
// Output:
40
// {
41
// name: 'my-awesome-feature',
42
// className: 'MyAwesomeFeature',
43
// propertyName: 'myAwesomeFeature',
44
// constantName: 'MY_AWESOME_FEATURE',
45
// fileName: 'my-awesome-feature'
46
// }
47
48
// Use in template generation
49
const templateVars = {
50
...nameVariants,
51
template: '' // Remove .template extension
52
};
53
54
// Results in files like:
55
// - my-awesome-feature.component.ts (using fileName)
56
// - MyAwesomeFeature class (using className)
57
// - myAwesomeFeature property (using propertyName)
58
// - MY_AWESOME_FEATURE constant (using constantName)
59
}
60
```
61
62
### Path Manipulation
63
64
Functions for handling file paths consistently across platforms.
65
66
```typescript { .api }
67
/**
68
* Join path fragments safely
69
* @param fragments - Path segments to join
70
* @returns Joined path string
71
*/
72
function joinPathFragments(...fragments: string[]): string;
73
74
/**
75
* Normalize file paths to use forward slashes
76
* @param osSpecificPath - OS-specific path to normalize
77
* @returns Normalized path with forward slashes
78
*/
79
function normalizePath(osSpecificPath: string): string;
80
81
/**
82
* Calculate relative path from a directory to workspace root
83
* @param dir - Directory path relative to workspace root
84
* @returns Relative path to workspace root (e.g., "../../")
85
*/
86
function offsetFromRoot(dir: string): string;
87
88
/**
89
* Workspace root directory (absolute path)
90
*/
91
const workspaceRoot: string;
92
93
/**
94
* @deprecated Use workspaceRoot instead
95
* Application root path
96
*/
97
const appRootPath: string;
98
```
99
100
**Usage Examples:**
101
102
```typescript
103
import {
104
joinPathFragments,
105
normalizePath,
106
offsetFromRoot,
107
workspaceRoot
108
} from "@nrwl/devkit";
109
110
function handlePaths() {
111
// Join path fragments safely
112
const configPath = joinPathFragments('libs', 'my-lib', 'src', 'config.ts');
113
console.log(configPath); // "libs/my-lib/src/config.ts"
114
115
// Handle Windows paths
116
const windowsPath = 'libs\\my-lib\\src\\index.ts';
117
const normalized = normalizePath(windowsPath);
118
console.log(normalized); // "libs/my-lib/src/index.ts"
119
120
// Calculate offset to workspace root
121
const libDir = 'libs/shared/utils';
122
const offset = offsetFromRoot(libDir);
123
console.log(offset); // "../../../"
124
125
// Get workspace root
126
console.log('Workspace root:', workspaceRoot);
127
128
// Build absolute paths
129
const absoluteConfigPath = joinPathFragments(
130
workspaceRoot,
131
'libs',
132
'my-lib',
133
'project.json'
134
);
135
}
136
```
137
138
### String Manipulation
139
140
Functions for processing and transforming strings.
141
142
```typescript { .api }
143
/**
144
* Remove common leading indentation from multi-line strings
145
* @param strings - Template string array
146
* @param values - Template interpolation values
147
* @returns String with leading indentation stripped
148
*/
149
function stripIndents(strings: TemplateStringsArray, ...values: any[]): string;
150
```
151
152
**Usage Examples:**
153
154
```typescript
155
import { stripIndents } from "@nrwl/devkit";
156
157
function generateCode() {
158
const className = 'MyService';
159
const interfaceName = 'IMyService';
160
161
// Generate formatted code with proper indentation
162
const code = stripIndents`
163
export interface ${interfaceName} {
164
process(data: any): Promise<void>;
165
validate(input: string): boolean;
166
}
167
168
export class ${className} implements ${interfaceName} {
169
async process(data: any): Promise<void> {
170
// Implementation here
171
console.log('Processing:', data);
172
}
173
174
validate(input: string): boolean {
175
return input && input.length > 0;
176
}
177
}
178
`;
179
180
console.log(code);
181
// Output will have proper indentation without leading spaces
182
}
183
```
184
185
### String Changes and Transformations
186
187
Advanced string manipulation for code modifications.
188
189
```typescript { .api }
190
/**
191
* Types of string change operations
192
*/
193
enum ChangeType {
194
Insert = 'insert',
195
Delete = 'delete'
196
}
197
198
/**
199
* Base interface for string changes
200
*/
201
interface StringChange {
202
type: ChangeType;
203
index: number;
204
}
205
206
/**
207
* String insertion operation
208
*/
209
interface StringInsertion extends StringChange {
210
type: ChangeType.Insert;
211
/** Position to insert at */
212
index: number;
213
/** Text to insert */
214
text: string;
215
}
216
217
/**
218
* String deletion operation
219
*/
220
interface StringDeletion extends StringChange {
221
type: ChangeType.Delete;
222
/** Start position */
223
index: number;
224
/** Number of characters to delete */
225
length: number;
226
}
227
228
/**
229
* Union type for all string changes
230
*/
231
type StringChange = StringInsertion | StringDeletion;
232
233
/**
234
* Apply a series of changes to a string
235
* @param text - Original text
236
* @param changes - Array of changes to apply
237
* @returns Modified text
238
*/
239
function applyChangesToString(text: string, changes: StringChange[]): string;
240
```
241
242
**Usage Examples:**
243
244
```typescript
245
import {
246
applyChangesToString,
247
StringInsertion,
248
StringDeletion,
249
ChangeType
250
} from "@nrwl/devkit";
251
252
function modifySourceCode() {
253
const originalCode = `
254
export class MyClass {
255
constructor() {}
256
}
257
`;
258
259
const changes: (StringInsertion | StringDeletion)[] = [
260
// Insert a method after constructor
261
{
262
type: ChangeType.Insert,
263
index: originalCode.indexOf('constructor() {}') + 'constructor() {}'.length,
264
text: '\n\n public getValue(): string {\n return "value";\n }'
265
},
266
// Insert import at the beginning
267
{
268
type: ChangeType.Insert,
269
index: 0,
270
text: 'import { Injectable } from "@angular/core";\n\n'
271
}
272
];
273
274
const modifiedCode = applyChangesToString(originalCode, changes);
275
console.log(modifiedCode);
276
}
277
```
278
279
### Directory and File Operations
280
281
Utilities for working with directory structures and file movements.
282
283
```typescript { .api }
284
/**
285
* Move files from one directory to another and update import statements
286
* @param tree - Virtual file system tree
287
* @param from - Source directory path
288
* @param to - Destination directory path
289
* @param exclude - Files to exclude from moving
290
*/
291
function moveFilesToNewDirectory(
292
tree: Tree,
293
from: string,
294
to: string,
295
exclude?: string[]
296
): void;
297
298
/**
299
* Get workspace layout configuration
300
* @param tree - Virtual file system tree
301
* @returns Workspace layout information
302
*/
303
function getWorkspaceLayout(tree: Tree): {
304
appsDir: string;
305
libsDir: string;
306
npmScope?: string;
307
};
308
309
/**
310
* Extract layout directory information from configuration
311
* @param nxJson - Nx configuration object
312
* @returns Layout directory configuration
313
*/
314
function extractLayoutDirectory(nxJson?: NxJsonConfiguration): {
315
appsDir: string;
316
libsDir: string;
317
};
318
```
319
320
**Usage Examples:**
321
322
```typescript
323
import {
324
Tree,
325
moveFilesToNewDirectory,
326
getWorkspaceLayout
327
} from "@nrwl/devkit";
328
329
function reorganizeFiles(tree: Tree) {
330
// Get workspace layout
331
const layout = getWorkspaceLayout(tree);
332
console.log(`Apps in: ${layout.appsDir}`);
333
console.log(`Libs in: ${layout.libsDir}`);
334
335
// Move files from old location to new location
336
moveFilesToNewDirectory(
337
tree,
338
'libs/old-location',
339
'libs/new-location',
340
['*.spec.ts', '*.test.ts'] // Exclude test files
341
);
342
343
// This will:
344
// 1. Move all files from old-location to new-location
345
// 2. Update import statements that reference the moved files
346
// 3. Preserve directory structure
347
// 4. Skip excluded files
348
}
349
```
350
351
### Advanced String Utilities
352
353
Additional string processing functions for specialized use cases.
354
355
```typescript { .api }
356
/**
357
* Convert string to various naming conventions
358
* @param str - Input string
359
* @returns Object with different naming formats
360
*/
361
function classify(str: string): string;
362
function camelize(str: string): string;
363
function underscore(str: string): string;
364
function dasherize(str: string): string;
365
function capitalize(str: string): string;
366
367
/**
368
* Check if string is a valid identifier
369
* @param str - String to check
370
* @returns Whether string is a valid identifier
371
*/
372
function isValidIdentifier(str: string): boolean;
373
374
/**
375
* Escape string for use in regular expressions
376
* @param str - String to escape
377
* @returns Escaped string
378
*/
379
function escapeRegExp(str: string): string;
380
```
381
382
**Usage Examples:**
383
384
```typescript
385
import {
386
classify,
387
camelize,
388
underscore,
389
dasherize,
390
isValidIdentifier
391
} from "@nrwl/devkit";
392
393
function stringTransformations() {
394
const input = 'my-awesome-component';
395
396
console.log('Classify:', classify(input)); // "MyAwesomeComponent"
397
console.log('Camelize:', camelize(input)); // "myAwesomeComponent"
398
console.log('Underscore:', underscore(input)); // "my_awesome_component"
399
console.log('Dasherize:', dasherize(input)); // "my-awesome-component"
400
401
// Validation
402
console.log('Valid identifier:', isValidIdentifier('myVar')); // true
403
console.log('Valid identifier:', isValidIdentifier('my-var')); // false
404
console.log('Valid identifier:', isValidIdentifier('123var')); // false
405
}
406
```