@verdaccio/store 7.0.0-next.6 → 8.0.0-next-8.0

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 (47) hide show
  1. package/CHANGELOG.md +340 -0
  2. package/README.md +24 -57
  3. package/build/index.d.ts +0 -1
  4. package/build/index.js +0 -12
  5. package/build/index.js.map +1 -1
  6. package/build/lib/star-utils.js.map +1 -1
  7. package/build/lib/storage-utils.d.ts +3 -0
  8. package/build/lib/storage-utils.js +35 -2
  9. package/build/lib/storage-utils.js.map +1 -1
  10. package/build/lib/versions-utils.d.ts +14 -0
  11. package/build/lib/versions-utils.js +52 -1
  12. package/build/lib/versions-utils.js.map +1 -1
  13. package/build/local-storage.js +3 -3
  14. package/build/local-storage.js.map +1 -1
  15. package/build/storage.d.ts +14 -15
  16. package/build/storage.js +198 -161
  17. package/build/storage.js.map +1 -1
  18. package/build/type.d.ts +5 -0
  19. package/build/type.js.map +1 -1
  20. package/jest.config.js +2 -2
  21. package/package.json +17 -16
  22. package/src/index.ts +0 -1
  23. package/src/lib/storage-utils.ts +40 -2
  24. package/src/lib/versions-utils.ts +50 -1
  25. package/src/local-storage.ts +3 -2
  26. package/src/storage.ts +228 -149
  27. package/src/type.ts +6 -0
  28. package/test/fixtures/config/publishWithOwnerAndCheck.yaml +18 -0
  29. package/test/fixtures/config/publishWithOwnerDefault.yaml +15 -0
  30. package/test/fixtures/config/syncDoubleUplinksMetadata.yaml +2 -18
  31. package/test/search.spec.ts +28 -7
  32. package/test/storage-utils.spec.ts +1 -0
  33. package/test/storage.spec.ts +466 -80
  34. package/test/versions.spec.ts +58 -1
  35. package/build/lib/TransFormResults.d.ts +0 -15
  36. package/build/lib/TransFormResults.js +0 -51
  37. package/build/lib/TransFormResults.js.map +0 -1
  38. package/build/lib/search-utils.d.ts +0 -4
  39. package/build/lib/search-utils.js +0 -50
  40. package/build/lib/search-utils.js.map +0 -1
  41. package/build/lib/uplink-util.d.ts +0 -10
  42. package/build/lib/uplink-util.js +0 -43
  43. package/build/lib/uplink-util.js.map +0 -1
  44. package/src/lib/TransFormResults.ts +0 -42
  45. package/src/lib/search-utils.ts +0 -50
  46. package/src/lib/uplink-util.ts +0 -42
  47. /package/test/fixtures/config/{getTarballNext-getupstream.yaml → getTarball-getupstream.yaml} +0 -0
@@ -24,7 +24,14 @@ import {
24
24
  generateRemotePackageMetadata,
25
25
  getDeprecatedPackageMetadata,
26
26
  } from '@verdaccio/test-helper';
27
- import { AbbreviatedManifest, ConfigYaml, Manifest, PackageUsers, Version } from '@verdaccio/types';
27
+ import {
28
+ AbbreviatedManifest,
29
+ Author,
30
+ ConfigYaml,
31
+ Manifest,
32
+ PackageUsers,
33
+ Version,
34
+ } from '@verdaccio/types';
28
35
 
29
36
  import { Storage } from '../src';
30
37
  import manifestFooRemoteNpmjs from './fixtures/manifests/foo-npmjs.json';
@@ -37,7 +44,7 @@ function generateRandomStorage() {
37
44
  return path.join(tempRoot, tempStorage);
38
45
  }
39
46
 
40
- setup({ type: 'stdout', format: 'pretty', level: 'trace' });
47
+ const logger = setup({ type: 'stdout', format: 'pretty', level: 'trace' });
41
48
 
42
49
  const domain = 'https://registry.npmjs.org';
43
50
  const fakeHost = 'localhost:4873';
@@ -89,6 +96,31 @@ const executeStarPackage = async (
89
96
  });
90
97
  };
91
98
 
