0
# Package Unpublishing
1
2
Functionality for removing packages or specific versions from npm registries with proper dist-tag management and tarball cleanup.
3
4
## Capabilities
5
6
### Unpublish Function
7
8
Removes packages or specific versions from the npm registry with intelligent handling of dist-tags and version management.
9
10
```javascript { .api }
11
/**
12
* Unpublishes a package or specific version from the registry
13
* @param spec - Package specification (name, name@version, or npm-package-arg parsed object)
14
* @param opts - Configuration options extending npm-registry-fetch options
15
* @returns Promise resolving to boolean (true on success)
16
*/
17
function unpublish(spec: string | Object, opts?: UnpublishOptions): Promise<boolean>;
18
19
interface UnpublishOptions {
20
/** Force unpublish operation (default: false) */
21
force?: boolean;
22
/** Authentication token for registry */
23
token?: string;
24
/** Registry URL */
25
registry?: string;
26
}
27
```
28
29
**Usage Examples:**
30
31
```javascript
32
const { unpublish } = require('libnpmpublish');
33
34
// Unpublish entire package (all versions)
35
await unpublish('my-package', {
36
token: 'npm_1234567890abcdef'
37
});
38
39
// Unpublish specific version
40
await unpublish('my-package@1.0.0', {
41
token: 'npm_1234567890abcdef'
42
});
43
44
// Unpublish all versions using wildcard
45
await unpublish('my-package@*', {
46
token: 'npm_1234567890abcdef'
47
});
48
49
// Unpublish scoped package
50
await unpublish('@myorg/my-package@2.1.0', {
51
token: 'npm_1234567890abcdef'
52
});
53
54
// Force unpublish with explicit force flag
55
await unpublish('my-package', {
56
token: 'npm_1234567890abcdef',
57
force: true
58
});
59
```
60
61
### Package Specification Formats
62
63
Accepts various formats for specifying what to unpublish.
64
65
```javascript { .api }
66
/** Package specification types */
67
type PackageSpec = string | ParsedSpec;
68
69
interface ParsedSpec {
70
name: string;
71
rawSpec?: string;
72
scope?: string;
73
escapedName: string;
74
}
75
```
76
77
**Supported Formats:**
78
79
- **Package name only**: `'lodash'` - Unpublishes all versions
80
- **Package with version**: `'lodash@4.17.21'` - Unpublishes specific version
81
- **Package with wildcard**: `'lodash@*'` - Unpublishes all versions
82
- **Scoped package**: `'@babel/core@7.0.0'` - Unpublishes specific version of scoped package
83
- **Parsed object**: Pre-parsed npm-package-arg object
84
85
```javascript
86
// Different specification formats
87
await unpublish('package-name'); // All versions
88
await unpublish('package-name@1.0.0'); // Specific version
89
await unpublish('package-name@*'); // All versions (explicit)
90
await unpublish('@scope/package@2.0.0'); // Scoped package version
91
92
// Using parsed specification
93
const npa = require('npm-package-arg');
94
const spec = npa('package-name@1.0.0');
95
await unpublish(spec, opts);
96
```
97
98
### Unpublish Behavior
99
100
The function exhibits different behavior based on the specification provided:
101
102
#### Complete Package Removal
103
104
When no version is specified or `*` is used, removes the entire package:
105
106
- Deletes all package versions
107
- Removes all dist-tags
108
- Deletes package metadata
109
- Removes all associated tarballs
110
111
```javascript
112
// These all remove the entire package
113
await unpublish('my-package');
114
await unpublish('my-package@*');
115
```
116
117
#### Specific Version Removal
118
119
When a specific version is provided, removes only that version:
120
121
- Deletes the specified version from the versions object
122
- Updates dist-tags that pointed to the removed version
123
- Recalculates the 'latest' tag if it pointed to the removed version
124
- Removes the associated tarball file
125
126
```javascript
127
// Remove only version 1.0.0
128
await unpublish('my-package@1.0.0');
129
```
130
131
### Dist-Tag Management
132
133
Automatically manages dist-tags when removing specific versions:
134
135
```javascript { .api }
136
interface DistTagBehavior {
137
/** Removes all dist-tags pointing to the unpublished version */
138
tagCleanup: boolean;
139
/** Recalculates 'latest' tag to point to highest remaining version */
140
latestRecalculation: boolean;
141
}
142
```
143
144
**Example Behavior:**
145
146
```javascript
147
// Before: my-package has versions 1.0.0, 1.1.0, 2.0.0
148
// Dist-tags: { latest: "2.0.0", stable: "1.1.0", beta: "2.0.0" }
149
150
await unpublish('my-package@2.0.0');
151
152
// After: my-package has versions 1.0.0, 1.1.0
153
// Dist-tags: { latest: "1.1.0", stable: "1.1.0" }
154
// (beta tag removed, latest recalculated)
155
```
156
157
### Registry Integration
158
159
Works with npm-registry-fetch for all HTTP operations:
160
161
```javascript
162
// Custom registry
163
await unpublish('my-package', {
164
registry: 'https://my-private-registry.com/',
165
token: 'private_registry_token'
166
});
167
168
// With additional npm-registry-fetch options
169
await unpublish('my-package', {
170
token: 'npm_token',
171
timeout: 30000,
172
retry: {
173
retries: 2,
174
factor: 2
175
}
176
});
177
```
178
179
### Error Handling
180
181
Returns `true` on successful unpublish, handles common error conditions gracefully:
182
183
#### Package Not Found (E404)
184
185
Returns `true` when attempting to unpublish non-existent packages or versions:
186
187
```javascript
188
// Returns true even if package doesn't exist
189
const result = await unpublish('non-existent-package');
190
console.log(result); // true
191
192
// Returns true if specific version doesn't exist
193
const result2 = await unpublish('existing-package@999.0.0');
194
console.log(result2); // true
195
```
196
197
#### Version Already Removed
198
199
Returns `true` when attempting to unpublish already-removed versions:
200
201
```javascript
202
await unpublish('my-package@1.0.0'); // First call removes it
203
const result = await unpublish('my-package@1.0.0'); // Second call returns true
204
```
205
206
#### Authentication Errors
207
208
Propagates authentication and permission errors:
209
210
```javascript
211
try {
212
await unpublish('my-package', {
213
token: 'invalid-token'
214
});
215
} catch (error) {
216
// Handle authentication/authorization errors
217
console.error('Unpublish failed:', error.message);
218
}
219
```
220
221
### Edge Cases
222
223
#### Single Version Package
224
225
When unpublishing the only version of a package:
226
227
```javascript
228
// If my-package only has version 1.0.0
229
await unpublish('my-package@1.0.0');
230
// Effectively removes the entire package
231
```
232
233
#### Empty Package State
234
235
Handles packages with no versions gracefully:
236
237
```javascript
238
// Returns true for packages with no versions
239
await unpublish('empty-package@1.0.0'); // true
240
```
241
242
#### Last Version Removal
243
244
When removing the last remaining version:
245
246
```javascript
247
// Package with only version 2.0.0
248
await unpublish('my-package@2.0.0');
249
// Package is completely removed from registry
250
```
251
252
## Authentication Requirements
253
254
All unpublish operations require appropriate authentication:
255
256
- **Package owner**: Can unpublish any version
257
- **Organization member**: Can unpublish organization packages (with permissions)
258
- **Registry admin**: Can unpublish any package (registry-dependent)
259
260
```javascript
261
await unpublish('my-package', {
262
token: 'npm_1234567890abcdef', // Required
263
registry: 'https://registry.npmjs.org/'
264
});
265
```