0
# Utility Functions
1
2
Supporting utility functions for field parsing, environment variable handling, type validation, and configuration processing.
3
4
## Capabilities
5
6
### Field Parsing
7
8
Parse and coerce configuration field values according to type definitions with validation.
9
10
```javascript { .api }
11
const parseField = require('@npmcli/config/lib/parse-field');
12
13
/**
14
* Parse configuration field value with type coercion and validation
15
* @param field - Field type definition or type constructor
16
* @param key - Configuration key name for error reporting
17
* @param options - Configuration context and definitions
18
* @param listElement - Whether this value is an array element
19
* @returns Parsed and coerced value
20
*/
21
function parseField(field: any, key: string, options: ParseOptions, listElement?: boolean): any;
22
23
interface ParseOptions {
24
/** Type definitions for validation */
25
types: Record<string, TypeDefinition>;
26
/** Configuration type definitions */
27
typeDefs: Record<string, TypeDefinition>;
28
/** Default values */
29
defaults: Record<string, any>;
30
/** Current configuration data */
31
data: Record<string, any>;
32
/** Configuration key for context */
33
key: string;
34
}
35
```
36
37
**Usage Examples:**
38
39
```javascript
40
const parseField = require('@npmcli/config/lib/parse-field');
41
42
// Parse string value
43
const parsed = parseField(String, 'loglevel', {
44
types: { String },
45
typeDefs: { String: { type: String } },
46
defaults: { loglevel: 'notice' },
47
data: {},
48
key: 'loglevel'
49
}, false);
50
51
// Parse number with validation
52
const port = parseField(Number, 'port', {
53
types: { Number },
54
typeDefs: { Number: { type: Number, description: 'numeric value' } },
55
defaults: { port: 8080 },
56
data: {},
57
key: 'port'
58
}, false);
59
60
// Parse array of strings
61
const tags = parseField([String], 'tag', options, true);
62
```
63
64
### Environment Variable Replacement
65
66
Replace environment variable references in configuration strings with actual values.
67
68
```javascript { .api }
69
const envReplace = require('@npmcli/config/lib/env-replace');
70
71
/**
72
* Replace ${VAR} patterns in strings with environment variable values
73
* @param string - String potentially containing ${VAR} patterns
74
* @param env - Environment variables object (defaults to process.env)
75
* @returns String with environment variables expanded
76
*/
77
function envReplace(string: string, env?: Record<string, string>): string;
78
```
79
80
**Usage Examples:**
81
82
```javascript
83
const envReplace = require('@npmcli/config/lib/env-replace');
84
85
// Replace environment variables in configuration values
86
const registryUrl = envReplace('${NPM_REGISTRY}/api/v1', process.env);
87
// If NPM_REGISTRY="https://registry.company.com"
88
// Result: "https://registry.company.com/api/v1"
89
90
// Replace multiple variables
91
const cachePath = envReplace('${HOME}/.npm/${USER}-cache', {
92
HOME: '/home/john',
93
USER: 'john'
94
});
95
// Result: "/home/john/.npm/john-cache"
96
97
// Handle missing variables (left unchanged)
98
const withMissing = envReplace('${MISSING_VAR}/path', {});
99
// Result: "${MISSING_VAR}/path"
100
```
101
102
### Nerf-dart URI Processing
103
104
Convert URLs to nerf-dart identifiers for scoped configuration keys.
105
106
```javascript { .api }
107
const nerfDart = require('@npmcli/config/lib/nerf-dart');
108
109
/**
110
* Convert URL to nerf-dart identifier for configuration scoping
111
* @param url - URL to convert
112
* @returns Nerf-dart identifier string
113
*/
114
function nerfDart(url: string): string;
115
```
116
117
**Usage Examples:**
118
119
```javascript
120
const nerfDart = require('@npmcli/config/lib/nerf-dart');
121
122
// Convert registry URLs to configuration keys
123
const npmKey = nerfDart('https://registry.npmjs.org/');
124
// Result: "//registry.npmjs.org/"
125
126
const privateKey = nerfDart('https://npm.company.com:8443/registry/');
127
// Result: "//npm.company.com:8443/registry/"
128
129
// Use for scoped configuration
130
const scopedKey = nerfDart('https://registry.company.com/@scope/');
131
// Result: "//registry.company.com/@scope/"
132
```
133
134
### Environment Variable Setting
135
136
Set npm_config_* environment variables based on configuration differences from defaults.
137
138
```javascript { .api }
139
const setEnvs = require('@npmcli/config/lib/set-envs');
140
141
/**
142
* Set npm_config_* environment variables for configuration values
143
* that differ from defaults, making them available to child processes
144
* @param config - Configuration object with flat configuration data
145
*/
146
function setEnvs(config: ConfigForEnvs): void;
147
148
interface ConfigForEnvs {
149
/** Flattened configuration values */
150
flat: Record<string, any>;
151
/** Default configuration values */
152
defaults: Record<string, any>;
153
/** Environment variables object to modify */
154
env: Record<string, string>;
155
}
156
```
157
158
**Usage Examples:**
159
160
```javascript
161
const setEnvs = require('@npmcli/config/lib/set-envs');
162
163
// Set environment variables from config
164
setEnvs({
165
flat: {
166
registry: 'https://npm.company.com/',
167
loglevel: 'verbose',
168
'save-dev': true
169
},
170
defaults: {
171
registry: 'https://registry.npmjs.org/',
172
loglevel: 'notice',
173
'save-dev': false
174
},
175
env: process.env
176
});
177
178
// Now process.env contains:
179
// npm_config_registry = "https://npm.company.com/"
180
// npm_config_loglevel = "verbose"
181
// npm_config_save_dev = "true"
182
// (default values are not set as environment variables)
183
```
184
185
### Type Description Generation
186
187
Generate human-readable descriptions of configuration field types for help text and documentation.
188
189
```javascript { .api }
190
const typeDescription = require('@npmcli/config/lib/type-description');
191
192
/**
193
* Generate human-readable description array for configuration field type
194
* @param type - Type definition or constructor
195
* @returns Array of description strings for the type
196
*/
197
function typeDescription(type: any): string[];
198
```
199
200
**Usage Examples:**
201
202
```javascript
203
const typeDescription = require('@npmcli/config/lib/type-description');
204
205
// Get description for basic types
206
const stringDesc = typeDescription(String);
207
// Result: ["string"]
208
209
const numberDesc = typeDescription(Number);
210
// Result: ["number"]
211
212
const booleanDesc = typeDescription(Boolean);
213
// Result: ["boolean"]
214
215
// Get description for array types
216
const stringArrayDesc = typeDescription([String]);
217
// Result: ["string", "(can be set multiple times)"]
218
219
// Get description for complex types
220
const urlDesc = typeDescription(require('nopt').typeDefs.url);
221
// Result: ["url"]
222
223
// Use for help text generation
224
const fieldType = [String, Number];
225
const desc = typeDescription(fieldType);
226
// Result: ["string", "number"]
227
console.log(`Field accepts: ${desc.join(' or ')}`);
228
```
229
230
### Umask Utilities
231
232
File permission mask parsing, validation, and conversion utilities.
233
234
```javascript { .api }
235
const { Umask, parse, validate } = require('@npmcli/config/lib/umask');
236
237
/**
238
* Umask type class for file permission masks
239
*/
240
class Umask {
241
constructor(value: string | number);
242
toString(): string;
243
valueOf(): number;
244
}
245
246
/**
247
* Parse umask string or number into Umask instance
248
* @param value - Umask value as string or number
249
* @returns Umask instance
250
*/
251
function parse(value: string | number): Umask;
252
253
/**
254
* Validate umask value for nopt type system
255
* @param data - Configuration data object
256
* @param key - Configuration key
257
* @param value - Value to validate
258
* @returns Boolean indicating if value is valid
259
*/
260
function validate(data: any, key: string, value: any): boolean;
261
```
262
263
**Usage Examples:**
264
265
```javascript
266
const { Umask, parse, validate } = require('@npmcli/config/lib/umask');
267
268
// Create umask from octal string
269
const umask1 = new Umask('0o755');
270
console.log(umask1.toString()); // "0o755"
271
console.log(umask1.valueOf()); // 493
272
273
// Create umask from number
274
const umask2 = new Umask(755);
275
console.log(umask2.toString()); // "0o755"
276
277
// Parse umask values
278
const parsed = parse('644');
279
console.log(parsed.toString()); // "0o644"
280
281
// Validate umask in configuration
282
const config = {};
283
const isValid = validate(config, 'umask', '0o644');
284
console.log(isValid); // true
285
console.log(config.umask); // Umask instance
286
```
287
288
### Type Definitions
289
290
Extended type definitions with validation and descriptions for configuration fields.
291
292
```javascript { .api }
293
const typeDefs = require('@npmcli/config/lib/type-defs');
294
295
// Available type definitions
296
interface TypeDefinitions {
297
/** SemVer validation type */
298
semver: {
299
type: typeof import('semver');
300
validate: (data: any, key: string, value: any) => boolean;
301
description: string;
302
};
303
304
/** Umask file permission type */
305
Umask: {
306
type: typeof Umask;
307
validate: (data: any, key: string, value: any) => boolean;
308
description: string;
309
};
310
311
/** URL type with validation */
312
url: {
313
type: typeof URL;
314
validate: (data: any, key: string, value: any) => boolean;
315
description: string;
316
};
317
318
/** File system path type */
319
path: {
320
type: typeof String;
321
validate: (data: any, key: string, value: any) => boolean;
322
description: string;
323
};
324
325
/** Numeric value type */
326
Number: {
327
type: typeof Number;
328
description: string;
329
};
330
331
/** Boolean value type */
332
Boolean: {
333
type: typeof Boolean;
334
description: string;
335
};
336
337
/** Date value type */
338
Date: {
339
type: typeof Date;
340
description: string;
341
};
342
343
/** String value type */
344
String: {
345
type: typeof String;
346
description: string;
347
};
348
349
/** Array type */
350
Array: {
351
type: typeof Array;
352
description: string;
353
};
354
}
355
```
356
357
**Usage Examples:**
358
359
```javascript
360
const typeDefs = require('@npmcli/config/lib/type-defs');
361
362
// Use type definitions in configuration
363
const configDefs = {
364
version: {
365
type: typeDefs.semver.type,
366
validate: typeDefs.semver.validate,
367
description: 'Package version (valid semver)'
368
},
369
370
umask: {
371
type: typeDefs.Umask.type,
372
validate: typeDefs.Umask.validate,
373
description: 'File creation mask'
374
},
375
376
registry: {
377
type: typeDefs.url.type,
378
validate: typeDefs.url.validate,
379
description: 'Package registry URL'
380
}
381
};
382
383
// Access type descriptions
384
console.log(typeDefs.semver.description); // "full valid SemVer string"
385
console.log(typeDefs.Umask.description); // "octal number in range 0o000..0o777 (0..511)"
386
```
387
388
### ConfigData Class
389
390
Configuration data container class representing configuration from a specific source layer.
391
392
```javascript { .api }
393
/**
394
* Configuration data container for a specific configuration layer
395
* Accessible through Config.data Map as individual layer data
396
*/
397
class ConfigData {
398
/**
399
* Create configuration data instance
400
* @param parent - Parent ConfigData instance (for inheritance)
401
*/
402
constructor(parent?: ConfigData);
403
404
/** Configuration data object (getter) */
405
data: Record<string, any>;
406
407
/** Validation status (getter) */
408
valid: boolean;
409
410
/** Configuration source identifier (getter/setter) */
411
source: string;
412
413
/** Load error if configuration loading failed (getter/setter) */
414
loadError: Error | null;
415
416
/** Raw configuration data before processing (getter/setter) */
417
raw: any;
418
}
419
```
420
421
**Usage Examples:**
422
423
```javascript
424
// Access ConfigData instances through Config.data
425
const config = new Config({ definitions, shorthands, flatten, npmPath });
426
await config.load();
427
428
// Get specific configuration layer data
429
const userConfigData = config.data.get('user');
430
console.log(userConfigData.source); // "user"
431
console.log(userConfigData.valid); // true/false
432
console.log(userConfigData.data); // { registry: "...", ... }
433
434
// Check for load errors
435
const projectConfigData = config.data.get('project');
436
if (projectConfigData.loadError) {
437
console.error('Failed to load project config:', projectConfigData.loadError);
438
}
439
440
// Access raw configuration data
441
console.log(projectConfigData.raw); // Original file contents before parsing
442
443
// Iterate through all configuration layers
444
for (const [layerName, configData] of config.data.entries()) {
445
console.log(`Layer: ${layerName}`);
446
console.log(`Source: ${configData.source}`);
447
console.log(`Valid: ${configData.valid}`);
448
console.log(`Data:`, configData.data);
449
}
450
451
// Configuration layers are available in priority order:
452
// - cli: Command line arguments
453
// - env: Environment variables
454
// - project: Project .npmrc file
455
// - user: User .npmrc file
456
// - global: Global .npmrc file
457
// - builtin: Built-in npm configuration
458
// - default: Default values
459
```