99
+ const executeChangeOwners = async (
100
+ storage,
101
+ options: {
102
+ maintainers: Author[];
103
+ username: string;
104
+ name: string;
105
+ _rev: string;
106
+ _id?: string;
107
+ }
108
+ ) => {
109
+ const { name, _rev, _id, maintainers, username } = options;
110
+ const ownerManifest = {
111
+ _rev,
112
+ _id,
113
+ maintainers,
114
+ };
115
+ return storage.updateManifest(ownerManifest, {
116
+ signal: new AbortController().signal,
117
+ name,
118
+ uplinksLook: true,
119
+ revision: '1',
120
+ requestOptions: { ...defaultRequestOptions, username },
121
+ });
122
+ };
123
+
92
124
  describe('storage', () => {
93
125
  beforeEach(() => {
94
126
  nock.cleanAll();
@@ -117,7 +149,7 @@ describe('storage', () => {
117
149
  __dirname
118
150
  )
119
151
  );
120
- const storage = new Storage(config);
152
+ const storage = new Storage(config, logger);
121
153
  await storage.init(config);
122
154
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
123
155
  await storage.updateManifest(bodyNewManifest, {
@@ -141,6 +173,8 @@ describe('storage', () => {
141
173
  modified: mockDate,
142
174
  });
143
175
  expect(manifest[DIST_TAGS]).toEqual({ latest: '1.0.0' });
176
+ // verdaccio keeps latest version of readme on manifest level but not by version
177
+ expect(manifest.versions['1.0.0'].readme).not.toBeDefined();
144
178
  expect(manifest.readme).toEqual('# test');
145
179
  expect(manifest._attachments).toEqual({});
146
180
  expect(typeof manifest._rev).toBeTruthy();
@@ -160,7 +194,7 @@ describe('storage', () => {
160
194
  __dirname
161
195
  )
162
196
  );
163
- const storage = new Storage(config);
197
+ const storage = new Storage(config, logger);
164
198
  await storage.init(config);
165
199
  const ac = new AbortController();
166
200
  setTimeout(() => {
@@ -205,7 +239,7 @@ describe('storage', () => {
205
239
  __dirname
206
240
  )
207
241
  );
208
- const storage = new Storage(config);
242
+ const storage = new Storage(config, logger);
209
243
  await storage.init(config);
210
244
  // create a package
211
245
  const bodyNewManifest1 = generatePackageMetadata(pkgName, '1.0.0');
@@ -260,10 +294,12 @@ describe('storage', () => {
260
294
  expect(manifestVersion._id).toEqual(`${pkgName}@1.0.1`);
261
295
  expect(manifestVersion.description).toEqual('package generated');
262
296
  expect(manifestVersion.dist).toEqual({
297
+ fileCount: 4,
263
298
  integrity:
264
299
  'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
265
300
  shasum: '2c03764f651a9f016ca0b7620421457b619151b9',
266
301
  tarball: 'http://localhost:5555/upstream/-/upstream-1.0.1.tgz',
302
+ unpackedSize: 543,
267
303
  });
268
304
 
269
305
  expect(manifestVersion.contributors).toEqual([]);
@@ -288,11 +324,11 @@ describe('storage', () => {
288
324
  {
289
325
  storage: generateRandomStorage(),
290
326
  },
291
- './fixtures/config/getTarballNext-getupstream.yaml',
327
+ './fixtures/config/getTarball-getupstream.yaml',
292
328
  __dirname
293
329
  )
294
330
  );
295
- const storage = new Storage(config);
331
+ const storage = new Storage(config, logger);
296
332
  await storage.init(config);
297
333
  const bodyNewManifest1 = generatePackageMetadata(pkgName, '1.0.0');
298
334
  const bodyNewManifest2 = generatePackageMetadata(pkgName, '1.0.0');
@@ -309,13 +345,57 @@ describe('storage', () => {
309
345
  })
310
346
  ).rejects.toThrow(API_ERROR.PACKAGE_EXIST);
311
347
  });
348
+
349
+ test('create private package with readme only in manifest', async () => {
350
+ const mockDate = '2018-01-14T11:17:40.712Z';
351
+ MockDate.set(mockDate);
352
+ const pkgName = 'upstream';
353
+ const requestOptions = {
354
+ host: 'localhost',
355
+ protocol: 'http',
356
+ headers: {},
357
+ };
358
+ const config = new Config(
359
+ configExample(
360
+ {
361
+ ...getDefaultConfig(),
362
+ storage: generateRandomStorage(),
363
+ },
364
+ './fixtures/config/updateManifest-1.yaml',
365
+ __dirname
366
+ )
367
+ );
368
+ const storage = new Storage(config, logger);
369
+ await storage.init(config);
370
+ const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
371
+
372
+ // Remove readme from version to simulate behaviour of older package managers like npm6
373
+ bodyNewManifest.versions['1.0.0'].readme = '';
374
+
375
+ await storage.updateManifest(bodyNewManifest, {
376
+ signal: new AbortController().signal,
377
+ name: pkgName,
378
+ uplinksLook: true,
379
+ revision: '1',
380
+ requestOptions,
381
+ });
382
+ const manifest = (await storage.getPackageByOptions({
383
+ name: pkgName,
384
+ uplinksLook: true,
385
+ requestOptions,
386
+ })) as Manifest;
387
+
388
+ // verdaccio keeps latest version of readme on manifest level but not by version
389
+ expect(manifest.versions['1.0.0'].readme).not.toBeDefined();
390
+ expect(manifest.readme).toEqual('# test');
391
+ });
312
392
  });
313
393
  describe('deprecate', () => {
314
394
  test.each([['foo'], ['@scope/foo']])('deprecate package %s', async (pkgName) => {
315
395
  const mockDate = '2018-01-14T11:17:40.712Z';
316
396
  MockDate.set(mockDate);
317
397
  const config = getConfig('deprecate.yaml');
318
- const storage = new Storage(config);
398
+ const storage = new Storage(config, logger);
319
399
  await storage.init(config);
320
400
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
321
401
  await storage.updateManifest(bodyNewManifest, {
@@ -362,7 +442,7 @@ describe('storage', () => {
362
442
  const mockDate = '2018-01-14T11:17:40.712Z';
363
443
  MockDate.set(mockDate);
364
444
  const config = getConfig('deprecate.yaml');
365
- const storage = new Storage(config);
445
+ const storage = new Storage(config, logger);
366
446
  await storage.init(config);
367
447
  // publish new package
368
448
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
@@ -436,7 +516,7 @@ describe('storage', () => {
436
516
  describe('star', () => {
437
517
  test.each([['foo']])('star package %s', async (pkgName) => {
438
518
  const config = getConfig('deprecate.yaml');
439
- const storage = new Storage(config);
519
+ const storage = new Storage(config, logger);
440
520
  await storage.init(config);
441
521
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
442
522
  await storage.updateManifest(bodyNewManifest, {
@@ -469,7 +549,7 @@ describe('storage', () => {
469
549
  const mockDate = '2018-01-14T11:17:40.712Z';
470
550
  MockDate.set(mockDate);
471
551
  const config = getConfig('deprecate.yaml');
472
- const storage = new Storage(config);
552
+ const storage = new Storage(config, logger);
473
553
  await storage.init(config);
474
554
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
475
555
  await storage.updateManifest(bodyNewManifest, {
@@ -511,7 +591,7 @@ describe('storage', () => {
511
591
  const mockDate = '2018-01-14T11:17:40.712Z';
512
592
  MockDate.set(mockDate);
513
593
  const config = getConfig('deprecate.yaml');
514
- const storage = new Storage(config);
594
+ const storage = new Storage(config, logger);
515
595
  await storage.init(config);
516
596
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
517
597
  await storage.updateManifest(bodyNewManifest, {
@@ -550,7 +630,7 @@ describe('storage', () => {
550
630
 
551
631
  test.each([['foo']])('should unstar a package %s', async (pkgName) => {
552
632
  const config = getConfig('deprecate.yaml');
553
- const storage = new Storage(config);
633
+ const storage = new Storage(config, logger);
554
634
  await storage.init(config);
555
635
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
556
636
  await storage.updateManifest(bodyNewManifest, {
@@ -587,7 +667,7 @@ describe('storage', () => {
587
667
 
588
668
  test.each([['foo']])('should handle missing username %s', async (pkgName) => {
589
669
  const config = getConfig('deprecate.yaml');
590
- const storage = new Storage(config);
670
+ const storage = new Storage(config, logger);
591
671
  await storage.init(config);
592
672
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
593
673
  await storage.updateManifest(bodyNewManifest, {
@@ -609,9 +689,248 @@ describe('storage', () => {
609
689
  ).rejects.toThrow();
610
690
  });
611
691
  });
692
+ describe('owner', () => {
693
+ test.each([
694
+ ['foo', 'publishWithOwnerDefault.yaml'],
695
+ ['foo', 'publishWithOwnerAndCheck.yaml'],
696
+ ])('new package %s, %s (anonymous)', async (pkgName, configFile) => {
697
+ const config = getConfig(configFile);
698
+ const storage = new Storage(config, logger);
699
+ await storage.init(config);
700
+ const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
701
+ await storage.updateManifest(bodyNewManifest, {
702
+ signal: new AbortController().signal,
703
+ name: pkgName,
704
+ uplinksLook: true,
705
+ requestOptions: defaultRequestOptions,
706
+ });
707
+ const manifest = (await storage.getPackageByOptions({
708
+ name: pkgName,
709
+ uplinksLook: true,
710
+ requestOptions: defaultRequestOptions,
711
+ })) as Manifest;
712
+ expect(manifest?.maintainers).toEqual([{ name: 'Anonymous', email: '' }]);
713
+ });
714
+
715
+ test.each([
716
+ ['foo', 'publishWithOwnerDefault.yaml'],
717
+ ['foo', 'publishWithOwnerAndCheck.yaml'],
718
+ ])('new package %s, %s (logged in)', async (pkgName, configFile) => {
719
+ const config = getConfig(configFile);
720
+ const storage = new Storage(config, logger);
721
+ await storage.init(config);
722
+ const owner = { name: 'fooUser', email: '' };
723
+ const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
724
+ const options = { ...defaultRequestOptions, username: owner.name };
725
+ await storage.updateManifest(bodyNewManifest, {
726
+ signal: new AbortController().signal,
727
+ name: pkgName,
728
+ uplinksLook: true,
729
+ requestOptions: options,
730
+ });
731
+ const manifest = (await storage.getPackageByOptions({
732
+ name: pkgName,
733
+ uplinksLook: true,
734
+ requestOptions: defaultRequestOptions,
735
+ })) as Manifest;
736
+ expect(manifest?.maintainers).toEqual([owner]);
737
+ expect(manifest?.versions['1.0.0'].maintainers).toEqual([owner]);
738
+ });
739
+
740
+ test.each([
741
+ ['foo', 'publishWithOwnerDefault.yaml'],
742
+ ['foo', 'publishWithOwnerAndCheck.yaml'],
743
+ ])('add/remove owner %s, %s', async (pkgName, configFile) => {
744
+ const config = getConfig(configFile);
745
+ const storage = new Storage(config, logger);
746
+ await storage.init(config);
747
+ const firstOwner = { name: 'fooUser', email: '' };
748
+ const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
749
+ const options = { ...defaultRequestOptions, username: firstOwner.name };
750
+ await storage.updateManifest(bodyNewManifest, {
751
+ signal: new AbortController().signal,
752
+ name: pkgName,
753
+ uplinksLook: false,
754
+ requestOptions: options,
755
+ });
756
+
757
+ // add owner
758
+ const secondOwner = { name: 'barUser', email: '' };
759
+ const maintainers = [firstOwner, secondOwner];
760
+
761
+ const message = await executeChangeOwners(storage, {
762
+ _rev: bodyNewManifest._rev,
763
+ _id: bodyNewManifest._id,
764
+ name: pkgName,
765
+ username: firstOwner.name,
766
+ maintainers: maintainers,
767
+ });
768
+ expect(message).toEqual(API_MESSAGE.PKG_CHANGED);
769
+
770
+ const manifest = (await storage.getPackageByOptions({
771
+ name: pkgName,
772
+ uplinksLook: false,
773
+ requestOptions: options,
774
+ })) as Manifest;
775
+ expect(manifest?.maintainers).toEqual(maintainers);
776
+ // published version should not be affected
777
+ expect(manifest?.versions['1.0.0'].maintainers).toEqual([firstOwner]);
778
+
779
+ // remove owner
780
+ const maintainers2 = [secondOwner];
781
+ const message2 = await executeChangeOwners(storage, {
782
+ _rev: bodyNewManifest._rev,
783
+ _id: bodyNewManifest._id,
784
+ name: pkgName,
785
+ username: firstOwner.name,
786
+ maintainers: maintainers2,
787
+ });
788
+ expect(message2).toEqual(API_MESSAGE.PKG_CHANGED);
789
+
790
+ const manifest2 = (await storage.getPackageByOptions({
791
+ name: pkgName,
792
+ uplinksLook: false,
793
+ requestOptions: options,
794
+ })) as Manifest;
795
+ expect(manifest2?.maintainers).toEqual(maintainers2);
796
+ // published version should not be affected
797
+ expect(manifest2?.versions['1.0.0'].maintainers).toEqual([firstOwner]);
798
+ });
799
+
800
+ test.each([
801
+ ['foo', 'publishWithOwnerDefault.yaml'],
802
+ ['foo', 'publishWithOwnerAndCheck.yaml'],
803
+ ])('should fail removing last owner %s, %s', async (pkgName, configFile) => {
804
+ const config = getConfig(configFile);
805
+ const storage = new Storage(config, logger);
806
+ await storage.init(config);
807
+ const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
808
+ const owner = 'fooUser';
809
+ const options = { ...defaultRequestOptions, username: owner };
810
+ await storage.updateManifest(bodyNewManifest, {
811
+ signal: new AbortController().signal,
812
+ name: pkgName,
813
+ uplinksLook: false,
814
+ requestOptions: options,
815
+ });
816
+
817
+ // no owners
818
+ await expect(
819
+ executeChangeOwners(storage, {
820
+ _rev: bodyNewManifest._rev,
821
+ _id: bodyNewManifest._id,
822
+ name: pkgName,
823
+ username: owner,
824
+ maintainers: [],
825
+ })
826
+ ).rejects.toThrow();
827
+ });
828
+
829
+ test.each([['foo', 'publishWithOwnerDefault.yaml']])(
830
+ 'ok to publish as non-owner without check %s, %s',
831
+ async (pkgName, configFile) => {
832
+ const config = getConfig(configFile);
833
+ const storage = new Storage(config, logger);
834
+ await storage.init(config);
835
+ const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
836
+ const owner = 'fooUser';
837
+ const options = { ...defaultRequestOptions, username: owner };
838
+ await storage.updateManifest(bodyNewManifest, {
839
+ signal: new AbortController().signal,
840
+ name: pkgName,
841
+ uplinksLook: false,
842
+ requestOptions: options,
843
+ });
844
+
845
+ // try to publish as user who's not an owner
846
+ const bodyNewManifest2 = generatePackageMetadata(pkgName, '1.0.1');
847
+ const nonOwner = 'barUser';
848
+ const options2 = { ...defaultRequestOptions, username: nonOwner };
849
+ const message2 = await storage.updateManifest(bodyNewManifest2, {
850
+ signal: new AbortController().signal,
851
+ name: pkgName,
852
+ uplinksLook: false,
853
+ requestOptions: options2,
854
+ });
855
+ expect(message2).toEqual(API_MESSAGE.PKG_CHANGED);
856
+ }
857
+ );
858
+
859
+ test.each([['foo', 'publishWithOwnerAndCheck.yaml']])(
860
+ 'should fail publishing as non-owner with check %s, %s',
861
+ async (pkgName, configFile) => {
862
+ const config = getConfig(configFile);
863
+ const storage = new Storage(config, logger);
864
+ await storage.init(config);
865
+ const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
866
+ const owner = 'fooUser';
867
+ const options = { ...defaultRequestOptions, username: owner };
868
+ await storage.updateManifest(bodyNewManifest, {
869
+ signal: new AbortController().signal,
870
+ name: pkgName,
871
+ uplinksLook: false,
872
+ requestOptions: options,
873
+ });
874
+
875
+ // try to publish as user who's not an owner
876
+ const bodyNewManifest2 = generatePackageMetadata(pkgName, '1.0.1');
877
+ const nonOwner = 'barUser';
878
+ const options2 = { ...defaultRequestOptions, username: nonOwner };
879
+ await expect(
880
+ storage.updateManifest(bodyNewManifest2, {
881
+ signal: new AbortController().signal,
882
+ name: pkgName,
883
+ uplinksLook: false,
884
+ requestOptions: options2,
885
+ })
886
+ ).rejects.toThrow();
887
+ }
888
+ );
889
+ });
612
890
  });
613
891
 
614
- describe('getTarballNext', () => {
892
+ describe('getTarball', () => {
893
+ test('should get a package from local storage', (done) => {
894
+ const pkgName = 'foo';
895
+ const config = new Config(
896
+ configExample({
897
+ ...getDefaultConfig(),
898
+ storage: generateRandomStorage(),
899
+ })
900
+ );
901
+ const storage = new Storage(config, logger);
902
+ storage.init(config).then(() => {
903
+ const ac = new AbortController();
904
+ const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
905
+ storage
906
+ .updateManifest(bodyNewManifest, {
907
+ signal: ac.signal,
908
+ name: pkgName,
909
+ uplinksLook: false,
910
+ requestOptions: defaultRequestOptions,
911
+ })
912
+ .then(() => {
913
+ const abort = new AbortController();
914
+ storage
915
+ .getTarball(pkgName, `${pkgName}-1.0.0.tgz`, {
916
+ signal: abort.signal,
917
+ })
918
+ .then((stream) => {
919
+ stream.on('data', (dat) => {
920
+ expect(dat).toBeDefined();
921
+ expect(dat.length).toEqual(512);
922
+ });
923
+ stream.on('end', () => {
924
+ done();
925
+ });
926
+ stream.on('error', () => {
927
+ done('this should not happen');
928
+ });
929
+ });
930
+ });
931
+ });
932
+ });
933
+
615
934
  test('should not found a package anywhere', (done) => {
616
935
  const config = new Config(
617
936
  configExample({
@@ -619,11 +938,11 @@ describe('storage', () => {
619
938
  storage: generateRandomStorage(),
620
939
  })
621
940
  );
622
- const storage = new Storage(config);
941
+ const storage = new Storage(config, logger);
623
942
  storage.init(config).then(() => {
624
943
  const abort = new AbortController();
625
944
  storage
626
- .getTarballNext('some-tarball', 'some-tarball-1.0.0.tgz', {
945
+ .getTarball('some-tarball', 'some-tarball-1.0.0.tgz', {
627
946
  signal: abort.signal,
628
947
  })
629
948
  .then((stream) => {
@@ -655,15 +974,15 @@ describe('storage', () => {
655
974
  {
656
975
  storage: generateRandomStorage(),
657
976
  },
658
- './fixtures/config/getTarballNext-getupstream.yaml',
977
+ './fixtures/config/getTarball-getupstream.yaml',
659
978
  __dirname
660
979
  )
661
980
  );
662
- const storage = new Storage(config);
981
+ const storage = new Storage(config, logger);
663
982
  storage.init(config).then(() => {
664
983
  const abort = new AbortController();
665
984
  storage
666
- .getTarballNext(pkgName, `${pkgName}-1.0.0.tgz`, {
985
+ .getTarball(pkgName, `${pkgName}-1.0.0.tgz`, {
667
986
  signal: abort.signal,
668
987
  })
669
988
  .then((stream) => {
@@ -683,7 +1002,7 @@ describe('storage', () => {
683
1002
  test('should serve fetch tarball from upstream without dist info local', (done) => {
684
1003
  const pkgName = 'upstream';
685
1004
  const upstreamManifest = addNewVersion(
686
- generateRemotePackageMetadata(pkgName, '1.0.0'),
1005
+ generateRemotePackageMetadata(pkgName, '1.0.0') as Manifest,
687
1006
  '1.0.1'
688
1007
  );
689
1008
  nock('https://registry.verdaccio.org').get(`/${pkgName}`).reply(201, upstreamManifest);
@@ -699,11 +1018,11 @@ describe('storage', () => {
699
1018
  {
700
1019
  storage: generateRandomStorage(),
701
1020
  },
702
- './fixtures/config/getTarballNext-getupstream.yaml',
1021
+ './fixtures/config/getTarball-getupstream.yaml',
703
1022
  __dirname
704
1023
  )
705
1024
  );
706
- const storage = new Storage(config);
1025
+ const storage = new Storage(config, logger);
707
1026
  storage.init(config).then(() => {
708
1027
  const ac = new AbortController();
709
1028
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
@@ -722,7 +1041,7 @@ describe('storage', () => {
722
1041
  .then(() => {
723
1042
  const abort = new AbortController();
724
1043
  storage
725
- .getTarballNext(pkgName, `${pkgName}-1.0.1.tgz`, {
1044
+ .getTarball(pkgName, `${pkgName}-1.0.1.tgz`, {
726
1045
  signal: abort.signal,
727
1046
  })
728
1047
  .then((stream) => {
@@ -743,7 +1062,7 @@ describe('storage', () => {
743
1062
  test('should serve fetch tarball from upstream without with info local', (done) => {
744
1063
  const pkgName = 'upstream';
745
1064
  const upstreamManifest = addNewVersion(
746
- addNewVersion(generateRemotePackageMetadata(pkgName, '1.0.0'), '1.0.1'),
1065
+ addNewVersion(generateRemotePackageMetadata(pkgName, '1.0.0') as Manifest, '1.0.1'),
747
1066
  '1.0.2'
748
1067
  );
749
1068
  nock('https://registry.verdaccio.org')
@@ -763,11 +1082,11 @@ describe('storage', () => {
763
1082
  {
764
1083
  storage: storagePath,
765
1084
  },
766
- './fixtures/config/getTarballNext-getupstream.yaml',
1085
+ './fixtures/config/getTarball-getupstream.yaml',
767
1086
  __dirname
768
1087
  )
769
1088
  );
770
- const storage = new Storage(config);
1089
+ const storage = new Storage(config, logger);
771
1090
  storage.init(config).then(() => {
772
1091
  const req = httpMocks.createRequest({
773
1092
  method: 'GET',
@@ -791,7 +1110,7 @@ describe('storage', () => {
791
1110
  .then(() => {
792
1111
  const abort = new AbortController();
793
1112
  storage
794
- .getTarballNext(pkgName, `${pkgName}-1.0.0.tgz`, {
1113
+ .getTarball(pkgName, `${pkgName}-1.0.0.tgz`, {
795
1114
  signal: abort.signal,
796
1115
  })
797
1116
  .then((stream) => {
@@ -816,11 +1135,11 @@ describe('storage', () => {
816
1135
  {
817
1136
  storage: generateRandomStorage(),
818
1137
  },
819
- './fixtures/config/getTarballNext-getupstream.yaml',
1138
+ './fixtures/config/getTarball-getupstream.yaml',
820
1139
  __dirname
821
1140
  )
822
1141
  );
823
- const storage = new Storage(config);
1142
+ const storage = new Storage(config, logger);
824
1143
  storage.init(config).then(() => {
825
1144
  const ac = new AbortController();
826
1145
  const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
@@ -839,7 +1158,7 @@ describe('storage', () => {
839
1158
  .then(() => {
840
1159
  const abort = new AbortController();
841
1160
  storage
842
- .getTarballNext(pkgName, `${pkgName}-1.0.0.tgz`, {
1161
+ .getTarball(pkgName, `${pkgName}-1.0.0.tgz`, {
843
1162
  signal: abort.signal,
844
1163
  })
845
1164
  .then((stream) => {
@@ -858,44 +1177,36 @@ describe('storage', () => {
858
1177
  });
859
1178
  });
860
1179
 
861
- describe('syncUplinksMetadataNext()', () => {
1180
+ describe('syncUplinksMetadata()', () => {
862
1181
  describe('error handling', () => {
863
1182
  test('should handle double failure on uplinks with timeout', async () => {
864
1183
  const fooManifest = generatePackageMetadata('timeout', '8.0.0');
865
-
866
- nock('https://registry.domain.com')
1184
+ nock('https://registry.timeout.com')
867
1185
  .get(`/${fooManifest.name}`)
868
- .times(10)
869
- .delayConnection(4000)
1186
+ .delayConnection(8000)
870
1187
  .reply(201, manifestFooRemoteNpmjs);
871
1188
 
872
1189
  const config = new Config(
873
1190
  configExample(
874
1191
  {
875
1192
  storage: generateRandomStorage(),
876
- uplinks: {
877
- npmjs: {
878
- url: 'https://registry.npmjs.org',
879
- timeout: '2s',
880
- },
881
- },
882
1193
  },
883
1194
  './fixtures/config/syncDoubleUplinksMetadata.yaml',
884
1195
  __dirname
885
1196
  )
886
1197
  );
887
1198
 
888
- const storage = new Storage(config);
1199
+ const storage = new Storage(config, logger);
889
1200
  await storage.init(config);
890
1201
  await expect(
891
- storage.syncUplinksMetadataNext(fooManifest.name, null, {
892
- retry: { limit: 0 },
1202
+ storage.syncUplinksMetadata(fooManifest.name, null, {
1203
+ retry: { limit: 3 },
893
1204
  timeout: {
894
1205
  request: 1000,
895
1206
  },
896
1207
  })
897
1208
  ).rejects.toThrow(API_ERROR.NO_PACKAGE);
898
- }, 10000);
1209
+ }, 18000);
899
1210
 
900
1211
  test('should handle one proxy fails', async () => {
901
1212
  const fooManifest = generatePackageMetadata('foo', '8.0.0');
@@ -909,10 +1220,10 @@ describe('storage', () => {
909
1220
  __dirname
910
1221
  )
911
1222
  );
912
- const storage = new Storage(config);
1223
+ const storage = new Storage(config, logger);
913
1224
  await storage.init(config);
914
1225
  await expect(
915
- storage.syncUplinksMetadataNext(fooManifest.name, null, {
1226
+ storage.syncUplinksMetadata(fooManifest.name, null, {
916
1227
  retry: { limit: 0 },
917
1228
  })
918
1229
  ).rejects.toThrow(API_ERROR.NO_PACKAGE);
@@ -930,10 +1241,10 @@ describe('storage', () => {
930
1241
  __dirname
931
1242
  )
932
1243
  );
933
- const storage = new Storage(config);
1244
+ const storage = new Storage(config, logger);
934
1245
  await storage.init(config);
935
- const [manifest] = await storage.syncUplinksMetadataNext(fooManifest.name, fooManifest, {
936
- retry: 0,
1246
+ const [manifest] = await storage.syncUplinksMetadata(fooManifest.name, fooManifest, {
1247
+ retry: { limit: 0 },
937
1248
  });
938
1249
  expect(manifest).toBe(fooManifest);
939
1250
  });
@@ -952,10 +1263,10 @@ describe('storage', () => {
952
1263
  __dirname
953
1264
  )
954
1265
  );
955
- const storage = new Storage(config);
1266
+ const storage = new Storage(config, logger);
956
1267
  await storage.init(config);
957
1268
 
958
- const [response] = await storage.syncUplinksMetadataNext(fooManifest.name, fooManifest);
1269
+ const [response] = await storage.syncUplinksMetadata(fooManifest.name, fooManifest);
959
1270
  expect(response).not.toBeNull();
960
1271
  expect((response as Manifest).name).toEqual(fooManifest.name);
961
1272
  expect(Object.keys((response as Manifest).versions)).toEqual([
@@ -993,10 +1304,10 @@ describe('storage', () => {
993
1304
  __dirname
994
1305
  )
995
1306
  );
996
- const storage = new Storage(config);
1307
+ const storage = new Storage(config, logger);
997
1308
  await storage.init(config);
998
1309
 
999
- const [response] = await storage.syncUplinksMetadataNext(fooManifest.name, null);
1310
+ const [response] = await storage.syncUplinksMetadata(fooManifest.name, null);
1000
1311
  // the latest from the remote manifest
1001
1312
  expect(response).not.toBeNull();
1002
1313
  expect((response as Manifest).name).toEqual(fooManifest.name);
@@ -1015,10 +1326,10 @@ describe('storage', () => {
1015
1326
  __dirname
1016
1327
  )
1017
1328
  );
1018
- const storage = new Storage(config);
1329
+ const storage = new Storage(config, logger);
1019
1330
  await storage.init(config);
1020
1331
 
1021
- const [response] = await storage.syncUplinksMetadataNext(fooManifest.name, fooManifest);
1332
+ const [response] = await storage.syncUplinksMetadata(fooManifest.name, fooManifest);
1022
1333
  expect(response).not.toBeNull();
1023
1334
  expect((response as Manifest).name).toEqual(fooManifest.name);
1024
1335
  expect((response as Manifest)[DIST_TAGS].latest).toEqual('8.0.0');
@@ -1039,10 +1350,10 @@ describe('storage', () => {
1039
1350
  __dirname
1040
1351
  )
1041
1352
  );
1042
- const storage = new Storage(config);
1353
+ const storage = new Storage(config, logger);
1043
1354
  await storage.init(config);
1044
1355
 
1045
- const [response] = await storage.syncUplinksMetadataNext(fooManifest.name, fooManifest, {
1356
+ const [response] = await storage.syncUplinksMetadata(fooManifest.name, fooManifest, {
1046
1357
  uplinksLook: false,
1047
1358
  });
1048
1359
 
@@ -1068,10 +1379,10 @@ describe('storage', () => {
1068
1379
  __dirname
1069
1380
  )
1070
1381
  );
1071
- const storage = new Storage(config);
1382
+ const storage = new Storage(config, logger);
1072
1383
  await storage.init(config);
1073
1384
 
1074
- const [response] = await storage.syncUplinksMetadataNext('foo', null, {
1385
+ const [response] = await storage.syncUplinksMetadata('foo', null, {
1075
1386
  uplinksLook: true,
1076
1387
  });
1077
1388
 
@@ -1082,19 +1393,19 @@ describe('storage', () => {
1082
1393
  });
1083
1394
 
1084
1395
  describe('getLocalDatabase', () => {
1085
- test('should return 0 local packages', async () => {
1396
+ test('should return no results', async () => {
1086
1397
  const config = new Config(
1087
1398
  configExample({
1088
1399
  ...getDefaultConfig(),
1089
1400
  storage: generateRandomStorage(),
1090
1401
  })
1091
1402
  );
1092
- const storage = new Storage(config);
1403
+ const storage = new Storage(config, logger);
1093
1404
  await storage.init(config);
1094
1405
  await expect(storage.getLocalDatabase()).resolves.toHaveLength(0);
1095
1406
  });
1096
1407
 
1097
- test('should return 1 local packages', async () => {
1408
+ test('should return single result', async () => {
1098
1409
  const config = new Config(
1099
1410
  configExample({
1100
1411
  ...getDefaultConfig(),
@@ -1109,7 +1420,7 @@ describe('storage', () => {
1109
1420
  },
1110
1421
  url: '/',
1111
1422
  });
1112
- const storage = new Storage(config);
1423
+ const storage = new Storage(config, logger);
1113
1424
  await storage.init(config);
1114
1425
  const manifest = generatePackageMetadata('foo');
1115
1426
  const ac = new AbortController();
@@ -1138,7 +1449,7 @@ describe('storage', () => {
1138
1449
  storage: generateRandomStorage(),
1139
1450
  })
1140
1451
  );
1141
- const storage = new Storage(config);
1452
+ const storage = new Storage(config, logger);
1142
1453
  await storage.init(config);
1143
1454
  await storage.saveToken({
1144
1455
  user: 'foo',
@@ -1160,7 +1471,7 @@ describe('storage', () => {
1160
1471
  storage: generateRandomStorage(),
1161
1472
  })
1162
1473
  );
1163
- const storage = new Storage(config);
1474
+ const storage = new Storage(config, logger);
1164
1475
  await storage.init(config);
1165
1476
  await storage.saveToken({
1166
1477
  user: 'foo',
@@ -1180,15 +1491,16 @@ describe('storage', () => {
1180
1491
 
1181
1492
  describe('removeTarball', () => {
1182
1493
  test('should fail on remove tarball of package does not exist', async () => {
1494
+ const username = 'foouser';
1183
1495
  const config = new Config(
1184
1496
  configExample({
1185
1497
  ...getDefaultConfig(),
1186
1498
  storage: generateRandomStorage(),
1187
1499
  })
1188
1500
  );
1189
- const storage = new Storage(config);
1501
+ const storage = new Storage(config, logger);
1190
1502
  await storage.init(config);
1191
- await expect(storage.removeTarball('foo', 'foo-1.0.0.tgz', 'rev')).rejects.toThrow(
1503
+ await expect(storage.removeTarball('foo', 'foo-1.0.0.tgz', 'rev', username)).rejects.toThrow(
1192
1504
  API_ERROR.NO_PACKAGE
1193
1505
  );
1194
1506
  });
@@ -1196,6 +1508,7 @@ describe('storage', () => {
1196
1508
 
1197
1509
  describe('removePackage', () => {
1198
1510
  test('should remove entirely a package', async () => {
1511
+ const username = 'foouser';
1199
1512
  const config = new Config(
1200
1513
  configExample({
1201
1514
  ...getDefaultConfig(),
@@ -1211,7 +1524,7 @@ describe('storage', () => {
1211
1524
  },
1212
1525
  url: '/',
1213
1526
  });
1214
- const storage = new Storage(config);
1527
+ const storage = new Storage(config, logger);
1215
1528
  await storage.init(config);
1216
1529
 
1217
1530
  const manifest = generatePackageMetadata('foo');
@@ -1240,10 +1553,10 @@ describe('storage', () => {
1240
1553
  const _rev = manifest1._rev;
1241
1554
  // 3. remove the tarball
1242
1555
  await expect(
1243
- storage.removeTarball(manifest1.name, 'foo-1.0.0.tgz', _rev)
1556
+ storage.removeTarball(manifest1.name, 'foo-1.0.0.tgz', _rev, username)
1244
1557
  ).resolves.toBeDefined();
1245
1558
  // 4. remove the package
1246
- await storage.removePackage(manifest1.name, _rev);
1559
+ await storage.removePackage(manifest1.name, _rev, username);
1247
1560
  // 5. fails if package does not exist anymore in storage
1248
1561
  await expect(
1249
1562
  storage.getPackageByOptions({
@@ -1257,6 +1570,76 @@ describe('storage', () => {
1257
1570
  })
1258
1571
  ).rejects.toThrow('package does not exist on uplink: foo');
1259
1572
  });
1573
+
1574
+ test('ok to remove package as non-owner without check', async () => {
1575
+ const config = getConfig('publishWithOwnerDefault.yaml');
1576
+ const storage = new Storage(config, logger);
1577
+ await storage.init(config);
1578
+ const owner = 'fooUser';
1579
+ const options = { ...defaultRequestOptions, username: owner };
1580
+
1581
+ // 1. publish a package
1582
+ const bodyNewManifest = generatePackageMetadata('foo', '1.0.0');
1583
+ await storage.updateManifest(bodyNewManifest, {
1584
+ signal: new AbortController().signal,
1585
+ name: 'foo',
1586
+ uplinksLook: true,
1587
+ requestOptions: options,
1588
+ });
1589
+ // 2. request package (should be available in the local cache)
1590
+ const manifest1 = (await storage.getPackageByOptions({
1591
+ name: 'foo',
1592
+ uplinksLook: false,
1593
+ requestOptions: options,
1594
+ })) as Manifest;
1595
+ const _rev = manifest1._rev;
1596
+ // 3. remove the tarball as other user
1597
+ const nonOwner = 'barUser';
1598
+ await expect(
1599
+ storage.removeTarball(manifest1.name, 'foo-1.0.0.tgz', _rev, nonOwner)
1600
+ ).resolves.toBeDefined();
1601
+ // 4. remove the package as other user
1602
+ await storage.removePackage(manifest1.name, _rev, nonOwner);
1603
+ // 5. fails if package does not exist anymore in storage
1604
+ await expect(
1605
+ storage.getPackageByOptions({
1606
+ name: 'foo',
1607
+ uplinksLook: false,
1608
+ requestOptions: options,
1609
+ })
1610
+ ).rejects.toThrow('package does not exist on uplink: foo');
1611
+ });
1612
+
1613
+ test('should fail as non-owner with check', async () => {
1614
+ const config = getConfig('publishWithOwnerAndCheck.yaml');
1615
+ const storage = new Storage(config, logger);
1616
+ await storage.init(config);
1617
+ const owner = 'fooUser';
1618
+ const options = { ...defaultRequestOptions, username: owner };
1619
+
1620
+ // 1. publish a package
1621
+ const bodyNewManifest = generatePackageMetadata('foo', '1.0.0');
1622
+ await storage.updateManifest(bodyNewManifest, {
1623
+ signal: new AbortController().signal,
1624
+ name: 'foo',
1625
+ uplinksLook: true,
1626
+ requestOptions: options,
1627
+ });
1628
+ // 2. request package (should be available in the local cache)
1629
+ const manifest1 = (await storage.getPackageByOptions({
1630
+ name: 'foo',
1631
+ uplinksLook: false,
1632
+ requestOptions: options,
1633
+ })) as Manifest;
1634
+ const _rev = manifest1._rev;
1635
+ // 3. try removing the tarball
1636
+ const nonOwner = 'barUser';
1637
+ await expect(
1638
+ storage.removeTarball(manifest1.name, 'foo-1.0.0.tgz', _rev, nonOwner)
1639
+ ).rejects.toThrow();
1640
+ // 4. try removing the package
1641
+ await expect(storage.removePackage(manifest1.name, _rev, nonOwner)).rejects.toThrow();
1642
+ });
1260
1643
  });
1261
1644
 
1262
1645
  describe('getPackageByOptions()', () => {
@@ -1278,7 +1661,7 @@ describe('storage', () => {
1278
1661
  },
1279
1662
  url: '/',
1280
1663
  });
1281
- const storage = new Storage(config);
1664
+ const storage = new Storage(config, logger);
1282
1665
  await storage.init(config);
1283
1666
  await expect(
1284
1667
  storage.getPackageByOptions({
@@ -1310,7 +1693,7 @@ describe('storage', () => {
1310
1693
  },
1311
1694
  url: '/',
1312
1695
  });
1313
- const storage = new Storage(config);
1696
+ const storage = new Storage(config, logger);
1314
1697
  await storage.init(config);
1315
1698
  await expect(
1316
1699
  storage.getPackageByOptions({
@@ -1343,7 +1726,7 @@ describe('storage', () => {
1343
1726
  },
1344
1727
  url: '/',
1345
1728
  });
1346
- const storage = new Storage(config);
1729
+ const storage = new Storage(config, logger);
1347
1730
  await storage.init(config);
1348
1731
  await expect(
1349
1732
  storage.getPackageByOptions({
@@ -1376,7 +1759,7 @@ describe('storage', () => {
1376
1759
  },
1377
1760
  url: '/',
1378
1761
  });
1379
- const storage = new Storage(config);
1762
+ const storage = new Storage(config, logger);
1380
1763
  await storage.init(config);
1381
1764
  await expect(
1382
1765
  storage.getPackageByOptions({
@@ -1416,7 +1799,7 @@ describe('storage', () => {
1416
1799
  },
1417
1800
  url: '/',
1418
1801
  });
1419
- const storage = new Storage(config);
1802
+ const storage = new Storage(config, logger);
1420
1803
  await storage.init(config);
1421
1804
  await expect(
1422
1805
  storage.getPackageByOptions({
@@ -1456,7 +1839,7 @@ describe('storage', () => {
1456
1839
  },
1457
1840
  url: '/',
1458
1841
  });
1459
- const storage = new Storage(config);
1842
+ const storage = new Storage(config, logger);
1460
1843
  await storage.init(config);
1461
1844
  await expect(
1462
1845
  storage.getPackageByOptions({
@@ -1490,7 +1873,7 @@ describe('storage', () => {
1490
1873
  },
1491
1874
  url: '/',
1492
1875
  });
1493
- const storage = new Storage(config);
1876
+ const storage = new Storage(config, logger);
1494
1877
  await storage.init(config);
1495
1878
 
1496
1879
  const manifest = (await storage.getPackageByOptions({
@@ -1511,7 +1894,6 @@ describe('storage', () => {
1511
1894
  expect(Object.keys(version)).toEqual([
1512
1895
  'name',
1513
1896
  'version',
1514
- 'description',
1515
1897
  'deprecated',
1516
1898
  'bin',
1517
1899
  'dist',
@@ -1523,6 +1905,10 @@ describe('storage', () => {
1523
1905
  'peerDependencies',
1524
1906
  'optionalDependencies',
1525
1907
  'bundleDependencies',
1908
+ 'cpu',
1909
+ 'os',
1910
+ 'peerDependenciesMeta',
1911
+ 'acceptDependencies',
1526
1912
  '_hasShrinkwrap',
1527
1913
  'hasInstallScript',
1528
1914
  ]);