@verdaccio/store 6.0.0-6-next.21 → 6.0.0-6-next.24

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 (72) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/build/index.d.ts +5 -4
  3. package/build/index.js +31 -15
  4. package/build/index.js.map +1 -1
  5. package/build/lib/TransFormResults.d.ts +15 -0
  6. package/build/lib/TransFormResults.js +61 -0
  7. package/build/lib/TransFormResults.js.map +1 -0
  8. package/build/lib/search-utils.d.ts +4 -0
  9. package/build/lib/search-utils.js +59 -0
  10. package/build/lib/search-utils.js.map +1 -0
  11. package/build/lib/star-utils.d.ts +14 -0
  12. package/build/{star-utils.js → lib/star-utils.js} +16 -2
  13. package/build/lib/star-utils.js.map +1 -0
  14. package/build/lib/storage-utils.d.ts +82 -0
  15. package/build/{storage-utils.js → lib/storage-utils.js} +173 -60
  16. package/build/lib/storage-utils.js.map +1 -0
  17. package/build/lib/uplink-util.d.ts +10 -0
  18. package/build/lib/uplink-util.js +49 -0
  19. package/build/lib/uplink-util.js.map +1 -0
  20. package/build/lib/versions-utils.d.ts +28 -0
  21. package/build/lib/versions-utils.js +104 -0
  22. package/build/lib/versions-utils.js.map +1 -0
  23. package/build/local-storage.d.ts +3 -165
  24. package/build/local-storage.js +6 -1166
  25. package/build/local-storage.js.map +1 -1
  26. package/build/storage.d.ts +242 -86
  27. package/build/storage.js +1681 -548
  28. package/build/storage.js.map +1 -1
  29. package/build/type.d.ts +42 -19
  30. package/build/type.js.map +1 -1
  31. package/jest.config.js +8 -2
  32. package/package.json +71 -71
  33. package/src/index.ts +5 -4
  34. package/src/lib/TransFormResults.ts +42 -0
  35. package/src/lib/search-utils.ts +50 -0
  36. package/src/{star-utils.ts → lib/star-utils.ts} +16 -5
  37. package/src/lib/storage-utils.ts +362 -0
  38. package/src/lib/uplink-util.ts +41 -0
  39. package/src/lib/versions-utils.ts +87 -0
  40. package/src/local-storage.ts +7 -1217
  41. package/src/storage.ts +1683 -635
  42. package/src/type.ts +47 -21
  43. package/test/fixtures/config/getTarballNext-getupstream.yaml +17 -0
  44. package/test/fixtures/config/syncDoubleUplinksMetadata.yaml +25 -0
  45. package/test/fixtures/config/syncNoUplinksMetadata.yaml +17 -0
  46. package/test/fixtures/config/syncSingleUplinksMetadata.yaml +21 -0
  47. package/test/fixtures/config/updateManifest-1.yaml +16 -0
  48. package/test/fixtures/manifests/foo-npmjs.json +253 -0
  49. package/test/fixtures/manifests/foo-verdaccio.json +253 -0
  50. package/test/fixtures/tarball.tgz +0 -0
  51. package/test/helpers.ts +22 -0
  52. package/test/local-store.__disabled__.ts +553 -0
  53. package/test/search.spec.ts +4 -5
  54. package/test/star.spec.ts +31 -0
  55. package/test/storage-utils.spec.ts +129 -42
  56. package/test/storage.spec.ts +943 -33
  57. package/test/versions.spec.ts +109 -0
  58. package/tsconfig.json +6 -3
  59. package/build/search.d.ts +0 -35
  60. package/build/search.js +0 -198
  61. package/build/search.js.map +0 -1
  62. package/build/star-utils.d.ts +0 -9
  63. package/build/star-utils.js.map +0 -1
  64. package/build/storage-utils.d.ts +0 -39
  65. package/build/storage-utils.js.map +0 -1
  66. package/build/uplink-util.d.ts +0 -7
  67. package/build/uplink-util.js +0 -38
  68. package/build/uplink-util.js.map +0 -1
  69. package/src/search.ts +0 -175
  70. package/src/storage-utils.ts +0 -263
  71. package/src/uplink-util.ts +0 -32
  72. package/test/local-storage.spec.ts +0 -583
@@ -3,9 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.noSuchFile = exports.PROTO_NAME = exports.LocalStorage = void 0;
7
- exports.normalizeSearchPackage = normalizeSearchPackage;
8
- exports.resourceNotAvailable = void 0;
6
+ exports.resourceNotAvailable = exports.noSuchFile = exports.LocalStorage = void 0;
9
7
 
10
8
  var _assert = _interopRequireDefault(require("assert"));
11
9
 
@@ -13,20 +11,12 @@ var _debug = _interopRequireDefault(require("debug"));
13
11
 
14
12
  var _lodash = _interopRequireDefault(require("lodash"));
15
13
 
16
- var _url = _interopRequireDefault(require("url"));
17
-
18
14
  var _core = require("@verdaccio/core");
19
15
 
20
16
  var _loaders = require("@verdaccio/loaders");
21
17
 
22
18
  var _localStorage = _interopRequireDefault(require("@verdaccio/local-storage"));
23
19
 
24
- var _streams = require("@verdaccio/streams");
25
-
26
- var _utils = require("@verdaccio/utils");
27
-
28
- var _storageUtils = require("./storage-utils");
29
-
30
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
21
 
32
22
  const debug = (0, _debug.default)('verdaccio:storage:local');
@@ -35,45 +25,9 @@ exports.noSuchFile = noSuchFile;
35
25
  const resourceNotAvailable = 'EAGAIN';
36
26
  exports.resourceNotAvailable = resourceNotAvailable;
37
27
 
