@eik/core 2.1.46 → 2.1.47

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 (52) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/lib/classes/http-incoming.js +4 -0
  3. package/lib/classes/http-outgoing.js +4 -0
  4. package/lib/classes/package.js +8 -0
  5. package/lib/classes/versions.js +16 -2
  6. package/lib/handlers/alias.delete.js +13 -4
  7. package/lib/handlers/alias.get-v2.js +22 -10
  8. package/lib/handlers/alias.get.js +10 -1
  9. package/lib/handlers/alias.post.js +19 -4
  10. package/lib/handlers/alias.put.js +19 -4
  11. package/lib/handlers/auth.post.js +7 -1
  12. package/lib/handlers/map.get.js +20 -10
  13. package/lib/handlers/map.put.js +38 -13
  14. package/lib/handlers/pkg.get.js +22 -10
  15. package/lib/handlers/pkg.log.js +21 -10
  16. package/lib/handlers/pkg.put.js +26 -4
  17. package/lib/handlers/versions.get.js +20 -10
  18. package/lib/multipart/form-file.js +3 -0
  19. package/lib/multipart/parser.js +65 -37
  20. package/lib/sinks/mem-entry.js +3 -0
  21. package/lib/sinks/test.js +40 -10
  22. package/lib/utils/healthcheck.js +16 -2
  23. package/lib/utils/utils.js +25 -0
  24. package/package.json +16 -20
  25. package/types/classes/alias.d.ts +4 -4
  26. package/types/classes/asset.d.ts +5 -5
  27. package/types/classes/author.d.ts +2 -2
  28. package/types/classes/http-incoming.d.ts +4 -4
  29. package/types/classes/http-outgoing.d.ts +7 -3
  30. package/types/classes/meta.d.ts +2 -2
  31. package/types/classes/package.d.ts +136 -11
  32. package/types/classes/versions.d.ts +14 -4
  33. package/types/handlers/alias.delete.d.ts +13 -6
  34. package/types/handlers/alias.get-v2.d.ts +16 -9
  35. package/types/handlers/alias.get.d.ts +15 -8
  36. package/types/handlers/alias.post.d.ts +24 -11
  37. package/types/handlers/alias.put.d.ts +24 -11
  38. package/types/handlers/auth.post.d.ts +15 -9
  39. package/types/handlers/map.get.d.ts +14 -9
  40. package/types/handlers/map.put.d.ts +32 -13
  41. package/types/handlers/pkg.get.d.ts +16 -9
  42. package/types/handlers/pkg.log.d.ts +15 -9
  43. package/types/handlers/pkg.put.d.ts +35 -15
  44. package/types/handlers/versions.get.d.ts +14 -9
  45. package/types/main.d.ts +2 -0
  46. package/types/multipart/form-field.d.ts +2 -2
  47. package/types/multipart/parser.d.ts +18 -6
  48. package/types/sinks/test.d.ts +26 -13
  49. package/types/utils/healthcheck.d.ts +6 -4
  50. package/types/utils/path-builders-fs.d.ts +27 -27
  51. package/types/utils/path-builders-uri.d.ts +16 -16
  52. package/types/utils/utils.d.ts +26 -3
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [2.1.47](https://github.com/eik-lib/core/compare/v2.1.46...v2.1.47) (2026-05-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Bump dependencies ([#587](https://github.com/eik-lib/core/issues/587)) ([c81b101](https://github.com/eik-lib/core/commit/c81b10179c6e6fc8d4f4a2ee82b95f1c0e1533e7))
7
+
1
8
  ## [2.1.46](https://github.com/eik-lib/core/compare/v2.1.45...v2.1.46) (2026-05-22)
2
9
 
3
10
 
@@ -4,6 +4,10 @@
4
4
  * @class HttpIncoming
5
5
  */
6
6
  const HttpIncoming = class HttpIncoming {
7
+ /**
8
+ * @param {any} [request]
9
+ * @param {{ version?: string, extras?: string, author?: object, alias?: string, type?: string, name?: string, org?: string }} [options]
10
+ */
7
11
  constructor(
8
12
  request,
9
13
  {
@@ -14,7 +14,9 @@ const HttpOutgoing = class HttpOutgoing {
14
14
  this._statusCode = 200;
15
15
  this._mimeType = "text/plain";
16
16
  this._location = "";
17
+ /** @type {import("node:stream").Readable | undefined} */
17
18
  this._stream = undefined;
19
+ /** @type {any} */
18
20
  this._body = undefined;
19
21
  this._etag = "";
20
22
  }
@@ -63,6 +65,7 @@ const HttpOutgoing = class HttpOutgoing {
63
65
  this._stream = value;
64
66
  }
65
67
 
68
+ /** @returns {import("node:stream").Readable | undefined} */
66
69
  get stream() {
67
70
  return this._stream;
68
71
  }
@@ -71,6 +74,7 @@ const HttpOutgoing = class HttpOutgoing {
71
74
  this._body = value;
72
75
  }
73
76
 
77
+ /** @returns {any} */
74
78
  get body() {
75
79
  return this._body;
76
80
  }
@@ -17,7 +17,9 @@ const Package = class Package {
17
17
  this._type = type;
18
18
  this._name = name;
19
19
  this._org = org;
20
+ /** @type {import("./asset.js").default[]} */
20
21
  this._files = [];
22
+ /** @type {import("./meta.js").default[]} */
21
23
  this._meta = [];
22
24
  }
23
25
 
@@ -56,12 +58,18 @@ const Package = class Package {
56
58
  return this._org;
57
59
  }
58
60
 
61
+ /**
62
+ * @param {import("./asset.js").default} asset
63
+ */
59
64
  setAsset(asset) {
60
65
  if (!(asset instanceof Asset))
61
66
  throw new TypeError('Argument "asset" must be an instance of Asset');
62
67
  this._files.push(asset);
63
68
  }
64
69
 
70
+ /**
71
+ * @param {import("./meta.js").default} meta
72
+ */
65
73
  setMeta(meta) {
66
74
  if (!(meta instanceof Meta))
67
75
  throw new TypeError('Argument "meta" must be an instance of Meta');
@@ -1,6 +1,9 @@
1
1
  import semver from "semver";
2
2
 
3
3
  const Versions = class Versions {
4
+ /**
5
+ * @param {{ versions?: [any, any][], type?: string, name?: string, org?: string }} [options]
6
+ */
4
7
  constructor({ versions = [], type = "", name = "", org = "" } = {}) {
5
8
  this._versions = new Map(versions);
6
9
  this._type = type;
@@ -9,8 +12,9 @@ const Versions = class Versions {
9
12
  }
10
13
 
11
14
  get versions() {
12
- return Array.from(this._versions.entries()).sort((a, b) =>
13
- a[0] > b[0] ? -1 : 1,
15
+ return [...this._versions.entries()].toSorted(
16
+ (/** @type {[any, any]} */ a, /** @type {[any, any]} */ b) =>
17
+ a[0] > b[0] ? -1 : 1,
14
18
  );
15
19
  }
16
20
 
@@ -26,6 +30,10 @@ const Versions = class Versions {
26
30
  return this._org;
27
31
  }
28
32
 
33
+ /**
34
+ * @param {string} version
35
+ * @param {string} integrity
36
+ */
29
37
  setVersion(version, integrity) {
30
38
  const major = semver.major(version);
31
39
  this._versions.set(major, {
@@ -34,10 +42,16 @@ const Versions = class Versions {
34
42
  });
35
43
  }
36
44
 
45
+ /**
46
+ * @param {number} major
47
+ */
37
48
  getVersion(major) {
38
49
  return this._versions.get(major);
39
50
  }
40
51
 
52
+ /**
53
+ * @param {string} version
54
+ */
41
55
  check(version) {
42
56
  const major = semver.major(version);
43
57
  const previous = this.getVersion(major);
@@ -46,7 +46,7 @@ const AliasDel = class AliasDel {
46
46
 
47
47
  async _exist(path = "") {
48
48
  try {
49
- await this._sink.exist(path);
49
+ if (this._sink) await this._sink.exist(path);
50
50
  return true;
51
51
  // eslint-disable-next-line no-unused-vars
52
52
  } catch (error) {
@@ -54,6 +54,13 @@ const AliasDel = class AliasDel {
54
54
  }
55
55
  }
56
56
 
57
+ /**
58
+ * @param {any} req
59
+ * @param {any} user
60
+ * @param {string} type
61
+ * @param {string} name
62
+ * @param {string} alias
63
+ */
57
64
  async handler(req, user, type, name, alias) {
58
65
  const end = this._histogram.timer();
59
66
 
@@ -65,7 +72,9 @@ const AliasDel = class AliasDel {
65
72
  validators.name(pName);
66
73
  validators.type(type);
67
74
  } catch (error) {
68
- this._log.info(`alias:del - Validation failed - ${error.message}`);
75
+ this._log.info(
76
+ `alias:del - Validation failed - ${error instanceof Error ? error.message : String(error)}`,
77
+ );
69
78
  const e = new HttpError.NotFound();
70
79
  end({ labels: { success: false, status: e.status } });
71
80
  throw e;
@@ -103,7 +112,7 @@ const AliasDel = class AliasDel {
103
112
  this._log.info(
104
113
  `alias:del - Start deleting alias from sink - Pathname: ${path}`,
105
114
  );
106
- await this._sink.delete(path);
115
+ if (this._sink) await this._sink.delete(path);
107
116
  } catch (error) {
108
117
  this._log.error(
109
118
  `alias:del - Failed deleting alias from sink - Pathname: ${path}`,
@@ -119,7 +128,7 @@ const AliasDel = class AliasDel {
119
128
  );
120
129
 
121
130
  const outgoing = new HttpOutgoing();
122
- outgoing.cacheControl = this._cacheControl;
131
+ outgoing.cacheControl = this._cacheControl || "";
123
132
  outgoing.statusCode = 204;
124
133
 
125
134
  end({ labels: { status: outgoing.statusCode, type } });
@@ -52,6 +52,13 @@ const AliasGet = class AliasGet {
52
52
  return this._metrics;
53
53
  }
54
54
 
55
+ /**
56
+ * @param {any} req
57
+ * @param {string} type
58
+ * @param {string} name
59
+ * @param {string} alias
60
+ * @param {string} extra
61
+ */
55
62
  async handler(req, type, name, alias, extra) {
56
63
  const end = this._histogram.timer();
57
64
 
@@ -65,7 +72,9 @@ const AliasGet = class AliasGet {
65
72
  validators.name(pName);
66
73
  validators.type(type);
67
74
  } catch (error) {
68
- this._log.debug(`alias:get - Validation failed - ${error.message}`);
75
+ this._log.debug(
76
+ `alias:get - Validation failed - ${error instanceof Error ? error.message : String(error)}`,
77
+ );
69
78
  const e = new HttpError.NotFound();
70
79
  end({ labels: { success: false, status: e.status } });
71
80
  throw e;
@@ -103,7 +112,7 @@ const AliasGet = class AliasGet {
103
112
 
104
113
  const assetPath = createFilePathToAsset(asset);
105
114
 
106
- const file = await this._sink.read(assetPath);
115
+ const file = await (this._sink && this._sink.read(assetPath));
107
116
  const outgoing = new HttpOutgoing();
108
117
  outgoing.cacheControl = this._cacheControl;
109
118
  outgoing.mimeType = asset.mimeType;
@@ -119,14 +128,17 @@ const AliasGet = class AliasGet {
119
128
  outgoing.statusCode = 200;
120
129
  outgoing.stream = file.stream;
121
130
 
122
- outgoing.stream.on("error", (err) => {
123
- this._log.info(`alias:get - File stream error - ${err}`);
124
- end({ labels: { success: false, status: 503, type } });
125
- });
126
-
127
- outgoing.stream.on("end", () => {
128
- end({ labels: { status: outgoing.statusCode, type } });
129
- });
131
+ const outgoingStream = outgoing.stream;
132
+ if (outgoingStream) {
133
+ outgoingStream.on("error", (err) => {
134
+ this._log.info(`alias:get - File stream error - ${err}`);
135
+ end({ labels: { success: false, status: 503, type } });
136
+ });
137
+
138
+ outgoingStream.on("end", () => {
139
+ end({ labels: { status: outgoing.statusCode, type } });
140
+ });
141
+ }
130
142
  }
131
143
 
132
144
  this._log.debug(`alias:get - Alias found - Pathname: ${path}`);
@@ -45,6 +45,13 @@ const AliasGet = class AliasGet {
45
45
  return this._metrics;
46
46
  }
47
47
 
48
+ /**
49
+ * @param {any} req
50
+ * @param {string} type
51
+ * @param {string} name
52
+ * @param {string} alias
53
+ * @param {string} extra
54
+ */
48
55
  async handler(req, type, name, alias, extra) {
49
56
  const end = this._histogram.timer();
50
57
 
@@ -58,7 +65,9 @@ const AliasGet = class AliasGet {
58
65
  validators.name(pName);
59
66
  validators.type(type);
60
67
  } catch (error) {
61
- this._log.debug(`alias:get - Validation failed - ${error.message}`);
68
+ this._log.debug(
69
+ `alias:get - Validation failed - ${error instanceof Error ? error.message : String(error)}`,
70
+ );
62
71
  const e = new HttpError.NotFound();
63
72
  end({ labels: { success: false, status: e.status } });
64
73
  throw e;
@@ -57,6 +57,9 @@ const AliasPost = class AliasPost {
57
57
  return this._metrics;
58
58
  }
59
59
 
60
+ /**
61
+ * @param {any} incoming
62
+ */
60
63
  _parser(incoming) {
61
64
  return new Promise((resolve, reject) => {
62
65
  this._multipart
@@ -88,7 +91,7 @@ const AliasPost = class AliasPost {
88
91
  name: alias.name,
89
92
  version: alias.version,
90
93
  });
91
- await this._sink.read(path);
94
+ if (this._sink) await this._sink.read(path);
92
95
  } catch (error) {
93
96
  this._log.error(
94
97
  `alias:post - Unable to locate requested published package version - Version ${alias.name}@${alias.version}`,
@@ -127,10 +130,13 @@ const AliasPost = class AliasPost {
127
130
  });
128
131
  }
129
132
 
133
+ /**
134
+ * @param {any} incoming
135
+ */
130
136
  async _exist(incoming) {
131
137
  try {
132
138
  const path = createFilePathToAlias(incoming);
133
- await this._sink.exist(path);
139
+ if (this._sink) await this._sink.exist(path);
134
140
  return true;
135
141
  // eslint-disable-next-line no-unused-vars
136
142
  } catch (error) {
@@ -138,6 +144,13 @@ const AliasPost = class AliasPost {
138
144
  }
139
145
  }
140
146
 
147
+ /**
148
+ * @param {any} req
149
+ * @param {any} user
150
+ * @param {string} type
151
+ * @param {string} name
152
+ * @param {string} alias
153
+ */
141
154
  async handler(req, user, type, name, alias) {
142
155
  const end = this._histogram.timer();
143
156
 
@@ -149,7 +162,9 @@ const AliasPost = class AliasPost {
149
162
  validators.name(pName);
150
163
  validators.type(type);
151
164
  } catch (error) {
152
- this._log.info(`alias:post - Validation failed - ${error.message}`);
165
+ this._log.info(
166
+ `alias:post - Validation failed - ${error instanceof Error ? error.message : String(error)}`,
167
+ );
153
168
  const e = new HttpError.NotFound();
154
169
  end({ labels: { success: false, status: e.status } });
155
170
  throw e;
@@ -190,7 +205,7 @@ const AliasPost = class AliasPost {
190
205
  await this._parser(incoming);
191
206
 
192
207
  const outgoing = new HttpOutgoing();
193
- outgoing.cacheControl = this._cacheControl;
208
+ outgoing.cacheControl = this._cacheControl || "";
194
209
  outgoing.statusCode = 303;
195
210
  outgoing.location = createURIToAlias(incoming);
196
211
 
@@ -57,6 +57,9 @@ const AliasPut = class AliasPut {
57
57
  return this._metrics;
58
58
  }
59
59
 
60
+ /**
61
+ * @param {any} incoming
62
+ */
60
63
  _parser(incoming) {
61
64
  return new Promise((resolve, reject) => {
62
65
  this._multipart
@@ -88,7 +91,7 @@ const AliasPut = class AliasPut {
88
91
  name: alias.name,
89
92
  version: alias.version,
90
93
  });
91
- await this._sink.read(path);
94
+ if (this._sink) await this._sink.read(path);
92
95
  } catch (error) {
93
96
  this._log.error(
94
97
  `alias:post - Unable to locate requested published package version - Version ${alias.name}@${alias.version}`,
@@ -127,10 +130,13 @@ const AliasPut = class AliasPut {
127
130
  });
128
131
  }
129
132
 
133
+ /**
134
+ * @param {any} incoming
135
+ */
130
136
  async _exist(incoming) {
131
137
  try {
132
138
  const path = createFilePathToAlias(incoming);
133
- await this._sink.exist(path);
139
+ if (this._sink) await this._sink.exist(path);
134
140
  return true;
135
141
  // eslint-disable-next-line no-unused-vars
136
142
  } catch (error) {
@@ -138,6 +144,13 @@ const AliasPut = class AliasPut {
138
144
  }
139
145
  }
140
146
 
147
+ /**
148
+ * @param {any} req
149
+ * @param {any} user
150
+ * @param {string} type
151
+ * @param {string} name
152
+ * @param {string} alias
153
+ */
141
154
  async handler(req, user, type, name, alias) {
142
155
  const end = this._histogram.timer();
143
156
 
@@ -149,7 +162,9 @@ const AliasPut = class AliasPut {
149
162
  validators.name(pName);
150
163
  validators.type(type);
151
164
  } catch (error) {
152
- this._log.info(`alias:put - Validation failed - ${error.message}`);
165
+ this._log.info(
166
+ `alias:put - Validation failed - ${error instanceof Error ? error.message : String(error)}`,
167
+ );
153
168
  const e = new HttpError.BadRequest();
154
169
  end({ labels: { success: false, status: e.status } });
155
170
  throw e;
@@ -190,7 +205,7 @@ const AliasPut = class AliasPut {
190
205
  await this._parser(incoming);
191
206
 
192
207
  const outgoing = new HttpOutgoing();
193
- outgoing.cacheControl = this._cacheControl;
208
+ outgoing.cacheControl = this._cacheControl || "";
194
209
  outgoing.statusCode = 303;
195
210
  outgoing.location = createURIToAlias(incoming);
196
211
 
@@ -48,6 +48,9 @@ const AuthPost = class AuthPost {
48
48
  return this._metrics;
49
49
  }
50
50
 
51
+ /**
52
+ * @param {any} incoming
53
+ */
51
54
  _parser(incoming) {
52
55
  return new Promise((resolve, reject) => {
53
56
  this._multipart
@@ -76,6 +79,9 @@ const AuthPost = class AuthPost {
76
79
  });
77
80
  }
78
81
 
82
+ /**
83
+ * @param {any} req
84
+ */
79
85
  async handler(req) {
80
86
  const end = this._histogram.timer();
81
87
 
@@ -98,7 +104,7 @@ const AuthPost = class AuthPost {
98
104
  const obj = await this._parser(incoming);
99
105
 
100
106
  const outgoing = new HttpOutgoing();
101
- outgoing.cacheControl = this._cacheControl;
107
+ outgoing.cacheControl = this._cacheControl || "";
102
108
  outgoing.statusCode = 200;
103
109
  outgoing.mimeType = "application/json";
104
110
  outgoing.body = obj;
@@ -46,6 +46,11 @@ const MapGet = class MapGet {
46
46
  return this._metrics;
47
47
  }
48
48
 
49
+ /**
50
+ * @param {any} req
51
+ * @param {string} name
52
+ * @param {string} version
53
+ */
49
54
  async handler(req, name, version) {
50
55
  const end = this._histogram.timer();
51
56
 
@@ -56,7 +61,9 @@ const MapGet = class MapGet {
56
61
  validators.version(pVersion);
57
62
  validators.name(pName);
58
63
  } catch (error) {
59
- this._log.debug(`map:get - Validation failed - ${error.message}`);
64
+ this._log.debug(
65
+ `map:get - Validation failed - ${error instanceof Error ? error.message : String(error)}`,
66
+ );
60
67
  const e = new HttpError.NotFound();
61
68
  end({ labels: { success: false, status: e.status } });
62
69
  throw e;
@@ -81,7 +88,7 @@ const MapGet = class MapGet {
81
88
  });
82
89
 
83
90
  try {
84
- const file = await this._sink.read(path);
91
+ const file = await (this._sink && this._sink.read(path));
85
92
  const outgoing = new HttpOutgoing();
86
93
  outgoing.cacheControl = this._cacheControl;
87
94
  outgoing.mimeType = "application/json";
@@ -97,14 +104,17 @@ const MapGet = class MapGet {
97
104
  outgoing.statusCode = 200;
98
105
  outgoing.stream = file.stream;
99
106
 
100
- outgoing.stream.on("error", (err) => {
101
- this._log.info(`map:get - File stream error - ${err}`);
102
- end({ labels: { success: false, status: 503, type: "map" } });
103
- });
104
-
105
- outgoing.stream.on("end", () => {
106
- end({ labels: { status: outgoing.statusCode, type: "map" } });
107
- });
107
+ const outgoingStream = outgoing.stream;
108
+ if (outgoingStream) {
109
+ outgoingStream.on("error", (err) => {
110
+ this._log.info(`map:get - File stream error - ${err}`);
111
+ end({ labels: { success: false, status: 503, type: "map" } });
112
+ });
113
+
114
+ outgoingStream.on("end", () => {
115
+ end({ labels: { status: outgoing.statusCode, type: "map" } });
116
+ });
117
+ }
108
118
  }
109
119
 
110
120
  this._log.debug(`map:get - Import map found - Pathname: ${path}`);
@@ -67,9 +67,13 @@ const MapPut = class MapPut {
67
67
  return this._metrics;
68
68
  }
69
69
 
70
+ /**
71
+ * @param {any} incoming
72
+ */
70
73
  _parser(incoming) {
71
74
  return new Promise((resolve, reject) => {
72
75
  const path = createFilePathToImportMap(incoming);
76
+ /** @type {Promise<any>[]} */
73
77
  const queue = [];
74
78
 
75
79
  const busboy = Busboy({
@@ -81,15 +85,18 @@ const MapPut = class MapPut {
81
85
  },
82
86
  });
83
87
 
84
- busboy.on("file", (fieldname, file) => {
85
- queue.push(
86
- this._handleFile({
87
- fieldname,
88
- file,
89
- path,
90
- }),
91
- );
92
- });
88
+ busboy.on(
89
+ "file",
90
+ (/** @type {any} */ fieldname, /** @type {any} */ file) => {
91
+ queue.push(
92
+ this._handleFile({
93
+ fieldname,
94
+ file,
95
+ path,
96
+ }),
97
+ );
98
+ },
99
+ );
93
100
 
94
101
  busboy.on("close", () => {
95
102
  Promise.all(queue)
@@ -103,7 +110,7 @@ const MapPut = class MapPut {
103
110
  });
104
111
  });
105
112
 
106
- busboy.on("error", (error) => {
113
+ busboy.on("error", (/** @type {any} */ error) => {
107
114
  reject(error);
108
115
  });
109
116
 
@@ -114,6 +121,9 @@ const MapPut = class MapPut {
114
121
  });
115
122
  }
116
123
 
124
+ /**
125
+ * @param {{ fieldname: any, file: any, path: any }} options
126
+ */
117
127
  async _handleFile({ fieldname, file, path }) {
118
128
  // We accept only one file on this given fieldname.
119
129
  // Throw if any other files is posted.
@@ -128,7 +138,7 @@ const MapPut = class MapPut {
128
138
 
129
139
  // Buffer up the incoming file and check if we can
130
140
  // parse it as JSON or not.
131
- let obj = {};
141
+ let obj;
132
142
  try {
133
143
  const str = await streamCollector(file);
134
144
  hasher.update(str);
@@ -160,6 +170,9 @@ const MapPut = class MapPut {
160
170
  return `sha512-${hasher.digest("base64")}`;
161
171
  }
162
172
 
173
+ /**
174
+ * @param {any} incoming
175
+ */
163
176
  async _readVersions(incoming) {
164
177
  const path = createFilePathToVersion(incoming);
165
178
  let versions;
@@ -180,6 +193,10 @@ const MapPut = class MapPut {
180
193
  return versions;
181
194
  }
182
195
 
196
+ /**
197
+ * @param {any} incoming
198
+ * @param {any} versions
199
+ */
183
200
  async _writeVersions(incoming, versions) {
184
201
  const path = createFilePathToVersion(incoming);
185
202
  await writeJSON(this._sink, path, versions, "application/json");
@@ -188,6 +205,12 @@ const MapPut = class MapPut {
188
205
  );
189
206
  }
190
207
 
208
+ /**
209
+ * @param {any} req
210
+ * @param {any} user
211
+ * @param {string} name
212
+ * @param {string} version
213
+ */
191
214
  async handler(req, user, name, version) {
192
215
  const end = this._histogram.timer();
193
216
 
@@ -198,7 +221,9 @@ const MapPut = class MapPut {
198
221
  validators.version(pVersion);
199
222
  validators.name(pName);
200
223
  } catch (error) {
201
- this._log.info(`map:put - Validation failed - ${error.message}`);
224
+ this._log.info(
225
+ `map:put - Validation failed - ${error instanceof Error ? error.message : String(error)}`,
226
+ );
202
227
  const e = new HttpError.BadRequest();
203
228
  end({ labels: { success: false, status: e.status } });
204
229
  throw e;
@@ -250,7 +275,7 @@ const MapPut = class MapPut {
250
275
  }
251
276
 
252
277
  const outgoing = new HttpOutgoing();
253
- outgoing.cacheControl = this._cacheControl;
278
+ outgoing.cacheControl = this._cacheControl || "";
254
279
  outgoing.statusCode = 303;
255
280
  outgoing.location = createURIPathToImportMap(incoming);
256
281
 
@@ -48,6 +48,13 @@ const PkgGet = class PkgGet {
48
48
  return this._metrics;
49
49
  }
50
50
 
51
+ /**
52
+ * @param {any} req
53
+ * @param {string} type
54
+ * @param {string} name
55
+ * @param {string} version
56
+ * @param {string} extra
57
+ */
51
58
  async handler(req, type, name, version, extra) {
52
59
  const end = this._histogram.timer();
53
60
 
@@ -61,7 +68,9 @@ const PkgGet = class PkgGet {
61
68
  validators.name(pName);
62
69
  validators.type(type);
63
70
  } catch (error) {
64
- this._log.debug(`pkg:get - Validation failed - ${error.message}`);
71
+ this._log.debug(
72
+ `pkg:get - Validation failed - ${error instanceof Error ? error.message : String(error)}`,
73
+ );
65
74
  const e = new HttpError.NotFound();
66
75
  end({ labels: { success: false, status: e.status } });
67
76
  throw e;
@@ -90,7 +99,7 @@ const PkgGet = class PkgGet {
90
99
  const path = createFilePathToAsset(asset);
91
100
 
92
101
  try {
93
- const file = await this._sink.read(path);
102
+ const file = await (this._sink && this._sink.read(path));
94
103
  const outgoing = new HttpOutgoing();
95
104
  outgoing.cacheControl = this._cacheControl;
96
105
  outgoing.mimeType = asset.mimeType;
@@ -106,14 +115,17 @@ const PkgGet = class PkgGet {
106
115
  outgoing.statusCode = 200;
107
116
  outgoing.stream = file.stream;
108
117
 
109
- outgoing.stream.on("error", (err) => {
110
- this._log.info(`pkg:get - File stream error - ${err}`);
111
- end({ labels: { success: false, status: 503, type } });
112
- });
113
-
114
- outgoing.stream.on("end", () => {
115
- end({ labels: { status: outgoing.statusCode, type } });
116
- });
118
+ const outgoingStream = outgoing.stream;
119
+ if (outgoingStream) {
120
+ outgoingStream.on("error", (err) => {
121
+ this._log.info(`pkg:get - File stream error - ${err}`);
122
+ end({ labels: { success: false, status: 503, type } });
123
+ });
124
+
125
+ outgoingStream.on("end", () => {
126
+ end({ labels: { status: outgoing.statusCode, type } });
127
+ });
128
+ }
117
129
  }
118
130
 
119
131
  this._log.debug(`pkg:get - Asset found - Pathname: ${path}`);