@wener/utils 1.1.13 → 1.1.14
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/dist/LICENSE.txt +1 -135
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/server.cjs +1 -1
- package/dist/cjs/server.cjs.map +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server.js +1 -1
- package/dist/esm/server.js.map +1 -1
- package/dist/system/index.js +2 -2
- package/dist/system/index.js.map +1 -1
- package/dist/system/server.js +1 -1
- package/dist/system/server.js.map +1 -1
- package/lib/server.js +3 -1
- package/lib/server.js.map +1 -1
- package/lib/servers/createFetchWithProxy.js +13 -0
- package/lib/servers/createFetchWithProxy.js.map +1 -0
- package/lib/servers/{createProxyFetch.js → createFetchWithProxyByNodeFetch.js} +6 -3
- package/lib/servers/createFetchWithProxyByNodeFetch.js.map +1 -0
- package/lib/servers/createFetchWithProxyByUndici.js +28 -0
- package/lib/servers/createFetchWithProxyByUndici.js.map +1 -0
- package/package.json +20 -28
- package/src/asyncs/createLazyPromise.test.ts +21 -21
- package/src/crypto/hashing.test.ts +10 -12
- package/src/crypto/pem/__snapshots__/pem.test.ts.snap +18 -0
- package/src/crypto/pem/pem.test.ts +14 -17
- package/src/crypto/ulid.test.ts +9 -9
- package/src/i18n/createTranslate.test.ts +76 -88
- package/src/io/ArrayBuffer.test-d.ts +4 -2
- package/src/io/ArrayBuffers.base64.test.ts +17 -17
- package/src/io/ArrayBuffers.test.ts +8 -8
- package/src/io/Buffer.test.ts +4 -4
- package/src/io/isBuffer.test.ts +4 -4
- package/src/io/isTransferable.test.ts +7 -6
- package/src/isomorphics/structuredClone.test.ts +4 -4
- package/src/langs/deepEqual.test.ts +4 -4
- package/src/langs/langs.test.ts +3 -3
- package/src/libs/ms.test.ts +311 -0
- package/src/logging/logger.test.ts +8 -8
- package/src/modules/parseModuleId.test.ts +3 -3
- package/src/objects/get.test-d.ts +30 -22
- package/src/objects/parseObjectPath.test.ts +3 -3
- package/src/objects/set.test.ts +98 -117
- package/src/server.ts +3 -1
- package/src/servers/createFetchWithLogger.ts +75 -0
- package/src/servers/createFetchWithProxy.ts +12 -0
- package/src/servers/{createProxyFetch.ts → createFetchWithProxyByNodeFetch.ts} +4 -1
- package/src/servers/createFetchWithProxyByUndici.ts +36 -0
- package/src/servers/polyfillBrowser.test.ts +9 -9
- package/src/strings/renderTemplate.test.ts +6 -9
- package/src/validations/parseTimestamp.test.ts +4 -4
- package/dist/cjs/index-da9513d6.js +0 -13
- package/dist/cjs/index-da9513d6.js.map +0 -1
- package/dist/esm/index-c696799a.js +0 -13
- package/dist/esm/index-c696799a.js.map +0 -1
- package/dist/system/index-2dfef0f3.js +0 -13
- package/dist/system/index-2dfef0f3.js.map +0 -1
- package/lib/servers/createProxyFetch.js.map +0 -1
- package/src/crypto/pem/pem.test.ts.md +0 -24
- package/src/crypto/pem/pem.test.ts.snap +0 -0
- package/src/objects/get.test.ts +0 -63
package/src/objects/set.test.ts
CHANGED
|
@@ -1,36 +1,30 @@
|
|
|
1
1
|
/* eslint no-proto:0 no-prototype-builtins:0 */
|
|
2
|
-
import test from '
|
|
2
|
+
import { describe, expect, test, it } from 'vitest';
|
|
3
3
|
import { set } from './set';
|
|
4
4
|
|
|
5
|
-
test('set basics', (
|
|
6
|
-
|
|
5
|
+
test('set basics', () => {
|
|
6
|
+
expect(set({}, 'c', 3), 'should not give return value').toBe(undefined);
|
|
7
7
|
{
|
|
8
8
|
const item = { foo: 1 };
|
|
9
9
|
set(item, 'bar', 123);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
foo: 1,
|
|
15
|
-
bar: 123,
|
|
16
|
-
},
|
|
17
|
-
'should mutate original object',
|
|
18
|
-
);
|
|
10
|
+
expect(item, 'should mutate original object').toEqual({
|
|
11
|
+
foo: 1,
|
|
12
|
+
bar: 123,
|
|
13
|
+
});
|
|
19
14
|
}
|
|
20
15
|
});
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
describe('set objects', () => {
|
|
23
18
|
const prepare = (x: any) => ({ input: x, copy: JSON.parse(JSON.stringify(x)) });
|
|
24
|
-
|
|
25
|
-
t.log(s);
|
|
26
|
-
f();
|
|
27
|
-
};
|
|
19
|
+
|
|
28
20
|
const orig = set;
|
|
29
21
|
|
|
30
22
|
function run(isMerge: boolean) {
|
|
31
|
-
const set = (a: any, b: any, c: any) => {
|
|
23
|
+
const set = (a: any, b: any, c: any) => {
|
|
24
|
+
orig(a, b, c, isMerge);
|
|
25
|
+
};
|
|
32
26
|
const verb = isMerge ? 'merge' : 'overwrite';
|
|
33
|
-
|
|
27
|
+
it(`should ${verb} existing object value :: simple`, () => {
|
|
34
28
|
const { input } = prepare({
|
|
35
29
|
hello: { a: 1 },
|
|
36
30
|
});
|
|
@@ -38,20 +32,20 @@ test('set objects', (t) => {
|
|
|
38
32
|
set(input, 'hello', { foo: 123 });
|
|
39
33
|
|
|
40
34
|
if (isMerge) {
|
|
41
|
-
|
|
35
|
+
expect(input).toStrictEqual({
|
|
42
36
|
hello: {
|
|
43
37
|
a: 1,
|
|
44
38
|
foo: 123,
|
|
45
39
|
},
|
|
46
40
|
});
|
|
47
41
|
} else {
|
|
48
|
-
|
|
42
|
+
expect(input).toStrictEqual({
|
|
49
43
|
hello: { foo: 123 },
|
|
50
44
|
});
|
|
51
45
|
}
|
|
52
46
|
});
|
|
53
47
|
|
|
54
|
-
|
|
48
|
+
it(`should ${verb} existing object value :: nested`, () => {
|
|
55
49
|
const { input, copy } = prepare({
|
|
56
50
|
a: {
|
|
57
51
|
b: {
|
|
@@ -68,22 +62,22 @@ test('set objects', (t) => {
|
|
|
68
62
|
copy.a.b = { foo: 123 };
|
|
69
63
|
}
|
|
70
64
|
|
|
71
|
-
|
|
65
|
+
expect(input).toStrictEqual(copy);
|
|
72
66
|
});
|
|
73
67
|
|
|
74
|
-
|
|
68
|
+
it(`should ${verb} existing array value :: simple`, () => {
|
|
75
69
|
const { input } = prepare([{ foo: 1 }]);
|
|
76
70
|
|
|
77
71
|
set(input, '0', { bar: 2 });
|
|
78
72
|
|
|
79
73
|
if (isMerge) {
|
|
80
|
-
|
|
74
|
+
expect(input).toEqual([{ foo: 1, bar: 2 }]);
|
|
81
75
|
} else {
|
|
82
|
-
|
|
76
|
+
expect(input).toEqual([{ bar: 2 }]);
|
|
83
77
|
}
|
|
84
78
|
});
|
|
85
79
|
|
|
86
|
-
|
|
80
|
+
it(`should ${verb} existing array value :: nested`, () => {
|
|
87
81
|
const { input } = prepare([
|
|
88
82
|
{ name: 'bob', age: 56, friends: ['foobar'] },
|
|
89
83
|
{ name: 'alice', age: 47, friends: ['mary'] },
|
|
@@ -94,13 +88,13 @@ test('set objects', (t) => {
|
|
|
94
88
|
set(input, '2', { name: 'mary', age: 49, friends: ['bob'] });
|
|
95
89
|
|
|
96
90
|
if (isMerge) {
|
|
97
|
-
|
|
91
|
+
expect(input).toEqual([
|
|
98
92
|
{ name: 'bob', age: 57, friends: ['alice', 'mary'] },
|
|
99
93
|
{ name: 'alice', age: 47, friends: ['bob'] },
|
|
100
94
|
{ name: 'mary', age: 49, friends: ['bob'] },
|
|
101
95
|
]);
|
|
102
96
|
} else {
|
|
103
|
-
|
|
97
|
+
expect(input).toEqual([
|
|
104
98
|
{ age: 57, friends: ['alice', 'mary'] },
|
|
105
99
|
{ friends: ['bob'] },
|
|
106
100
|
{ name: 'mary', age: 49, friends: ['bob'] },
|
|
@@ -113,56 +107,53 @@ test('set objects', (t) => {
|
|
|
113
107
|
run(false);
|
|
114
108
|
});
|
|
115
109
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
t.log(s);
|
|
119
|
-
f();
|
|
120
|
-
};
|
|
121
|
-
arrays('should create array instead of object via numeric key :: simple', () => {
|
|
110
|
+
describe('set arrays', () => {
|
|
111
|
+
it('should create array instead of object via numeric key :: simple', () => {
|
|
122
112
|
const input: any = { a: 1 };
|
|
123
113
|
set(input, 'e.0', 2);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
expect(Array.isArray(input.e)).toBeTruthy();
|
|
115
|
+
expect(input.e[0]).toBe(2);
|
|
116
|
+
expect(input).toStrictEqual({
|
|
127
117
|
a: 1,
|
|
128
118
|
e: [2],
|
|
129
119
|
});
|
|
130
120
|
});
|
|
131
121
|
|
|
132
|
-
|
|
122
|
+
it('should create array instead of object via numeric key :: nested', () => {
|
|
133
123
|
const input: any = { a: 1 };
|
|
134
124
|
set(input, 'e.0.0', 123);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
125
|
+
expect(input.e instanceof Array).toBeTruthy();
|
|
126
|
+
expect(input.e[0][0]).toBe(123);
|
|
127
|
+
expect(input).toEqual({
|
|
138
128
|
a: 1,
|
|
139
129
|
e: [[123]],
|
|
140
130
|
});
|
|
141
131
|
});
|
|
142
132
|
|
|
143
|
-
|
|
133
|
+
it('should be able to create object inside of array', () => {
|
|
144
134
|
const input: any = {};
|
|
145
135
|
set(input, ['x', '0', 'z'], 123);
|
|
146
|
-
|
|
147
|
-
|
|
136
|
+
expect(input.x instanceof Array).toBeTruthy();
|
|
137
|
+
|
|
138
|
+
expect(input).toEqual({
|
|
148
139
|
x: [{ z: 123 }],
|
|
149
140
|
});
|
|
150
141
|
});
|
|
151
142
|
|
|
152
|
-
|
|
143
|
+
it('should create arrays with hole(s) if needed', () => {
|
|
153
144
|
const input: any = {};
|
|
154
145
|
set(input, ['x', '1', 'z'], 123);
|
|
155
|
-
|
|
156
|
-
|
|
146
|
+
expect(input.x instanceof Array).toBeTruthy();
|
|
147
|
+
expect(input).toEqual({
|
|
157
148
|
x: [undefined, { z: 123 }],
|
|
158
149
|
});
|
|
159
150
|
});
|
|
160
151
|
|
|
161
|
-
|
|
152
|
+
it('should create object from decimal-like key :: array :: zero :: string', () => {
|
|
162
153
|
const input: any = {};
|
|
163
154
|
set(input, ['x', '10.0', 'z'], 123);
|
|
164
|
-
|
|
165
|
-
|
|
155
|
+
expect(input.x instanceof Array).toBeFalsy();
|
|
156
|
+
expect(input).toEqual({
|
|
166
157
|
x: {
|
|
167
158
|
'10.0': {
|
|
168
159
|
z: 123,
|
|
@@ -171,21 +162,21 @@ test('set arrays', (t) => {
|
|
|
171
162
|
});
|
|
172
163
|
});
|
|
173
164
|
|
|
174
|
-
|
|
165
|
+
it('should create array from decimal-like key :: array :: zero :: number', () => {
|
|
175
166
|
const input: any = {};
|
|
176
167
|
set(input, ['x', 10.0, 'z'], 123);
|
|
177
|
-
|
|
168
|
+
expect(input.x instanceof Array).toBeTruthy();
|
|
178
169
|
|
|
179
170
|
const x = Array(10);
|
|
180
171
|
x.push({ z: 123 });
|
|
181
|
-
|
|
172
|
+
expect(input).toEqual({ x });
|
|
182
173
|
});
|
|
183
174
|
|
|
184
|
-
|
|
175
|
+
it('should create object from decimal-like key :: array :: nonzero', () => {
|
|
185
176
|
const input: any = {};
|
|
186
177
|
set(input, ['x', '10.2', 'z'], 123);
|
|
187
|
-
|
|
188
|
-
|
|
178
|
+
expect(input.x instanceof Array).toBeFalsy();
|
|
179
|
+
expect(input).toEqual({
|
|
189
180
|
x: {
|
|
190
181
|
'10.2': {
|
|
191
182
|
z: 123,
|
|
@@ -195,55 +186,51 @@ test('set arrays', (t) => {
|
|
|
195
186
|
});
|
|
196
187
|
});
|
|
197
188
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
t.log(s);
|
|
201
|
-
f();
|
|
202
|
-
};
|
|
203
|
-
pollution('should protect against "__proto__" assignment', () => {
|
|
189
|
+
describe('set pollution', () => {
|
|
190
|
+
it('should protect against "__proto__" assignment', () => {
|
|
204
191
|
const input: any = { abc: 123 };
|
|
205
192
|
const before = input.__proto__;
|
|
206
193
|
set(input, '__proto__.hello', 123);
|
|
207
194
|
|
|
208
|
-
|
|
209
|
-
|
|
195
|
+
expect(input.__proto__).toEqual(before);
|
|
196
|
+
expect(input).toEqual({
|
|
210
197
|
abc: 123,
|
|
211
198
|
});
|
|
212
199
|
});
|
|
213
200
|
|
|
214
|
-
|
|
201
|
+
it('should protect against "__proto__" assignment :: nested', () => {
|
|
215
202
|
const input: any = { abc: 123 };
|
|
216
203
|
const before = input.__proto__;
|
|
217
204
|
set(input, ['xyz', '__proto__', 'hello'], 123);
|
|
218
205
|
|
|
219
|
-
|
|
220
|
-
|
|
206
|
+
expect(input.__proto__).toEqual(before);
|
|
207
|
+
expect(input).toEqual({
|
|
221
208
|
abc: 123,
|
|
222
209
|
xyz: {
|
|
223
210
|
// empty
|
|
224
211
|
},
|
|
225
212
|
});
|
|
226
213
|
|
|
227
|
-
|
|
214
|
+
expect(input.hello).toBe(undefined);
|
|
228
215
|
});
|
|
229
216
|
|
|
230
|
-
|
|
217
|
+
it('should ignore "prototype" assignment', () => {
|
|
231
218
|
const input: any = { a: 123 };
|
|
232
219
|
set(input, 'a.prototype.hello', 'world');
|
|
233
220
|
|
|
234
|
-
|
|
235
|
-
|
|
221
|
+
expect(input.a.prototype).toBe(undefined);
|
|
222
|
+
expect(input.a.hello).toBe(undefined);
|
|
236
223
|
|
|
237
|
-
|
|
224
|
+
expect(input).toEqual({
|
|
238
225
|
a: {
|
|
239
226
|
// converted, then aborted
|
|
240
227
|
},
|
|
241
228
|
});
|
|
242
229
|
|
|
243
|
-
|
|
230
|
+
expect(JSON.stringify(input)).toBe('{"a":{}}');
|
|
244
231
|
});
|
|
245
232
|
|
|
246
|
-
|
|
233
|
+
it('should ignore "constructor" assignment :: direct', () => {
|
|
247
234
|
const input: any = { a: 123 };
|
|
248
235
|
|
|
249
236
|
function Custom() {
|
|
@@ -251,55 +238,52 @@ test('set pollution', (t) => {
|
|
|
251
238
|
}
|
|
252
239
|
|
|
253
240
|
set(input, 'a.constructor', Custom);
|
|
254
|
-
|
|
255
|
-
|
|
241
|
+
expect(input.a.constructor).not.toBe(Custom);
|
|
242
|
+
expect(input.a instanceof Custom).toBeFalsy();
|
|
256
243
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
244
|
+
expect(input.a.constructor instanceof Object, '~> 123 -> {}').toBeTruthy();
|
|
245
|
+
expect(input.a.hasOwnProperty('constructor')).toBe(false);
|
|
246
|
+
expect(input).toEqual({ a: {} });
|
|
260
247
|
});
|
|
261
248
|
|
|
262
|
-
|
|
249
|
+
it('should ignore "constructor" assignment :: nested', () => {
|
|
263
250
|
const input: any = {};
|
|
264
251
|
|
|
265
252
|
set(input, 'constructor.prototype.hello', 'world');
|
|
266
|
-
|
|
267
|
-
|
|
253
|
+
expect(input.hasOwnProperty('constructor')).toBe(false);
|
|
254
|
+
expect(input.hasOwnProperty('hello')).toBe(false);
|
|
268
255
|
|
|
269
|
-
|
|
256
|
+
expect(input).toEqual({
|
|
270
257
|
// empty
|
|
271
258
|
});
|
|
272
259
|
});
|
|
273
260
|
|
|
274
261
|
// Test for CVE-2022-25645 - CWE-1321
|
|
275
|
-
|
|
262
|
+
it('should ignore JSON.parse crafted object with "__proto__" key', () => {
|
|
276
263
|
const a: any = { b: { c: 1 } };
|
|
277
|
-
|
|
264
|
+
expect(a.polluted).toBe(undefined);
|
|
278
265
|
set(a, 'b', JSON.parse('{"__proto__":{"polluted":"Yes!"}}'));
|
|
279
|
-
|
|
266
|
+
expect(a.polluted).toBe(undefined);
|
|
280
267
|
});
|
|
281
268
|
});
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
f();
|
|
286
|
-
};
|
|
287
|
-
assigns('should add value to key path :: shallow :: string', () => {
|
|
269
|
+
|
|
270
|
+
describe('set assigns', () => {
|
|
271
|
+
it('should add value to key path :: shallow :: string', () => {
|
|
288
272
|
const input: any = {};
|
|
289
273
|
set(input, 'abc', 123);
|
|
290
|
-
|
|
274
|
+
expect(input).toEqual({ abc: 123 });
|
|
291
275
|
});
|
|
292
276
|
|
|
293
|
-
|
|
277
|
+
it('should add value to key path :: shallow :: array', () => {
|
|
294
278
|
const input: any = {};
|
|
295
279
|
set(input, ['abc'], 123);
|
|
296
|
-
|
|
280
|
+
expect(input).toEqual({ abc: 123 });
|
|
297
281
|
});
|
|
298
282
|
|
|
299
|
-
|
|
283
|
+
it('should add value to key path :: nested :: string', () => {
|
|
300
284
|
const input: any = {};
|
|
301
285
|
set(input, 'a.b.c', 123);
|
|
302
|
-
|
|
286
|
+
expect(input).toEqual({
|
|
303
287
|
a: {
|
|
304
288
|
b: {
|
|
305
289
|
c: 123,
|
|
@@ -308,10 +292,10 @@ test('set assigns', (t) => {
|
|
|
308
292
|
});
|
|
309
293
|
});
|
|
310
294
|
|
|
311
|
-
|
|
295
|
+
it('should add value to key path :: nested :: array', () => {
|
|
312
296
|
const input: any = {};
|
|
313
297
|
set(input, ['a', 'b', 'c'], 123);
|
|
314
|
-
|
|
298
|
+
expect(input).toEqual({
|
|
315
299
|
a: {
|
|
316
300
|
b: {
|
|
317
301
|
c: 123,
|
|
@@ -320,30 +304,27 @@ test('set assigns', (t) => {
|
|
|
320
304
|
});
|
|
321
305
|
});
|
|
322
306
|
|
|
323
|
-
|
|
307
|
+
it('should create Array via integer key :: string', () => {
|
|
324
308
|
const input: any = {};
|
|
325
309
|
set(input, ['foo', '0'], 123);
|
|
326
|
-
|
|
327
|
-
|
|
310
|
+
expect(input.foo instanceof Array).toBeTruthy();
|
|
311
|
+
expect(input).toEqual({
|
|
328
312
|
foo: [123],
|
|
329
313
|
});
|
|
330
314
|
});
|
|
331
315
|
|
|
332
|
-
|
|
316
|
+
it('should create Array via integer key :: number', () => {
|
|
333
317
|
const input: any = {};
|
|
334
318
|
set(input, ['foo', 0], 123);
|
|
335
|
-
|
|
336
|
-
|
|
319
|
+
expect(input.foo instanceof Array).toBeTruthy();
|
|
320
|
+
expect(input).toEqual({
|
|
337
321
|
foo: [123],
|
|
338
322
|
});
|
|
339
323
|
});
|
|
340
324
|
});
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
f();
|
|
345
|
-
};
|
|
346
|
-
preserves('should preserve existing object structure', () => {
|
|
325
|
+
|
|
326
|
+
describe('set preserves', () => {
|
|
327
|
+
it('should preserve existing object structure', () => {
|
|
347
328
|
const input = {
|
|
348
329
|
a: {
|
|
349
330
|
b: {
|
|
@@ -354,7 +335,7 @@ test('set preserves', (t) => {
|
|
|
354
335
|
|
|
355
336
|
set(input, 'a.b.x.y', 456);
|
|
356
337
|
|
|
357
|
-
|
|
338
|
+
expect(input).toEqual({
|
|
358
339
|
a: {
|
|
359
340
|
b: {
|
|
360
341
|
c: 123,
|
|
@@ -366,7 +347,7 @@ test('set preserves', (t) => {
|
|
|
366
347
|
});
|
|
367
348
|
});
|
|
368
349
|
|
|
369
|
-
|
|
350
|
+
it('should overwrite existing non-object values as object', () => {
|
|
370
351
|
const input = {
|
|
371
352
|
a: {
|
|
372
353
|
b: 123,
|
|
@@ -375,7 +356,7 @@ test('set preserves', (t) => {
|
|
|
375
356
|
|
|
376
357
|
set(input, 'a.b.c', 'hello');
|
|
377
358
|
|
|
378
|
-
|
|
359
|
+
expect(input).toEqual({
|
|
379
360
|
a: {
|
|
380
361
|
b: {
|
|
381
362
|
c: 'hello',
|
|
@@ -384,7 +365,7 @@ test('set preserves', (t) => {
|
|
|
384
365
|
});
|
|
385
366
|
});
|
|
386
367
|
|
|
387
|
-
|
|
368
|
+
it('should preserve existing object tree w/ array value', () => {
|
|
388
369
|
const input = {
|
|
389
370
|
a: {
|
|
390
371
|
b: {
|
|
@@ -398,7 +379,7 @@ test('set preserves', (t) => {
|
|
|
398
379
|
|
|
399
380
|
set(input, 'a.b.d.z', [1, 2, 3, 4]);
|
|
400
381
|
|
|
401
|
-
|
|
382
|
+
expect(input.a.b.d).toEqual({
|
|
402
383
|
e: 5,
|
|
403
384
|
z: [1, 2, 3, 4],
|
|
404
385
|
});
|
package/src/server.ts
CHANGED
|
@@ -2,4 +2,6 @@ export { polyfillCrypto } from './servers/polyfillCrypto';
|
|
|
2
2
|
export { polyfillFetch } from './servers/polyfillFetch';
|
|
3
3
|
export { polyfillJsDom } from './servers/polyfillJsDom';
|
|
4
4
|
export { polyfillBrowser } from './servers/polyfillBrowser';
|
|
5
|
-
export {
|
|
5
|
+
export { createFetchWithProxyByNodeFetch } from './servers/createFetchWithProxyByNodeFetch';
|
|
6
|
+
export { createFetchWithProxyByUndici } from './servers/createFetchWithProxyByUndici';
|
|
7
|
+
export { createFetchWithProxy } from './servers/createFetchWithProxy';
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { FetchLike } from '../fetch';
|
|
2
|
+
|
|
3
|
+
export function createFetchWithLogger({
|
|
4
|
+
fetch = globalThis.fetch,
|
|
5
|
+
logger = console.log,
|
|
6
|
+
}: {
|
|
7
|
+
fetch?: FetchLike;
|
|
8
|
+
logger?: (s: string) => void;
|
|
9
|
+
} = {}): FetchLike {
|
|
10
|
+
return async (...args) => {
|
|
11
|
+
const [, init = { method: 'GET', headers: {} } as RequestInit] = args;
|
|
12
|
+
const url = typeof args[0] === 'string' ? args[0] : args[0].url;
|
|
13
|
+
|
|
14
|
+
let dumpRequest = `-> ${init.method} ${url}
|
|
15
|
+
${Array.from(new Headers(init.headers).entries())
|
|
16
|
+
.map(([k, v]) => `${k}: ${v}`)
|
|
17
|
+
.join('\n')}
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
if (init.body) {
|
|
21
|
+
if (init.body instanceof ReadableStream) {
|
|
22
|
+
const [a, b] = init.body.tee();
|
|
23
|
+
init.body = a;
|
|
24
|
+
const signal = init.signal;
|
|
25
|
+
Promise.resolve().then(async () => {
|
|
26
|
+
const reader = b.getReader();
|
|
27
|
+
logger(dumpRequest);
|
|
28
|
+
while (true) {
|
|
29
|
+
if (signal?.aborted) {
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let { done, value } = await reader.read();
|
|
34
|
+
value instanceof Uint8Array && (value = new TextDecoder().decode(value));
|
|
35
|
+
dumpRequest += value;
|
|
36
|
+
logger(value);
|
|
37
|
+
if (!done) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// maybe for archive
|
|
42
|
+
dumpRequest += `\n`;
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
dumpRequest += `
|
|
46
|
+
${init.body}
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
console.log(dumpRequest);
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
let res = await fetch(...args);
|
|
54
|
+
let dumpResponse = `<- ${res.status} ${res.statusText} ${init.method} ${url}
|
|
55
|
+
${Array.from(res.headers.entries())
|
|
56
|
+
.map(([k, v]) => `${k}: ${v}`)
|
|
57
|
+
.join('\n')}
|
|
58
|
+
`;
|
|
59
|
+
let contentType = res.headers.get('content-type');
|
|
60
|
+
// text/event-stream
|
|
61
|
+
if (contentType?.includes('application/json') || contentType?.includes('text/plain')) {
|
|
62
|
+
const body = await res.text();
|
|
63
|
+
dumpResponse += `\n${body}\n`;
|
|
64
|
+
res = new Response(body, res);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
logger(dumpResponse);
|
|
68
|
+
|
|
69
|
+
return res;
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.error(`[Error] -> ${init.method} ${url} :${e}`);
|
|
72
|
+
throw e;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FetchLike } from '../fetch';
|
|
2
|
+
import { createFetchWithProxyByNodeFetch } from '../server';
|
|
3
|
+
import { createFetchWithProxyByUndici } from './createFetchWithProxyByUndici';
|
|
4
|
+
|
|
5
|
+
export function createFetchWithProxy({ proxy, fetch }: { proxy?: string; fetch?: FetchLike }): FetchLike {
|
|
6
|
+
if (!proxy) {
|
|
7
|
+
return fetch || globalThis.fetch;
|
|
8
|
+
}
|
|
9
|
+
return parseInt(process.versions.node) >= 18
|
|
10
|
+
? createFetchWithProxyByUndici({ proxy, fetch })
|
|
11
|
+
: createFetchWithProxyByNodeFetch({ proxy, fetch });
|
|
12
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { type FetchLike } from '../fetch';
|
|
2
2
|
import { globalThis } from '../isomorphics/globalThis';
|
|
3
3
|
|
|
4
|
-
export function
|
|
4
|
+
export function createFetchWithProxyByNodeFetch({
|
|
5
|
+
proxy,
|
|
6
|
+
fetch,
|
|
7
|
+
}: { proxy?: string; fetch?: FetchLike } = {}): FetchLike {
|
|
5
8
|
if (!proxy) {
|
|
6
9
|
return fetch || globalThis.fetch;
|
|
7
10
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { MaybePromise } from 'rollup';
|
|
2
|
+
import { FetchLike } from '../fetch';
|
|
3
|
+
|
|
4
|
+
export function createFetchWithProxyByUndici({
|
|
5
|
+
proxy,
|
|
6
|
+
fetch,
|
|
7
|
+
undici,
|
|
8
|
+
}: {
|
|
9
|
+
proxy?: string;
|
|
10
|
+
fetch?: FetchLike;
|
|
11
|
+
undici?: MaybePromise<{ fetch: any; ProxyAgent: any }>;
|
|
12
|
+
} = {}): FetchLike {
|
|
13
|
+
if (!proxy) {
|
|
14
|
+
return fetch || globalThis.fetch;
|
|
15
|
+
}
|
|
16
|
+
let agent: any;
|
|
17
|
+
return async (...args) => {
|
|
18
|
+
const init: RequestInit & { duplex?: string; dispatcher?: any } = (args[1] ||= {});
|
|
19
|
+
if (init.body instanceof ReadableStream) {
|
|
20
|
+
// https://github.com/nodejs/node/issues/46221
|
|
21
|
+
init.duplex ||= 'half';
|
|
22
|
+
}
|
|
23
|
+
if (!agent) {
|
|
24
|
+
// if in next use 'next/dist/compiled/undici'
|
|
25
|
+
undici ||= import('undici');
|
|
26
|
+
const mod = await undici;
|
|
27
|
+
const ProxyAgent = mod.ProxyAgent;
|
|
28
|
+
fetch ||= mod.fetch;
|
|
29
|
+
agent = new ProxyAgent(proxy);
|
|
30
|
+
// https://github.com/nodejs/node/issues/43187#issuecomment-1134634174
|
|
31
|
+
// (global as any)[Symbol.for('undici.globalDispatcher.1')] = agent;
|
|
32
|
+
}
|
|
33
|
+
init.dispatcher = agent;
|
|
34
|
+
return await fetch!(...args);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import test from 'ava';
|
|
2
1
|
import * as nodeFetch from 'node-fetch';
|
|
2
|
+
import { test, expect, beforeAll } from 'vitest';
|
|
3
3
|
import { polyfillBrowser } from './polyfillBrowser';
|
|
4
4
|
import { polyfillFetch } from './polyfillFetch';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
beforeAll(async () => {
|
|
7
7
|
// return false in nodejs18
|
|
8
8
|
polyfillFetch(nodeFetch);
|
|
9
|
-
|
|
9
|
+
expect(polyfillFetch()).toBeFalsy();
|
|
10
10
|
await polyfillBrowser();
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
test('polyfillBrowser', (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
test('polyfillBrowser', () => {
|
|
14
|
+
expect(fetch).toBeTruthy();
|
|
15
|
+
expect(window).toBeTruthy();
|
|
16
|
+
expect(document).toBeTruthy();
|
|
17
|
+
expect(crypto).toBeTruthy();
|
|
18
18
|
// not the same
|
|
19
|
-
|
|
19
|
+
expect(window).not.toBe(globalThis);
|
|
20
20
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint no-template-curly-in-string:0 */
|
|
2
|
-
import test from '
|
|
2
|
+
import { expect, test } from 'vitest';
|
|
3
3
|
import { renderTemplate } from './renderTemplate';
|
|
4
4
|
|
|
5
|
-
test('renderTemplate', (
|
|
5
|
+
test('renderTemplate', () => {
|
|
6
6
|
const obj = {
|
|
7
7
|
name: 'wener',
|
|
8
8
|
authors: [
|
|
@@ -15,12 +15,9 @@ test('renderTemplate', (t) => {
|
|
|
15
15
|
'My name is ${name}': 'My name is wener',
|
|
16
16
|
'My name is ${ authors[0].name }': 'My name is wener',
|
|
17
17
|
})) {
|
|
18
|
-
|
|
18
|
+
expect(renderTemplate(k, obj)).toBe(v);
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
);
|
|
24
|
-
t.is(renderTemplate('My name is ${name}', obj, 'common'), 'My name is ${name}');
|
|
25
|
-
t.is(renderTemplate('My name is {{name}}', obj, 'common'), 'My name is wener');
|
|
20
|
+
expect(renderTemplate('My name is ${name}', (v) => v)).toBe('My name is name');
|
|
21
|
+
expect(renderTemplate('My name is ${name}', obj, 'common')).toBe('My name is ${name}');
|
|
22
|
+
expect(renderTemplate('My name is {{name}}', obj, 'common')).toBe('My name is wener');
|
|
26
23
|
});
|