@mauroandre/velojs 0.0.26 → 0.0.28
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/README.md +81 -2
- package/dist/events.d.ts +58 -3
- package/dist/events.js +174 -135
- package/dist/hooks.d.ts +56 -0
- package/dist/hooks.js +128 -68
- package/dist/index.d.ts +2 -1
- package/dist/server.js +51 -50
- package/dist/sockets.d.ts +109 -0
- package/dist/sockets.js +196 -0
- package/dist/testing/index.js +454 -291
- package/dist/testing/socketSession.d.ts +13 -0
- package/dist/testing/types.d.ts +36 -0
- package/dist/vite.d.ts +8 -0
- package/dist/vite.js +267 -236
- package/package.json +6 -1
package/dist/testing/index.js
CHANGED
|
@@ -1,245 +1,496 @@
|
|
|
1
|
-
import { getRegisteredStreams as
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { getRegisteredStreams as D } from "../events.js";
|
|
2
|
+
import { trackSocketSession as U, getAppSockets as q, abortAllSocketSessions as V } from "../sockets.js";
|
|
3
|
+
import { createIsolatedContext as B, withAppContext as W } from "../app-context.js";
|
|
4
|
+
function R(e) {
|
|
4
5
|
if (!e) return;
|
|
5
|
-
const
|
|
6
|
-
if (
|
|
7
|
-
return
|
|
6
|
+
const s = Object.entries(e);
|
|
7
|
+
if (s.length !== 0)
|
|
8
|
+
return s.map(([n, u]) => `${encodeURIComponent(n)}=${encodeURIComponent(u)}`).join("; ");
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
-
const
|
|
11
|
-
for (const
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
14
|
-
const c = a.slice(0,
|
|
15
|
-
c && (
|
|
10
|
+
function L(e) {
|
|
11
|
+
const s = {}, n = e.getSetCookie?.() ?? [];
|
|
12
|
+
for (const u of n) {
|
|
13
|
+
const l = u.indexOf(";"), a = l === -1 ? u : u.slice(0, l), p = a.indexOf("=");
|
|
14
|
+
if (p === -1) continue;
|
|
15
|
+
const c = a.slice(0, p).trim(), t = a.slice(p + 1).trim();
|
|
16
|
+
c && (s[c] = decodeURIComponent(t));
|
|
16
17
|
}
|
|
17
|
-
return
|
|
18
|
+
return s;
|
|
18
19
|
}
|
|
19
|
-
function
|
|
20
|
+
function N(e) {
|
|
20
21
|
if (!e) return "";
|
|
21
|
-
const
|
|
22
|
-
for (const [
|
|
23
|
-
if (Array.isArray(
|
|
24
|
-
for (const a of
|
|
22
|
+
const s = new URLSearchParams();
|
|
23
|
+
for (const [u, l] of Object.entries(e))
|
|
24
|
+
if (Array.isArray(l))
|
|
25
|
+
for (const a of l) s.append(u, a);
|
|
25
26
|
else
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
return
|
|
27
|
+
s.set(u, l);
|
|
28
|
+
const n = s.toString();
|
|
29
|
+
return n ? `?${n}` : "";
|
|
29
30
|
}
|
|
30
|
-
function
|
|
31
|
-
const
|
|
32
|
-
return e.forEach((
|
|
33
|
-
|
|
34
|
-
}),
|
|
31
|
+
function z(e) {
|
|
32
|
+
const s = {};
|
|
33
|
+
return e.forEach((n, u) => {
|
|
34
|
+
s[u] = n;
|
|
35
|
+
}), s;
|
|
35
36
|
}
|
|
36
|
-
function
|
|
37
|
+
function F(e) {
|
|
37
38
|
return e == null ? { body: null, contentType: null } : typeof e == "string" || e instanceof FormData || e instanceof URLSearchParams || e instanceof Blob || e instanceof ArrayBuffer || ArrayBuffer.isView(e) ? { body: e, contentType: null } : {
|
|
38
39
|
body: JSON.stringify(e),
|
|
39
40
|
contentType: "application/json"
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
|
-
const
|
|
43
|
-
function
|
|
44
|
-
const
|
|
45
|
-
return e.startsWith("http://") || e.startsWith("https://") ? e +
|
|
43
|
+
const $ = "http://velojs.test";
|
|
44
|
+
function I(e, s) {
|
|
45
|
+
const n = N(s);
|
|
46
|
+
return e.startsWith("http://") || e.startsWith("https://") ? e + n : (e.startsWith("/") || (e = "/" + e), $ + e + n);
|
|
46
47
|
}
|
|
47
|
-
function
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
function J(e = {}) {
|
|
49
|
+
const { user: s, params: n = {}, query: u = {}, body: l, headers: a = {}, cookies: p } = e, c = R(p), t = new Headers(a);
|
|
50
|
+
c && !t.has("cookie") && t.set("cookie", c);
|
|
51
|
+
const r = $ + "/_mock" + N(u), f = {
|
|
52
|
+
method: l == null ? "GET" : "POST",
|
|
53
|
+
headers: t
|
|
54
|
+
};
|
|
55
|
+
l != null && (typeof l == "string" || l instanceof FormData || l instanceof Blob ? f.body = l : (f.body = JSON.stringify(l), t.has("content-type") || t.set("content-type", "application/json")));
|
|
56
|
+
const d = new Request(r, f), w = /* @__PURE__ */ new Map();
|
|
57
|
+
return s !== void 0 && w.set("user", s), {
|
|
58
|
+
req: {
|
|
59
|
+
raw: d,
|
|
60
|
+
url: d.url,
|
|
61
|
+
method: d.method,
|
|
62
|
+
param(o) {
|
|
63
|
+
return o === void 0 ? n : n[o];
|
|
64
|
+
},
|
|
65
|
+
query(o) {
|
|
66
|
+
if (o === void 0) {
|
|
67
|
+
const i = {};
|
|
68
|
+
for (const [m, v] of Object.entries(u))
|
|
69
|
+
i[m] = String(v);
|
|
70
|
+
return i;
|
|
71
|
+
}
|
|
72
|
+
return u[o];
|
|
73
|
+
},
|
|
74
|
+
queries(o) {
|
|
75
|
+
const i = u[o];
|
|
76
|
+
if (i !== void 0)
|
|
77
|
+
return Array.isArray(i) ? i : [i];
|
|
78
|
+
},
|
|
79
|
+
header(o) {
|
|
80
|
+
if (o === void 0) {
|
|
81
|
+
const i = {};
|
|
82
|
+
return t.forEach((m, v) => {
|
|
83
|
+
i[v] = m;
|
|
84
|
+
}), i;
|
|
85
|
+
}
|
|
86
|
+
return t.get(o) ?? void 0;
|
|
87
|
+
},
|
|
88
|
+
async json() {
|
|
89
|
+
return l == null ? null : typeof l == "object" ? l : JSON.parse(String(l));
|
|
90
|
+
},
|
|
91
|
+
async text() {
|
|
92
|
+
return l == null ? "" : typeof l == "string" ? l : JSON.stringify(l);
|
|
93
|
+
},
|
|
94
|
+
async parseBody() {
|
|
95
|
+
return l ?? {};
|
|
96
|
+
},
|
|
97
|
+
path: "/_mock"
|
|
98
|
+
},
|
|
99
|
+
res: void 0,
|
|
100
|
+
env: {},
|
|
101
|
+
finalized: !1,
|
|
102
|
+
get(o) {
|
|
103
|
+
return w.get(o);
|
|
104
|
+
},
|
|
105
|
+
set(o, i) {
|
|
106
|
+
w.set(o, i);
|
|
107
|
+
},
|
|
108
|
+
var: new Proxy({}, {
|
|
109
|
+
get(o, i) {
|
|
110
|
+
return w.get(i);
|
|
111
|
+
}
|
|
112
|
+
}),
|
|
113
|
+
json(o, i = 200) {
|
|
114
|
+
return new Response(JSON.stringify(o), {
|
|
115
|
+
status: i,
|
|
116
|
+
headers: { "content-type": "application/json" }
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
text(o, i = 200) {
|
|
120
|
+
return new Response(o, { status: i });
|
|
121
|
+
},
|
|
122
|
+
html(o, i = 200) {
|
|
123
|
+
return new Response(o, {
|
|
124
|
+
status: i,
|
|
125
|
+
headers: { "content-type": "text/html; charset=UTF-8" }
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
body(o, i = 200) {
|
|
129
|
+
return new Response(o, { status: i });
|
|
130
|
+
},
|
|
131
|
+
redirect(o, i = 302) {
|
|
132
|
+
return new Response(null, { status: i, headers: { location: o } });
|
|
133
|
+
},
|
|
134
|
+
header(o, i) {
|
|
135
|
+
},
|
|
136
|
+
status(o) {
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function G(e, s) {
|
|
141
|
+
if (typeof s == "string") {
|
|
142
|
+
const n = q(e).get(s);
|
|
143
|
+
if (!n)
|
|
144
|
+
throw new Error(
|
|
145
|
+
`[velojs/testing] no socket handler registered at "${s}". Make sure the route exports a socket_* handler and routes are wired.`
|
|
146
|
+
);
|
|
147
|
+
return { handler: n.handler, path: s };
|
|
148
|
+
}
|
|
149
|
+
if (typeof s == "function") {
|
|
150
|
+
const n = s.__path;
|
|
151
|
+
if (!n)
|
|
152
|
+
throw new Error(
|
|
153
|
+
"[velojs/testing] socket handler has no __path. Make sure your vitest.config.ts loads veloPlugin() and your routes are registered."
|
|
154
|
+
);
|
|
155
|
+
return { handler: s, path: n };
|
|
156
|
+
}
|
|
157
|
+
if (s && typeof s == "object" && typeof s.__path == "string") {
|
|
158
|
+
const n = s.__path, u = q(e).get(n);
|
|
159
|
+
if (!u)
|
|
160
|
+
throw new Error(
|
|
161
|
+
`[velojs/testing] stub with __path="${n}" has no matching server handler.`
|
|
162
|
+
);
|
|
163
|
+
return { handler: u.handler, path: n };
|
|
164
|
+
}
|
|
165
|
+
throw new Error("[velojs/testing] socket(): unrecognized handler argument");
|
|
166
|
+
}
|
|
167
|
+
async function Q(e, s, n = {}) {
|
|
168
|
+
const { handler: u, path: l } = G(e, s), a = {
|
|
169
|
+
params: n.params ?? {},
|
|
170
|
+
query: {
|
|
171
|
+
...n.query,
|
|
172
|
+
...n.channel ? { channel: n.channel } : {}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
n.user !== void 0 && (a.user = n.user), n.headers && (a.headers = n.headers), n.cookies && (a.cookies = n.cookies);
|
|
176
|
+
const p = J(a), c = [];
|
|
177
|
+
let t = null, r = !1;
|
|
178
|
+
const f = {
|
|
179
|
+
async *[Symbol.asyncIterator]() {
|
|
180
|
+
for (; ; ) {
|
|
181
|
+
for (; c.length > 0; )
|
|
182
|
+
yield c.shift();
|
|
183
|
+
if (r) return;
|
|
184
|
+
await new Promise((g) => t = g), t = null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}, d = (g) => {
|
|
188
|
+
r || (c.push(g), t?.());
|
|
189
|
+
}, w = () => {
|
|
190
|
+
r || (r = !0, t?.());
|
|
191
|
+
}, h = [];
|
|
192
|
+
let o = [];
|
|
193
|
+
const i = (g) => {
|
|
194
|
+
h.push(g);
|
|
195
|
+
const j = o;
|
|
196
|
+
o = [];
|
|
197
|
+
for (const S of j)
|
|
198
|
+
try {
|
|
199
|
+
S();
|
|
200
|
+
} catch {
|
|
201
|
+
}
|
|
202
|
+
}, m = new AbortController(), v = U(e, m);
|
|
203
|
+
let k = !1, y = !1;
|
|
204
|
+
const b = (g) => {
|
|
205
|
+
y || (typeof g == "string" || g instanceof Uint8Array ? i(g) : i(JSON.stringify(g)));
|
|
206
|
+
}, C = (g, j) => {
|
|
207
|
+
T();
|
|
208
|
+
}, O = () => {
|
|
209
|
+
k = !0;
|
|
210
|
+
}, T = () => {
|
|
211
|
+
if (y) return;
|
|
212
|
+
if (y = !0, !m.signal.aborted)
|
|
213
|
+
try {
|
|
214
|
+
m.abort();
|
|
215
|
+
} catch {
|
|
216
|
+
}
|
|
217
|
+
v(), w();
|
|
218
|
+
const g = o;
|
|
219
|
+
o = [];
|
|
220
|
+
for (const j of g)
|
|
221
|
+
try {
|
|
222
|
+
j();
|
|
223
|
+
} catch {
|
|
224
|
+
}
|
|
225
|
+
}, H = {
|
|
226
|
+
incoming: f,
|
|
227
|
+
send: b,
|
|
228
|
+
close: C,
|
|
229
|
+
keepOpen: O,
|
|
230
|
+
abortSignal: m.signal,
|
|
231
|
+
c: p,
|
|
232
|
+
params: n.params ?? {},
|
|
233
|
+
query: {
|
|
234
|
+
...n.query ?? {},
|
|
235
|
+
...n.channel ? { channel: n.channel } : {}
|
|
236
|
+
}
|
|
237
|
+
}, A = (async () => {
|
|
238
|
+
try {
|
|
239
|
+
await u(H);
|
|
240
|
+
} catch (g) {
|
|
241
|
+
console.error("[velojs/testing] socket handler threw:", g);
|
|
242
|
+
}
|
|
243
|
+
k || T();
|
|
244
|
+
})(), P = (g) => new Promise((j, S) => {
|
|
245
|
+
const x = setTimeout(() => {
|
|
246
|
+
o = o.filter((M) => M !== _), S(new Error(`[velojs/testing] socket.next() timed out after ${g}ms`));
|
|
247
|
+
}, g), _ = () => {
|
|
248
|
+
clearTimeout(x), j();
|
|
249
|
+
};
|
|
250
|
+
o.push(_);
|
|
251
|
+
});
|
|
252
|
+
let E = 0;
|
|
253
|
+
return {
|
|
254
|
+
send(g) {
|
|
255
|
+
y || (typeof g == "string" || g instanceof Uint8Array ? d(g) : d(JSON.stringify(g)));
|
|
256
|
+
},
|
|
257
|
+
get messages() {
|
|
258
|
+
return h;
|
|
259
|
+
},
|
|
260
|
+
get closed() {
|
|
261
|
+
return y;
|
|
262
|
+
},
|
|
263
|
+
async next(g) {
|
|
264
|
+
for (; E >= h.length; ) {
|
|
265
|
+
if (y)
|
|
266
|
+
throw new Error("[velojs/testing] socket closed before next()");
|
|
267
|
+
await P(g.timeoutMs);
|
|
268
|
+
}
|
|
269
|
+
return h[E++];
|
|
270
|
+
},
|
|
271
|
+
async nextN(g, j) {
|
|
272
|
+
const S = Date.now() + j.timeoutMs, x = [];
|
|
273
|
+
for (; x.length < g; ) {
|
|
274
|
+
if (E < h.length) {
|
|
275
|
+
x.push(h[E++]);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (y)
|
|
279
|
+
throw new Error("[velojs/testing] socket closed before nextN()");
|
|
280
|
+
const _ = S - Date.now();
|
|
281
|
+
if (_ <= 0)
|
|
282
|
+
throw new Error(
|
|
283
|
+
`[velojs/testing] socket.nextN() timed out after ${j.timeoutMs}ms`
|
|
284
|
+
);
|
|
285
|
+
await P(_);
|
|
286
|
+
}
|
|
287
|
+
return x;
|
|
288
|
+
},
|
|
289
|
+
async close(g, j) {
|
|
290
|
+
T(), await Promise.race([
|
|
291
|
+
A,
|
|
292
|
+
new Promise((S) => setTimeout(S, 50))
|
|
293
|
+
]);
|
|
294
|
+
},
|
|
295
|
+
done: A
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function K(e) {
|
|
299
|
+
const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
|
|
300
|
+
function u(l) {
|
|
301
|
+
for (const a of l) {
|
|
302
|
+
const p = a.module?.metadata?.moduleId, c = a.module?.metadata?.fullPath;
|
|
303
|
+
if (a.module && p) {
|
|
304
|
+
for (const r of Object.keys(a.module)) {
|
|
305
|
+
if (!r.startsWith("action_")) continue;
|
|
306
|
+
const f = a.module[r];
|
|
56
307
|
if (typeof f != "function") continue;
|
|
57
|
-
const d =
|
|
58
|
-
|
|
308
|
+
const d = r.replace("action_", "");
|
|
309
|
+
s.set(f, {
|
|
59
310
|
name: d,
|
|
60
311
|
fn: f,
|
|
61
|
-
moduleId:
|
|
62
|
-
url: `/_action/${
|
|
312
|
+
moduleId: p,
|
|
313
|
+
url: `/_action/${p}/${d}`
|
|
63
314
|
});
|
|
64
315
|
}
|
|
65
316
|
const t = a.module.loader;
|
|
66
317
|
if (typeof t == "function" && c) {
|
|
67
|
-
const
|
|
68
|
-
|
|
318
|
+
const r = n.get(t);
|
|
319
|
+
r ? r.paths.push(c) : n.set(t, {
|
|
69
320
|
fn: t,
|
|
70
|
-
moduleId:
|
|
321
|
+
moduleId: p,
|
|
71
322
|
paths: [c]
|
|
72
323
|
});
|
|
73
324
|
}
|
|
74
325
|
}
|
|
75
|
-
a.children &&
|
|
326
|
+
a.children && u(a.children);
|
|
76
327
|
}
|
|
77
328
|
}
|
|
78
|
-
return
|
|
329
|
+
return u(e), { actions: s, loaders: n };
|
|
79
330
|
}
|
|
80
|
-
function
|
|
81
|
-
if (typeof
|
|
82
|
-
const
|
|
83
|
-
if (!
|
|
331
|
+
function X(e, s) {
|
|
332
|
+
if (typeof s == "string") return s;
|
|
333
|
+
const n = e.actions.get(s);
|
|
334
|
+
if (!n)
|
|
84
335
|
throw new Error(
|
|
85
336
|
`[velojs/testing] action_* function was not found in the route tree.
|
|
86
337
|
Make sure your Vitest config loads the VeloJS Vite plugin so that metadata is injected. See https://github.com/mauro-andre/velojs#testing`
|
|
87
338
|
);
|
|
88
|
-
return
|
|
339
|
+
return n.url;
|
|
89
340
|
}
|
|
90
|
-
function
|
|
91
|
-
if (typeof
|
|
92
|
-
const
|
|
93
|
-
if (!
|
|
341
|
+
function Y(e, s, n) {
|
|
342
|
+
if (typeof s == "string") return s;
|
|
343
|
+
const u = e.loaders.get(s);
|
|
344
|
+
if (!u)
|
|
94
345
|
throw new Error(
|
|
95
346
|
`[velojs/testing] loader function was not found in the route tree.
|
|
96
347
|
Make sure your Vitest config loads the VeloJS Vite plugin so that metadata is injected.`
|
|
97
348
|
);
|
|
98
|
-
let
|
|
99
|
-
if (
|
|
100
|
-
for (const [a,
|
|
101
|
-
|
|
102
|
-
return
|
|
349
|
+
let l = u.paths[0];
|
|
350
|
+
if (n)
|
|
351
|
+
for (const [a, p] of Object.entries(n))
|
|
352
|
+
l = l.replace(`:${a}`, encodeURIComponent(p));
|
|
353
|
+
return l;
|
|
103
354
|
}
|
|
104
|
-
class
|
|
355
|
+
class Z {
|
|
105
356
|
buffer = "";
|
|
106
357
|
current = {
|
|
107
358
|
event: "message",
|
|
108
359
|
data: []
|
|
109
360
|
};
|
|
110
|
-
push(
|
|
111
|
-
this.buffer +=
|
|
112
|
-
const
|
|
113
|
-
let
|
|
114
|
-
for (; (
|
|
361
|
+
push(s) {
|
|
362
|
+
this.buffer += s;
|
|
363
|
+
const n = [];
|
|
364
|
+
let u;
|
|
365
|
+
for (; (u = this.buffer.indexOf(`
|
|
115
366
|
`)) !== -1; ) {
|
|
116
|
-
const
|
|
117
|
-
if (this.buffer = this.buffer.slice(
|
|
367
|
+
const l = this.buffer.slice(0, u);
|
|
368
|
+
if (this.buffer = this.buffer.slice(u + 1), l === "") {
|
|
118
369
|
if (this.current.data.length > 0 || this.current.event !== "message") {
|
|
119
370
|
const t = {
|
|
120
371
|
event: this.current.event,
|
|
121
372
|
data: this.current.data.join(`
|
|
122
373
|
`)
|
|
123
374
|
};
|
|
124
|
-
this.current.id !== void 0 && (t.id = this.current.id),
|
|
375
|
+
this.current.id !== void 0 && (t.id = this.current.id), n.push(t);
|
|
125
376
|
}
|
|
126
377
|
this.current = { event: "message", data: [] };
|
|
127
378
|
continue;
|
|
128
379
|
}
|
|
129
|
-
if (
|
|
130
|
-
const a =
|
|
380
|
+
if (l.startsWith(":")) continue;
|
|
381
|
+
const a = l.indexOf(":");
|
|
131
382
|
if (a === -1) continue;
|
|
132
|
-
const
|
|
133
|
-
let c =
|
|
134
|
-
c.startsWith(" ") && (c = c.slice(1)),
|
|
383
|
+
const p = l.slice(0, a);
|
|
384
|
+
let c = l.slice(a + 1);
|
|
385
|
+
c.startsWith(" ") && (c = c.slice(1)), p === "event" ? this.current.event = c : p === "data" ? this.current.data.push(c) : p === "id" && (this.current.id = c);
|
|
135
386
|
}
|
|
136
|
-
return
|
|
387
|
+
return n;
|
|
137
388
|
}
|
|
138
389
|
}
|
|
139
|
-
async function
|
|
140
|
-
const { response:
|
|
141
|
-
let
|
|
390
|
+
async function ee(e) {
|
|
391
|
+
const { response: s } = e, n = s.status, u = [];
|
|
392
|
+
let l = null, a = !1, p = null;
|
|
142
393
|
const c = [];
|
|
143
|
-
let t = null,
|
|
144
|
-
const f = (
|
|
394
|
+
let t = null, r = Promise.resolve(void 0);
|
|
395
|
+
const f = (h) => {
|
|
145
396
|
for (; c.length > 0; ) {
|
|
146
|
-
const
|
|
147
|
-
|
|
397
|
+
const o = c.shift();
|
|
398
|
+
h ? o.reject(h) : o.reject(new Error("[velojs/testing] subscription closed before next event"));
|
|
148
399
|
}
|
|
149
400
|
};
|
|
150
|
-
if (
|
|
151
|
-
t =
|
|
152
|
-
const
|
|
153
|
-
|
|
401
|
+
if (n >= 200 && n < 300 && s.body) {
|
|
402
|
+
t = s.body.getReader();
|
|
403
|
+
const h = new TextDecoder(), o = new Z();
|
|
404
|
+
r = (async () => {
|
|
154
405
|
try {
|
|
155
406
|
for (; ; ) {
|
|
156
|
-
const { value:
|
|
157
|
-
if (
|
|
407
|
+
const { value: i, done: m } = await t.read();
|
|
408
|
+
if (m) {
|
|
158
409
|
a || (a = !0), f();
|
|
159
410
|
return;
|
|
160
411
|
}
|
|
161
|
-
const
|
|
162
|
-
for (const
|
|
163
|
-
if (
|
|
412
|
+
const v = h.decode(i, { stream: !0 }), k = o.push(v);
|
|
413
|
+
for (const y of k) {
|
|
414
|
+
if (y.event === "snapshot") {
|
|
164
415
|
try {
|
|
165
|
-
|
|
416
|
+
l = JSON.parse(y.data);
|
|
166
417
|
} catch (b) {
|
|
167
|
-
|
|
418
|
+
p = b;
|
|
168
419
|
}
|
|
169
420
|
continue;
|
|
170
421
|
}
|
|
171
|
-
if (
|
|
422
|
+
if (y.event === "close") {
|
|
172
423
|
a = !0, f(), t.cancel().catch(() => {
|
|
173
424
|
});
|
|
174
425
|
return;
|
|
175
426
|
}
|
|
176
|
-
if (
|
|
427
|
+
if (y.event !== "heartbeat")
|
|
177
428
|
try {
|
|
178
|
-
const b = JSON.parse(
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
429
|
+
const b = JSON.parse(y.data);
|
|
430
|
+
u.push(b);
|
|
431
|
+
const C = c.shift();
|
|
432
|
+
C && C.resolve(b);
|
|
182
433
|
} catch (b) {
|
|
183
|
-
|
|
434
|
+
p = b;
|
|
184
435
|
}
|
|
185
436
|
}
|
|
186
437
|
}
|
|
187
|
-
} catch (
|
|
188
|
-
if (
|
|
438
|
+
} catch (i) {
|
|
439
|
+
if (i?.name === "AbortError") {
|
|
189
440
|
f();
|
|
190
441
|
return;
|
|
191
442
|
}
|
|
192
|
-
f(
|
|
443
|
+
f(i);
|
|
193
444
|
}
|
|
194
445
|
})();
|
|
195
446
|
} else
|
|
196
|
-
await
|
|
447
|
+
await s.text().catch(() => ""), a = !0;
|
|
197
448
|
const d = {
|
|
198
449
|
get status() {
|
|
199
|
-
return
|
|
450
|
+
return n;
|
|
200
451
|
},
|
|
201
452
|
get events() {
|
|
202
|
-
return
|
|
453
|
+
return u;
|
|
203
454
|
},
|
|
204
455
|
get snapshot() {
|
|
205
|
-
return
|
|
456
|
+
return l;
|
|
206
457
|
},
|
|
207
458
|
get closed() {
|
|
208
459
|
return a;
|
|
209
460
|
},
|
|
210
|
-
async next({ timeoutMs:
|
|
211
|
-
if (
|
|
212
|
-
if (
|
|
213
|
-
const
|
|
214
|
-
return
|
|
461
|
+
async next({ timeoutMs: h }) {
|
|
462
|
+
if (p) throw p;
|
|
463
|
+
if (u.length > w) {
|
|
464
|
+
const o = u[w];
|
|
465
|
+
return w++, o;
|
|
215
466
|
}
|
|
216
467
|
if (a)
|
|
217
468
|
throw new Error("[velojs/testing] subscription is closed");
|
|
218
|
-
return new Promise((
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
`[velojs/testing] timed out after ${
|
|
469
|
+
return new Promise((o, i) => {
|
|
470
|
+
const m = setTimeout(() => {
|
|
471
|
+
const y = c.findIndex((b) => b.resolve === v);
|
|
472
|
+
y !== -1 && c.splice(y, 1), i(new Error(
|
|
473
|
+
`[velojs/testing] timed out after ${h}ms waiting for next event`
|
|
223
474
|
));
|
|
224
|
-
},
|
|
225
|
-
clearTimeout(
|
|
226
|
-
},
|
|
227
|
-
clearTimeout(
|
|
475
|
+
}, h), v = (y) => {
|
|
476
|
+
clearTimeout(m), w++, o(y);
|
|
477
|
+
}, k = (y) => {
|
|
478
|
+
clearTimeout(m), i(y);
|
|
228
479
|
};
|
|
229
|
-
c.push({ resolve:
|
|
480
|
+
c.push({ resolve: v, reject: k });
|
|
230
481
|
});
|
|
231
482
|
},
|
|
232
|
-
async nextN(
|
|
233
|
-
const
|
|
234
|
-
for (let
|
|
235
|
-
const
|
|
236
|
-
if (
|
|
483
|
+
async nextN(h, { timeoutMs: o }) {
|
|
484
|
+
const i = Date.now(), m = [];
|
|
485
|
+
for (let v = 0; v < h; v++) {
|
|
486
|
+
const k = o - (Date.now() - i);
|
|
487
|
+
if (k <= 0)
|
|
237
488
|
throw new Error(
|
|
238
|
-
`[velojs/testing] timed out after ${
|
|
489
|
+
`[velojs/testing] timed out after ${o}ms waiting for ${h} events (got ${m.length})`
|
|
239
490
|
);
|
|
240
|
-
|
|
491
|
+
m.push(await d.next({ timeoutMs: k }));
|
|
241
492
|
}
|
|
242
|
-
return
|
|
493
|
+
return m;
|
|
243
494
|
},
|
|
244
495
|
async close() {
|
|
245
496
|
if (t)
|
|
@@ -247,183 +498,94 @@ async function H(e) {
|
|
|
247
498
|
await t.cancel();
|
|
248
499
|
} catch {
|
|
249
500
|
}
|
|
250
|
-
a = !0, f(), await
|
|
501
|
+
a = !0, f(), await r.catch(() => {
|
|
251
502
|
});
|
|
252
503
|
}
|
|
253
504
|
};
|
|
254
|
-
let
|
|
505
|
+
let w = 0;
|
|
255
506
|
return d;
|
|
256
507
|
}
|
|
257
|
-
function
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
const o = C + "/_mock" + x(l), f = {
|
|
261
|
-
method: i == null ? "GET" : "POST",
|
|
262
|
-
headers: t
|
|
263
|
-
};
|
|
264
|
-
i != null && (typeof i == "string" || i instanceof FormData || i instanceof Blob ? f.body = i : (f.body = JSON.stringify(i), t.has("content-type") || t.set("content-type", "application/json")));
|
|
265
|
-
const d = new Request(o, f), y = /* @__PURE__ */ new Map();
|
|
266
|
-
return r !== void 0 && y.set("user", r), {
|
|
267
|
-
req: {
|
|
268
|
-
raw: d,
|
|
269
|
-
url: d.url,
|
|
270
|
-
method: d.method,
|
|
271
|
-
param(n) {
|
|
272
|
-
return n === void 0 ? u : u[n];
|
|
273
|
-
},
|
|
274
|
-
query(n) {
|
|
275
|
-
if (n === void 0) {
|
|
276
|
-
const s = {};
|
|
277
|
-
for (const [w, g] of Object.entries(l))
|
|
278
|
-
s[w] = String(g);
|
|
279
|
-
return s;
|
|
280
|
-
}
|
|
281
|
-
return l[n];
|
|
282
|
-
},
|
|
283
|
-
queries(n) {
|
|
284
|
-
const s = l[n];
|
|
285
|
-
if (s !== void 0)
|
|
286
|
-
return Array.isArray(s) ? s : [s];
|
|
287
|
-
},
|
|
288
|
-
header(n) {
|
|
289
|
-
if (n === void 0) {
|
|
290
|
-
const s = {};
|
|
291
|
-
return t.forEach((w, g) => {
|
|
292
|
-
s[g] = w;
|
|
293
|
-
}), s;
|
|
294
|
-
}
|
|
295
|
-
return t.get(n) ?? void 0;
|
|
296
|
-
},
|
|
297
|
-
async json() {
|
|
298
|
-
return i == null ? null : typeof i == "object" ? i : JSON.parse(String(i));
|
|
299
|
-
},
|
|
300
|
-
async text() {
|
|
301
|
-
return i == null ? "" : typeof i == "string" ? i : JSON.stringify(i);
|
|
302
|
-
},
|
|
303
|
-
async parseBody() {
|
|
304
|
-
return i ?? {};
|
|
305
|
-
},
|
|
306
|
-
path: "/_mock"
|
|
307
|
-
},
|
|
308
|
-
res: void 0,
|
|
309
|
-
env: {},
|
|
310
|
-
finalized: !1,
|
|
311
|
-
get(n) {
|
|
312
|
-
return y.get(n);
|
|
313
|
-
},
|
|
314
|
-
set(n, s) {
|
|
315
|
-
y.set(n, s);
|
|
316
|
-
},
|
|
317
|
-
var: new Proxy({}, {
|
|
318
|
-
get(n, s) {
|
|
319
|
-
return y.get(s);
|
|
320
|
-
}
|
|
321
|
-
}),
|
|
322
|
-
json(n, s = 200) {
|
|
323
|
-
return new Response(JSON.stringify(n), {
|
|
324
|
-
status: s,
|
|
325
|
-
headers: { "content-type": "application/json" }
|
|
326
|
-
});
|
|
327
|
-
},
|
|
328
|
-
text(n, s = 200) {
|
|
329
|
-
return new Response(n, { status: s });
|
|
330
|
-
},
|
|
331
|
-
html(n, s = 200) {
|
|
332
|
-
return new Response(n, {
|
|
333
|
-
status: s,
|
|
334
|
-
headers: { "content-type": "text/html; charset=UTF-8" }
|
|
335
|
-
});
|
|
336
|
-
},
|
|
337
|
-
body(n, s = 200) {
|
|
338
|
-
return new Response(n, { status: s });
|
|
339
|
-
},
|
|
340
|
-
redirect(n, s = 302) {
|
|
341
|
-
return new Response(null, { status: s, headers: { location: n } });
|
|
342
|
-
},
|
|
343
|
-
header(n, s) {
|
|
344
|
-
},
|
|
345
|
-
status(n) {
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
async function W(e) {
|
|
350
|
-
const r = E();
|
|
351
|
-
return await R(r, async () => {
|
|
508
|
+
async function ae(e) {
|
|
509
|
+
const s = B();
|
|
510
|
+
return await W(s, async () => {
|
|
352
511
|
e.bootstrap && await e.bootstrap();
|
|
353
|
-
const { createApp:
|
|
354
|
-
return
|
|
512
|
+
const { createApp: n } = await import("../server.js"), u = await n(e.routes), l = K(e.routes);
|
|
513
|
+
return te(u, s, l, e, void 0);
|
|
355
514
|
});
|
|
356
515
|
}
|
|
357
|
-
function
|
|
358
|
-
async function a(t,
|
|
359
|
-
const d =
|
|
360
|
-
|
|
361
|
-
let
|
|
516
|
+
function te(e, s, n, u, l) {
|
|
517
|
+
async function a(t, r, f = {}) {
|
|
518
|
+
const d = I(r, f.query), w = new Headers(f.headers ?? {}), h = { ...f.cookies ?? {} }, o = R(h);
|
|
519
|
+
o && w.set("cookie", o);
|
|
520
|
+
let i = null;
|
|
362
521
|
if (f.body !== void 0) {
|
|
363
|
-
const
|
|
364
|
-
|
|
522
|
+
const y = F(f.body);
|
|
523
|
+
i = y.body, y.contentType && !w.has("content-type") && w.set("content-type", y.contentType);
|
|
365
524
|
}
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
return await
|
|
525
|
+
const m = { method: t, headers: w };
|
|
526
|
+
i !== null && (m.body = i);
|
|
527
|
+
const v = new Request(d, m), k = await e.fetch(v);
|
|
528
|
+
return await ne(k);
|
|
370
529
|
}
|
|
371
|
-
async function
|
|
372
|
-
const d =
|
|
530
|
+
async function p(t, r, f = {}) {
|
|
531
|
+
const d = I(r, {
|
|
373
532
|
...f.query ?? {},
|
|
374
533
|
...f.channel ? { channel: f.channel } : {}
|
|
375
|
-
}),
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
return await e.fetch(
|
|
534
|
+
}), w = new Headers(f.headers ?? {}), h = { ...f.cookies ?? {} }, o = R(h);
|
|
535
|
+
o && w.set("cookie", o);
|
|
536
|
+
const i = new Request(d, { method: t, headers: w });
|
|
537
|
+
return await e.fetch(i);
|
|
379
538
|
}
|
|
380
539
|
const c = {
|
|
381
540
|
hono: e,
|
|
382
541
|
// HTTP
|
|
383
|
-
get: (t,
|
|
384
|
-
post: (t,
|
|
385
|
-
put: (t,
|
|
386
|
-
patch: (t,
|
|
387
|
-
delete: (t,
|
|
388
|
-
async action(t,
|
|
389
|
-
const f =
|
|
542
|
+
get: (t, r) => a("GET", t, r ?? {}),
|
|
543
|
+
post: (t, r) => a("POST", t, r ?? {}),
|
|
544
|
+
put: (t, r) => a("PUT", t, r ?? {}),
|
|
545
|
+
patch: (t, r) => a("PATCH", t, r ?? {}),
|
|
546
|
+
delete: (t, r) => a("DELETE", t, r ?? {}),
|
|
547
|
+
async action(t, r = {}) {
|
|
548
|
+
const f = X(n, t);
|
|
390
549
|
return await a("POST", f, {
|
|
391
|
-
...
|
|
392
|
-
body:
|
|
550
|
+
...r,
|
|
551
|
+
body: r.body ?? {}
|
|
393
552
|
});
|
|
394
553
|
},
|
|
395
|
-
async loader(t,
|
|
396
|
-
const f =
|
|
397
|
-
...
|
|
398
|
-
query: { ...
|
|
554
|
+
async loader(t, r = {}) {
|
|
555
|
+
const f = Y(n, t, r.params), d = await a("GET", f, {
|
|
556
|
+
...r,
|
|
557
|
+
query: { ...r.query ?? {}, _data: "1" }
|
|
399
558
|
});
|
|
400
559
|
if (d.status >= 300 && d.status < 400 || d.status >= 400) return d;
|
|
401
|
-
const
|
|
402
|
-
return
|
|
560
|
+
const w = typeof t == "function" ? n.loaders.get(t)?.moduleId : void 0, h = await d.json();
|
|
561
|
+
return w && h && typeof h == "object" && w in h ? h[w] : h;
|
|
562
|
+
},
|
|
563
|
+
async subscribe(t, r = {}) {
|
|
564
|
+
const f = typeof t == "string" ? t : t.__path ?? se(), d = await p("GET", f, r);
|
|
565
|
+
return await ee({ response: d });
|
|
403
566
|
},
|
|
404
|
-
async
|
|
405
|
-
|
|
406
|
-
return await H({ response: d });
|
|
567
|
+
async socket(t, r = {}) {
|
|
568
|
+
return await Q(e, t, r);
|
|
407
569
|
},
|
|
408
570
|
async sessionCookies({ user: t }) {
|
|
409
|
-
if (!
|
|
571
|
+
if (!u.getSessionCookie)
|
|
410
572
|
throw new Error(
|
|
411
573
|
"[velojs/testing] sessionCookies/as requires `getSessionCookie` in createTestApp options."
|
|
412
574
|
);
|
|
413
|
-
return await
|
|
575
|
+
return await u.getSessionCookie({ user: t });
|
|
414
576
|
},
|
|
415
577
|
as({ user: t }) {
|
|
416
|
-
if (!
|
|
578
|
+
if (!u.getSessionCookie)
|
|
417
579
|
throw new Error(
|
|
418
580
|
"[velojs/testing] app.as() requires `getSessionCookie` in createTestApp options."
|
|
419
581
|
);
|
|
420
|
-
let
|
|
421
|
-
const f = () => (
|
|
422
|
-
const
|
|
423
|
-
...
|
|
424
|
-
cookies: { ...
|
|
582
|
+
let r = null;
|
|
583
|
+
const f = () => (r || (r = Promise.resolve(u.getSessionCookie({ user: t }))), r), d = (h) => (async (...o) => {
|
|
584
|
+
const i = await f(), [m, v] = o, k = {
|
|
585
|
+
...v ?? {},
|
|
586
|
+
cookies: { ...i, ...v?.cookies ?? {} }
|
|
425
587
|
};
|
|
426
|
-
return await
|
|
588
|
+
return await h.call(c, m, k);
|
|
427
589
|
});
|
|
428
590
|
return {
|
|
429
591
|
hono: e,
|
|
@@ -435,6 +597,7 @@ function V(e, r, u, l, i) {
|
|
|
435
597
|
action: d(c.action),
|
|
436
598
|
loader: d(c.loader),
|
|
437
599
|
subscribe: d(c.subscribe),
|
|
600
|
+
socket: d(c.socket),
|
|
438
601
|
sessionCookies: c.sessionCookies,
|
|
439
602
|
as: c.as,
|
|
440
603
|
// chaining .as.as works — last wins
|
|
@@ -444,45 +607,45 @@ function V(e, r, u, l, i) {
|
|
|
444
607
|
};
|
|
445
608
|
},
|
|
446
609
|
mockContext(t = {}) {
|
|
447
|
-
return
|
|
610
|
+
return J(t);
|
|
448
611
|
},
|
|
449
612
|
async reset() {
|
|
450
|
-
for (const t of
|
|
613
|
+
for (const t of D())
|
|
451
614
|
try {
|
|
452
615
|
t.__reset();
|
|
453
|
-
} catch (
|
|
454
|
-
console.error("[velojs/testing] stream.__reset failed:",
|
|
616
|
+
} catch (r) {
|
|
617
|
+
console.error("[velojs/testing] stream.__reset failed:", r);
|
|
455
618
|
}
|
|
456
619
|
},
|
|
457
620
|
async close() {
|
|
458
|
-
await c.reset();
|
|
459
|
-
for (const t of
|
|
621
|
+
await c.reset(), V(e);
|
|
622
|
+
for (const t of s.disposers)
|
|
460
623
|
try {
|
|
461
624
|
t();
|
|
462
|
-
} catch (
|
|
463
|
-
console.error("[velojs/testing] disposer failed:",
|
|
625
|
+
} catch (r) {
|
|
626
|
+
console.error("[velojs/testing] disposer failed:", r);
|
|
464
627
|
}
|
|
465
|
-
|
|
628
|
+
s.disposers.clear();
|
|
466
629
|
}
|
|
467
630
|
};
|
|
468
631
|
return c;
|
|
469
632
|
}
|
|
470
|
-
async function
|
|
633
|
+
async function ne(e) {
|
|
471
634
|
return {
|
|
472
635
|
status: e.status,
|
|
473
|
-
headers:
|
|
474
|
-
cookies:
|
|
636
|
+
headers: z(e.headers),
|
|
637
|
+
cookies: L(e.headers),
|
|
475
638
|
json: () => e.clone().json(),
|
|
476
639
|
text: () => e.clone().text(),
|
|
477
640
|
blob: () => e.clone().blob(),
|
|
478
641
|
raw: e
|
|
479
642
|
};
|
|
480
643
|
}
|
|
481
|
-
function
|
|
644
|
+
function se(e) {
|
|
482
645
|
throw new Error(
|
|
483
646
|
"[velojs/testing] subscribe(stream) — stream has no __path. If this is a stream_* declaration, make sure your routes import is processed by the VeloJS Vite plugin (your vitest.config.ts must include `veloPlugin()`)."
|
|
484
647
|
);
|
|
485
648
|
}
|
|
486
649
|
export {
|
|
487
|
-
|
|
650
|
+
ae as createTestApp
|
|
488
651
|
};
|