@verdaccio/core 6.0.0-6-next.3 → 6.0.0-6-next.6

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/CHANGELOG.md +92 -0
  2. package/build/constants.d.ts +15 -0
  3. package/build/constants.js +20 -2
  4. package/build/constants.js.map +1 -1
  5. package/build/error-utils.d.ts +2 -0
  6. package/build/error-utils.js +2 -0
  7. package/build/error-utils.js.map +1 -1
  8. package/build/file-utils.d.ts +13 -0
  9. package/build/file-utils.js +37 -0
  10. package/build/file-utils.js.map +1 -1
  11. package/build/index.d.ts +7 -6
  12. package/build/index.js +18 -17
  13. package/build/index.js.map +1 -1
  14. package/build/path-utils.js.map +1 -1
  15. package/build/pkg-utils.d.ts +11 -3
  16. package/build/pkg-utils.js +18 -0
  17. package/build/pkg-utils.js.map +1 -1
  18. package/build/plugin-utils.js.map +1 -1
  19. package/build/schemes/publish-manifest.d.ts +7 -0
  20. package/build/schemes/publish-manifest.js +49 -0
  21. package/build/schemes/publish-manifest.js.map +1 -0
  22. package/build/search-utils.d.ts +8 -4
  23. package/build/search-utils.js +2 -0
  24. package/build/search-utils.js.map +1 -1
  25. package/build/stream-utils.d.ts +1 -1
  26. package/build/stream-utils.js.map +1 -1
  27. package/build/validation-utils.d.ts +5 -3
  28. package/build/validation-utils.js +25 -14
  29. package/build/validation-utils.js.map +1 -1
  30. package/build/warning-utils.d.ts +0 -3
  31. package/build/warning-utils.js +2 -8
  32. package/build/warning-utils.js.map +1 -1
  33. package/package.json +61 -57
  34. package/src/constants.ts +18 -0
  35. package/src/error-utils.ts +3 -0
  36. package/src/file-utils.ts +26 -0
  37. package/src/index.ts +8 -6
  38. package/src/pkg-utils.ts +20 -3
  39. package/src/plugin-utils.ts +1 -0
  40. package/src/schemes/publish-manifest.ts +38 -0
  41. package/src/search-utils.ts +15 -4
  42. package/src/stream-utils.ts +1 -1
  43. package/src/validation-utils.ts +19 -13
  44. package/src/warning-utils.ts +2 -18
  45. package/test/errors.spec.ts +7 -7
  46. package/test/merge.dist.tags.spec.ts +1 -1
  47. package/test/mystreams.spec.ts +2 -1
  48. package/test/pkg-utils.spec.ts +42 -0
  49. package/test/validation-utilts.spec.ts +96 -2
@@ -1,4 +1,5 @@
1
1
  import { Config, IPackageStorage, Token, TokenFilter } from '@verdaccio/types';
2
+
2
3
  import { searchUtils } from '.';
3
4
 
