@eik/node-client 2.0.6 → 2.0.7
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/CHANGELOG.md +7 -0
- package/dist/index.cjs +40 -8
- package/package.json +4 -4
- package/src/index.js +41 -9
- package/types/index.d.ts +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [2.0.7](https://github.com/eik-lib/node-client/compare/v2.0.6...v2.0.7) (2025-05-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* redirections bug with Node 24 ([#230](https://github.com/eik-lib/node-client/issues/230)) ([9111ad0](https://github.com/eik-lib/node-client/commit/9111ad0c0fbc90dd89368507b6675740cb99cd5f))
|
|
7
|
+
|
|
1
8
|
## [2.0.6](https://github.com/eik-lib/node-client/compare/v2.0.5...v2.0.6) (2025-04-28)
|
|
2
9
|
|
|
3
10
|
|
package/dist/index.cjs
CHANGED
|
@@ -60,21 +60,47 @@ const trimSlash = (value = "") => {
|
|
|
60
60
|
return value;
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
/**
|
|
64
|
+
* @param {string[]} urls
|
|
65
|
+
* @param {object} options
|
|
66
|
+
* @param {number} options.maxRedirections - undici option for limiting redirects
|
|
67
|
+
* @returns {Promise<ImportMap[]>}
|
|
68
|
+
*/
|
|
69
|
+
const fetchImportMaps = async (urls = [], options) => {
|
|
64
70
|
try {
|
|
65
71
|
const maps = urls.map(async (map) => {
|
|
66
|
-
const
|
|
67
|
-
|
|
72
|
+
const response = await undici.request(map, {
|
|
73
|
+
dispatcher: new undici.Agent().compose(
|
|
74
|
+
undici.interceptors.redirect({
|
|
75
|
+
maxRedirections: options.maxRedirections,
|
|
76
|
+
}),
|
|
77
|
+
),
|
|
68
78
|
});
|
|
69
79
|
|
|
70
|
-
if (statusCode === 404) {
|
|
80
|
+
if (response.statusCode === 404) {
|
|
71
81
|
throw new Error("Import map could not be found on server");
|
|
72
|
-
} else if (statusCode >= 400 && statusCode < 500) {
|
|
82
|
+
} else if (response.statusCode >= 400 && response.statusCode < 500) {
|
|
73
83
|
throw new Error("Server rejected client request");
|
|
74
|
-
} else if (statusCode >= 500) {
|
|
84
|
+
} else if (response.statusCode >= 500) {
|
|
75
85
|
throw new Error("Server error");
|
|
76
86
|
}
|
|
77
|
-
|
|
87
|
+
let contentType = response.headers["content-type"];
|
|
88
|
+
if (!Array.isArray(contentType)) contentType = [contentType];
|
|
89
|
+
|
|
90
|
+
if (!contentType.find((type) => type.startsWith("application/json"))) {
|
|
91
|
+
const content = await response.body.text();
|
|
92
|
+
if (content.length === 0) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`${map} did not return JSON, got an empty response. HTTP status: ${response.statusCode}`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
throw new Error(
|
|
98
|
+
`${map} did not return JSON, got: ${content}. HTTP status: ${response.statusCode}`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const json = await response.body.json();
|
|
103
|
+
return /** @type {ImportMap}*/ (json);
|
|
78
104
|
});
|
|
79
105
|
return await Promise.all(maps);
|
|
80
106
|
} catch (err) {
|
|
@@ -90,6 +116,7 @@ const fetchImportMaps = async (urls = []) => {
|
|
|
90
116
|
* @property {boolean} [development=false]
|
|
91
117
|
* @property {boolean} [loadMaps=false]
|
|
92
118
|
* @property {string} [path=process.cwd()]
|
|
119
|
+
* @property {number} [maxRedirections=2] Maximum number of redirects when looking up URLs.
|
|
93
120
|
*/
|
|
94
121
|
|
|
95
122
|
/**
|
|
@@ -163,6 +190,7 @@ class Eik {
|
|
|
163
190
|
#path;
|
|
164
191
|
#base;
|
|
165
192
|
#maps;
|
|
193
|
+
#maxRedirections;
|
|
166
194
|
|
|
167
195
|
/**
|
|
168
196
|
* @param {Options} options
|
|
@@ -172,6 +200,7 @@ class Eik {
|
|
|
172
200
|
loadMaps = false,
|
|
173
201
|
base = "",
|
|
174
202
|
path = process.cwd(),
|
|
203
|
+
maxRedirections = 2,
|
|
175
204
|
} = {}) {
|
|
176
205
|
this.#development = development;
|
|
177
206
|
this.#loadMaps = loadMaps;
|
|
@@ -179,6 +208,7 @@ class Eik {
|
|
|
179
208
|
this.#path = path;
|
|
180
209
|
this.#base = trimSlash(base);
|
|
181
210
|
this.#maps = [];
|
|
211
|
+
this.#maxRedirections = maxRedirections;
|
|
182
212
|
}
|
|
183
213
|
|
|
184
214
|
/**
|
|
@@ -191,7 +221,9 @@ class Eik {
|
|
|
191
221
|
async load() {
|
|
192
222
|
this.#config = await common.helpers.getDefaults(this.#path);
|
|
193
223
|
if (this.#loadMaps) {
|
|
194
|
-
this.#maps = await fetchImportMaps(this.#config.map
|
|
224
|
+
this.#maps = await fetchImportMaps(this.#config.map, {
|
|
225
|
+
maxRedirections: this.#maxRedirections,
|
|
226
|
+
});
|
|
195
227
|
}
|
|
196
228
|
}
|
|
197
229
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eik/node-client",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
4
4
|
"description": "Utilities for working with assets and import maps on an Eik server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@eik/common": "5.0.4",
|
|
47
47
|
"abslog": "2.4.4",
|
|
48
|
-
"undici": "
|
|
48
|
+
"undici": "7.8.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@eik/eslint-config": "1.0.
|
|
51
|
+
"@eik/eslint-config": "1.0.13",
|
|
52
52
|
"@eik/prettier-config": "1.0.1",
|
|
53
53
|
"@eik/semantic-release-config": "1.0.2",
|
|
54
54
|
"@eik/typescript-config": "1.0.0",
|
|
55
|
-
"eslint": "9.
|
|
55
|
+
"eslint": "9.25.1",
|
|
56
56
|
"npm-run-all2": "7.0.2",
|
|
57
57
|
"prettier": "3.4.1",
|
|
58
58
|
"rimraf": "6.0.1",
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { helpers } from "@eik/common";
|
|
2
|
-
import { request } from "undici";
|
|
2
|
+
import { request, interceptors, Agent } from "undici";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { Asset } from "./asset.js";
|
|
5
5
|
|
|
@@ -8,21 +8,47 @@ const trimSlash = (value = "") => {
|
|
|
8
8
|
return value;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* @param {string[]} urls
|
|
13
|
+
* @param {object} options
|
|
14
|
+
* @param {number} options.maxRedirections - undici option for limiting redirects
|
|
15
|
+
* @returns {Promise<ImportMap[]>}
|
|
16
|
+
*/
|
|
17
|
+
const fetchImportMaps = async (urls = [], options) => {
|
|
12
18
|
try {
|
|
13
19
|
const maps = urls.map(async (map) => {
|
|
14
|
-
const
|
|
15
|
-
|
|
20
|
+
const response = await request(map, {
|
|
21
|
+
dispatcher: new Agent().compose(
|
|
22
|
+
interceptors.redirect({
|
|
23
|
+
maxRedirections: options.maxRedirections,
|
|
24
|
+
}),
|
|
25
|
+
),
|
|
16
26
|
});
|
|
17
27
|
|
|
18
|
-
if (statusCode === 404) {
|
|
28
|
+
if (response.statusCode === 404) {
|
|
19
29
|
throw new Error("Import map could not be found on server");
|
|
20
|
-
} else if (statusCode >= 400 && statusCode < 500) {
|
|
30
|
+
} else if (response.statusCode >= 400 && response.statusCode < 500) {
|
|
21
31
|
throw new Error("Server rejected client request");
|
|
22
|
-
} else if (statusCode >= 500) {
|
|
32
|
+
} else if (response.statusCode >= 500) {
|
|
23
33
|
throw new Error("Server error");
|
|
24
34
|
}
|
|
25
|
-
|
|
35
|
+
let contentType = response.headers["content-type"];
|
|
36
|
+
if (!Array.isArray(contentType)) contentType = [contentType];
|
|
37
|
+
|
|
38
|
+
if (!contentType.find((type) => type.startsWith("application/json"))) {
|
|
39
|
+
const content = await response.body.text();
|
|
40
|
+
if (content.length === 0) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`${map} did not return JSON, got an empty response. HTTP status: ${response.statusCode}`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
throw new Error(
|
|
46
|
+
`${map} did not return JSON, got: ${content}. HTTP status: ${response.statusCode}`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const json = await response.body.json();
|
|
51
|
+
return /** @type {ImportMap}*/ (json);
|
|
26
52
|
});
|
|
27
53
|
return await Promise.all(maps);
|
|
28
54
|
} catch (err) {
|
|
@@ -38,6 +64,7 @@ const fetchImportMaps = async (urls = []) => {
|
|
|
38
64
|
* @property {boolean} [development=false]
|
|
39
65
|
* @property {boolean} [loadMaps=false]
|
|
40
66
|
* @property {string} [path=process.cwd()]
|
|
67
|
+
* @property {number} [maxRedirections=2] Maximum number of redirects when looking up URLs.
|
|
41
68
|
*/
|
|
42
69
|
|
|
43
70
|
/**
|
|
@@ -111,6 +138,7 @@ export default class Eik {
|
|
|
111
138
|
#path;
|
|
112
139
|
#base;
|
|
113
140
|
#maps;
|
|
141
|
+
#maxRedirections;
|
|
114
142
|
|
|
115
143
|
/**
|
|
116
144
|
* @param {Options} options
|
|
@@ -120,6 +148,7 @@ export default class Eik {
|
|
|
120
148
|
loadMaps = false,
|
|
121
149
|
base = "",
|
|
122
150
|
path = process.cwd(),
|
|
151
|
+
maxRedirections = 2,
|
|
123
152
|
} = {}) {
|
|
124
153
|
this.#development = development;
|
|
125
154
|
this.#loadMaps = loadMaps;
|
|
@@ -127,6 +156,7 @@ export default class Eik {
|
|
|
127
156
|
this.#path = path;
|
|
128
157
|
this.#base = trimSlash(base);
|
|
129
158
|
this.#maps = [];
|
|
159
|
+
this.#maxRedirections = maxRedirections;
|
|
130
160
|
}
|
|
131
161
|
|
|
132
162
|
/**
|
|
@@ -139,7 +169,9 @@ export default class Eik {
|
|
|
139
169
|
async load() {
|
|
140
170
|
this.#config = await helpers.getDefaults(this.#path);
|
|
141
171
|
if (this.#loadMaps) {
|
|
142
|
-
this.#maps = await fetchImportMaps(this.#config.map
|
|
172
|
+
this.#maps = await fetchImportMaps(this.#config.map, {
|
|
173
|
+
maxRedirections: this.#maxRedirections,
|
|
174
|
+
});
|
|
143
175
|
}
|
|
144
176
|
}
|
|
145
177
|
|
package/types/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* @property {boolean} [development=false]
|
|
5
5
|
* @property {boolean} [loadMaps=false]
|
|
6
6
|
* @property {string} [path=process.cwd()]
|
|
7
|
+
* @property {number} [maxRedirections=2] Maximum number of redirects when looking up URLs.
|
|
7
8
|
*/
|
|
8
9
|
/**
|
|
9
10
|
* @typedef {object} ImportMap
|
|
@@ -72,7 +73,7 @@ export default class Eik {
|
|
|
72
73
|
/**
|
|
73
74
|
* @param {Options} options
|
|
74
75
|
*/
|
|
75
|
-
constructor({ development, loadMaps, base, path, }?: Options);
|
|
76
|
+
constructor({ development, loadMaps, base, path, maxRedirections, }?: Options);
|
|
76
77
|
/**
|
|
77
78
|
* Reads the Eik config from disk into the object instance, used for building {@link file} links in production.
|
|
78
79
|
*
|
|
@@ -212,6 +213,10 @@ export type Options = {
|
|
|
212
213
|
development?: boolean;
|
|
213
214
|
loadMaps?: boolean;
|
|
214
215
|
path?: string;
|
|
216
|
+
/**
|
|
217
|
+
* Maximum number of redirects when looking up URLs.
|
|
218
|
+
*/
|
|
219
|
+
maxRedirections?: number;
|
|
215
220
|
};
|
|
216
221
|
export type ImportMap = {
|
|
217
222
|
imports: Record<string, string>;
|