@eik/core 1.3.54 → 1.3.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/classes/alias.js +48 -48
- package/lib/classes/asset.js +99 -92
- package/lib/classes/author.js +20 -20
- package/lib/classes/http-incoming.js +52 -52
- package/lib/classes/http-outgoing.js +84 -83
- package/lib/classes/meta.js +20 -23
- package/lib/classes/package.js +73 -70
- package/lib/classes/versions.js +62 -60
- package/lib/handlers/alias.delete.js +125 -120
- package/lib/handlers/alias.get.js +92 -87
- package/lib/handlers/alias.post.js +196 -203
- package/lib/handlers/alias.put.js +196 -202
- package/lib/handlers/auth.post.js +95 -93
- package/lib/handlers/map.get.js +110 -111
- package/lib/handlers/map.put.js +256 -231
- package/lib/handlers/pkg.get.js +120 -122
- package/lib/handlers/pkg.log.js +112 -110
- package/lib/handlers/pkg.put.js +223 -213
- package/lib/handlers/versions.get.js +92 -101
- package/lib/main.js +47 -47
- package/lib/multipart/form-field.js +20 -23
- package/lib/multipart/form-file.js +22 -24
- package/lib/multipart/parser.js +231 -217
- package/lib/sinks/mem-entry.js +26 -31
- package/lib/sinks/test.js +289 -273
- package/lib/utils/defaults.js +11 -11
- package/lib/utils/globals.js +5 -5
- package/lib/utils/healthcheck.js +131 -108
- package/lib/utils/path-builders-fs.js +61 -29
- package/lib/utils/path-builders-uri.js +26 -18
- package/lib/utils/utils.js +76 -79
- package/package.json +20 -15
- package/types/classes/alias.d.ts +28 -0
- package/types/classes/asset.d.ts +48 -0
- package/types/classes/author.d.ts +17 -0
- package/types/classes/http-incoming.d.ts +37 -0
- package/types/classes/http-outgoing.d.ts +20 -0
- package/types/classes/meta.d.ts +17 -0
- package/types/classes/package.d.ts +40 -0
- package/types/classes/versions.d.ts +28 -0
- package/types/handlers/alias.delete.d.ts +33 -0
- package/types/handlers/alias.get.d.ts +48 -0
- package/types/handlers/alias.post.d.ts +83 -0
- package/types/handlers/alias.put.d.ts +83 -0
- package/types/handlers/auth.post.d.ts +82 -0
- package/types/handlers/map.get.d.ts +51 -0
- package/types/handlers/map.put.d.ts +78 -0
- package/types/handlers/pkg.get.d.ts +51 -0
- package/types/handlers/pkg.log.d.ts +51 -0
- package/types/handlers/pkg.put.d.ts +107 -0
- package/types/handlers/versions.get.d.ts +48 -0
- package/types/main.d.ts +44 -0
- package/types/multipart/form-field.d.ts +17 -0
- package/types/multipart/form-file.d.ts +17 -0
- package/types/multipart/parser.d.ts +52 -0
- package/types/sinks/mem-entry.d.ts +15 -0
- package/types/sinks/test.d.ts +32 -0
- package/types/utils/defaults.d.ts +9 -0
- package/types/utils/globals.d.ts +8 -0
- package/types/utils/healthcheck.d.ts +24 -0
- package/types/utils/path-builders-fs.d.ts +41 -0
- package/types/utils/path-builders-uri.d.ts +26 -0
- package/types/utils/utils.d.ts +6 -0
package/lib/classes/meta.js
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
const Meta = class Meta {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
this._value = value;
|
|
7
|
-
this._name = name;
|
|
8
|
-
}
|
|
2
|
+
constructor({ value = "", name = "" } = {}) {
|
|
3
|
+
this._value = value;
|
|
4
|
+
this._name = name;
|
|
5
|
+
}
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
get value() {
|
|
8
|
+
return this._value;
|
|
9
|
+
}
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
get name() {
|
|
12
|
+
return this._name;
|
|
13
|
+
}
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
toJSON() {
|
|
16
|
+
return {
|
|
17
|
+
value: this.value,
|
|
18
|
+
name: this.name,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
22
|
+
get [Symbol.toStringTag]() {
|
|
23
|
+
return "Meta";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
29
26
|
|
|
30
27
|
export default Meta;
|
package/lib/classes/package.js
CHANGED
|
@@ -1,86 +1,89 @@
|
|
|
1
|
-
import crypto from
|
|
2
|
-
import Asset from
|
|
3
|
-
import Meta from
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import Asset from "./asset.js";
|
|
3
|
+
import Meta from "./meta.js";
|
|
4
4
|
|
|
5
5
|
const Package = class Package {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
constructor({
|
|
7
|
+
version = "",
|
|
8
|
+
type = "",
|
|
9
|
+
name = "",
|
|
10
|
+
org = "",
|
|
11
|
+
author = {},
|
|
12
|
+
} = {}) {
|
|
13
|
+
this._version = version;
|
|
14
|
+
// @ts-expect-error
|
|
15
|
+
this._created = Math.floor(new Date() / 1000);
|
|
16
|
+
this._author = author;
|
|
17
|
+
this._type = type;
|
|
18
|
+
this._name = name;
|
|
19
|
+
this._org = org;
|
|
20
|
+
this._files = [];
|
|
21
|
+
this._meta = [];
|
|
22
|
+
}
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
get integrity() {
|
|
25
|
+
const hasher = crypto.createHash("sha512");
|
|
26
|
+
const hashes = this._files.map((file) => file.integrity);
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
for (const hash of hashes.sort()) {
|
|
29
|
+
hasher.update(hash);
|
|
30
|
+
}
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
return `sha512-${hasher.digest("base64")}`;
|
|
33
|
+
}
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
get version() {
|
|
36
|
+
return this._version;
|
|
37
|
+
}
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
get created() {
|
|
40
|
+
return this._created;
|
|
41
|
+
}
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
get author() {
|
|
44
|
+
return this._author;
|
|
45
|
+
}
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
get type() {
|
|
48
|
+
return this._type;
|
|
49
|
+
}
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
get name() {
|
|
52
|
+
return this._name;
|
|
53
|
+
}
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
get org() {
|
|
56
|
+
return this._org;
|
|
57
|
+
}
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this._files.push(asset);
|
|
58
|
-
}
|
|
59
|
+
setAsset(asset) {
|
|
60
|
+
if (!(asset instanceof Asset))
|
|
61
|
+
throw new TypeError('Argument "asset" must be an instance of Asset');
|
|
62
|
+
this._files.push(asset);
|
|
63
|
+
}
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this._meta.push(meta);
|
|
66
|
-
}
|
|
65
|
+
setMeta(meta) {
|
|
66
|
+
if (!(meta instanceof Meta))
|
|
67
|
+
throw new TypeError('Argument "meta" must be an instance of Meta');
|
|
68
|
+
this._meta.push(meta);
|
|
69
|
+
}
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
71
|
+
toJSON() {
|
|
72
|
+
return {
|
|
73
|
+
integrity: this.integrity,
|
|
74
|
+
version: this.version,
|
|
75
|
+
created: this.created,
|
|
76
|
+
author: this.author,
|
|
77
|
+
type: this.type,
|
|
78
|
+
name: this.name,
|
|
79
|
+
org: this.org,
|
|
80
|
+
files: this._files,
|
|
81
|
+
meta: this._meta,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
85
|
+
get [Symbol.toStringTag]() {
|
|
86
|
+
return "Package";
|
|
87
|
+
}
|
|
88
|
+
};
|
|
86
89
|
export default Package;
|
package/lib/classes/versions.js
CHANGED
|
@@ -1,63 +1,65 @@
|
|
|
1
|
-
import semver from
|
|
1
|
+
import semver from "semver";
|
|
2
2
|
|
|
3
3
|
const Versions = class Versions {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
4
|
+
constructor({ versions = [], type = "", name = "", org = "" } = {}) {
|
|
5
|
+
this._versions = new Map(versions);
|
|
6
|
+
this._type = type;
|
|
7
|
+
this._name = name;
|
|
8
|
+
this._org = org;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get versions() {
|
|
12
|
+
return Array.from(this._versions.entries()).sort((a, b) =>
|
|
13
|
+
a[0] > b[0] ? -1 : 1,
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get type() {
|
|
18
|
+
return this._type;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get name() {
|
|
22
|
+
return this._name;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
get org() {
|
|
26
|
+
return this._org;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setVersion(version, integrity) {
|
|
30
|
+
const major = semver.major(version);
|
|
31
|
+
this._versions.set(major, {
|
|
32
|
+
version,
|
|
33
|
+
integrity,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
getVersion(major) {
|
|
38
|
+
return this._versions.get(major);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
check(version) {
|
|
42
|
+
const major = semver.major(version);
|
|
43
|
+
const previous = this.getVersion(major);
|
|
44
|
+
if (previous) {
|
|
45
|
+
if (semver.gte(previous.version, version)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
toJSON() {
|
|
53
|
+
return {
|
|
54
|
+
versions: this.versions,
|
|
55
|
+
type: this.type,
|
|
56
|
+
name: this.name,
|
|
57
|
+
org: this.org,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get [Symbol.toStringTag]() {
|
|
62
|
+
return "Versions";
|
|
63
|
+
}
|
|
64
|
+
};
|
|
63
65
|
export default Versions;
|
|
@@ -1,125 +1,130 @@
|
|
|
1
|
-
import { validators } from
|
|
2
|
-
import originalUrl from
|
|
3
|
-
import HttpError from
|
|
4
|
-
import Metrics from
|
|
5
|
-
import abslog from
|
|
1
|
+
import { validators } from "@eik/common";
|
|
2
|
+
import originalUrl from "original-url";
|
|
3
|
+
import HttpError from "http-errors";
|
|
4
|
+
import Metrics from "@metrics/client";
|
|
5
|
+
import abslog from "abslog";
|
|
6
6
|
|
|
7
|
-
import { createFilePathToAlias } from
|
|
8
|
-
import { decodeUriComponent } from
|
|
9
|
-
import HttpOutgoing from
|
|
10
|
-
import config from
|
|
7
|
+
import { createFilePathToAlias } from "../utils/path-builders-fs.js";
|
|
8
|
+
import { decodeUriComponent } from "../utils/utils.js";
|
|
9
|
+
import HttpOutgoing from "../classes/http-outgoing.js";
|
|
10
|
+
import config from "../utils/defaults.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {object} AliasDeleteOptions
|
|
14
|
+
* @property {string} [cacheControl]
|
|
15
|
+
* @property {Array<[string, string]>} [organizations] List of key-value pairs [hostname, organization]
|
|
16
|
+
* @property {import("@eik/sink").default} [sink]
|
|
17
|
+
* @property {import("abslog").AbstractLoggerOptions} [logger]
|
|
18
|
+
*/
|
|
11
19
|
|
|
12
20
|
const AliasDel = class AliasDel {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return outgoing;
|
|
123
|
-
}
|
|
21
|
+
/**
|
|
22
|
+
* @param {AliasDeleteOptions} options
|
|
23
|
+
*/
|
|
24
|
+
constructor({ organizations, cacheControl, logger, sink } = {}) {
|
|
25
|
+
this._organizations = organizations || config.organizations;
|
|
26
|
+
this._cacheControl = cacheControl;
|
|
27
|
+
this._sink = sink;
|
|
28
|
+
this._log = abslog(logger);
|
|
29
|
+
this._metrics = new Metrics();
|
|
30
|
+
this._histogram = this._metrics.histogram({
|
|
31
|
+
name: "eik_core_alias_del_handler",
|
|
32
|
+
description:
|
|
33
|
+
"Histogram measuring time taken in @eik/core AliasDel handler method",
|
|
34
|
+
labels: {
|
|
35
|
+
success: true,
|
|
36
|
+
type: "unknown",
|
|
37
|
+
},
|
|
38
|
+
buckets: [0.005, 0.01, 0.06, 0.1, 0.6, 1.0, 2.0, 4.0],
|
|
39
|
+
});
|
|
40
|
+
this._orgRegistry = new Map(this._organizations);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get metrics() {
|
|
44
|
+
return this._metrics;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async _exist(path = "") {
|
|
48
|
+
try {
|
|
49
|
+
await this._sink.exist(path);
|
|
50
|
+
return true;
|
|
51
|
+
// eslint-disable-next-line no-unused-vars
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async handler(req, user, type, name, alias) {
|
|
58
|
+
const end = this._histogram.timer();
|
|
59
|
+
|
|
60
|
+
const pAlias = decodeUriComponent(alias);
|
|
61
|
+
const pName = decodeUriComponent(name);
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
validators.alias(pAlias);
|
|
65
|
+
validators.name(pName);
|
|
66
|
+
validators.type(type);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
this._log.info(`alias:del - Validation failed - ${error.message}`);
|
|
69
|
+
const e = new HttpError.NotFound();
|
|
70
|
+
end({ labels: { success: false, status: e.status } });
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const url = originalUrl(req);
|
|
75
|
+
const org = this._orgRegistry.get(url.hostname);
|
|
76
|
+
|
|
77
|
+
if (!org) {
|
|
78
|
+
this._log.info(
|
|
79
|
+
`alias:del - Hostname does not match a configured organization - ${url.hostname}`,
|
|
80
|
+
);
|
|
81
|
+
const e = new HttpError.BadRequest();
|
|
82
|
+
end({ labels: { success: false, status: e.status, type } });
|
|
83
|
+
throw e;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const path = createFilePathToAlias({
|
|
87
|
+
org,
|
|
88
|
+
type,
|
|
89
|
+
name: pName,
|
|
90
|
+
alias: pAlias,
|
|
91
|
+
});
|
|
92
|
+
const exist = await this._exist(path);
|
|
93
|
+
if (!exist) {
|
|
94
|
+
this._log.info(
|
|
95
|
+
`alias:del - Alias does not exists - Org: ${org} - Type: ${type} - Name: ${pName} - Alias: ${pAlias}`,
|
|
96
|
+
);
|
|
97
|
+
const e = new HttpError.NotFound();
|
|
98
|
+
end({ labels: { success: false, status: e.status, type } });
|
|
99
|
+
throw e;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
this._log.info(
|
|
104
|
+
`alias:del - Start deleting alias from sink - Pathname: ${path}`,
|
|
105
|
+
);
|
|
106
|
+
await this._sink.delete(path);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
this._log.error(
|
|
109
|
+
`alias:del - Failed deleting alias from sink - Pathname: ${path}`,
|
|
110
|
+
);
|
|
111
|
+
this._log.trace(error);
|
|
112
|
+
const e = new HttpError.BadGateway();
|
|
113
|
+
end({ labels: { success: false, status: e.status, type } });
|
|
114
|
+
return e;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
this._log.info(
|
|
118
|
+
`alias:del - Successfully deleted alias from sink - Pathname: ${path}`,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const outgoing = new HttpOutgoing();
|
|
122
|
+
outgoing.cacheControl = this._cacheControl;
|
|
123
|
+
outgoing.statusCode = 204;
|
|
124
|
+
|
|
125
|
+
end({ labels: { status: outgoing.statusCode, type } });
|
|
126
|
+
|
|
127
|
+
return outgoing;
|
|
128
|
+
}
|
|
124
129
|
};
|
|
125
130
|
export default AliasDel;
|