@verdaccio/api 6.0.0-6-next.25 → 6.0.0-6-next.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +106 -0
- package/build/dist-tags.js +40 -35
- package/build/dist-tags.js.map +1 -1
- package/build/index.js +1 -7
- package/build/index.js.map +1 -1
- package/build/package.js +39 -28
- package/build/package.js.map +1 -1
- package/build/ping.js.map +1 -1
- package/build/publish.d.ts +79 -22
- package/build/publish.js +89 -313
- package/build/publish.js.map +1 -1
- package/build/search.js.map +1 -1
- package/build/star.js +53 -54
- package/build/star.js.map +1 -1
- package/build/stars.js +6 -6
- package/build/stars.js.map +1 -1
- package/build/user.js +19 -1
- package/build/user.js.map +1 -1
- package/build/v1/profile.js.map +1 -1
- package/build/v1/search.js +2 -4
- package/build/v1/search.js.map +1 -1
- package/build/v1/token.js.map +1 -1
- package/build/whoami.js +11 -25
- package/build/whoami.js.map +1 -1
- package/jest.config.js +8 -1
- package/package.json +71 -69
- package/src/dist-tags.ts +63 -50
- package/src/index.ts +1 -6
- package/src/package.ts +37 -44
- package/src/publish.ts +115 -336
- package/src/star.ts +53 -52
- package/src/stars.ts +9 -11
- package/src/user.ts +19 -2
- package/src/v1/search.ts +3 -3
- package/src/whoami.ts +8 -24
- package/test/integration/_helper.ts +97 -54
- package/test/integration/config/distTag.yaml +25 -0
- package/test/integration/config/package.yaml +3 -8
- package/test/integration/config/ping.yaml +2 -6
- package/test/integration/config/publish.yaml +4 -10
- package/test/integration/config/search.yaml +29 -0
- package/test/integration/config/token.jwt.yaml +27 -0
- package/test/integration/config/token.yaml +19 -0
- package/test/integration/config/user.jwt.yaml +37 -0
- package/test/integration/config/user.yaml +8 -14
- package/test/integration/config/whoami.yaml +4 -11
- package/test/integration/distTag.spec.ts +76 -0
- package/test/integration/package.spec.ts +53 -75
- package/test/integration/ping.spec.ts +4 -3
- package/test/integration/publish.spec.ts +60 -25
- package/test/integration/search.spec.ts +126 -0
- package/test/integration/token.spec.ts +124 -0
- package/test/integration/user.jwt.spec.ts +87 -0
- package/test/integration/user.spec.ts +1 -0
- package/test/integration/whoami.spec.ts +21 -39
- package/test/unit/publish.disabled.ts +252 -0
- package/tsconfig.json +1 -1
- package/__mocks__/@verdaccio/logger/index.js +0 -21
- package/build/utils.d.ts +0 -7
- package/build/utils.js +0 -36
- package/build/utils.js.map +0 -1
- package/src/utils.ts +0 -25
- package/test/unit/__snapshots__/publish.spec.ts.snap +0 -49
- package/test/unit/publish.spec.ts +0 -300
package/src/publish.ts
CHANGED
|
@@ -1,40 +1,21 @@
|
|
|
1
1
|
import buildDebug from 'debug';
|
|
2
2
|
import { Router } from 'express';
|
|
3
|
-
import _ from 'lodash';
|
|
4
3
|
import mime from 'mime';
|
|
5
|
-
import Path from 'path';
|
|
6
4
|
|
|
7
5
|
import { IAuth } from '@verdaccio/auth';
|
|
8
|
-
import {
|
|
9
|
-
API_ERROR,
|
|
10
|
-
API_MESSAGE,
|
|
11
|
-
DIST_TAGS,
|
|
12
|
-
HEADERS,
|
|
13
|
-
HTTP_STATUS,
|
|
14
|
-
errorUtils,
|
|
15
|
-
} from '@verdaccio/core';
|
|
16
|
-
import { notify } from '@verdaccio/hooks';
|
|
6
|
+
import { API_MESSAGE, HTTP_STATUS } from '@verdaccio/core';
|
|
17
7
|
import { logger } from '@verdaccio/logger';
|
|
18
8
|
import { allow, expectJson, media } from '@verdaccio/middleware';
|
|
19
9
|
import { Storage } from '@verdaccio/store';
|
|
20
|
-
import { Callback, CallbackAction, Config, MergeTags, Package, Version } from '@verdaccio/types';
|
|
21
|
-
import { hasDiffOneKey, isObject, validateMetadata } from '@verdaccio/utils';
|
|
22
10
|
|
|
23
11
|
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
|
|
24
|
-
import star from './star';
|
|
25
|
-
import { isPublishablePackage, isRelatedToDeprecation } from './utils';
|
|
26
12
|
|
|
27
|
-
|
|
13
|
+
// import star from './star';
|
|
14
|
+
// import { isPublishablePackage, isRelatedToDeprecation } from './utils';
|
|
28
15
|
|
|
29
|
-
|
|
30
|
-
router: Router,
|
|
31
|
-
auth: IAuth,
|
|
32
|
-
storage: Storage,
|
|
33
|
-
config: Config
|
|
34
|
-
): void {
|
|
35
|
-
const can = allow(auth);
|
|
16
|
+
const debug = buildDebug('verdaccio:api:publish');
|
|
36
17
|
|
|
37
|
-
|
|
18
|
+
/**
|
|
38
19
|
* Publish a package / update package / un/start a package
|
|
39
20
|
*
|
|
40
21
|
* There are multiples scenarios here to be considered:
|
|
@@ -73,13 +54,27 @@ export default function publish(
|
|
|
73
54
|
*
|
|
74
55
|
* Example flow of unpublish.
|
|
75
56
|
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* npm
|
|
80
|
-
* npm
|
|
81
|
-
*
|
|
57
|
+
* There are two possible flows:
|
|
58
|
+
*
|
|
59
|
+
* - Remove all packages (entirely)
|
|
60
|
+
* eg: npm unpublish package-name@* --force
|
|
61
|
+
* eg: npm unpublish package-name --force
|
|
62
|
+
*
|
|
63
|
+
* npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1680ms
|
|
64
|
+
* npm http fetch DELETE 201 http://localhost:4873/custom-name/-/test1-1.0.3.tgz/-rev/16-e11c8db282b2d992 19ms
|
|
82
65
|
*
|
|
66
|
+
* - Remove a specific version
|
|
67
|
+
* eg: npm unpublish package-name@1.0.0 --force
|
|
68
|
+
*
|
|
69
|
+
* Get fresh manifest
|
|
70
|
+
* npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1680ms
|
|
71
|
+
* Update manifest without the version to be unpublished
|
|
72
|
+
* npm http fetch PUT 201 http://localhost:4873/custom-name/-rev/14-5d500cfce92f90fd 956606ms
|
|
73
|
+
* Get fresh manifest (revision should be different)
|
|
74
|
+
* npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1601ms
|
|
75
|
+
* Remove the tarball
|
|
76
|
+
* npm http fetch DELETE 201 http://localhost:4873/custom-name/-/test1-1.0.3.tgz/-rev/16-e11c8db282b2d992 19ms
|
|
77
|
+
*
|
|
83
78
|
* 3. Star a package
|
|
84
79
|
*
|
|
85
80
|
* Permissions: start a package depends of the publish and unpublish permissions, there is no
|
|
@@ -98,12 +93,24 @@ export default function publish(
|
|
|
98
93
|
}
|
|
99
94
|
*
|
|
100
95
|
*/
|
|
96
|
+
export default function publish(router: Router, auth: IAuth, storage: Storage): void {
|
|
97
|
+
const can = allow(auth);
|
|
98
|
+
// publish (update manifest) v6
|
|
101
99
|
router.put(
|
|
102
|
-
'/:package
|
|
100
|
+
'/:package',
|
|
103
101
|
can('publish'),
|
|
104
102
|
media(mime.getType('json')),
|
|
105
103
|
expectJson,
|
|
106
|
-
|
|
104
|
+
publishPackageNext(storage)
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// unpublish a pacakge v6
|
|
108
|
+
router.put(
|
|
109
|
+
'/:package/-rev/:revision',
|
|
110
|
+
can('unpublish'),
|
|
111
|
+
media(mime.getType('json')),
|
|
112
|
+
expectJson,
|
|
113
|
+
publishPackageNext(storage)
|
|
107
114
|
);
|
|
108
115
|
|
|
109
116
|
/**
|
|
@@ -111,330 +118,102 @@ export default function publish(
|
|
|
111
118
|
*
|
|
112
119
|
* This scenario happens when the first call detect there is only one version remaining
|
|
113
120
|
* in the metadata, then the client decides to DELETE the resource
|
|
114
|
-
* npm http fetch GET 304 http://localhost:4873
|
|
115
|
-
|
|
121
|
+
* npm http fetch GET 304 http://localhost:4873/package-name?write=true 1076ms (from cache)
|
|
122
|
+
* npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
|
|
116
123
|
*/
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// removing a tarball
|
|
124
|
+
// v6
|
|
120
125
|
router.delete(
|
|
121
|
-
'/:package
|
|
126
|
+
'/:package/-rev/:revision',
|
|
122
127
|
can('unpublish'),
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
media(HEADERS.OCTET_STREAM),
|
|
132
|
-
uploadPackageTarball(storage)
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
// adding a version
|
|
136
|
-
router.put(
|
|
137
|
-
'/:package/:version/-tag/:tag',
|
|
138
|
-
can('publish'),
|
|
139
|
-
media(mime.getType('json')),
|
|
140
|
-
expectJson,
|
|
141
|
-
addVersion(storage)
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Publish a package
|
|
147
|
-
*/
|
|
148
|
-
export function publishPackage(storage: Storage, config: Config, auth: IAuth): any {
|
|
149
|
-
const starApi = star(storage);
|
|
150
|
-
return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
|
151
|
-
const packageName = req.params.package;
|
|
152
|
-
|
|
153
|
-
debug('publishing or updating a new version for %o', packageName);
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Write tarball of stream data from package clients.
|
|
157
|
-
*/
|
|
158
|
-
const createTarball = function (filename: string, data, cb: Callback): void {
|
|
159
|
-
const stream = storage.addTarball(packageName, filename);
|
|
160
|
-
stream.on('error', function (err) {
|
|
161
|
-
debug(
|
|
162
|
-
'error on stream a tarball %o for %o with error %o',
|
|
163
|
-
filename,
|
|
164
|
-
packageName,
|
|
165
|
-
err.message
|
|
166
|
-
);
|
|
167
|
-
cb(err);
|
|
168
|
-
});
|
|
169
|
-
stream.on('success', function () {
|
|
170
|
-
debug('success on stream a tarball %o for %o', filename, packageName);
|
|
171
|
-
cb();
|
|
172
|
-
});
|
|
173
|
-
// this is dumb and memory-consuming, but what choices do we have?
|
|
174
|
-
// flow: we need first refactor this file before decides which type use here
|
|
175
|
-
stream.end(Buffer.from(data.data, 'base64'));
|
|
176
|
-
stream.done();
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Add new package version in storage
|
|
181
|
-
*/
|
|
182
|
-
const createVersion = function (version: string, metadata: Version, cb: CallbackAction): void {
|
|
183
|
-
debug('add a new package version %o to storage %o', version, metadata);
|
|
184
|
-
storage.addVersion(packageName, version, metadata, null, cb);
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Add new tags in storage
|
|
189
|
-
*/
|
|
190
|
-
const addTags = function (tags: MergeTags, cb: CallbackAction): void {
|
|
191
|
-
debug('add new tag %o to storage', packageName);
|
|
192
|
-
storage.mergeTags(packageName, tags, cb);
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const afterChange = function (error, okMessage, metadata: Package): void {
|
|
196
|
-
const metadataCopy: Package = { ...metadata };
|
|
197
|
-
debug('after change metadata %o', metadata);
|
|
198
|
-
|
|
199
|
-
const { _attachments, versions } = metadataCopy;
|
|
200
|
-
|
|
201
|
-
// `npm star` wouldn't have attachments
|
|
202
|
-
// and `npm deprecate` would have attachments as a empty object, i.e {}
|
|
203
|
-
if (_.isNil(_attachments) || JSON.stringify(_attachments) === '{}') {
|
|
204
|
-
debug('no attachments detected');
|
|
205
|
-
if (error) {
|
|
206
|
-
debug('no_attachments: after change error with %o', error.message);
|
|
207
|
-
return next(error);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
debug('no_attachments: after change success');
|
|
128
|
+
async function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
|
129
|
+
const packageName = req.params.package;
|
|
130
|
+
const rev = req.params.revision;
|
|
131
|
+
|
|
132
|
+
logger.debug({ packageName }, `unpublishing @{packageName}`);
|
|
133
|
+
try {
|
|
134
|
+
await storage.removePackage(packageName, rev);
|
|
135
|
+
debug('package %s unpublished', packageName);
|
|
211
136
|
res.status(HTTP_STATUS.CREATED);
|
|
212
|
-
return next({
|
|
213
|
-
|
|
214
|
-
success: true,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* npm-registry-client 0.3+ embeds tarball into the json upload
|
|
220
|
-
* issue https://github.com/rlidwka/sinopia/issues/31, dealing with it here:
|
|
221
|
-
*/
|
|
222
|
-
|
|
223
|
-
const isInvalidBodyFormat =
|
|
224
|
-
isObject(_attachments) === false ||
|
|
225
|
-
hasDiffOneKey(_attachments) ||
|
|
226
|
-
isObject(versions) === false ||
|
|
227
|
-
hasDiffOneKey(versions);
|
|
228
|
-
|
|
229
|
-
if (isInvalidBodyFormat) {
|
|
230
|
-
// npm is doing something strange again
|
|
231
|
-
// if this happens in normal circumstances, report it as a bug
|
|
232
|
-
debug('invalid body format');
|
|
233
|
-
logger.info({ packageName }, `wrong package format on publish a package @{packageName}`);
|
|
234
|
-
return next(errorUtils.getBadRequest(API_ERROR.UNSUPORTED_REGISTRY_CALL));
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (error && error.status !== HTTP_STATUS.CONFLICT) {
|
|
238
|
-
debug('error on change or update a package with %o', error.message);
|
|
239
|
-
return next(error);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// at this point document is either created or existed before
|
|
243
|
-
const [firstAttachmentKey] = Object.keys(_attachments);
|
|
244
|
-
|
|
245
|
-
createTarball(
|
|
246
|
-
Path.basename(firstAttachmentKey),
|
|
247
|
-
_attachments[firstAttachmentKey],
|
|
248
|
-
function (error) {
|
|
249
|
-
debug('creating a tarball %o', firstAttachmentKey);
|
|
250
|
-
if (error) {
|
|
251
|
-
debug('error on create a tarball for %o with error %o', packageName, error.message);
|
|
252
|
-
return next(error);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const versionToPublish = Object.keys(versions)[0];
|
|
256
|
-
|
|
257
|
-
versions[versionToPublish].readme =
|
|
258
|
-
_.isNil(metadataCopy.readme) === false ? String(metadataCopy.readme) : '';
|
|
259
|
-
|
|
260
|
-
createVersion(versionToPublish, versions[versionToPublish], function (error) {
|
|
261
|
-
if (error) {
|
|
262
|
-
debug('error on create a version for %o with error %o', packageName, error.message);
|
|
263
|
-
return next(error);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
addTags(metadataCopy[DIST_TAGS], async function (error) {
|
|
267
|
-
if (error) {
|
|
268
|
-
debug('error on create a tag for %o with error %o', packageName, error.message);
|
|
269
|
-
return next(error);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
try {
|
|
273
|
-
await notify(
|
|
274
|
-
metadataCopy,
|
|
275
|
-
config,
|
|
276
|
-
req.remote_user,
|
|
277
|
-
`${metadataCopy.name}@${versionToPublish}`
|
|
278
|
-
);
|
|
279
|
-
} catch (error: any) {
|
|
280
|
-
debug(
|
|
281
|
-
'error on notify add a new tag %o',
|
|
282
|
-
`${metadataCopy.name}@${versionToPublish}`
|
|
283
|
-
);
|
|
284
|
-
logger.error({ error }, 'notify batch service has failed: @{error}');
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
debug('add a tag succesfully for %o', `${metadataCopy.name}@${versionToPublish}`);
|
|
288
|
-
res.status(HTTP_STATUS.CREATED);
|
|
289
|
-
return next({ ok: okMessage, success: true });
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
);
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
if (isPublishablePackage(req.body) === false && isObject(req.body.users)) {
|
|
297
|
-
debug('starting star a package');
|
|
298
|
-
return starApi(req, res, next);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
try {
|
|
302
|
-
debug('pre validation metadata to publish %o', req.body);
|
|
303
|
-
const metadata = validateMetadata(req.body, packageName);
|
|
304
|
-
debug('post validation metadata to publish %o', metadata);
|
|
305
|
-
// treating deprecation as updating a package
|
|
306
|
-
if (req.params._rev || isRelatedToDeprecation(req.body)) {
|
|
307
|
-
debug('updating a new version for %o', packageName);
|
|
308
|
-
// we check unpublish permissions, an update is basically remove versions
|
|
309
|
-
const remote = req.remote_user;
|
|
310
|
-
auth.allow_unpublish({ packageName }, remote, (error) => {
|
|
311
|
-
debug('allowed to unpublish a package %o', packageName);
|
|
312
|
-
if (error) {
|
|
313
|
-
debug('not allowed to unpublish a version for %o', packageName);
|
|
314
|
-
return next(error);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
debug('update a package');
|
|
318
|
-
storage.changePackage(packageName, metadata, req.params.revision, function (error) {
|
|
319
|
-
afterChange(error, API_MESSAGE.PKG_CHANGED, metadata);
|
|
320
|
-
});
|
|
321
|
-
});
|
|
322
|
-
} else {
|
|
323
|
-
debug('adding a new version for the package %o', packageName);
|
|
324
|
-
storage.addPackage(packageName, metadata, function (error) {
|
|
325
|
-
debug('package metadata updated %o', metadata);
|
|
326
|
-
afterChange(error, API_MESSAGE.PKG_CREATED, metadata);
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
} catch (error: any) {
|
|
330
|
-
debug('error on publish, bad package format %o', packageName);
|
|
331
|
-
logger.error({ packageName }, 'error on publish, bad package data for @{packageName}');
|
|
332
|
-
return next(errorUtils.getBadData(API_ERROR.BAD_PACKAGE_DATA));
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* un-publish a package
|
|
339
|
-
*/
|
|
340
|
-
export function unPublishPackage(storage: Storage) {
|
|
341
|
-
return async function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
|
342
|
-
const packageName = req.params.package;
|
|
343
|
-
|
|
344
|
-
logger.debug({ packageName }, `unpublishing @{packageName}`);
|
|
345
|
-
try {
|
|
346
|
-
await storage.removePackage(packageName);
|
|
347
|
-
} catch (err) {
|
|
348
|
-
if (err) {
|
|
137
|
+
return next({ ok: API_MESSAGE.PKG_REMOVED });
|
|
138
|
+
} catch (err) {
|
|
349
139
|
return next(err);
|
|
350
140
|
}
|
|
351
141
|
}
|
|
352
|
-
|
|
353
|
-
return next({ ok: API_MESSAGE.PKG_REMOVED });
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Delete tarball
|
|
359
|
-
*/
|
|
360
|
-
export function removeTarball(storage: Storage) {
|
|
361
|
-
return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
|
362
|
-
const packageName = req.params.package;
|
|
363
|
-
const { filename, revision } = req.params;
|
|
142
|
+
);
|
|
364
143
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
144
|
+
/*
|
|
145
|
+
Remove a tarball, this happens when npm unpublish a package unique version.
|
|
146
|
+
npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
|
|
147
|
+
*/
|
|
148
|
+
router.delete(
|
|
149
|
+
'/:package/-/:filename/-rev/:revision',
|
|
150
|
+
can('unpublish'),
|
|
151
|
+
can('publish'),
|
|
152
|
+
async function (
|
|
153
|
+
req: $RequestExtend,
|
|
154
|
+
res: $ResponseExtend,
|
|
155
|
+
next: $NextFunctionVer
|
|
156
|
+
): Promise<void> {
|
|
157
|
+
const packageName = req.params.package;
|
|
158
|
+
const { filename, revision } = req.params;
|
|
374
159
|
|
|
375
160
|
logger.debug(
|
|
376
161
|
{ packageName, filename, revision },
|
|
377
|
-
`
|
|
162
|
+
`removing a tarball for @{packageName}-@{tarballName}-@{revision}`
|
|
378
163
|
);
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Adds a new version
|
|
385
|
-
*/
|
|
386
|
-
export function addVersion(storage: Storage) {
|
|
387
|
-
return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
|
388
|
-
const { version, tag } = req.params;
|
|
389
|
-
const packageName = req.params.package;
|
|
390
|
-
debug('add a new version %o and tag %o for %o', version, tag, packageName);
|
|
164
|
+
try {
|
|
165
|
+
await storage.removeTarball(packageName, filename, revision);
|
|
166
|
+
res.status(HTTP_STATUS.CREATED);
|
|
391
167
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
168
|
+
logger.debug(
|
|
169
|
+
{ packageName, filename, revision },
|
|
170
|
+
`success remove tarball for @{packageName}-@{tarballName}-@{revision}`
|
|
171
|
+
);
|
|
172
|
+
return next({ ok: API_MESSAGE.TARBALL_REMOVED });
|
|
173
|
+
} catch (err) {
|
|
174
|
+
return next(err);
|
|
396
175
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
res.status(HTTP_STATUS.CREATED);
|
|
400
|
-
return next({
|
|
401
|
-
ok: API_MESSAGE.PKG_PUBLISHED,
|
|
402
|
-
});
|
|
403
|
-
});
|
|
404
|
-
};
|
|
176
|
+
}
|
|
177
|
+
);
|
|
405
178
|
}
|
|
406
179
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
180
|
+
export function publishPackageNext(storage: Storage): any {
|
|
181
|
+
return async function (
|
|
182
|
+
req: $RequestExtend,
|
|
183
|
+
_res: $ResponseExtend,
|
|
184
|
+
next: $NextFunctionVer
|
|
185
|
+
): Promise<void> {
|
|
186
|
+
const ac = new AbortController();
|
|
412
187
|
const packageName = req.params.package;
|
|
413
|
-
const
|
|
414
|
-
req.
|
|
188
|
+
const { revision } = req.params;
|
|
189
|
+
const metadata = req.body;
|
|
415
190
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
return res.locals.report_error(err);
|
|
431
|
-
});
|
|
191
|
+
try {
|
|
192
|
+
debug('publishing %s', packageName);
|
|
193
|
+
await storage.updateManifest(metadata, {
|
|
194
|
+
name: packageName,
|
|
195
|
+
revision,
|
|
196
|
+
signal: ac.signal,
|
|
197
|
+
requestOptions: {
|
|
198
|
+
host: req.hostname,
|
|
199
|
+
protocol: req.protocol,
|
|
200
|
+
// @ts-ignore
|
|
201
|
+
headers: req.headers,
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
_res.status(HTTP_STATUS.CREATED);
|
|
432
205
|
|
|
433
|
-
stream.on('success', function () {
|
|
434
|
-
res.status(HTTP_STATUS.CREATED);
|
|
435
206
|
return next({
|
|
436
|
-
|
|
207
|
+
// TODO: this could be also Package Updated based on the
|
|
208
|
+
// action, deprecate, star, publish new version, or create a package
|
|
209
|
+
// the mssage some return from the method
|
|
210
|
+
ok: API_MESSAGE.PKG_CREATED,
|
|
211
|
+
success: true,
|
|
437
212
|
});
|
|
438
|
-
})
|
|
213
|
+
} catch (err: any) {
|
|
214
|
+
// TODO: review if we need the abort controller here
|
|
215
|
+
ac.abort();
|
|
216
|
+
next(err);
|
|
217
|
+
}
|
|
439
218
|
};
|
|
440
219
|
}
|
package/src/star.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1
2
|
import buildDebug from 'debug';
|
|
2
3
|
import { Response } from 'express';
|
|
3
4
|
import _ from 'lodash';
|
|
@@ -27,61 +28,61 @@ export default function (
|
|
|
27
28
|
return (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
|
|
28
29
|
const name = req.params.package;
|
|
29
30
|
debug('starring a package for %o', name);
|
|
30
|
-
const afterChangePackage = function (err?: Error) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
// const afterChangePackage = function (err?: Error) {
|
|
32
|
+
// if (err) {
|
|
33
|
+
// debug('error on update package for %o', name);
|
|
34
|
+
// return next(err);
|
|
35
|
+
// }
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
};
|
|
37
|
+
// debug('succes update package for %o', name);
|
|
38
|
+
// res.status(HTTP_STATUS.OK);
|
|
39
|
+
// next({
|
|
40
|
+
// success: true,
|
|
41
|
+
// });
|
|
42
|
+
// };
|
|
42
43
|
|
|
43
44
|
debug('get package info package for %o', name);
|
|
44
45
|
// @ts-ignore
|
|
45
|
-
storage.getPackage({
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
});
|
|
46
|
+
// storage.getPackage({
|
|
47
|
+
// name,
|
|
48
|
+
// req,
|
|
49
|
+
// callback: function (err, info) {
|
|
50
|
+
// if (err) {
|
|
51
|
+
// debug('error on get package info package for %o', name);
|
|
52
|
+
// return next(err);
|
|
53
|
+
// }
|
|
54
|
+
// const newStarUser = req.body[USERS];
|
|
55
|
+
// const remoteUsername = req.remote_user.name;
|
|
56
|
+
// const localStarUsers = info[USERS];
|
|
57
|
+
// // Check is star or unstar
|
|
58
|
+
// const isStar = Object.keys(newStarUser).includes(remoteUsername);
|
|
59
|
+
// debug('is start? %o', isStar);
|
|
60
|
+
// if (
|
|
61
|
+
// _.isNil(localStarUsers) === false &&
|
|
62
|
+
// validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)
|
|
63
|
+
// ) {
|
|
64
|
+
// return afterChangePackage();
|
|
65
|
+
// }
|
|
66
|
+
// const users = isStar
|
|
67
|
+
// ? {
|
|
68
|
+
// ...localStarUsers,
|
|
69
|
+
// [remoteUsername]: true,
|
|
70
|
+
// }
|
|
71
|
+
// : _.reduce(
|
|
72
|
+
// localStarUsers,
|
|
73
|
+
// (users, value, key) => {
|
|
74
|
+
// if (key !== remoteUsername) {
|
|
75
|
+
// users[key] = value;
|
|
76
|
+
// }
|
|
77
|
+
// return users;
|
|
78
|
+
// },
|
|
79
|
+
// {}
|
|
80
|
+
// );
|
|
81
|
+
// debug('update package for %o', name);
|
|
82
|
+
// storage.changePackage(name, { ...info, users }, req.body._rev, function (err) {
|
|
83
|
+
// afterChangePackage(err);
|
|
84
|
+
// });
|
|
85
|
+
// },
|
|
86
|
+
// });
|
|
86
87
|
};
|
|
87
88
|
}
|
package/src/stars.ts
CHANGED
|
@@ -3,34 +3,32 @@ import _ from 'lodash';
|
|
|
3
3
|
|
|
4
4
|
import { HTTP_STATUS, USERS } from '@verdaccio/core';
|
|
5
5
|
import { Storage } from '@verdaccio/store';
|
|
6
|
-
import {
|
|
6
|
+
import { Version } from '@verdaccio/types';
|
|
7
7
|
|
|
8
8
|
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
|
|
9
9
|
|
|
10
|
-
type Packages = Package[];
|
|
11
|
-
|
|
12
10
|
export default function (route: Router, storage: Storage): void {
|
|
13
11
|
route.get(
|
|
14
12
|
'/-/_view/starredByUser',
|
|
15
|
-
(req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
|
|
13
|
+
async (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> => {
|
|
16
14
|
const remoteUsername = req.remote_user.name;
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return next(err);
|
|
21
|
-
}
|
|
16
|
+
try {
|
|
17
|
+
const localPackages: Version[] = await storage.getLocalDatabaseNext();
|
|
22
18
|
|
|
23
|
-
const filteredPackages:
|
|
19
|
+
const filteredPackages: Version[] = localPackages.filter((localPackage: Version) =>
|
|
24
20
|
_.keys(localPackage[USERS]).includes(remoteUsername)
|
|
25
21
|
);
|
|
26
22
|
|
|
27
23
|
res.status(HTTP_STATUS.OK);
|
|
28
24
|
next({
|
|
29
|
-
rows: filteredPackages.map((filteredPackage:
|
|
25
|
+
rows: filteredPackages.map((filteredPackage: Version) => ({
|
|
30
26
|
value: filteredPackage.name,
|
|
31
27
|
})),
|
|
32
28
|
});
|
|
33
|
-
})
|
|
29
|
+
} catch (err: any) {
|
|
30
|
+
return next(err);
|
|
31
|
+
}
|
|
34
32
|
}
|
|
35
33
|
);
|
|
36
34
|
}
|