38
- function normalizeSearchPackage(pkg, searchItem) {
39
- const latest = _core.pkgUtils.getLatest(pkg);
40
-
41
- const version = pkg.versions[latest];
42
- const result = {
43
- name: version.name,
44
- scope: '',
45
- description: version.description,
46
- version: latest,
47
- keywords: version.keywords,
48
- date: pkg.time[latest],
49
- // FIXME: type
50
- author: version.author,
51
- // FIXME: not possible fill this out from a private package
52
- publisher: {},
53
- // FIXME: type
54
- maintainers: version.maintainers,
55
- links: {
56
- npm: '',
57
- homepage: version.homepage,
58
- repository: version.repository,
59
- bugs: version.bugs
60
- }
61
- };
62
-
63
- if (typeof searchItem.package.scoped === 'string') {
64
- result.scope = searchItem.package.scoped;
65
- }
66
-
67
- return result;
68
- }
69
-
70
- const PROTO_NAME = '__proto__';
71
28
  /**
72
29
  * Implements Storage interface (same for storage.js, local-storage.js, up-storage.js).
73
30
  */
74
-
75
- exports.PROTO_NAME = PROTO_NAME;
76
-
77
31
  class LocalStorage {
78
32
  constructor(config, logger) {
79
33
  debug('local storage created');
@@ -98,1102 +52,12 @@ class LocalStorage {
98
52
  return;
99
53
  }
100
54
 
101
- addPackage(name, pkg, callback) {
102
- debug(`creating a package for`, name);
103
-
104
- const storage = this._getLocalStorage(name);
105
-
106
- if (_lodash.default.isNil(storage)) {
107
- debug(`storage is missing for %o package cannot be added`, name);
108
- return callback(_core.errorUtils.getNotFound('this package cannot be added'));
109
- }
110
-
111
- storage.createPackage(name, (0, _storageUtils.generatePackageTemplate)(name), err => {
112
- if (_lodash.default.isNull(err) === false && (err.code === _storageUtils.STORAGE.FILE_EXIST_ERROR || err.code === _core.HTTP_STATUS.CONFLICT)) {
113
- debug(`error on creating a package for %o with error %o`, name, err.message);
114
- return callback(_core.errorUtils.getConflict());
115
- }
116
-
117
- const latest = (0, _utils.getLatestVersion)(pkg);
118
-
119
- if (_lodash.default.isNil(latest) === false && pkg.versions[latest]) {
120
- debug('latest version found %o for %o', latest, name);
121
- return callback(null, pkg.versions[latest]);
122
- }
123
-
124
- debug('no latest version found for %o', name);
125
- return callback();
126
- });
127
- }
128
- /**
129
- * Remove package with all it contents.
130
- */
131
-
132
-
133
- async removePackage(name) {
134
- debug('remove package %s', name);
135
-
136
- const storage = this._getLocalStorage(name);
137
-
138
- if (_lodash.default.isNil(storage)) {
139
- throw _core.errorUtils.getNotFound();
140
- }
141
-
142
- return new Promise((resolve, reject) => {
143
- storage.readPackage(name, async (err, data) => {
144
- if (_lodash.default.isNil(err) === false) {
145
- if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
146
- debug(`error on not found %o with error %o`, name, err.message);
147
- return reject(_core.errorUtils.getNotFound());
148
- }
149
-
150
- return reject(err);
151
- }
152
-
153
- data = (0, _storageUtils.normalizePackage)(data);
154
-
155
- try {
156
- await this.storagePlugin.remove(name); // remove each attachment
157
-
158
- const attachments = Object.keys(data._attachments);
159
- debug('attachments to remove %s', attachments === null || attachments === void 0 ? void 0 : attachments.length);
160
-
161
- for (let attachment of attachments) {
162
- debug('remove attachment %s', attachment);
163
- await storage.deletePackage(attachment);
164
- } // remove package.json
165
-
166
-
167
- debug('remove package.json');
168
- await storage.deletePackage(_storageUtils.STORAGE.PACKAGE_FILE_NAME); // remove folder
169
-
170
- debug('remove package folder');
171
- await storage.removePackage();
172
- resolve();
173
- } catch (err) {
174
- this.logger.error({
175
- err
176
- }, 'removed package has failed @{err.message}');
177
- throw _core.errorUtils.getBadData(err.message);
178
- }
179
- });
180
- });
181
- }
182
- /**
183
- * Synchronize remote package info with the local one
184
- * @param {*} name
185
- * @param {*} packageInfo
186
- * @param {*} callback
187
- */
188
-
189
-
190
- updateVersions(name, packageInfo, callback) {
191
- debug(`updating versions for package %o`, name);
192
-
193
- this._readCreatePackage(name, (err, packageLocalJson) => {
194
- if (err) {
195
- return callback(err);
196
- }
197
-
198
- let change = false; // updating readme
199
-
200
- packageLocalJson.readme = (0, _storageUtils.getLatestReadme)(packageInfo);
201
-
202
- if (packageInfo.readme !== packageLocalJson.readme) {
203
- change = true;
204
- }
205
-
206
- debug('update versions');
207
-
208
- for (const versionId in packageInfo.versions) {
209
- if (_lodash.default.isNil(packageLocalJson.versions[versionId])) {
210
- var _version, _version$dist;
211
-
212
- let version = packageInfo.versions[versionId]; // we don't keep readme for package versions,
213
- // only one readme per package
214
-
215
- version = (0, _storageUtils.cleanUpReadme)(version);
216
- debug('clean up readme for %o', versionId);
217
- version.contributors = (0, _utils.normalizeContributors)(version.contributors);
218
- change = true;
219
- packageLocalJson.versions[versionId] = version;
220
-
221
- if ((_version = version) !== null && _version !== void 0 && (_version$dist = _version.dist) !== null && _version$dist !== void 0 && _version$dist.tarball) {
222
- const urlObject = _url.default.parse(version.dist.tarball);
223
-
224
- const filename = urlObject.pathname.replace(/^.*\//, ''); // we do NOT overwrite any existing records
225
-
226
- if (_lodash.default.isNil(packageLocalJson._distfiles[filename])) {
227
- const hash = packageLocalJson._distfiles[filename] = {
228
- url: version.dist.tarball,
229
- sha: version.dist.shasum
230
- };
231
- const upLink = version[Symbol.for('__verdaccio_uplink')];
232
-
233
- if (_lodash.default.isNil(upLink) === false) {
234
- this._updateUplinkToRemoteProtocol(hash, upLink);
235
- }
236
- }
237
- }
238
- }
239
- }
240
-
241
- debug('update dist-tags');
242
-
243
- for (const tag in packageInfo[_core.DIST_TAGS]) {
244
- if (!packageLocalJson[_core.DIST_TAGS][tag] || packageLocalJson[_core.DIST_TAGS][tag] !== packageInfo[_core.DIST_TAGS][tag]) {
245
- change = true;
246
- packageLocalJson[_core.DIST_TAGS][tag] = packageInfo[_core.DIST_TAGS][tag];
247
- }
248
- }
249
-
250
- for (const up in packageInfo._uplinks) {
251
- if (Object.prototype.hasOwnProperty.call(packageInfo._uplinks, up)) {
252
- const need_change = !(0, _utils.isObject)(packageLocalJson._uplinks[up]) || packageInfo._uplinks[up].etag !== packageLocalJson._uplinks[up].etag || packageInfo._uplinks[up].fetched !== packageLocalJson._uplinks[up].fetched;
253
-
254
- if (need_change) {
255
- change = true;
256
- packageLocalJson._uplinks[up] = packageInfo._uplinks[up];
257
- }
258
- }
259
- }
260
-
261
- debug('update time');
262
-
263
- if ('time' in packageInfo && !_lodash.default.isEqual(packageLocalJson.time, packageInfo.time)) {
264
- packageLocalJson.time = packageInfo.time;
265
- change = true;
266
- }
267
-
268
- if (change) {
269
- debug('updating package info %o', name);
270
-
271
- this._writePackage(name, packageLocalJson, function (err) {
272
- callback(err, packageLocalJson);
273
- });
274
- } else {
275
- callback(null, packageLocalJson);
276
- }
277
- });
278
- }
279
- /**
280
- * Add a new version to a previous local package.
281
- * @param {*} name
282
- * @param {*} version
283
- * @param {*} metadata
284
- * @param {*} tag
285
- * @param {*} callback
286
- */
287
-
288
-
289
- addVersion(name, version, metadata, tag, callback) {
290
- debug(`add version %s package for %s`, version, name);
291
-
292
- this._updatePackage(name, async (data, cb) => {
293
- debug('%s package is being updated', name); // keep only one readme per package
294
-
295
- data.readme = metadata.readme;
296
- debug('%s` readme mutated', name); // TODO: lodash remove
297
-
298
- metadata = (0, _storageUtils.cleanUpReadme)(metadata);
299
- metadata.contributors = (0, _utils.normalizeContributors)(metadata.contributors);
300
- debug('%s` contributors normalized', name);
301
- const hasVersion = data.versions[version] != null;
302
-
303
- if (hasVersion) {
304
- debug('%s version %s already exists', name, version);
305
- return cb(_core.errorUtils.getConflict());
306
- } // if uploaded tarball has a different shasum, it's very likely that we
307
- // have some kind of error
308
-
309
-
310
- if (_core.validatioUtils.isObject(metadata.dist) && _lodash.default.isString(metadata.dist.tarball)) {
311
- const tarball = metadata.dist.tarball.replace(/.*\//, '');
312
-
313
- if (_core.validatioUtils.isObject(data._attachments[tarball])) {
314
- if (_lodash.default.isNil(data._attachments[tarball].shasum) === false && _lodash.default.isNil(metadata.dist.shasum) === false) {
315
- if (data._attachments[tarball].shasum != metadata.dist.shasum) {
316
- const errorMessage = `shasum error, ` + `${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
317
- return cb(_core.errorUtils.getBadRequest(errorMessage));
318
- }
319
- }
320
-
321
- const currentDate = new Date().toISOString(); // some old storage do not have this field #740
322
-
323
- if (_lodash.default.isNil(data.time)) {
324
- data.time = {};
325
- }
326
-
327
- data.time['modified'] = currentDate;
328
-
329
- if ('created' in data.time === false) {
330
- data.time.created = currentDate;
331
- }
332
-
333
- data.time[version] = currentDate;
334
- data._attachments[tarball].version = version;
335
- }
336
- }
337
-
338
- data.versions[version] = metadata;
339
- (0, _storageUtils.tagVersion)(data, version, tag);
340
-
341
- try {
342
- debug('%s` add on database', name);
343
- await this.storagePlugin.add(name);
344
- cb();
345
- } catch (err) {
346
- cb(_core.errorUtils.getBadData(err.message));
347
- }
348
- }, callback);
349
- }
350
-
351
- async addVersionNext(name, version, metadata, tag) {
352
- debug(`add version %s package for %s`, version, name);
353
- await this.updatePackageNext(name, async data => {
354
- debug('%s package is being updated', name); // keep only one readme per package
355
-
356
- data.readme = metadata.readme;
357
- debug('%s` readme mutated', name); // TODO: lodash remove
358
-
359
- metadata = (0, _storageUtils.cleanUpReadme)(metadata);
360
- metadata.contributors = (0, _utils.normalizeContributors)(metadata.contributors);
361
- debug('%s` contributors normalized', name);
362
- const hasVersion = data.versions[version] != null;
363
-
364
- if (hasVersion) {
365
- debug('%s version %s already exists', name, version);
366
- throw _core.errorUtils.getConflict();
367
- } // if uploaded tarball has a different shasum, it's very likely that we
368
- // have some kind of error
369
-
370
-
371
- if (_core.validatioUtils.isObject(metadata.dist) && _lodash.default.isString(metadata.dist.tarball)) {
372
- const tarball = metadata.dist.tarball.replace(/.*\//, '');
373
-
374
- if (_core.validatioUtils.isObject(data._attachments[tarball])) {
375
- if (_lodash.default.isNil(data._attachments[tarball].shasum) === false && _lodash.default.isNil(metadata.dist.shasum) === false) {
376
- if (data._attachments[tarball].shasum != metadata.dist.shasum) {
377
- const errorMessage = `shasum error, ` + `${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
378
- throw _core.errorUtils.getBadRequest(errorMessage);
379
- }
380
- }
381
-
382
- const currentDate = new Date().toISOString(); // some old storage do not have this field #740
383
-
384
- if (_lodash.default.isNil(data.time)) {
385
- data.time = {};
386
- }
387
-
388
- data.time['modified'] = currentDate;
389
-
390
- if ('created' in data.time === false) {
391
- data.time.created = currentDate;
392
- }
393
-
394
- data.time[version] = currentDate;
395
- data._attachments[tarball].version = version;
396
- }
397
- }
398
-
399
- data.versions[version] = metadata;
400
- (0, _storageUtils.tagVersion)(data, version, tag);
401
-
402
- try {
403
- debug('%s` add on database', name);
404
- await this.storagePlugin.add(name);
405
- } catch (err) {
406
- throw _core.errorUtils.getBadData(err.message);
407
- }
408
-
409
- return data;
410
- }); // this._updatePackage(
411
- // name,
412
- // async (data, cb: Callback): Promise<void> => {
413
- // debug('%s package is being updated', name);
414
- // // keep only one readme per package
415
- // data.readme = metadata.readme;
416
- // debug('%s` readme mutated', name);
417
- // // TODO: lodash remove
418
- // metadata = cleanUpReadme(metadata);
419
- // metadata.contributors = normalizeContributors(metadata.contributors as Author[]);
420
- // debug('%s` contributors normalized', name);
421
- // const hasVersion = data.versions[version] != null;
422
- // if (hasVersion) {
423
- // debug('%s version %s already exists', name, version);
424
- // return cb(errorUtils.getConflict());
425
- // }
426
- // // if uploaded tarball has a different shasum, it's very likely that we
427
- // // have some kind of error
428
- // if (validatioUtils.isObject(metadata.dist) && _.isString(metadata.dist.tarball)) {
429
- // const tarball = metadata.dist.tarball.replace(/.*\//, '');
430
- // if (validatioUtils.isObject(data._attachments[tarball])) {
431
- // if (
432
- // _.isNil(data._attachments[tarball].shasum) === false &&
433
- // _.isNil(metadata.dist.shasum) === false
434
- // ) {
435
- // if (data._attachments[tarball].shasum != metadata.dist.shasum) {
436
- // const errorMessage =
437
- // `shasum error, ` +
438
- // `${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
439
- // return cb(errorUtils.getBadRequest(errorMessage));
440
- // }
441
- // }
442
- // const currentDate = new Date().toISOString();
443
- // // some old storage do not have this field #740
444
- // if (_.isNil(data.time)) {
445
- // data.time = {};
446
- // }
447
- // data.time['modified'] = currentDate;
448
- // if ('created' in data.time === false) {
449
- // data.time.created = currentDate;
450
- // }
451
- // data.time[version] = currentDate;
452
- // data._attachments[tarball].version = version;
453
- // }
454
- // }
455
- // data.versions[version] = metadata;
456
- // tagVersion(data, version, tag);
457
- // try {
458
- // debug('%s` add on database', name);
459
- // await this.storagePlugin.add(name);
460
- // cb();
461
- // } catch (err: any) {
462
- // cb(errorUtils.getBadData(err.message));
463
- // }
464
- // },
465
- // callback
466
- // );
467
- }
468
- /**
469
- * Merge a new list of tags for a local packages with the existing one.
470
- * @param {*} pkgName
471
- * @param {*} tags
472
- * @param {*} callback
473
- */
474
-
475
-
476
- mergeTags(pkgName, tags, callback) {
477
- debug(`merge tags for`, pkgName);
478
-
479
- this._updatePackage(pkgName, (data, cb) => {
480
- /* eslint guard-for-in: 0 */
481
- for (const tag in tags) {
482
- // this handle dist-tag rm command
483
- if (_lodash.default.isNull(tags[tag])) {
484
- delete data[_core.DIST_TAGS][tag];
485
- continue;
486
- }
487
-
488
- if (_lodash.default.isNil(data.versions[tags[tag]])) {
489
- return cb(_core.errorUtils.getNotFound(_core.API_ERROR.VERSION_NOT_EXIST));
490
- }
491
-
492
- const version = tags[tag];
493
- (0, _storageUtils.tagVersion)(data, version, tag);
494
- }
495
-
496
- cb(null);
497
- }, callback);
498
- }
499
- /**
500
- * Update the package metadata, tags and attachments (tarballs).
501
- * Note: Currently supports unpublishing and deprecation.
502
- * @param {*} name
503
- * @param {*} incomingPkg
504
- * @param {*} revision
505
- * @param {*} callback
506
- * @return {Function}
507
- */
508
-
509
-
510
- changePackage(name, incomingPkg, revision, callback) {
511
- debug(`change package tags for %o revision %s`, name, revision);
512
-
513
- if (!_core.validatioUtils.isObject(incomingPkg.versions) || !_core.validatioUtils.isObject(incomingPkg[_core.DIST_TAGS])) {
514
- debug(`change package bad data for %o`, name);
515
- return callback(_core.errorUtils.getBadData());
516
- }
517
-
518
- debug(`change package udapting package for %o`, name);
519
-
520
- this._updatePackage(name, (localData, cb) => {
521
- for (const version in localData.versions) {
522
- const incomingVersion = incomingPkg.versions[version];
523
-
524
- if (_lodash.default.isNil(incomingVersion)) {
525
- this.logger.info({
526
- name: name,
527
- version: version
528
- }, 'unpublishing @{name}@@{version}'); // FIXME: I prefer return a new object rather mutate the metadata
529
-
530
- delete localData.versions[version];
531
- delete localData.time[version];
532
-
533
- for (const file in localData._attachments) {
534
- if (localData._attachments[file].version === version) {
535
- delete localData._attachments[file].version;
536
- }
537
- }
538
- } else if (Object.prototype.hasOwnProperty.call(incomingVersion, 'deprecated')) {
539
- const incomingDeprecated = incomingVersion.deprecated;
540
-
541
- if (incomingDeprecated != localData.versions[version].deprecated) {
542
- if (!incomingDeprecated) {
543
- this.logger.info({
544
- name: name,
545
- version: version
546
- }, 'undeprecating @{name}@@{version}');
547
- delete localData.versions[version].deprecated;
548
- } else {
549
- this.logger.info({
550
- name: name,
551
- version: version
552
- }, 'deprecating @{name}@@{version}');
553
- localData.versions[version].deprecated = incomingDeprecated;
554
- }
555
-
556
- localData.time.modified = new Date().toISOString();
557
- }
558
- }
559
- }
560
-
561
- localData[_core.USERS] = incomingPkg[_core.USERS];
562
- localData[_core.DIST_TAGS] = incomingPkg[_core.DIST_TAGS];
563
- cb(null);
564
- }, function (err) {
565
- if (err) {
566
- return callback(err);
567
- }
568
-
569
- callback();
570
- });
571
- }
572
- /**
573
- * Update the package metadata, tags and attachments (tarballs).
574
- * Note: Currently supports unpublishing and deprecation.
575
- * @param {*} name
576
- * @param {*} incomingPkg
577
- * @param {*} revision
578
- * @param {*} callback
579
- * @return {Function}
580
- */
581
-
582
-
583
- async changePackageNext(name, incomingPkg, revision) {
584
- debug(`change package tags for %o revision %s`, name, revision);
585
-
586
- if (!_core.validatioUtils.isObject(incomingPkg.versions) || !_core.validatioUtils.isObject(incomingPkg[_core.DIST_TAGS])) {
587
- debug(`change package bad data for %o`, name);
588
- throw _core.errorUtils.getBadData();
589
- }
590
-
591
- debug(`change package udapting package for %o`, name);
592
- await this.updatePackageNext(name, async localData => {
593
- for (const version in localData.versions) {
594
- const incomingVersion = incomingPkg.versions[version];
595
-
596
- if (_lodash.default.isNil(incomingVersion)) {
597
- this.logger.info({
598
- name: name,
599
- version: version
600
- }, 'unpublishing @{name}@@{version}'); // FIXME: I prefer return a new object rather mutate the metadata
601
-
602
- delete localData.versions[version];
603
- delete localData.time[version];
604
-
605
- for (const file in localData._attachments) {
606
- if (localData._attachments[file].version === version) {
607
- delete localData._attachments[file].version;
608
- }
609
- }
610
- } else if (Object.prototype.hasOwnProperty.call(incomingVersion, 'deprecated')) {
611
- const incomingDeprecated = incomingVersion.deprecated;
612
-
613
- if (incomingDeprecated != localData.versions[version].deprecated) {
614
- if (!incomingDeprecated) {
615
- this.logger.info({
616
- name: name,
617
- version: version
618
- }, 'undeprecating @{name}@@{version}');
619
- delete localData.versions[version].deprecated;
620
- } else {
621
- this.logger.info({
622
- name: name,
623
- version: version
624
- }, 'deprecating @{name}@@{version}');
625
- localData.versions[version].deprecated = incomingDeprecated;
626
- }
627
-
628
- localData.time.modified = new Date().toISOString();
629
- }
630
- }
631
- }
632
-
633
- localData[_core.USERS] = incomingPkg[_core.USERS];
634
- localData[_core.DIST_TAGS] = incomingPkg[_core.DIST_TAGS];
635
- return localData;
636
- });
637
- }
638
- /**
639
- * Remove a tarball.
640
- * @param {*} name
641
- * @param {*} filename
642
- * @param {*} revision
643
- * @param {*} callback
644
- */
645
-
646
-
647
- removeTarball(name, filename, revision, callback) {
648
- debug('remove tarball %s for %s', filename, name);
649
- (0, _assert.default)(_core.validatioUtils.validateName(filename));
650
-
651
- this._updatePackage(name, (data, cb) => {
652
- if (data._attachments[filename]) {
653
- // TODO: avoid using delete
654
- delete data._attachments[filename];
655
- cb(null);
656
- } else {
657
- cb(_core.errorUtils.getNotFound('no such file available'));
658
- }
659
- }, err => {
660
- if (err) {
661
- this.logger.error({
662
- err
663
- }, 'remove tarball error @{err.message}');
664
- return callback(err);
665
- }
666
-
667
- const storage = this._getLocalStorage(name);
668
-
669
- if (storage) {
670
- debug('removing %s from storage', filename);
671
- storage.deletePackage(filename).then(() => {
672
- debug('package %s removed', filename);
673
- return callback(null);
674
- }).catch(err => {
675
- this.logger.error({
676
- err
677
- }, 'error removing %s from storage');
678
- return callback(null);
679
- });
680
- } else {
681
- callback(_core.errorUtils.getInternalError());
682
- }
683
- });
684
- }
685
- /**
686
- * Add a tarball.
687
- * @param {String} name
688
- * @param {String} filename
689
- * @return {Stream}
690
- */
691
-
692
-
693
- addTarball(name, filename) {
694
- debug(`add a tarball for %o`, name);
695
- (0, _assert.default)(_core.validatioUtils.validateName(filename));
696
- let length = 0;
697
- const shaOneHash = (0, _utils.createTarballHash)();
698
- const uploadStream = new _streams.UploadTarball({});
699
- const _transform = uploadStream._transform;
700
-
701
- const storage = this._getLocalStorage(name);
702
-
703
- uploadStream.abort = function () {};
704
-
705
- uploadStream.done = function () {};
706
-
707
- uploadStream._transform = function (data, ...args) {
708
- shaOneHash.update(data); // measure the length for validation reasons
709
-
710
- length += data.length;
711
- const appliedData = [data, ...args]; // FIXME: not sure about this approach, tsc complains
712
- // @ts-ignore
713
-
714
- _transform.apply(uploadStream, appliedData);
715
- };
716
-
717
- if (name === PROTO_NAME) {
718
- process.nextTick(() => {
719
- uploadStream.emit('error', _core.errorUtils.getForbidden());
720
- });
721
- return uploadStream;
722
- } // FIXME: this condition will never met, storage is always defined
723
-
724
-
725
- if (!storage) {
726
- process.nextTick(() => {
727
- uploadStream.emit('error', "can't upload this package");
728
- });
729
- return uploadStream;
730
- }
731
-
732
- const writeStream = storage.writeTarball(filename);
733
- writeStream.on('error', err => {
734
- // @ts-ignore
735
- if (err.code === _storageUtils.STORAGE.FILE_EXIST_ERROR || err.code === _core.HTTP_STATUS.CONFLICT) {
736
- uploadStream.emit('error', _core.errorUtils.getConflict());
737
- uploadStream.abort(); // @ts-ignore
738
- } else if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
739
- // check if package exists to throw an appropriate message
740
- this.getPackageMetadata(name, function (_err) {
741
- if (_err) {
742
- uploadStream.emit('error', _err);
743
- } else {
744
- uploadStream.emit('error', err);
745
- }
746
- });
747
- } else {
748
- uploadStream.emit('error', err);
749
- }
750
- });
751
- writeStream.on('open', function () {
752
- // re-emitting open because it's handled in storage.js
753
- uploadStream.emit('open');
754
- });
755
- writeStream.on('success', () => {
756
- this._updatePackage(name, function updater(data, cb) {
757
- // FUTURE: move this to tarballUtils
758
- data._attachments[filename] = {
759
- shasum: shaOneHash.digest('hex')
760
- };
761
- cb(null);
762
- }, function (err) {
763
- if (err) {
764
- // FIXME: if the update package fails, remove tarball to avoid left
765
- // orphan tarballs
766
- uploadStream.emit('error', err);
767
- } else {
768
- uploadStream.emit('success');
769
- }
770
- });
771
- });
772
-
773
- uploadStream.abort = function () {
774
- writeStream.abort();
775
- };
776
-
777
- uploadStream.done = function () {
778
- if (!length) {
779
- uploadStream.emit('error', _core.errorUtils.getBadData('refusing to accept zero-length file'));
780
- writeStream.abort();
781
- } else {
782
- writeStream.done();
783
- }
784
- };
785
-
786
- uploadStream.pipe(writeStream);
787
- return uploadStream;
788
- }
789
- /**
790
- * Get a tarball.
791
- * @param {*} name
792
- * @param {*} filename
793
- * @return {ReadTarball}
794
- */
795
-
796
-
797
- getTarball(name, filename) {
798
- (0, _assert.default)(_core.validatioUtils.validateName(filename));
799
-
800
- const storage = this._getLocalStorage(name);
801
-
802
- if (_lodash.default.isNil(storage)) {
803
- return this._createFailureStreamResponse();
804
- }
805
-
806
- return this._streamSuccessReadTarBall(storage, filename);
807
- }
808
- /**
809
- * Return a stream that emits a read failure.
810
- * @private
811
- * @return {ReadTarball}
812
- */
813
-
814
-
815
- _createFailureStreamResponse() {
816
- const stream = new _streams.ReadTarball({});
817
- process.nextTick(() => {
818
- stream.emit('error', _core.errorUtils.getNotFound('no such file available'));
819
- });
820
- return stream;
821
- }
822
- /**
823
- * Return a stream that emits the tarball data
824
- * @param {Object} storage
825
- * @param {String} filename
826
- * @private
827
- * @return {ReadTarball}
828
- */
829
-
830
-
831
- _streamSuccessReadTarBall(storage, filename) {
832
- const stream = new _streams.ReadTarball({});
833
- const readTarballStream = storage.readTarball(filename);
834
- const e404 = _core.errorUtils.getNotFound;
835
-
836
- stream.abort = function () {
837
- if (_lodash.default.isNil(readTarballStream) === false) {
838
- readTarballStream.abort();
839
- }
840
- };
841
-
842
- readTarballStream.on('error', function (err) {
843
- // @ts-ignore
844
- if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
845
- stream.emit('error', e404('no such file available'));
846
- } else {
847
- stream.emit('error', err);
848
- }
849
- });
850
- readTarballStream.on('content-length', function (content) {
851
- stream.emit('content-length', content);
852
- });
853
- readTarballStream.on('open', function () {
854
- // re-emitting open because it's handled in storage.js
855
- stream.emit('open');
856
- readTarballStream.pipe(stream);
857
- });
858
- return stream;
859
- }
860
-
861
- async getPackageMetadataNext(name) {
862
- const storage = this._getLocalStorage(name);
863
-
864
- debug('get package metadata for %o', name);
865
-
866
- if (typeof storage === 'undefined') {
867
- // TODO: this might be a better an error to throw
868
- // if storage is not there cannot be 404.
869
- throw _core.errorUtils.getNotFound();
870
- }
871
-
872
- return await this._readPackageNext(name, storage);
873
- }
874
- /**
875
- * Retrieve a package by name.
876
- * @param {*} name
877
- * @param {*} callback
878
- * @return {Function}
879
- * @deprecated
880
- */
881
-
882
-
883
- getPackageMetadata(name, callback = () => {}) {
884
- const storage = this._getLocalStorage(name);
885
-
886
- debug('get package metadata for %o', name);
887
-
888
- if (typeof storage === 'undefined') {
889
- return callback(_core.errorUtils.getNotFound());
890
- }
891
-
892
- this._readPackage(name, storage, callback);
893
- }
894
-
895
- async search(searchStream, query) {
896
- debug('search on each package');
897
- this.logger.info({
898
- t: query.text,
899
- q: query.quality,
900
- p: query.popularity,
901
- m: query.maintenance,
902
- s: query.size
903
- }, 'search by text @{t}| maintenance @{m}| quality @{q}| popularity @{p}');
904
-
905
- const getMetadata = searchItem => {
906
- return new Promise((resolve, reject) => {
907
- var _searchItem$package;
908
-
909
- this.getPackageMetadata(searchItem === null || searchItem === void 0 ? void 0 : (_searchItem$package = searchItem.package) === null || _searchItem$package === void 0 ? void 0 : _searchItem$package.name, (err, pkg) => {
910
- var _searchItem$package3;
911
-
912
- if (err) {
913
- var _searchItem$package2;
914
-
915
- this.logger.error({
916
- err,
917
- pkgName: searchItem === null || searchItem === void 0 ? void 0 : (_searchItem$package2 = searchItem.package) === null || _searchItem$package2 === void 0 ? void 0 : _searchItem$package2.name
918
- }, 'error on load package @{pkgName} metaadata @{err.message}');
919
- reject(err);
920
- }
921
-
922
- if (_lodash.default.isEmpty(pkg === null || pkg === void 0 ? void 0 : pkg.versions)) {
923
- return resolve({});
924
- }
925
-
926
- const searchPackage = normalizeSearchPackage(pkg, searchItem);
927
- const searchPackageItem = {
928
- package: searchPackage,
929
- score: searchItem.score,
930
- verdaccioPkgCached: searchItem.verdaccioPkgCached,
931
- verdaccioPrivate: searchItem.verdaccioPrivate,
932
- flags: searchItem === null || searchItem === void 0 ? void 0 : searchItem.flags,
933
- // FUTURE: find a better way to calculate the score
934
- searchScore: 1
935
- };
936
- debug('push to stream %o', searchItem === null || searchItem === void 0 ? void 0 : (_searchItem$package3 = searchItem.package) === null || _searchItem$package3 === void 0 ? void 0 : _searchItem$package3.name);
937
- resolve(searchPackageItem);
938
- });
939
- });
940
- };
941
-
942
- if (typeof this.storagePlugin.search === 'undefined') {
943
- this.logger.info('plugin search not implemented yet');
944
- searchStream.end();
945
- } else {
946
- debug('search on each package by plugin');
947
- const items = await this.storagePlugin.search(query);
948
-
949
- try {
950
- for (const item of items) {
951
- const metadata = await getMetadata(item);
952
- searchStream.write(metadata);
953
- }
954
-
955
- debug('search local stream end');
956
- searchStream.end();
957
- } catch (err) {
958
- this.logger.error({
959
- err,
960
- query
961
- }, 'error on search by plugin @{err.message}');
962
- searchStream.emit('error', err);
963
- }
964
- }
965
- }
966
- /**
967
- * Retrieve a wrapper that provide access to the package location.
968
- * @param {Object} pkgName package name.
969
- * @return {Object}
970
- */
971
-
972
-
973
- _getLocalStorage(pkgName) {
974
- debug('get local storage for %o', pkgName);
975
- return this.storagePlugin.getPackageStorage(pkgName);
976
- }
977
- /**
978
- * Read a json file from storage.
979
- * @param {Object} storage
980
- * @param {Function} callback
981
- * @deprecated
982
- */
983
-
984
-
985
- _readPackage(name, storage, callback) {
986
- storage.readPackage(name, (err, result) => {
987
- if (err) {
988
- if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
989
- debug('package %s not found', name);
990
- return callback(_core.errorUtils.getNotFound());
991
- }
992
-
993
- return callback(this._internalError(err, _storageUtils.STORAGE.PACKAGE_FILE_NAME, 'error reading'));
994
- }
995
-
996
- callback(err, (0, _storageUtils.normalizePackage)(result));
997
- });
998
- }
999
-
1000
- async _readPackageNext(name, storage) {
1001
- try {
1002
- const result = await storage.readPackageNext(name);
1003
- return (0, _storageUtils.normalizePackage)(result);
1004
- } catch (err) {
1005
- if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
1006
- debug('package %s not found', name);
1007
- throw _core.errorUtils.getNotFound();
1008
- }
1009
-
1010
- this.logger.error({
1011
- err: err,
1012
- file: _storageUtils.STORAGE.PACKAGE_FILE_NAME
1013
- }, `error reading @{file}: @{!err.message}`);
1014
- throw _core.errorUtils.getInternalError();
1015
- }
1016
- }
1017
- /**
1018
- * Retrieve either a previous created local package or a boilerplate.
1019
- * @param {*} pkgName
1020
- * @param {*} callback
1021
- * @return {Function}
1022
- */
1023
-
1024
-
1025
- _readCreatePackage(pkgName, callback) {
1026
- const storage = this._getLocalStorage(pkgName);
1027
-
1028
- if (_lodash.default.isNil(storage)) {
1029
- this._createNewPackage(pkgName, callback);
1030
-
1031
- return;
1032
- }
1033
-
1034
- storage.readPackage(pkgName, (err, data) => {
1035
- // TODO: race condition
1036
- if (_lodash.default.isNil(err) === false) {
1037
- if (err.code === _storageUtils.STORAGE.NO_SUCH_FILE_ERROR || err.code === _core.HTTP_STATUS.NOT_FOUND) {
1038
- data = (0, _storageUtils.generatePackageTemplate)(pkgName);
1039
- } else {
1040
- return callback(this._internalError(err, _storageUtils.STORAGE.PACKAGE_FILE_NAME, 'error reading'));
1041
- }
1042
- }
1043
-
1044
- callback(null, (0, _storageUtils.normalizePackage)(data));
1045
- });
1046
- }
1047
-
1048
- _createNewPackage(name, callback) {
1049
- return callback(null, (0, _storageUtils.normalizePackage)((0, _storageUtils.generatePackageTemplate)(name)));
1050
- }
1051
- /**
1052
- * Handle internal error
1053
- * @param {*} err
1054
- * @param {*} file
1055
- * @param {*} message
1056
- * @return {Object} Error instance
1057
- */
1058
-
1059
-
1060
- _internalError(err, file, message) {
1061
- this.logger.error({
1062
- err: err,
1063
- file: file
1064
- }, `${message} @{file}: @{!err.message}`);
1065
- return _core.errorUtils.getInternalError();
1066
- }
1067
- /**
1068
- * @param {*} name package name
1069
- * @param {*} updateHandler function(package, cb) - update function
1070
- * @param {*} callback callback that gets invoked after it's all updated
1071
- * @return {Function}
1072
- */
1073
-
1074
-
1075
- _updatePackage(name, updateHandler, onEnd) {
1076
- const storage = this._getLocalStorage(name);
1077
-
1078
- if (!storage) {
1079
- return onEnd(_core.errorUtils.getNotFound());
1080
- }
1081
-
1082
- storage.updatePackage(name, updateHandler, this._writePackage.bind(this), _storageUtils.normalizePackage, onEnd);
1083
- }
1084
- /**
1085
- * @param {*} name package name
1086
- * @param {*} updateHandler function(package, cb) - update function
1087
- * @param {*} callback callback that gets invoked after it's all updated
1088
- * @return {Function}
1089
- */
1090
-
1091
-
1092
- async updatePackageNext(name, updateHandler) {
1093
- const storage = this._getLocalStorage(name);
1094
-
1095
- if (!storage) {
1096
- throw _core.errorUtils.getNotFound();
1097
- } // we update the package on the local storage
1098
-
1099
-
1100
- const updatedManifest = await storage.updatePackageNext(name, updateHandler); // after correctly updated write to the storage
1101
-
1102
- try {
1103
- await this.writePackageNext(name, (0, _storageUtils.normalizePackage)(updatedManifest));
1104
- } catch (err) {
1105
- if (err.code === resourceNotAvailable) {
1106
- throw _core.errorUtils.getInternalError('resource temporarily unavailable');
1107
- } else if (err.code === noSuchFile) {
1108
- throw _core.errorUtils.getNotFound();
1109
- } else {
1110
- throw err;
1111
- }
1112
- }
1113
- }
1114
- /**
1115
- * Update the revision (_rev) string for a package.
1116
- * @param {*} name
1117
- * @param {*} json
1118
- * @param {*} callback
1119
- * @return {Function}
1120
- */
1121
-
1122
-
1123
- _writePackage(name, json, callback) {
1124
- const storage = this._getLocalStorage(name);
1125
-
1126
- if (_lodash.default.isNil(storage)) {
1127
- return callback();
1128
- }
1129
-
1130
- storage.savePackage(name, this._setDefaultRevision(json), callback);
1131
- }
1132
-
1133
- async writePackageNext(name, json) {
1134
- const storage = this._getLocalStorage(name);
1135
-
1136
- if (_lodash.default.isNil(storage)) {
1137
- // TODO: replace here 500 error
1138
- throw _core.errorUtils.getBadData();
55
+ getStoragePlugin() {
56
+ if (this.storagePlugin === null) {
57
+ throw _core.errorUtils.getInternalError('storage plugin is not initialized');
1139
58
  }
1140
59
 
1141
- await storage.savePackageNext(name, this._setDefaultRevision(json));
1142
- }
1143
-
1144
- _setDefaultRevision(json) {
1145
- // calculate revision from couch db
1146
- if (_lodash.default.isString(json._rev) === false) {
1147
- json._rev = _storageUtils.STORAGE.DEFAULT_REVISION;
1148
- } // this is intended in debug mode we do not want modify the store revision
1149
-
1150
-
1151
- if (_lodash.default.isNil(this.config._debug)) {
1152
- json._rev = (0, _storageUtils.generateRevision)(json._rev);
1153
- }
1154
-
1155
- return json;
1156
- } // private _deleteAttachments(storage: any, attachments: string[], callback: Callback): void {
1157
- // debug('deleting %o attachments total %o', attachments?.length);
1158
- // const unlinkNext = function (cb): void {
1159
- // if (_.isEmpty(attachments)) {
1160
- // return cb();
1161
- // }
1162
- // const attachment = attachments.shift();
1163
- // storage.deletePackage(attachment, function (): void {
1164
- // unlinkNext(cb);
1165
- // });
1166
- // };
1167
- // unlinkNext(function (): void {
1168
- // // try to unlink the directory, but ignore errors because it can fail
1169
- // storage.removePackage(function (err): void {
1170
- // callback(err);
1171
- // });
1172
- // });
1173
- // }
1174
-
1175
- /**
1176
- * Ensure the dist file remains as the same protocol
1177
- * @param {Object} hash metadata
1178
- * @param {String} upLinkKey registry key
1179
- * @private
1180
- */
1181
-
1182
-
1183
- _updateUplinkToRemoteProtocol(hash, upLinkKey) {
1184
- // if we got this information from a known registry,
1185
- // use the same protocol for the tarball
1186
- //
1187
- // see https://github.com/rlidwka/sinopia/issues/166
1188
- const tarballUrl = _url.default.parse(hash.url);
1189
-
1190
- const uplinkUrl = _url.default.parse(this.config.uplinks[upLinkKey].url);
1191
-
1192
- if (uplinkUrl.host === tarballUrl.host) {
1193
- tarballUrl.protocol = uplinkUrl.protocol;
1194
- hash.registry = upLinkKey;
1195
- hash.url = _url.default.format(tarballUrl);
1196
- }
60
+ return this.storagePlugin;
1197
61
  }
1198
62
 
1199
63
  async getSecret(config) {
@@ -1206,7 +70,7 @@ class LocalStorage {
1206
70
 
1207
71
  if (_lodash.default.isNil(Storage)) {
1208
72
  (0, _assert.default)(this.config.storage, 'CONFIG: storage path not defined');
1209
- return new _localStorage.default(this.config, logger);
73
+ return new _localStorage.default(config, logger);
1210
74
  }
1211
75
 
1212
76
  return Storage;
@@ -1223,30 +87,6 @@ class LocalStorage {
1223
87
  return _lodash.default.head(plugins);
1224
88
  }
1225
89
 
1226
- saveToken(token) {
1227
- if (_lodash.default.isFunction(this.storagePlugin.saveToken) === false) {
1228
- return Promise.reject(_core.errorUtils.getCode(_core.HTTP_STATUS.SERVICE_UNAVAILABLE, _core.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
1229
- }
1230
-
1231
- return this.storagePlugin.saveToken(token);
1232
- }
1233
-
1234
- deleteToken(user, tokenKey) {
1235
- if (_lodash.default.isFunction(this.storagePlugin.deleteToken) === false) {
1236
- return Promise.reject(_core.errorUtils.getCode(_core.HTTP_STATUS.SERVICE_UNAVAILABLE, _core.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
1237
- }
1238
-
1239
- return this.storagePlugin.deleteToken(user, tokenKey);
1240
- }
1241
-
1242
- readTokens(filter) {
1243
- if (_lodash.default.isFunction(this.storagePlugin.readTokens) === false) {
1244
- return Promise.reject(_core.errorUtils.getCode(_core.HTTP_STATUS.SERVICE_UNAVAILABLE, _core.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
1245
- }
1246
-
1247
- return this.storagePlugin.readTokens(filter);
1248
- }
1249
-
1250
90
  }
1251
91
 
1252
92
  exports.LocalStorage = LocalStorage;