@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/handlers/pkg.get.js
CHANGED
|
@@ -1,126 +1,124 @@
|
|
|
1
|
-
import { validators } from
|
|
2
|
-
import originalUrl from
|
|
3
|
-
import HttpError from
|
|
4
|
-
import abslog from
|
|
5
|
-
import Metrics from
|
|
6
|
-
|
|
7
|
-
import { createFilePathToAsset } from
|
|
8
|
-
import { decodeUriComponent } from
|
|
9
|
-
import HttpOutgoing from
|
|
10
|
-
import Asset from
|
|
11
|
-
import config from
|
|
1
|
+
import { validators } from "@eik/common";
|
|
2
|
+
import originalUrl from "original-url";
|
|
3
|
+
import HttpError from "http-errors";
|
|
4
|
+
import abslog from "abslog";
|
|
5
|
+
import Metrics from "@metrics/client";
|
|
6
|
+
|
|
7
|
+
import { createFilePathToAsset } from "../utils/path-builders-fs.js";
|
|
8
|
+
import { decodeUriComponent } from "../utils/utils.js";
|
|
9
|
+
import HttpOutgoing from "../classes/http-outgoing.js";
|
|
10
|
+
import Asset from "../classes/asset.js";
|
|
11
|
+
import config from "../utils/defaults.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {object} PkgGetOptions
|
|
15
|
+
* @property {boolean} [etag]
|
|
16
|
+
* @property {string} [cacheControl]
|
|
17
|
+
* @property {Array<[string, string]>} [organizations] List of key-value pairs [hostname, organization]
|
|
18
|
+
* @property {import("@eik/sink").default} [sink]
|
|
19
|
+
* @property {import("abslog").AbstractLoggerOptions} [logger]
|
|
20
|
+
*/
|
|
12
21
|
|
|
13
22
|
const PkgGet = class PkgGet {
|
|
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
|
-
end({ labels: { status: outgoing.statusCode, type } });
|
|
116
|
-
|
|
117
|
-
return outgoing;
|
|
118
|
-
} catch (error) {
|
|
119
|
-
this._log.debug(`pkg:get - Asset not found - Pathname: ${path}`);
|
|
120
|
-
const e = new HttpError.NotFound();
|
|
121
|
-
end({ labels: { success: false, status: e.status, type } });
|
|
122
|
-
throw e;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @param {PkgGetOptions} options
|
|
26
|
+
*/
|
|
27
|
+
constructor({ organizations, cacheControl, logger, sink, etag } = {}) {
|
|
28
|
+
this._organizations = organizations || config.organizations;
|
|
29
|
+
this._cacheControl = cacheControl || "public, max-age=31536000, immutable";
|
|
30
|
+
this._sink = sink;
|
|
31
|
+
this._etag = etag || config.etag;
|
|
32
|
+
this._log = abslog(logger);
|
|
33
|
+
this._metrics = new Metrics();
|
|
34
|
+
this._histogram = this._metrics.histogram({
|
|
35
|
+
name: "eik_core_pkg_get_handler",
|
|
36
|
+
description:
|
|
37
|
+
"Histogram measuring time taken in @eik/core PkgGet handler method",
|
|
38
|
+
labels: {
|
|
39
|
+
success: true,
|
|
40
|
+
type: "unknown",
|
|
41
|
+
},
|
|
42
|
+
buckets: [0.005, 0.01, 0.06, 0.1, 0.6, 1.0, 2.0, 4.0],
|
|
43
|
+
});
|
|
44
|
+
this._orgRegistry = new Map(this._organizations);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get metrics() {
|
|
48
|
+
return this._metrics;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async handler(req, type, name, version, extra) {
|
|
52
|
+
const end = this._histogram.timer();
|
|
53
|
+
|
|
54
|
+
const pVersion = decodeUriComponent(version);
|
|
55
|
+
const pExtra = decodeUriComponent(extra);
|
|
56
|
+
const pName = decodeUriComponent(name);
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
validators.version(pVersion);
|
|
60
|
+
validators.extra(pExtra);
|
|
61
|
+
validators.name(pName);
|
|
62
|
+
validators.type(type);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
this._log.debug(`pkg:get - Validation failed - ${error.message}`);
|
|
65
|
+
const e = new HttpError.NotFound();
|
|
66
|
+
end({ labels: { success: false, status: e.status } });
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const url = originalUrl(req);
|
|
71
|
+
const org = this._orgRegistry.get(url.hostname);
|
|
72
|
+
|
|
73
|
+
if (!org) {
|
|
74
|
+
this._log.info(
|
|
75
|
+
`pkg:get - Hostname does not match a configured organization - ${url.hostname}`,
|
|
76
|
+
);
|
|
77
|
+
const e = new HttpError.BadRequest();
|
|
78
|
+
end({ labels: { success: false, status: e.status, type } });
|
|
79
|
+
throw e;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const asset = new Asset({
|
|
83
|
+
pathname: pExtra,
|
|
84
|
+
version: pVersion,
|
|
85
|
+
name: pName,
|
|
86
|
+
type,
|
|
87
|
+
org,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const path = createFilePathToAsset(asset);
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const file = await this._sink.read(path);
|
|
94
|
+
const outgoing = new HttpOutgoing();
|
|
95
|
+
outgoing.cacheControl = this._cacheControl;
|
|
96
|
+
outgoing.mimeType = asset.mimeType;
|
|
97
|
+
|
|
98
|
+
if (this._etag) {
|
|
99
|
+
outgoing.etag = file.etag;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (this._etag && req.headers["if-none-match"] === file.etag) {
|
|
103
|
+
outgoing.statusCode = 304;
|
|
104
|
+
file.stream.destroy();
|
|
105
|
+
} else {
|
|
106
|
+
outgoing.statusCode = 200;
|
|
107
|
+
outgoing.stream = file.stream;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
this._log.debug(`pkg:get - Asset found - Pathname: ${path}`);
|
|
111
|
+
|
|
112
|
+
end({ labels: { status: outgoing.statusCode, type } });
|
|
113
|
+
|
|
114
|
+
return outgoing;
|
|
115
|
+
// eslint-disable-next-line no-unused-vars
|
|
116
|
+
} catch (error) {
|
|
117
|
+
this._log.debug(`pkg:get - Asset not found - Pathname: ${path}`);
|
|
118
|
+
const e = new HttpError.NotFound();
|
|
119
|
+
end({ labels: { success: false, status: e.status, type } });
|
|
120
|
+
throw e;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
125
123
|
};
|
|
126
124
|
export default PkgGet;
|
package/lib/handlers/pkg.log.js
CHANGED
|
@@ -1,115 +1,117 @@
|
|
|
1
|
-
import { validators } from
|
|
2
|
-
import originalUrl from
|
|
3
|
-
import HttpError from
|
|
4
|
-
import abslog from
|
|
5
|
-
import Metrics from
|
|
1
|
+
import { validators } from "@eik/common";
|
|
2
|
+
import originalUrl from "original-url";
|
|
3
|
+
import HttpError from "http-errors";
|
|
4
|
+
import abslog from "abslog";
|
|
5
|
+
import Metrics from "@metrics/client";
|
|
6
6
|
|
|
7
|
-
import { createFilePathToPackage } from
|
|
8
|
-
import { decodeUriComponent } from
|
|
9
|
-
import HttpOutgoing from
|
|
10
|
-
import config from
|
|
7
|
+
import { createFilePathToPackage } 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} PkgLogOptions
|
|
14
|
+
* @property {boolean} [etag]
|
|
15
|
+
* @property {string} [cacheControl]
|
|
16
|
+
* @property {Array<[string, string]>} [organizations] List of key-value pairs [hostname, organization]
|
|
17
|
+
* @property {import("@eik/sink").default} [sink]
|
|
18
|
+
* @property {import("abslog").AbstractLoggerOptions} [logger]
|
|
19
|
+
*/
|
|
11
20
|
|
|
12
21
|
const PkgLog = class PkgLog {
|
|
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
|
-
} catch (error) {
|
|
108
|
-
this._log.debug(`pkg:log - Package log found - Pathname: ${path}`);
|
|
109
|
-
const e = new HttpError.NotFound();
|
|
110
|
-
end({ labels: { success: false, status: e.status, type } });
|
|
111
|
-
throw e;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
22
|
+
/**
|
|
23
|
+
* @param {PkgLogOptions} options
|
|
24
|
+
*/
|
|
25
|
+
constructor({ organizations, cacheControl, logger, sink, etag } = {}) {
|
|
26
|
+
this._organizations = organizations || config.organizations;
|
|
27
|
+
this._cacheControl = cacheControl || "no-cache";
|
|
28
|
+
this._sink = sink;
|
|
29
|
+
this._etag = etag || config.etag;
|
|
30
|
+
this._log = abslog(logger);
|
|
31
|
+
this._metrics = new Metrics();
|
|
32
|
+
this._histogram = this._metrics.histogram({
|
|
33
|
+
name: "eik_core_pkg_log_handler",
|
|
34
|
+
description:
|
|
35
|
+
"Histogram measuring time taken in @eik/core PkgLog handler method",
|
|
36
|
+
labels: {
|
|
37
|
+
success: true,
|
|
38
|
+
type: "unknown",
|
|
39
|
+
},
|
|
40
|
+
buckets: [0.005, 0.01, 0.06, 0.1, 0.6, 1.0, 2.0, 4.0],
|
|
41
|
+
});
|
|
42
|
+
this._orgRegistry = new Map(this._organizations);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get metrics() {
|
|
46
|
+
return this._metrics;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async handler(req, type, name, version) {
|
|
50
|
+
const end = this._histogram.timer();
|
|
51
|
+
|
|
52
|
+
const pVersion = decodeUriComponent(version);
|
|
53
|
+
const pName = decodeUriComponent(name);
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
validators.version(pVersion);
|
|
57
|
+
validators.name(pName);
|
|
58
|
+
validators.type(type);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
this._log.debug(`pkg:log - Validation failed - ${error.message}`);
|
|
61
|
+
const e = new HttpError.NotFound();
|
|
62
|
+
end({ labels: { success: false, status: e.status, type } });
|
|
63
|
+
throw e;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const url = originalUrl(req);
|
|
67
|
+
const org = this._orgRegistry.get(url.hostname);
|
|
68
|
+
|
|
69
|
+
if (!org) {
|
|
70
|
+
this._log.info(
|
|
71
|
+
`pkg:log - Hostname does not match a configured organization - ${url.hostname}`,
|
|
72
|
+
);
|
|
73
|
+
const e = new HttpError.BadRequest();
|
|
74
|
+
end({ labels: { success: false, status: e.status, type } });
|
|
75
|
+
throw e;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const path = createFilePathToPackage({
|
|
79
|
+
org,
|
|
80
|
+
type,
|
|
81
|
+
name: pName,
|
|
82
|
+
version: pVersion,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const file = await this._sink.read(path);
|
|
87
|
+
const outgoing = new HttpOutgoing();
|
|
88
|
+
outgoing.cacheControl = this._cacheControl;
|
|
89
|
+
outgoing.mimeType = "application/json";
|
|
90
|
+
|
|
91
|
+
if (this._etag) {
|
|
92
|
+
outgoing.etag = file.etag;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (this._etag && req.headers["if-none-match"] === file.etag) {
|
|
96
|
+
outgoing.statusCode = 304;
|
|
97
|
+
file.stream.destroy();
|
|
98
|
+
} else {
|
|
99
|
+
outgoing.statusCode = 200;
|
|
100
|
+
outgoing.stream = file.stream;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
this._log.debug(`pkg:log - Package log found - Pathname: ${path}`);
|
|
104
|
+
|
|
105
|
+
end({ labels: { status: outgoing.statusCode, type } });
|
|
106
|
+
|
|
107
|
+
return outgoing;
|
|
108
|
+
// eslint-disable-next-line no-unused-vars
|
|
109
|
+
} catch (error) {
|
|
110
|
+
this._log.debug(`pkg:log - Package log found - Pathname: ${path}`);
|
|
111
|
+
const e = new HttpError.NotFound();
|
|
112
|
+
end({ labels: { success: false, status: e.status, type } });
|
|
113
|
+
throw e;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
114
116
|
};
|
|
115
117
|
export default PkgLog;
|