@server/next 0.21.1 → 0.21.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@server/next",
3
- "version": "0.21.1",
3
+ "version": "0.21.3",
4
4
  "description": "A fully-fledged web server with routing, file uploads, sessions, static files, schema validation, websockets, testing, etc.",
5
5
  "homepage": "https://server-js.com/",
6
6
  "repository": "https://github.com/franciscop/server-next.git",
@@ -16,17 +16,17 @@ describe("user creation flow", () => {
16
16
  .test();
17
17
 
18
18
  // Bun's bug: https://github.com/oven-sh/bun/issues/6348
19
- it.skip("can create a new user", async () => {
19
+ it("can create a new user", async () => {
20
20
  const register = await api.post("/auth/register/email", CREDENTIALS);
21
21
  expect(register).toSucceed();
22
22
  expect(await store.keys()).toEqual([
23
23
  "user:abc@test.com",
24
- "auth:" + register.headers["set-cookie"].split("=")[1],
24
+ "auth:" + register.headers["set-cookie"].split(";")[0].split("=")[1],
25
25
  ]);
26
26
 
27
27
  const me = await api.get("/me");
28
28
  expect(me).toSucceed();
29
- expect(me.data.email).toEqual(EMAIL);
29
+ expect(me.body.email).toEqual(EMAIL);
30
30
 
31
31
  const logout = await api.post("/auth/logout");
32
32
  expect(logout).toSucceed();
@@ -36,7 +36,7 @@ describe("user creation flow", () => {
36
36
  expect(login).toSucceed();
37
37
  expect(await store.keys()).toEqual([
38
38
  "user:abc@test.com",
39
- "auth:" + login.headers["set-cookie"].split("=")[1],
39
+ "auth:" + login.headers["set-cookie"].split(";")[0].split("=")[1],
40
40
  ]);
41
41
  });
42
42
  });
@@ -18,7 +18,7 @@ describe("user creation flow", () => {
18
18
  .test();
19
19
 
20
20
  // Bun's bug: https://github.com/oven-sh/bun/issues/6348
21
- it.skip("tests a long user flow with tokens", async () => {
21
+ it("tests a long user flow with tokens", async () => {
22
22
  // The latest updated token
23
23
  let token;
24
24
 
@@ -28,8 +28,8 @@ describe("user creation flow", () => {
28
28
  expect(register).toSucceed();
29
29
 
30
30
  expect(await users()).toEqual(["abc@test.com"]);
31
- expect(await sessions()).toEqual([register.data.token]);
32
- return register.data.token;
31
+ expect(await sessions()).toEqual([register.body.token]);
32
+ return register.body.token;
33
33
  })();
34
34
 
35
35
  // CAN GET MY OWN INFO
@@ -37,7 +37,7 @@ describe("user creation flow", () => {
37
37
  const headers = { authorization: "Bearer " + token };
38
38
  const me = await api.get("/me", { headers });
39
39
  expect(me).toSucceed();
40
- expect(me.data.email).toEqual(EMAIL);
40
+ expect(me.body.email).toEqual(EMAIL);
41
41
 
42
42
  expect(await users()).toEqual(["abc@test.com"]);
43
43
  expect(await sessions()).toEqual([token]);
@@ -57,8 +57,8 @@ describe("user creation flow", () => {
57
57
  const login = await api.post("/auth/login/email", CREDENTIALS);
58
58
  expect(login).toSucceed();
59
59
  expect(await users()).toEqual(["abc@test.com"]);
60
- expect(await sessions()).toEqual([login.data.token]);
61
- return login.data.token;
60
+ expect(await sessions()).toEqual([login.body.token]);
61
+ return login.body.token;
62
62
  })();
63
63
 
64
64
  // CAN GET MY OWN INFO
@@ -66,7 +66,7 @@ describe("user creation flow", () => {
66
66
  const headers = { authorization: "Bearer " + token };
67
67
  const me = await api.get("/me", { headers });
68
68
  expect(me).toSucceed();
69
- expect(me.data.email).toEqual(EMAIL);
69
+ expect(me.body.email).toEqual(EMAIL);
70
70
  })();
71
71
 
72
72
  // UPDATE PASSWORD
@@ -103,8 +103,8 @@ describe("user creation flow", () => {
103
103
  });
104
104
  expect(login).toSucceed();
105
105
  expect(await users()).toEqual(["abc@test.com"]);
106
- expect(await sessions()).toEqual([login.data.token]);
107
- return login.data.token;
106
+ expect(await sessions()).toEqual([login.body.token]);
107
+ return login.body.token;
108
108
  })();
109
109
  });
110
110
  });
package/src/auth/auth.js CHANGED
@@ -48,8 +48,8 @@ export default async function auth(ctx) {
48
48
 
49
49
  const auth = await options.session.get(sessionId);
50
50
  // Mmh, which one to do...
51
- if (!auth) throw ServerError.AUTH_NO_SESSION();
52
- // if (!auth) return; // SESSION ALREADY INVALID; no auth
51
+ // if (!auth) throw ServerError.AUTH_NO_SESSION();
52
+ if (!auth) return; // SESSION ALREADY INVALID; no auth
53
53
 
54
54
  if (!auth.provider) throw ServerError.AUTH_NO_PROVIDER();
55
55
  if (!options.provider.includes(auth.provider)) {
package/src/auth/index.js CHANGED
@@ -12,16 +12,16 @@ const load = async (ctx) => {
12
12
 
13
13
  const middle = async (ctx) => {
14
14
  if (ctx.options.auth) {
15
- ctx.app.post("/auth/logout", logout);
16
-
17
15
  if (ctx.options.auth.provider.includes("github")) {
18
16
  if (!env.GITHUB_ID) throw new Error("GITHUB_ID not defined");
19
17
  if (!env.GITHUB_SECRET) throw new Error("GITHUB_SECRET not defined");
18
+ ctx.app.get("/auth/logout", logout);
20
19
  ctx.app.get("/auth/login/github", providers.github.login);
21
20
  ctx.app.get("/auth/callback/github", providers.github.callback);
22
21
  }
23
22
 
24
23
  if (ctx.options.auth.provider.includes("email")) {
24
+ ctx.app.post("/auth/logout", logout);
25
25
  ctx.app.post("/auth/register/email", providers.email.register);
26
26
  ctx.app.post("/auth/login/email", providers.email.login);
27
27
  ctx.app.put("/auth/password/email", providers.email.password);
@@ -61,7 +61,8 @@ describe("token", () => {
61
61
  it("cannot get the session", async () => {
62
62
  const authorization = "Bearer REqA2l022l8Q0tuI";
63
63
  const req = await api.get("/", { headers: { authorization } });
64
- expect(req).not.toSucceed("Invalid session");
64
+ expect(req.status).toBe(404);
65
+ // expect(req).not.toSucceed("Invalid session");
65
66
  });
66
67
 
67
68
  it("cannot get the user", async () => {
@@ -112,7 +113,8 @@ describe("cookie", () => {
112
113
  it("can get the proper session", async () => {
113
114
  const cookie = "authentication=REqA2l022l8Q0tuI";
114
115
  const req = await api.get("/", { headers: { cookie } });
115
- expect(req).not.toSucceed("Invalid session");
116
+ expect(req.status).toBe(404);
117
+ // expect(req).not.toSucceed("Invalid session");
116
118
  });
117
119
 
118
120
  it("can get the proper session", async () => {
@@ -7,7 +7,7 @@ export default async function logout(ctx) {
7
7
  if (type === "token") {
8
8
  return { token: null };
9
9
  } else if (type === "cookie") {
10
- return cookies({ authorization: null }).send({});
10
+ return cookies({ authorization: null }).redirect("/");
11
11
  } else if (type === "jwt") {
12
12
  throw new Error("JWT auth not supported yet");
13
13
  } else if (type === "key") {
@@ -88,7 +88,7 @@ async function register(ctx) {
88
88
 
89
89
  const time = new Date().toISOString().replace(/\.[0-9]*/, "");
90
90
  const user = {
91
- id: createId(user.email),
91
+ id: createId(email),
92
92
  email,
93
93
  password: await hash.hash(password),
94
94
  time,
@@ -1,5 +1,9 @@
1
1
  const entities = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" };
2
- const encode = (str = "") => str.replace(/[&<>"]/g, (tag) => entities[tag]);
2
+ const encode = (str = "") => {
3
+ if (typeof str === "number") str = String(str);
4
+ if (typeof str !== "string") return ""; // nullify not-strings
5
+ return str.replace(/[&<>"]/g, (tag) => entities[tag]);
6
+ };
3
7
 
4
8
  const SELFCLOSE = new Set(
5
9
  "area,base,br,col,embed,hr,img,input,link,meta,source,track,wbr".split(","),
@@ -13,7 +17,7 @@ export const jsx = (tag, { children, ...props }) => {
13
17
  if (typeof tag === "function") return tag({ children, ...props });
14
18
 
15
19
  if (props.dangerouslySetInnerHTML)
16
- children = props.dangerouslySetInnerHTML.__html;
20
+ children = () => props.dangerouslySetInnerHTML.__html;
17
21
  if (!children) children = [];
18
22
  if (typeof children === "string") children = [children];
19
23
  children = (Array.isArray(children) ? children : [children])
@@ -22,12 +26,19 @@ export const jsx = (tag, { children, ...props }) => {
22
26
  .join("");
23
27
  if (!tag) return () => children;
24
28
  let attrStr = Object.entries(props || {})
29
+ .filter(([k, v]) => k !== "dangerouslySetInnerHTML")
25
30
  .filter(([k, v]) => !/on[A-Z]/.test(k) && typeof v !== "function")
26
- .map(([k, v]) => `${altAttrs[k.toLowerCase()] || encode(k)}="${encode(v)}"`)
31
+ .filter(([k, v]) => v !== false)
32
+ .map(([k, v]) =>
33
+ v === true
34
+ ? altAttrs[k.toLowerCase()] || encode(k)
35
+ : `${altAttrs[k.toLowerCase()] || encode(k)}="${encode(v)}"`,
36
+ )
27
37
  .join(" ");
28
38
  if (attrStr) attrStr = " " + attrStr;
29
39
  if (SELFCLOSE.has(tag)) return () => `<${tag}${attrStr} />`;
30
- return () => `<${tag}${attrStr}>${children}</${tag}>`;
40
+ const doctype = tag === "html" ? "<!DOCTYPE html>" : "";
41
+ return () => `${doctype}<${tag}${attrStr}>${children}</${tag}>`;
31
42
  };
32
43
  export const jsxDEV = jsx;
33
44
  export const Fragment = "";
@@ -0,0 +1,48 @@
1
+ import { jsx } from "./jsx.js";
2
+
3
+ const $ = (code) => code();
4
+
5
+ expect.extend({
6
+ toRender(fn, rendered) {
7
+ const html = fn();
8
+ if (this.isNot) {
9
+ const msg = `Expected "${html}" to render differently`;
10
+ return { pass: html === rendered, message: () => msg };
11
+ }
12
+ const msg = `Expected "${html}" to be rendered as "${rendered}"`;
13
+ return { pass: html === rendered, message: () => msg };
14
+ },
15
+ });
16
+
17
+ describe("jsx", () => {
18
+ it("can render a div", () => {
19
+ expect(<div>Hello</div>).toRender(`<div>Hello</div>`);
20
+ });
21
+
22
+ it("can render an input with attributes", () => {
23
+ expect(<input name="hello" />).toRender(`<input name="hello" />`);
24
+ });
25
+
26
+ it("will stringify an attribute", () => {
27
+ expect(<input value={5.2} />).toRender('<input value="5.2" />');
28
+ });
29
+
30
+ it("will ignore a boolean attribute", () => {
31
+ expect(<input disabled />).toRender("<input disabled />");
32
+ expect(<input disabled={true} />).toRender("<input disabled />");
33
+ expect(<input disabled={false} />).toRender("<input />");
34
+ });
35
+
36
+ it("will remove events", () => {
37
+ expect(<input onChange={() => console.log("hello")} />).toRender(
38
+ "<input />",
39
+ );
40
+ });
41
+
42
+ it("will inject the doctype for html", () => {
43
+ expect(<html>Hello</html>).toRender("<!DOCTYPE html><html>Hello</html>");
44
+ expect(<html lang="en">Hello</html>).toRender(
45
+ `<!DOCTYPE html><html lang="en">Hello</html>`,
46
+ );
47
+ });
48
+ });
package/src/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  parseHeaders,
12
12
  } from "./helpers/index.js";
13
13
 
14
- import middle from "./middle/index.js";
14
+ import { assets, auth } from "./middle/index.js";
15
15
 
16
16
  // Export the reply helpers
17
17
  export * from "./reply.js";
@@ -29,7 +29,7 @@ export default function server(options = {}) {
29
29
  }
30
30
 
31
31
  // Keep a copy of the options in the instance
32
- this.opts = options;
32
+ this.opts = config(options);
33
33
  this.platform = getMachine();
34
34
 
35
35
  // TODO: find a way to remove this hack
@@ -74,7 +74,10 @@ export default function server(options = {}) {
74
74
  this.node();
75
75
  }
76
76
 
77
- this.use(...middle);
77
+ this.use(assets);
78
+ if (this.opts.auth) {
79
+ this.use(auth({ options: this.opts, app: this }));
80
+ }
78
81
  }
79
82
 
80
83
  server.prototype.self = function () {
@@ -93,12 +96,11 @@ server.prototype.self = function () {
93
96
  // #region Runtimes
94
97
  // Node.js
95
98
  server.prototype.node = async function () {
96
- const options = config(this.opts);
97
99
  const http = await import("http");
98
100
  http
99
101
  .createServer(async (request, response) => {
100
102
  try {
101
- const ctx = await createNodeContext(request, options, this);
103
+ const ctx = await createNodeContext(request, this.opts, this);
102
104
  const out = await handleRequest(this.handlers, ctx);
103
105
 
104
106
  response.writeHead(out.status || 200, parseHeaders(out.headers));
@@ -125,8 +127,7 @@ server.prototype.callback = async function (request, context) {
125
127
  if (typeof Netlify === "undefined") {
126
128
  throw new Error("Netlify doesn't exist");
127
129
  }
128
- const options = config(this.opts);
129
- const ctx = await createWinterContext(request, options, this);
130
+ const ctx = await createWinterContext(request, this.opts, this);
130
131
  return await handleRequest(this.handlers, ctx);
131
132
  } catch (error) {
132
133
  return new Response(error.message, { status: error.status || 500 });
@@ -139,8 +140,7 @@ server.prototype.fetch = async function (request, env) {
139
140
  Object.assign(globalThis.env, env); // Extend env with the passed vars
140
141
 
141
142
  try {
142
- const options = config(this.opts);
143
- const ctx = await createWinterContext(request, options, this);
143
+ const ctx = await createWinterContext(request, this.opts, this);
144
144
  return await handleRequest(this.handlers, ctx);
145
145
  } catch (error) {
146
146
  return new Response(error.message, { status: error.status || 500 });
@@ -240,7 +240,7 @@ server.prototype.test = function () {
240
240
  } else {
241
241
  body = await res.text();
242
242
  }
243
- return { status: res.status, headers, body, data: body };
243
+ return { status: res.status, headers, body };
244
244
  };
245
245
  return {
246
246
  app: this,
package/src/index.test.js CHANGED
@@ -45,13 +45,13 @@ describe("return different types", () => {
45
45
  .test();
46
46
 
47
47
  it("can get the plain text", async () => {
48
- const { data } = await api.get("/text");
49
- expect(data).toBe("Hello world");
48
+ const { body } = await api.get("/text");
49
+ expect(body).toBe("Hello world");
50
50
  });
51
51
 
52
52
  it("can get the array", async () => {
53
- const { data } = await api.get("/array");
54
- expect(data).toEqual(["Hello world"]);
53
+ const { body } = await api.get("/array");
54
+ expect(body).toEqual(["Hello world"]);
55
55
  });
56
56
 
57
57
  it("can get the object", async () => {
@@ -71,19 +71,17 @@ describe("simple post works", () => {
71
71
  .post("/", (ctx) => status(201).send(ctx.body))
72
72
  .test();
73
73
 
74
- // Bun's bug: https://github.com/oven-sh/bun/issues/6348
75
- it.skip("can post new data", async () => {
76
- const { data, status, headers } = await api.post("/", "New Data");
74
+ it("can post new data", async () => {
75
+ const { body, status, headers } = await api.post("/", "New Data");
77
76
  expect(status).toBe(201);
78
- expect(data).toBe("New Data");
77
+ expect(body).toBe("New Data");
79
78
  expect(headers["content-type"]).toBe("text/plain; charset=utf-8");
80
79
  });
81
80
 
82
- // Bun's bug: https://github.com/oven-sh/bun/issues/6348
83
- it.skip("will return JSON", async () => {
84
- const { data, status, headers } = await api.post("/", { hello: "world" });
81
+ it("will return JSON", async () => {
82
+ const { body, status, headers } = await api.post("/", { hello: "world" });
85
83
  expect(status).toBe(201);
86
- expect(data).toEqual({ hello: "world" });
84
+ expect(body).toEqual({ hello: "world" });
87
85
  expect(headers["content-type"]).toBe("application/json; charset=utf-8");
88
86
  });
89
87
  });
@@ -2,7 +2,7 @@ import { type } from "../reply.js";
2
2
 
3
3
  export default async function assets(ctx) {
4
4
  if (!ctx.options.public) return;
5
- if (!ctx.method !== "get") return;
5
+ if (ctx.method !== "get") return;
6
6
  try {
7
7
  // TODO: streaming
8
8
  // Read it as buffer (null)
@@ -0,0 +1,10 @@
1
+ import server from "../";
2
+
3
+ describe("static assets", () => {
4
+ it("can serve a simple file", async () => {
5
+ const app = server({ public: "./src/middle/" }).test();
6
+ const { body, headers } = await app.get("/assets.test.js");
7
+ expect(body).toInclude("describe");
8
+ expect(headers["content-type"]).toBe("text/javascript");
9
+ });
10
+ });
@@ -1,4 +1,5 @@
1
- import auth from "../auth/index.js";
1
+ import authMod from "../auth/index.js";
2
2
  import assets from "./assets.js";
3
3
 
4
- export default [assets, auth.middle];
4
+ const auth = authMod.middle;
5
+ export { assets, auth };
@@ -20,27 +20,27 @@ describe("can route properly", () => {
20
20
 
21
21
  it("can get fallback when nothing matches", async () => {
22
22
  const res = await api.get("/");
23
- expect(res.data).toBe("Fallback");
23
+ expect(res.body).toBe("Fallback");
24
24
  });
25
25
 
26
26
  it("can get the base get", async () => {
27
27
  const res = await api.get("/hello");
28
- expect(res.data).toBe("Hello /hello");
28
+ expect(res.body).toBe("Hello /hello");
29
29
  });
30
30
 
31
31
  it("can get the nested get", async () => {
32
32
  const res = await api.get("/api/hello");
33
- expect(res.data).toBe("Hello /api/hello");
33
+ expect(res.body).toBe("Hello /api/hello");
34
34
  });
35
35
 
36
36
  it("can post to the base get", async () => {
37
37
  const res = await api.post("/hello");
38
- expect(res.data).toBe("Hello /hello");
38
+ expect(res.body).toBe("Hello /hello");
39
39
  });
40
40
 
41
41
  it("can post to the nested get", async () => {
42
42
  const res = await api.post("/api/hello");
43
- expect(res.data).toBe("Hello /api/hello");
43
+ expect(res.body).toBe("Hello /api/hello");
44
44
  });
45
45
 
46
46
  it("no status reuse", async () => {
@@ -20,22 +20,22 @@ describe("session", () => {
20
20
  await store.set("session:REqA2l022l8Q0tuIRtqLOPUy", { a: 0 });
21
21
 
22
22
  const res = await api.get("/hello", options);
23
- expect(res.data).toBe("Hello 0");
23
+ expect(res.body).toBe("Hello 0");
24
24
 
25
25
  const res2 = await api.post("/hello", {}, options);
26
- expect(res2.data).toBe("Bye 1");
26
+ expect(res2.body).toBe("Bye 1");
27
27
 
28
28
  const res3 = await api.get("/hello", options);
29
- expect(res3.data).toBe("Hello 1");
29
+ expect(res3.body).toBe("Hello 1");
30
30
  expect(await store.get("session:REqA2l022l8Q0tuIRtqLOPUy")).toEqual({
31
31
  a: 1,
32
32
  });
33
33
 
34
34
  const res4 = await api.post("/hello", {}, options);
35
- expect(res4.data).toBe("Bye 2");
35
+ expect(res4.body).toBe("Bye 2");
36
36
 
37
37
  const res5 = await api.get("/hello", options);
38
- expect(res5.data).toBe("Hello 2");
38
+ expect(res5.body).toBe("Hello 2");
39
39
  expect(await store.get("session:REqA2l022l8Q0tuIRtqLOPUy")).toEqual({
40
40
  a: 2,
41
41
  });
@@ -54,12 +54,12 @@ describe("missing store", () => {
54
54
  it("cannot read a session without a store", async () => {
55
55
  const res = await api.get("/read");
56
56
  expect(res.status).toBe(500);
57
- expect(res.data).toBe("You need a 'store' to read 'ctx.session.a'");
57
+ expect(res.body).toBe("You need a 'store' to read 'ctx.session.a'");
58
58
  });
59
59
 
60
60
  it("cannot write a session without a store", async () => {
61
61
  const res = await api.get("/write");
62
62
  expect(res.status).toBe(500);
63
- expect(res.data).toBe("You need a 'store' to write 'ctx.session.a'");
63
+ expect(res.body).toBe("You need a 'store' to write 'ctx.session.a'");
64
64
  });
65
65
  });
@@ -10,17 +10,17 @@ const spaceOrEnter = (msg) => {
10
10
  };
11
11
 
12
12
  export default function toSucceed(request, message) {
13
- const pass = request.status >= 200 && request.status < 300;
13
+ const pass = request.status >= 200 && request.status < 400;
14
14
 
15
- if (message && JSON.stringify(request.data) !== JSON.stringify(message)) {
15
+ if (message && JSON.stringify(request.body) !== JSON.stringify(message)) {
16
16
  if (pass) {
17
17
  return {
18
18
  message: () =>
19
19
  `${reset}Expected body:${spaceOrEnter(
20
- message
20
+ message,
21
21
  )}${this.utils.printExpected(message)}\nReceived body:${spaceOrEnter(
22
- request.data
23
- )}${this.utils.printReceived(request.data)}`,
22
+ request.body,
23
+ )}${this.utils.printReceived(request.body)}`,
24
24
  pass,
25
25
  };
26
26
  }
@@ -28,10 +28,10 @@ export default function toSucceed(request, message) {
28
28
  return {
29
29
  message: () =>
30
30
  `${reset}Expected error:${spaceOrEnter(
31
- message
31
+ message,
32
32
  )}${this.utils.printExpected(message)}\nReceived error:${spaceOrEnter(
33
- request.data
34
- )}${this.utils.printReceived(request.data)}`,
33
+ request.body,
34
+ )}${this.utils.printReceived(request.body)}`,
35
35
  pass: !pass,
36
36
  };
37
37
  }
@@ -40,9 +40,9 @@ export default function toSucceed(request, message) {
40
40
  return {
41
41
  message: () =>
42
42
  `${reset}Expected ${this.utils.printExpected(
43
- request.status
43
+ request.status,
44
44
  )} to be an error code, received body:\n${this.utils.printExpected(
45
- request.data
45
+ request.body,
46
46
  )}`,
47
47
  pass: true,
48
48
  };
@@ -51,11 +51,11 @@ export default function toSucceed(request, message) {
51
51
  return {
52
52
  message: () =>
53
53
  `${reset}Expected ${this.utils.printReceived(
54
- request.status
54
+ request.status,
55
55
  )} to succeed, received body:\n${this.utils.printReceived(
56
- request.data,
56
+ request.body,
57
57
  null,
58
- 2
58
+ 2,
59
59
  )}`,
60
60
  pass: false,
61
61
  };
package/src/url.test.js CHANGED
@@ -7,8 +7,8 @@ describe("can match the url", () => {
7
7
  .get("/*", (ctx) => ctx.url.params)
8
8
  .test();
9
9
 
10
- const { data, headers } = await api.get("/hello");
11
- expect(data).toEqual({ id: "hello" });
10
+ const { body, headers } = await api.get("/hello");
11
+ expect(body).toEqual({ id: "hello" });
12
12
  expect(headers["content-type"]).toEqual("application/json; charset=utf-8");
13
13
  });
14
14
 
@@ -19,8 +19,8 @@ describe("can match the url", () => {
19
19
  .get("/*", (ctx) => ctx.url.params)
20
20
  .test();
21
21
 
22
- const { data, headers, ...rest } = await api.get("/hello");
23
- expect(data).toEqual({ id: "hello" });
22
+ const { body, headers, ...rest } = await api.get("/hello");
23
+ expect(body).toEqual({ id: "hello" });
24
24
  expect(headers["content-type"]).toEqual("application/json; charset=utf-8");
25
25
  });
26
26
  });