@verdaccio/api 8.1.0-next-8.12 → 8.1.0-next-8.13

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.
Files changed (49) hide show
  1. package/README.md +17 -10
  2. package/package.json +16 -12
  3. package/.babelrc +0 -3
  4. package/.eslintrc +0 -5
  5. package/CHANGELOG.md +0 -2152
  6. package/src/dist-tags.ts +0 -106
  7. package/src/index.ts +0 -65
  8. package/src/package.ts +0 -117
  9. package/src/ping.ts +0 -14
  10. package/src/publish.ts +0 -262
  11. package/src/search.ts +0 -12
  12. package/src/stars.ts +0 -37
  13. package/src/user.ts +0 -179
  14. package/src/v1/profile.ts +0 -113
  15. package/src/v1/search.ts +0 -85
  16. package/src/v1/token.ts +0 -157
  17. package/src/whoami.ts +0 -26
  18. package/test/.eslintrc +0 -8
  19. package/test/integration/_helper.ts +0 -198
  20. package/test/integration/config/distTag.yaml +0 -25
  21. package/test/integration/config/owner.yaml +0 -24
  22. package/test/integration/config/package.yaml +0 -25
  23. package/test/integration/config/ping.yaml +0 -26
  24. package/test/integration/config/profile.yaml +0 -27
  25. package/test/integration/config/publish-proxy.yaml +0 -26
  26. package/test/integration/config/publish.yaml +0 -24
  27. package/test/integration/config/search.yaml +0 -29
  28. package/test/integration/config/star.yaml +0 -26
  29. package/test/integration/config/token.jwt.yaml +0 -27
  30. package/test/integration/config/token.yaml +0 -19
  31. package/test/integration/config/user.jwt.yaml +0 -37
  32. package/test/integration/config/user.yaml +0 -30
  33. package/test/integration/config/whoami.yaml +0 -29
  34. package/test/integration/distTag.spec.ts +0 -80
  35. package/test/integration/owner.spec.ts +0 -119
  36. package/test/integration/package.spec.ts +0 -107
  37. package/test/integration/ping.spec.ts +0 -18
  38. package/test/integration/profile.spec.ts +0 -112
  39. package/test/integration/publish.spec.ts +0 -232
  40. package/test/integration/search.spec.ts +0 -139
  41. package/test/integration/star.spec.ts +0 -74
  42. package/test/integration/token.spec.ts +0 -125
  43. package/test/integration/user.spec.ts +0 -222
  44. package/test/integration/whoami.spec.ts +0 -36
  45. package/test/unit/publish.disabled.ts +0 -252
  46. package/test/unit/validate.api.params.middleware.spec.ts +0 -44
  47. package/tsconfig.build.json +0 -9
  48. package/tsconfig.json +0 -41
  49. package/types/custom.d.ts +0 -16