4
5
  interface IPlugin {
@@ -0,0 +1,38 @@
1
+ import Ajv, { JSONSchemaType } from 'ajv';
2
+
3
+ const ajv = new Ajv();
4
+
5
+ // FIXME: this could extend from @verdaccio/types but we need
6
+ // schemas from @verdaccio/types to be able to validate them
7
+ interface Manifest {
8
+ name: string;
9
+ versions: object;
10
+ _attachments: object;
11
+ }
12
+
13
+ const schema: JSONSchemaType<Manifest> = {
14
+ type: 'object',
15
+ properties: {
16
+ name: { type: 'string' },
17
+ versions: { type: 'object', maxProperties: 1 },
18
+ _attachments: { type: 'object', maxProperties: 1 },
19
+ },
20
+ required: ['name', 'versions', '_attachments'],
21
+ additionalProperties: true,
22
+ };
23
+
24
+ // validate is a type guard for MyData - type is inferred from schema type
25
+ const validate = ajv.compile(schema);
26
+
27
+ /**
28
+ * Validate if a manifest has the correct structure when a new package
29
+ * is being created. The properties name, versions and _attachments must contain 1 element.
30
+ * @param data a manifest object
31
+ * @returns boolean
32
+ */
33
+ export function validatePublishSingleVersion(manifest: any) {
34
+ if (!manifest) {
35
+ return false;
36
+ }
37
+ return validate(manifest);
38
+ }
@@ -16,10 +16,19 @@ export type SearchItemPkg = {
16
16
  time?: number | Date;
17
17
  };
18
18
 
19
- export type SearchItem = {
19
+ type PrivatePackage = {
20
+ // note: prefixed to avoid external conflicts
21
+
22
+ // the package is published as private
23
+ verdaccioPrivate?: boolean;
24
+ // if the package is not private but is cached
25
+ verdaccioPkgCached?: boolean;
26
+ };
27
+
28
+ export interface SearchItem extends UnStable, PrivatePackage {
20
29
  package: SearchItemPkg;
21
30
  score: Score;
22
- } & UnStable;
31
+ }
23
32
 
24
33
  export type Score = {
25
34
  final: number;
@@ -32,11 +41,13 @@ export type SearchResults = {
32
41
  time: string;
33
42
  };
34
43
 
44
+ // @deprecated use @verdaccio/types
35
45
  type PublisherMaintainer = {
36
46
  username: string;
37
47
  email: string;
38
48
  };
39
49
 
50
+ // @deprecated use @verdaccio/types
40
51
  export type SearchPackageBody = {
41
52
  name: string;
42
53
  scope: string;
@@ -55,11 +66,11 @@ export type SearchPackageBody = {
55
66
  maintainers?: PublisherMaintainer[];
56
67
  };
57
68
 
58
- export type SearchPackageItem = {
69
+ export interface SearchPackageItem extends UnStable, PrivatePackage {
59
70
  package: SearchPackageBody;
60
71
  score: Score;
61
72
  searchScore?: number;
62
- } & UnStable;
73
+ }
63
74
 
64
75
  export const UNSCOPED = 'unscoped';
65
76
 
@@ -1,4 +1,4 @@
1
- import { PassThrough, TransformOptions, Transform } from 'stream';
1
+ import { PassThrough, Transform, TransformOptions } from 'stream';
2
2
 
3
3
  export interface IReadTarball {
4
4
  abort?: () => void;
@@ -1,7 +1,11 @@
1
1
  import assert from 'assert';
2
- import { Package } from '@verdaccio/types';
2
+
3
+ import { Manifest } from '@verdaccio/types';
4
+
3
5
  import { DIST_TAGS } from './constants';
4
6
 
7
+ export { validatePublishSingleVersion } from './schemes/publish-manifest';
8
+
5
9
  export function isPackageNameScoped(name: string): boolean {
6
10
  return name.startsWith('@');
7
11
  }
@@ -60,27 +64,29 @@ export function validatePackage(name: string): boolean {
60
64
  /**
61
65
  * Validate the package metadata, add additional properties whether are missing within
62
66
  * the metadata properties.
63
- * @param {*} object
67
+ * @param {*} manifest
64
68
  * @param {*} name
65
69
  * @return {Object} the object with additional properties as dist-tags ad versions
70
+ * FUTURE: rename to normalizeMetadata
66
71
  */
67
- export function validateMetadata(object: Package, name: string): Package {
68
- assert(isObject(object), 'not a json object');
69
- assert.strictEqual(object.name, name);
72
+ export function normalizeMetadata(manifest: Manifest, name: string): Manifest {
73
+ assert.strictEqual(manifest.name, name);
74
+ const _manifest = { ...manifest };
70
75
 
71
- if (!isObject(object[DIST_TAGS])) {
72
- object[DIST_TAGS] = {};
76
+ if (!isObject(manifest[DIST_TAGS])) {
77
+ _manifest[DIST_TAGS] = {};
73
78
  }
74
79
 
75
- if (!isObject(object['versions'])) {
76
- object['versions'] = {};
80
+ // This may not be nee dit
81
+ if (!isObject(manifest['versions'])) {
82
+ _manifest['versions'] = {};
77
83
  }
78
84
 
79
- if (!isObject(object['time'])) {
80
- object['time'] = {};
85
+ if (!isObject(manifest['time'])) {
86
+ _manifest['time'] = {};
81
87
  }
82
88
 
83
- return object;
89
+ return _manifest;
84
90
  }
85
91
 
86
92
  /**
@@ -89,7 +95,7 @@ export function validateMetadata(object: Package, name: string): Package {
89
95
  * @return {Boolean}
90
96
  */
91
97
  export function isObject(obj: any): boolean {
92
- if (obj === null || typeof obj === 'undefined') {
98
+ if (obj === null || typeof obj === 'undefined' || typeof obj === 'string') {
93
99
  return false;
94
100
  }
95
101
 
@@ -1,4 +1,4 @@
1
- import warning from 'fastify-warning';
1
+ import warning from 'process-warning';
2
2
 
3
3
  const warningInstance = warning();
4
4
  const verdaccioWarning = 'VerdaccioWarning';
@@ -6,11 +6,9 @@ const verdaccioDeprecation = 'VerdaccioDeprecation';
6
6
 
7
7
  export enum Codes {
8
8
  VERWAR001 = 'VERWAR001',
9
- VERWAR002 = 'VERWAR002',
10
9
  VERWAR003 = 'VERWAR003',
11
10
  VERWAR004 = 'VERWAR004',
12
- VERDEP001 = 'VERDEP001',
13
- VERDEP002 = 'VERDEP002',
11
+ // deprecation warnings
14
12
  VERDEP003 = 'VERDEP003',
15
13
  }
16
14
 
@@ -20,8 +18,6 @@ warningInstance.create(
20
18
  `Verdaccio doesn't need superuser privileges. don't run it under root`
21
19
  );
22
20
 
23
- warningInstance.create(verdaccioWarning, Codes.VERWAR002, 'logger is not defined');
24
-
25
21
  warningInstance.create(
26
22
  verdaccioWarning,
27
23
  Codes.VERWAR003,
@@ -36,18 +32,6 @@ host:port (e.g. "localhost:4873") or full url '(e.g. "http://localhost:4873/")
36
32
  https://verdaccio.org/docs/en/configuration#listen-port`
37
33
  );
38
34
 
39
- warningInstance.create(
40
- verdaccioDeprecation,
41
- Codes.VERDEP001,
42
- 'config.logs is deprecated, rename configuration to "config.log" in singular'
43
- );
44
-
45
- warningInstance.create(
46
- verdaccioDeprecation,
47
- Codes.VERDEP002,
48
- 'deprecate: multiple logger configuration is deprecated, please check the migration guide.'
49
- );
50
-
51
35
  warningInstance.create(
52
36
  verdaccioDeprecation,
53
37
  Codes.VERDEP003,
@@ -1,17 +1,17 @@
1
1
  import _ from 'lodash';
2
- import { HTTP_STATUS } from '../src/constants';
3
2
 
3
+ import { HTTP_STATUS } from '../src/constants';
4
4
  import {
5
- getNotFound,
5
+ API_ERROR,
6
6
  VerdaccioError,
7
- getConflict,
8
7
  getBadData,
9
- getInternalError,
10
- API_ERROR,
11
- getUnauthorized,
8
+ getCode,
9
+ getConflict,
12
10
  getForbidden,
11
+ getInternalError,
12
+ getNotFound,
13
13
  getServiceUnavailable,
14
- getCode,
14
+ getUnauthorized,
15
15
  } from '../src/error-utils';
16
16
 
17
17
  describe('testing errors', () => {
@@ -1,4 +1,4 @@
1
- import { semverSort, mergeVersions } from '../src/pkg-utils';
1
+ import { mergeVersions, semverSort } from '../src/pkg-utils';
2
2
 
3
3
  describe('Storage._merge_versions versions', () => {
4
4
  test('simple', () => {
@@ -1,5 +1,6 @@
1
1
  import { Stream } from 'stream';
2
- import { readableToString, ReadTarball, UploadTarball } from '../src/stream-utils';
2
+
3
+ import { ReadTarball, UploadTarball, readableToString } from '../src/stream-utils';
3
4
 
4
5
  describe('mystreams', () => {
5
6
  test('should delay events on ReadTarball abort', (cb) => {
@@ -0,0 +1,42 @@
1
+ import { DIST_TAGS, pkgUtils } from '../src';
2
+
3
+ describe('pkg-utils', () => {
4
+ test('extractTarballName', () => {
5
+ expect(pkgUtils.extractTarballName('https://registry.npmjs.org/test/-/test-0.0.2.tgz')).toBe(
6
+ 'test-0.0.2.tgz'
7
+ );
8
+ });
9
+
10
+ test('extractTarballName with no tarball should not fails', () => {
11
+ expect(pkgUtils.extractTarballName('https://registry.npmjs.org/')).toBe('');
12
+ });
13
+
14
+ test('extractTarballName fails', () => {
15
+ expect(() =>
16
+ pkgUtils.extractTarballName('xxxxregistry.npmjs.org/test/-/test-0.0.2.tgz')
17
+ ).toThrow();
18
+ });
19
+
20
+ test('getLatest fails if no versions', () => {
21
+ expect(() =>
22
+ // @ts-expect-error
23
+ pkgUtils.getLatest({
24
+ versions: {},
25
+ })
26
+ ).toThrow('cannot get lastest version of none');
27
+ });
28
+
29
+ test('getLatest get latest', () => {
30
+ expect(
31
+ pkgUtils.getLatest({
32
+ versions: {
33
+ // @ts-expect-error
34
+ '1.0.0': {},
35
+ },
36
+ [DIST_TAGS]: {
37
+ latest: '1.0.0',
38
+ },
39
+ })
40
+ ).toBe('1.0.0');
41
+ });
42
+ });
@@ -1,4 +1,11 @@
1
- import { validateName, validatePackage, isObject } from '../src/validation-utils';
1
+ import { DIST_TAGS } from '../src/constants';
2
+ import { validatePublishSingleVersion } from '../src/schemes/publish-manifest';
3
+ import {
4
+ isObject,
5
+ normalizeMetadata,
6
+ validateName,
7
+ validatePackage,
8
+ } from '../src/validation-utils';
2
9
 
3
10
  describe('validatePackage', () => {
4
11
  test('should validate package names', () => {
@@ -19,13 +26,41 @@ describe('validatePackage', () => {
19
26
  describe('isObject', () => {
20
27
  test('isObject metadata', () => {
21
28
  expect(isObject({ foo: 'bar' })).toBeTruthy();
22
- expect(isObject('foo')).toBeTruthy();
29
+ // expect(isObject('foo')).toBeTruthy();
23
30
  expect(isObject(['foo'])).toBeFalsy();
24
31
  expect(isObject(null)).toBeFalsy();
25
32
  expect(isObject(undefined)).toBeFalsy();
26
33
  });
27
34
  });
28
35
 
36
+ describe('normalizeMetadata', () => {
37
+ test('should fills an empty metadata object', () => {
38
+ // intended to fail with flow, do not remove
39
+ // @ts-ignore
40
+ expect(Object.keys(normalizeMetadata({}))).toContain(DIST_TAGS);
41
+ // @ts-ignore
42
+ expect(Object.keys(normalizeMetadata({}))).toContain('versions');
43
+ // @ts-ignore
44
+ expect(Object.keys(normalizeMetadata({}))).toContain('time');
45
+ });
46
+
47
+ test.skip('should fails the assertions is not an object', () => {
48
+ expect(function () {
49
+ // @ts-ignore
50
+ normalizeMetadata('');
51
+ // @ts-ignore
52
+ }).toThrow(expect.hasAssertions());
53
+ });
54
+
55
+ test('should fails the assertions is name does not match', () => {
56
+ expect(function () {
57
+ // @ts-ignore
58
+ normalizeMetadata({}, 'no-name');
59
+ // @ts-ignore
60
+ }).toThrow(expect.hasAssertions());
61
+ });
62
+ });
63
+
29
64
  describe('validateName', () => {
30
65
  test('should fails with no string', () => {
31
66
  // intended to fail with Typescript, do not remove
@@ -72,3 +107,62 @@ describe('validateName', () => {
72
107
  expect(validateName('pk:g')).toBeFalsy();
73
108
  });
74
109
  });
110
+
111
+ describe('validatePublishSingleVersion', () => {
112
+ test('should be valid', () => {
113
+ expect(
114
+ validatePublishSingleVersion({
115
+ name: 'foo-pkg',
116
+ _attachments: { '2': {} },
117
+ versions: { '1': {} },
118
+ })
119
+ ).toBeTruthy();
120
+ });
121
+
122
+ test('should be invalid if name is missing', () => {
123
+ expect(
124
+ validatePublishSingleVersion({
125
+ _attachments: { '2': {} },
126
+ versions: { '1': {} },
127
+ })
128
+ ).toBeFalsy();
129
+ });
130
+
131
+ test('should be invalid if _attachments is missing', () => {
132
+ expect(
133
+ validatePublishSingleVersion({
134
+ name: 'foo-pkg',
135
+ versions: { '1': {} },
136
+ })
137
+ ).toBeFalsy();
138
+ });
139
+
140
+ test('should be invalid if versions is missing', () => {
141
+ expect(
142
+ validatePublishSingleVersion({
143
+ name: 'foo-pkg',
144
+ _attachments: { '1': {} },
145
+ })
146
+ ).toBeFalsy();
147
+ });
148
+
149
+ test('should be invalid if versions is more than 1', () => {
150
+ expect(
151
+ validatePublishSingleVersion({
152
+ name: 'foo-pkg',
153
+ versions: { '1': {}, '2': {} },
154
+ _attachments: { '1': {} },
155
+ })
156
+ ).toBeFalsy();
157
+ });
158
+
159
+ test('should be invalid if _attachments is more than 1', () => {
160
+ expect(
161
+ validatePublishSingleVersion({
162
+ name: 'foo-pkg',
163
+ _attachments: { '1': {}, '2': {} },
164
+ versions: { '1': {} },
165
+ })
166
+ ).toBeFalsy();
167
+ });
168
+ });