0
# NPM Registry Operations
1
2
NPM registry interactions including package validation, publishing, 2FA management, and error handling for the publishing workflow.
3
4
## Capabilities
5
6
### NPM Information Functions
7
8
Functions for retrieving NPM registry and package information.
9
10
```javascript { .api }
11
/**
12
* Get the current npm version
13
* @returns Promise resolving to npm version string
14
*/
15
function version(): Promise<string>;
16
17
/**
18
* Check NPM registry connection
19
* @returns Promise that resolves if connection is successful
20
* @throws Error if unable to connect to registry
21
*/
22
function checkConnection(): Promise<void>;
23
24
/**
25
* Get the current npm username
26
* @param options - Configuration options
27
* @param options.externalRegistry - True if using external registry
28
* @returns Promise resolving to npm username
29
*/
30
function username(options: {externalRegistry?: boolean}): Promise<string>;
31
32
/**
33
* Check if package name is available on npm registry
34
* @param package_ - Package object with name property
35
* @returns Promise resolving to availability information
36
*/
37
function isPackageNameAvailable(package_: {name: string}): Promise<{
38
isAvailable: boolean;
39
isUnknown: boolean;
40
}>;
41
42
/**
43
* Get package collaborators/maintainers
44
* @param package_ - Package object with name property
45
* @returns Promise resolving to JSON string of collaborator information, or false if package doesn't exist
46
*/
47
function collaborators(package_: {name: string}): Promise<string | false>;
48
49
/**
50
* Get prerelease distribution tags for a package
51
* @param packageName - Name of the package
52
* @returns Promise resolving to array of prerelease tags
53
*/
54
function prereleaseTags(packageName: string): Promise<string[]>;
55
```
56
57
**Usage Examples:**
58
59
```javascript
60
import * as npm from "np/source/npm/util.js";
61
62
// Check npm environment
63
const npmVersion = await npm.version();
64
const currentUser = await npm.username({externalRegistry: false});
65
66
console.log(`NPM version: ${npmVersion}`);
67
console.log(`Logged in as: ${currentUser}`);
68
69
// Validate package name
70
const availability = await npm.isPackageNameAvailable({name: "my-package"});
71
if (availability.isAvailable) {
72
console.log("Package name is available - first publish");
73
} else if (availability.isUnknown) {
74
console.warn("Could not determine package availability");
75
} else {
76
console.log("Package exists - updating existing package");
77
}
78
79
// Check collaborators
80
const collaboratorInfo = await npm.collaborators({name: "my-package"});
81
if (collaboratorInfo) {
82
const maintainers = JSON.parse(collaboratorInfo);
83
console.log(`Package maintainers: ${Object.keys(maintainers).length}`);
84
} else {
85
console.log("Package does not exist");
86
}
87
```
88
89
### NPM Validation Functions
90
91
Functions for validating NPM environment and package configuration.
92
93
```javascript { .api }
94
/**
95
* Verify npm version meets minimum requirements
96
* @throws Error if npm version is too old
97
*/
98
function verifyRecentNpmVersion(): Promise<void>;
99
100
/**
101
* Check if package uses external npm registry
102
* @param package_ - Package object with publishConfig or registry info
103
* @returns True if using external registry
104
*/
105
function isExternalRegistry(package_: object): boolean;
106
107
/**
108
* Check ignore strategy for npm publishing
109
* @param files - Package files configuration
110
* @param rootDirectory - Project root directory
111
* @returns Promise resolving to ignore strategy information
112
*/
113
function checkIgnoreStrategy(
114
files: {files?: string[]},
115
rootDirectory: string
116
): Promise<object>;
117
118
/**
119
* Get list of files that will be packed by npm
120
* @param rootDirectory - Project root directory
121
* @returns Promise resolving to array of file paths
122
*/
123
function getFilesToBePacked(rootDirectory: string): Promise<string[]>;
124
```
125
126
**Usage Examples:**
127
128
```javascript
129
import * as npm from "np/source/npm/util.js";
130
131
// Validate npm environment
132
await npm.verifyRecentNpmVersion(); // Throws if npm < 9
133
134
// Check registry configuration
135
const isExternal = npm.isExternalRegistry(packageJson);
136
if (isExternal) {
137
console.log("Using external registry");
138
}
139
140
// Analyze package files
141
const filesToPack = await npm.getFilesToBePacked(process.cwd());
142
console.log(`${filesToPack.length} files will be published`);
143
144
// Check ignore configuration
145
const ignoreInfo = await npm.checkIgnoreStrategy(
146
{files: packageJson.files},
147
process.cwd()
148
);
149
```
150
151
### NPM Publishing Functions
152
153
Functions for executing NPM publish operations.
154
155
```javascript { .api }
156
/**
157
* Generate npm publish command arguments
158
* @param options - Publishing options
159
* @returns Array of command line arguments for npm publish
160
*/
161
function getPackagePublishArguments(options: {
162
tag?: string;
163
contents?: string;
164
otp?: string;
165
[key: string]: any;
166
}): string[];
167
168
/**
169
* Execute npm publish command
170
* @param arguments_ - Command arguments from getPackagePublishArguments
171
* @returns Child process (execa) that can be awaited or used with streams
172
*/
173
function runPublish(arguments_: string[]): ChildProcess;
174
```
175
176
**Usage Examples:**
177
178
```javascript
179
import { getPackagePublishArguments, runPublish } from "np/source/npm/publish.js";
180
181
// Generate publish arguments
182
const publishArgs = getPackagePublishArguments({
183
tag: "beta",
184
contents: "dist",
185
otp: "123456"
186
});
187
// Result: ["publish", "dist", "--tag", "beta", "--otp", "123456"]
188
189
// Execute publish
190
const publishProcess = runPublish(publishArgs);
191
192
// Stream output
193
publishProcess.stdout.on('data', (data) => {
194
console.log(data.toString());
195
});
196
197
publishProcess.stderr.on('data', (data) => {
198
console.error(data.toString());
199
});
200
201
// Promise-based usage
202
try {
203
await publishProcess;
204
console.log('Successfully published to npm');
205
} catch (error) {
206
console.error('Publish failed:', error.message);
207
}
208
```
209
210
### Two-Factor Authentication (2FA)
211
212
Functions for managing 2FA on npm packages.
213
214
```javascript { .api }
215
/**
216
* Generate arguments for enabling 2FA on a package
217
* @param packageName - Name of the package
218
* @param options - Configuration options
219
* @param options.otp - One-time password for authentication
220
* @returns Promise resolving to npm access command arguments
221
*/
222
function getEnable2faArguments(
223
packageName: string,
224
options: {otp?: string}
225
): Promise<string[]>;
226
227
/**
228
* Attempt to enable 2FA on a package with user interaction
229
* @param task - Listr task instance for user interaction
230
* @param packageName - Name of the package
231
* @param options - Configuration options
232
* @returns Promise that resolves when 2FA is enabled
233
*/
234
function tryEnable2fa(
235
task: object,
236
packageName: string,
237
options: {otp?: string}
238
): Promise<void>;
239
```
240
241
**Usage Examples:**
242
243
```javascript
244
import enable2fa, { getEnable2faArguments } from "np/source/npm/enable-2fa.js";
245
246
// Generate 2FA command
247
const args = await getEnable2faArguments("my-package", {otp: "123456"});
248
// Result: ["access", "2fa-required", "my-package", "--otp", "123456"]
249
250
// Enable 2FA in task context
251
await enable2fa(listrTask, "my-package", {otp: userOtp});
252
```
253
254
### NPM Error Handling
255
256
Advanced error handling for npm publish operations.
257
258
```javascript { .api }
259
/**
260
* Handle npm publish errors with OTP retry logic
261
* @param error - Error from npm publish command
262
* @param task - Listr task for user interaction
263
* @param retryFn - Function to retry publish with OTP
264
* @returns Promise that handles error and retry logic
265
*/
266
function handleNpmError(
267
error: Error,
268
task: object,
269
retryFn: (otp: string) => ChildProcess
270
): Promise<void>;
271
```
272
273
**Usage Examples:**
274
275
```javascript
276
import handleNpmError from "np/source/npm/handle-npm-error.js";
277
import { runPublish, getPackagePublishArguments } from "np/source/npm/publish.js";
278
279
// Use error handling in publish workflow
280
const publishStream = from(runPublish(getPackagePublishArguments(options)))
281
.pipe(
282
catchError(error => handleNpmError(error, task, (otp) => {
283
// Retry with OTP
284
const argsWithOtp = getPackagePublishArguments({...options, otp});
285
return runPublish(argsWithOtp);
286
}))
287
);
288
```
289
290
## NPM Workflow Integration
291
292
### Pre-publish Validation
293
294
NPM validation steps before publishing:
295
296
1. **NPM Version Check**: Ensure npm version ≥ 9.0.0
297
2. **Registry Connection**: Verify connection to npm registry
298
3. **Authentication**: Confirm user is logged in
299
4. **Package Name**: Check if package name is available/owned
300
5. **File Analysis**: Analyze files that will be published
301
6. **External Registry**: Handle external registry configuration
302
303
### Publishing Process
304
305
NPM operations during publishing:
306
307
1. **Argument Generation**: Create npm publish command arguments
308
2. **Execution**: Run npm publish with proper error handling
309
3. **OTP Handling**: Prompt for 2FA codes if required
310
4. **Error Recovery**: Handle network failures and authentication issues
311
5. **Success Confirmation**: Verify package was published successfully
312
313
### Post-publish Operations
314
315
NPM operations after successful publishing:
316
317
1. **2FA Setup**: Enable 2FA on new packages if configured
318
2. **Tag Management**: Verify correct dist-tag was applied
319
3. **Access Control**: Configure package access if needed
320
321
### Publishing Options
322
323
NPM publish supports various options:
324
325
```javascript
326
const options = {
327
tag: "beta", // Publish under beta tag
328
contents: "dist", // Publish from dist directory
329
otp: "123456", // One-time password for 2FA
330
access: "public", // Package access level
331
registry: "custom" // Custom registry URL
332
};
333
```
334
335
## Package Access Management
336
337
### Access Levels
338
339
NPM packages can have different access levels:
340
341
```javascript { .api }
342
/**
343
* Get npm package access information
344
* @param name - Package name
345
* @returns Promise resolving to access information
346
*/
347
function getNpmPackageAccess(name: string): Promise<{
348
access: 'public' | 'restricted';
349
[key: string]: any;
350
}>;
351
```
352
353
**Access Types:**
354
- **public**: Anyone can install (default for unscoped packages)
355
- **restricted**: Only collaborators can install (default for scoped packages)
356
357
### Scoped Packages
358
359
Handle scoped package publishing:
360
361
```javascript
362
// Scoped package names
363
"@myorg/my-package"
364
"@username/project-name"
365
366
// Require explicit public access
367
const publishArgs = getPackagePublishArguments({
368
access: "public" // Required for public scoped packages
369
});
370
```
371
372
## Registry Configuration
373
374
### Default Registry
375
376
Standard npm registry configuration:
377
378
```javascript
379
// Default npm registry
380
"https://registry.npmjs.org/"
381
382
// Package manager detection
383
const isNpm = packageManager.id === 'npm';
384
const registryUrl = isNpm ? undefined : packageManager.registry;
385
```
386
387
### External Registries
388
389
Support for external npm registries:
390
391
```javascript
392
// Custom registry in package.json
393
{
394
"publishConfig": {
395
"registry": "https://npm.example.com/"
396
}
397
}
398
399
// Detection
400
const isExternal = npm.isExternalRegistry(packageJson);
401
if (isExternal) {
402
// Disable 2FA setup
403
// Adjust publish commands
404
// Handle authentication differently
405
}
406
```
407
408
### Enterprise Registries
409
410
Enterprise registry considerations:
411
412
- **Authentication**: May use different auth mechanisms
413
- **2FA**: May not support 2FA enforcement
414
- **Tags**: May have different tag restrictions
415
- **Scopes**: May require specific scopes
416
417
## Error Conditions
418
419
### Common NPM Errors
420
421
**Authentication Errors:**
422
- Not logged in to npm
423
- Invalid credentials
424
- 2FA token required
425
- 2FA token expired
426
427
**Publishing Errors:**
428
- Package name conflicts
429
- Permission denied
430
- Network timeouts
431
- Registry unavailable
432
433
**Validation Errors:**
434
- Invalid package.json
435
- Missing required fields
436
- Version conflicts
437
- File access issues
438
439
### Error Recovery
440
441
NPM error handling strategies:
442
443
```javascript
444
// OTP retry for 2FA
445
if (error.code === 'EOTP') {
446
const otp = await promptForOTP();
447
return retryPublish({...options, otp});
448
}
449
450
// Network retry
451
if (error.code === 'ENOTFOUND') {
452
await delay(1000);
453
return retryPublish(options);
454
}
455
456
// Permission error guidance
457
if (error.code === 'E403') {
458
throw new Error('Permission denied. Run "npm login" or check package ownership');
459
}
460
```
461
462
### Debug Information
463
464
NPM operations provide detailed debug information:
465
466
- **Command executed**: Full npm command with arguments
467
- **Registry URL**: Target registry for publishing
468
- **User context**: Current npm user and authentication state
469
- **Package analysis**: Files included, size, and structure
470
- **Network details**: Request/response information for troubleshooting