package/src/dist-tags.ts DELETED
@@ -1,106 +0,0 @@
1
- import { Router } from 'express';
2
- import _ from 'lodash';
3
- import mime from 'mime';
4
-
5
- import { Auth } from '@verdaccio/auth';
6
- import { constants, errorUtils } from '@verdaccio/core';
7
- import { allow, media } from '@verdaccio/middleware';
8
- import { DIST_TAGS_API_ENDPOINTS } from '@verdaccio/middleware';
9
- import { Storage } from '@verdaccio/store';
10
- import { Logger } from '@verdaccio/types';
11
-
12
- import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
13
-
14
- export default function (route: Router, auth: Auth, storage: Storage, logger: Logger): void {
15
- const can = allow(auth, {
16
- beforeAll: (a, b) => logger.trace(a, b),
17
- afterAll: (a, b) => logger.trace(a, b),
18
- });
19
- const addTagPackageVersionMiddleware = async function (
20
- req: $RequestExtend,
21
- res: $ResponseExtend,
22
- next: $NextFunctionVer
23
- ): Promise<$NextFunctionVer> {
24
- if (_.isString(req.body) === false) {
25
- return next(errorUtils.getBadRequest('version is missing'));
26
- }
27
-
28
- const tags = {};
29
- tags[req.params.tag] = req.body;
30
- try {
31
- await storage.mergeTagsNext(req.params.package, tags);
32
- res.status(constants.HTTP_STATUS.CREATED);
33
- return next({
34
- ok: constants.API_MESSAGE.TAG_ADDED,
35
- });
36
- } catch (err) {
37
- next(err);
38
- }
39
- };
40
-
41
- // tagging a package.
42
- route.put(
43
- DIST_TAGS_API_ENDPOINTS.tagging,
44
- can('publish'),
45
- media(mime.getType('json')),
46
- addTagPackageVersionMiddleware
47
- );
48
-
49
- route.put(
50
- DIST_TAGS_API_ENDPOINTS.tagging_package,
51
- can('publish'),
52
- media(mime.getType('json')),
53
- addTagPackageVersionMiddleware
54
- );
55
-
56
- route.delete(
57
- DIST_TAGS_API_ENDPOINTS.tagging_package,
58
- can('publish'),
59
- async function (
60
- req: $RequestExtend,
61
- res: $ResponseExtend,
62
- next: $NextFunctionVer
63
- ): Promise<void> {
64
- const tags = {};
65
- tags[req.params.tag] = null;
66
- try {
67
- await storage.mergeTagsNext(req.params.package, tags);
68
- res.status(constants.HTTP_STATUS.CREATED);
69
- return next({
70
- ok: constants.API_MESSAGE.TAG_REMOVED,
71
- });
72
- } catch (err) {
73
- next(err);
74
- }
75
- }
76
- );
77
-
78
- route.get(
79
- DIST_TAGS_API_ENDPOINTS.get_dist_tags,
80
- can('access'),
81
- async function (
82
- req: $RequestExtend,
83
- res: $ResponseExtend,
84
- next: $NextFunctionVer
85
- ): Promise<void> {
86
- const name = req.params.package;
87
- const requestOptions = {
88
- protocol: req.protocol,
89
- headers: req.headers as any,
90
- // FIXME: if we migrate to req.hostname, the port is not longer included.
91
- host: req.host,
92
- remoteAddress: req.socket.remoteAddress,
93
- };
94
- try {
95
- const manifest = await storage.getPackageByOptions({
96
- name,
97
- uplinksLook: true,
98
- requestOptions,
99
- });
100
- next(manifest[constants.DIST_TAGS]);
101
- } catch (err) {
102
- next(err);
103
- }
104
- }
105
- );
106
- }
package/src/index.ts DELETED
@@ -1,65 +0,0 @@
1
- import express, { Router } from 'express';
2
-
3
- import { Auth } from '@verdaccio/auth';
4
- import {
5
- antiLoop,
6
- encodeScopePackage,
7
- makeURLrelative,
8
- match,
9
- validateName,
10
- validatePackage,
11
- } from '@verdaccio/middleware';
12
- import { Storage } from '@verdaccio/store';
13
- import { Config, Logger } from '@verdaccio/types';
14
-
15
- import distTags from './dist-tags';
16
- import pkg from './package';
17
- import ping from './ping';
18
- import publish from './publish';
19
- import search from './search';
20
- import stars from './stars';
21
- import user from './user';
22
- import profile from './v1/profile';
23
- import v1Search from './v1/search';
24
- import token from './v1/token';
25
- import whoami from './whoami';
26
-
27
- export default function (config: Config, auth: Auth, storage: Storage, logger: Logger): Router {
28
- /* eslint new-cap:off */
29
- const app = express.Router();
30
- /* eslint new-cap:off */
31
-
32
- // validate all of these params as a package name
33
- // this might be too harsh, so ask if it causes trouble
34
- app.param('package', validatePackage);
35
- app.param('filename', validateName);
36
- app.param('tag', validateName);
37
- app.param('version', validateName);
38
- app.param('revision', validateName);
39
- app.param('token', validateName);
40
-
41
- // Express route parameter names must be valid JavaScript identifiers, which means
42
- // they cannot start with a hyphen (-) or contain special characters like dots (.)
43
- app.param('_rev', match(/^-rev$/));
44
- app.param('org_couchdb_user', match(/^org\.couchdb\.user:/));
45
-
46
- app.use(auth.apiJWTmiddleware());
47
- app.use(express.json({ strict: false, limit: config.max_body_size || '10mb' }));
48
- app.use(antiLoop(config));
49
- app.use(makeURLrelative);
50
- // encode / in a scoped package name to be matched as a single parameter in routes
51
- app.use(encodeScopePackage);
52
- // for "npm whoami"
53
- whoami(app);
54
- profile(app, auth, config);
55
- search(app, logger);
56
- user(app, auth, config, logger);
57
- distTags(app, auth, storage, logger);
58
- publish(app, auth, storage, logger);
59
- ping(app);
60
- stars(app, storage);
61
- v1Search(app, auth, storage, logger);
62
- token(app, auth, storage, config, logger);
63
- pkg(app, auth, storage, logger);
64
- return app;
65
- }
package/src/package.ts DELETED
@@ -1,117 +0,0 @@
1
- import buildDebug from 'debug';
2
- import { Router } from 'express';
3
-
4
- import { Auth } from '@verdaccio/auth';
5
- import { HEADERS, HEADER_TYPE, stringUtils } from '@verdaccio/core';
6
- import { allow } from '@verdaccio/middleware';
7
- import { PACKAGE_API_ENDPOINTS } from '@verdaccio/middleware';
8
- import { Storage } from '@verdaccio/store';
9
- import { Logger } from '@verdaccio/types';
10
-
11
- import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
12
-
13
- const debug = buildDebug('verdaccio:api:package');
14
-
15
- export default function (route: Router, auth: Auth, storage: Storage, logger: Logger): void {
16
- const can = allow(auth, {
17
- beforeAll: (a, b) => logger.trace(a, b),
18
- afterAll: (a, b) => logger.trace(a, b),
19
- });
20
- route.get(
21
- PACKAGE_API_ENDPOINTS.get_package_by_version,
22
- can('access'),
23
- async function (
24
- req: $RequestExtend,
25
- _res: $ResponseExtend,
26
- next: $NextFunctionVer
27
- ): Promise<void> {
28
- debug('get package by version');
29
- const name = req.params.package;
30
- let version = req.params.version;
31
- const write = req.query.write === 'true';
32
- const username = req?.remote_user?.name;
33
- const abbreviated =
34
- stringUtils.getByQualityPriorityValue(req.get('Accept')) === Storage.ABBREVIATED_HEADER;
35
- if (debug.enabled) {
36
- debug('is write %o', write);
37
- debug('is abbreviated %o', abbreviated);
38
- debug('package %o', name);
39
- debug('version %o', version);
40
- debug('username %o', username);
41
- debug('remote address %o', req.socket.remoteAddress);
42
- debug('host %o', req.host);
43
- debug('protocol %o', req.protocol);
44
- debug('url %o', req.url);
45
- }
46
- const requestOptions = {
47
- protocol: req.protocol,
48
- headers: req.headers as any,
49
- // FIXME: if we migrate to req.hostname, the port is not longer included.
50
- host: req.host,
51
- remoteAddress: req.socket.remoteAddress,
52
- byPassCache: write,
53
- username,
54
- };
55
-
56
- try {
57
- const manifest = await storage.getPackageByOptions({
58
- name,
59
- uplinksLook: true,
60
- abbreviated,
61
- version,
62
- requestOptions,
63
- });
64
- if (abbreviated) {
65
- debug('abbreviated response');
66
- _res.setHeader(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_INSTALL_CHARSET);
67
- } else {
68
- debug('full response');
69
- _res.setHeader(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON);
70
- }
71
-
72
- next(manifest);
73
- } catch (err) {
74
- next(err);
75
- }
76
- }
77
- );
78
-
79
- route.get(
80
- PACKAGE_API_ENDPOINTS.get_package_tarball,
81
- can('access'),
82
- async function (req: $RequestExtend, res: $ResponseExtend, next): Promise<void> {
83
- const { package: pkgName, filename } = req.params;
84
- const abort = new AbortController();
85
- try {
86
- debug('downloading tarball %o', filename);
87
- const stream = (await storage.getTarball(pkgName, filename, {
88
- signal: abort.signal,
89
- // TODO: review why this param
90
- // enableRemote: true,
91
- })) as any;
92
-
93
- stream.on('content-length', (size) => {
94
- debug('tarball size %o', size);
95
- res.header(HEADER_TYPE.CONTENT_LENGTH, size);
96
- });
97
-
98
- stream.once('error', (err) => {
99
- debug('error on download tarball %o', err);
100
- res.locals.report_error(err);
101
- next(err);
102
- });
103
-
104
- req.on('abort', () => {
105
- debug('request aborted for %o', req.url);
106
- abort.abort();
107
- });
108
-
109
- res.header(HEADERS.CONTENT_TYPE, HEADERS.OCTET_STREAM);
110
- stream.pipe(res);
111
- } catch (err: any) {
112
- res.locals.report_error(err);
113
- next(err);
114
- }
115
- }
116
- );
117
- }
package/src/ping.ts DELETED
@@ -1,14 +0,0 @@
1
- import { Router } from 'express';
2
-
3
- import { PING_API_ENDPOINTS } from '@verdaccio/middleware';
4
-
5
- import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
6
-
7
- export default function (route: Router): void {
8
- route.get(
9
- PING_API_ENDPOINTS.ping,
10
- function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
11
- next({});
12
- }
13
- );
14
- }
package/src/publish.ts DELETED
@@ -1,262 +0,0 @@
1
- import buildDebug from 'debug';
2
- import { Router } from 'express';
3
- import mime from 'mime';
4
-
5
- import { Auth } from '@verdaccio/auth';
6
- import { API_MESSAGE, HTTP_STATUS } from '@verdaccio/core';
7
- import { allow, expectJson, media } from '@verdaccio/middleware';
8
- // import star from './star';
9
- import { PUBLISH_API_ENDPOINTS } from '@verdaccio/middleware';
10
- import { Storage } from '@verdaccio/store';
11
- import { Logger } from '@verdaccio/types';
12
-
13
- import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
14
-
15
- const debug = buildDebug('verdaccio:api:publish');
16
-
17
- /**
18
- * Publish a package / update package / un/start a package
19
- *
20
- * There are multiples scenarios here to be considered:
21
- *
22
- * 1. Publish scenario
23
- *
24
- * Publish a package consist of at least 1 step (PUT) with a metadata payload.
25
- * When a package is published, an _attachment property is present that contains the data
26
- * of the tarball.
27
- *
28
- * Example flow of publish.
29
- *
30
- * npm http fetch PUT 201 http://localhost:4873/@scope%2ftest1 9627ms
31
- npm info lifecycle @scope/test1@1.0.1~publish: @scope/test1@1.0.1
32
- npm info lifecycle @scope/test1@1.0.1~postpublish: @scope/test1@1.0.1
33
- + @scope/test1@1.0.1
34
- npm verb exit [ 0, true ]
35
- *
36
- *
37
- * 2. Unpublish scenario
38
- *
39
- * Unpublish consist in 3 steps.
40
- * 1. Try to fetch metadata -> if it fails, return 404
41
- * 2. Compute metadata locally (client side) and send a mutate payload excluding the version to
42
- * be unpublished
43
- * eg: if metadata reflects 1.0.1, 1.0.2 and 1.0.3, the computed metadata won't include 1.0.3.
44
- * 3. Once the second step has been successfully finished, delete the tarball.
45
- *
46
- * All these steps are consecutive and required, there is no transacions here, if step 3 fails,
47
- * metadata might get corrupted.
48
- *
49
- * Note the unpublish call will suffix in the url a /-rev/14-5d500cfce92f90fd revision number,
50
- * this not
51
- * used internally.
52
- *
53
- *
54
- * Example flow of unpublish.
55
- *
56
- * There are two possible flows:
57
- *
58
- * - Remove all packages (entirely)
59
- * eg: npm unpublish package-name@* --force
60
- * eg: npm unpublish package-name --force
61
- *
62
- * npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1680ms
63
- * npm http fetch DELETE 201 http://localhost:4873/custom-name/-/test1-1.0.3.tgz/-rev/16-e11c8db282b2d992 19ms
64
- *
65
- * - Remove a specific version
66
- * eg: npm unpublish package-name@1.0.0 --force
67
- *
68
- * Get fresh manifest
69
- * npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1680ms
70
- * Update manifest without the version to be unpublished
71
- * npm http fetch PUT 201 http://localhost:4873/custom-name/-rev/14-5d500cfce92f90fd 956606ms
72
- * Get fresh manifest (revision should be different)
73
- * npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1601ms
74
- * Remove the tarball
75
- * npm http fetch DELETE 201 http://localhost:4873/custom-name/-/test1-1.0.3.tgz/-rev/16-e11c8db282b2d992 19ms
76
- *
77
- * 3. Star a package
78
- *
79
- * Permissions: staring a package depends of the publish and unpublish permissions, there is no
80
- * specific flag for star or unstar.
81
- * The URL for star is similar to the unpublish (change package format)
82
- *
83
- * npm has no endpoint for staring a package, rather mutate the metadata and acts as, the difference
84
- * is the users property which is part of the payload and the body only includes
85
- *
86
- * {
87
- "_id": pkgName,
88
- "_rev": "3-b0cdaefc9bdb77c8",
89
- "users": {
90
- [username]: boolean value (true, false)
91
- }
92
- }
93
- *
94
- * 4. Change owners of a package
95
- *
96
- * Similar to staring a package, changing owners (maintainers) of a package uses the publish
97
- * endpoint.
98
- *
99
- * The body includes a list of the new owners with the following format
100
- *
101
- * {
102
- "_id": pkgName,
103
- "_rev": "4-b0cdaefc9bdb77c8",
104
- "maintainers": [
105
- { "name": "first owner", "email": "me@verdaccio.org" },
106
- { "name": "second owner", "email": "you@verdaccio.org" },
107
- ...
108
- ]
109
- }
110
- *
111
- */
112
- export default function publish(
113
- router: Router,
114
- auth: Auth,
115
- storage: Storage,
116
- logger: Logger
117
- ): void {
118
- const can = allow(auth, {
119
- beforeAll: (a, b) => logger.trace(a, b),
120
- afterAll: (a, b) => logger.trace(a, b),
121
- });
122
- router.put(
123
- PUBLISH_API_ENDPOINTS.add_package,
124
- can('publish'),
125
- media(mime.getType('json')),
126
- expectJson,
127
- publishPackage(storage, logger, 'publish one version')
128
- );
129
-
130
- router.put(
131
- PUBLISH_API_ENDPOINTS.publish_package,
132
- can('unpublish'),
133
- media(mime.getType('json')),
134
- expectJson,
135
- publishPackage(storage, logger, 'publish with revision')
136
- );
137
-
138
- /**
139
- * Un-publishing an entire package.
140
- *
141
- * This scenario happens when any of these scenarios happens:
142
- * - the first call detect there is only one version remaining
143
- * - no version is specified in the unpublish call
144
- * - all versions are removed npm unpublish package@*
145
- * - there is no versions on the metadata
146
-
147
- * then the client decides to DELETE the resource
148
- * Example:
149
- * Get fresh manifest (write=true is a flag to get the latest revision)
150
- * npm http fetch GET 304 http://localhost:4873/package-name?write=true 1076ms (from cache)
151
- * Send request to delete the package, this includes the revision number that must match
152
- * and the package name, it will delete the entire package and all tarballs (or tarball depends the scenario)
153
- * npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
154
- */
155
- router.delete(
156
- PUBLISH_API_ENDPOINTS.publish_package,
157
- can('unpublish'),
158
- async function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
159
- const packageName = req.params.package;
160
- const rev = req.params.revision;
161
- const username = req?.remote_user?.name;
162
-
163
- logger.debug({ packageName }, `unpublishing @{packageName}`);
164
- try {
165
- await storage.removePackage(packageName, rev, username);
166
- debug('package %s unpublished', packageName);
167
- res.status(HTTP_STATUS.CREATED);
168
- return next({ ok: API_MESSAGE.PKG_REMOVED });
169
- } catch (err) {
170
- return next(err);
171
- }
172
- }
173
- );
174
-
175
- /*
176
- Remove a tarball, this happens when npm unpublish a package unique version.
177
- npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
178
- */
179
- router.delete(
180
- PUBLISH_API_ENDPOINTS.remove_tarball,
181
- can('unpublish'),
182
- can('publish'),
183
- async function (
184
- req: $RequestExtend,
185
- res: $ResponseExtend,
186
- next: $NextFunctionVer
187
- ): Promise<void> {
188
- const packageName = req.params.package;
189
- const { filename, revision } = req.params;
190
- const username = req?.remote_user?.name;
191
-
192
- logger.debug(
193
- { packageName, filename, revision },
194
- `removing a tarball for @{packageName}-@{tarballName}-@{revision}`
195
- );
196
- try {
197
- await storage.removeTarball(packageName, filename, revision, username);
198
- res.status(HTTP_STATUS.CREATED);
199
-
200
- logger.debug(
201
- { packageName, filename, revision },
202
- `success remove tarball for @{packageName}-@{tarballName}-@{revision}`
203
- );
204
- return next({ ok: API_MESSAGE.TARBALL_REMOVED });
205
- } catch (err) {
206
- return next(err);
207
- }
208
- }
209
- );
210
- }
211
-
212
- export function publishPackage(storage: Storage, logger: Logger, origin: string): any {
213
- return async function (
214
- req: $RequestExtend,
215
- res: $ResponseExtend,
216
- next: $NextFunctionVer
217
- ): Promise<void> {
218
- debug(origin);
219
- const ac = new AbortController();
220
- const packageName = req.params.package;
221
- const { revision } = req.params;
222
- debug('publishing package %s', packageName);
223
- debug('revision %s', revision);
224
- if (debug.enabled) {
225
- debug('body %o', req.body);
226
- }
227
- const metadata = req.body;
228
- const username = req?.remote_user?.name;
229
-
230
- debug('publishing package %o for user %o', packageName, username);
231
- logger.debug(
232
- { packageName, username },
233
- 'publishing package @{packageName} for user @{username}'
234
- );
235
-
236
- try {
237
- const message = await storage.updateManifest(metadata, {
238
- name: packageName,
239
- revision,
240
- signal: ac.signal,
241
- requestOptions: {
242
- host: req.hostname,
243
- protocol: req.protocol,
244
- headers: req.headers as { [key: string]: string },
245
- username,
246
- },
247
- uplinksLook: false,
248
- });
249
- debug('package %s published', packageName);
250
-
251
- res.status(HTTP_STATUS.CREATED);
252
-
253
- return next({
254
- success: true,
255
- ok: message,
256
- });
257
- } catch (err: any) {
258
- // TODO: review if we need the abort controller here
259
- next(err);
260
- }
261
- };
262
- }
package/src/search.ts DELETED
@@ -1,12 +0,0 @@
1
- import { HTTP_STATUS } from '@verdaccio/core';
2
- import { SEARCH_API_ENDPOINTS } from '@verdaccio/middleware';
3
- import { Logger } from '@verdaccio/types';
4
-
5
- export default function (route, logger: Logger): void {
6
- // TODO: next major version, remove this
7
- route.get(SEARCH_API_ENDPOINTS.deprecated_search, function (_req, res) {
8
- logger.warn('search endpoint has been removed, please use search v1');
9
- res.status(HTTP_STATUS.NOT_FOUND);
10
- res.json({ error: 'not found, endpoint was removed' });
11
- });
12
- }
package/src/stars.ts DELETED
@@ -1,37 +0,0 @@
1
- import { Response, Router } from 'express';
2
- import _ from 'lodash';
3
-
4
- import { HTTP_STATUS, USERS, errorUtils } from '@verdaccio/core';
5
- import { STARS_API_ENDPOINTS } from '@verdaccio/middleware';
6
- import { Storage } from '@verdaccio/store';
7
- import { Version } from '@verdaccio/types';
8
-
9
- import { $NextFunctionVer, $RequestExtend } from '../types/custom';
10
-
11
- export default function (route: Router, storage: Storage): void {
12
- route.get(
13
- STARS_API_ENDPOINTS.get_user_starred_packages,
14
- async (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> => {
15
- const query: { key: string } = req.query;
16
- if (typeof query?.key !== 'string') {
17
- return next(errorUtils.getBadRequest('missing query key username'));
18
- }
19
-
20
- try {
21
- const localPackages: Version[] = await storage.getLocalDatabase();
22
- const filteredPackages: Version[] = localPackages.filter((localPackage: Version) =>
23
- _.keys(localPackage[USERS]).includes(query?.key.toString().replace(/['"]+/g, ''))
24
- );
25
-
26
- res.status(HTTP_STATUS.OK);
27
- next({
28
- rows: filteredPackages.map((filteredPackage: Version) => ({
29
- value: filteredPackage.name,
30
- })),
31
- });
32
- } catch (err: any) {
33
- return next(err);
34
- }
35
- }
36
- );
37
- }