@server/next 0.21.13 → 0.21.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@server/next",
3
- "version": "0.21.13",
3
+ "version": "0.21.14",
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",
@@ -14,19 +14,26 @@ export default function config(options = {}) {
14
14
  options.cors = options.cors || env.CORS || null;
15
15
  if (options.cors) {
16
16
  if (options.cors === true) {
17
- options.cors = { origin: true };
17
+ options.cors = { origin: options.cors };
18
18
  }
19
19
  if (typeof options.cors === "string") {
20
20
  options.cors = { origin: options.cors };
21
21
  }
22
+ if (Array.isArray(options.cors)) {
23
+ options.cors = { origin: options.cors };
24
+ }
25
+ if (Array.isArray(options.cors.origin)) {
26
+ options.cors.origin = options.cors.origin.join(",");
27
+ }
22
28
  if (typeof options.cors.origin === "string") {
23
29
  options.cors.origin = options.cors.origin.toLowerCase();
24
30
  }
31
+
25
32
  if (!options.cors.methods) {
26
- options.cors.methods = "GET,HEAD,POST,PUT,PATCH";
33
+ options.cors.methods = "GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS";
27
34
  }
28
35
  if (!options.cors.headers) {
29
- options.cors.methods = "*";
36
+ options.cors.headers = "*";
30
37
  }
31
38
  }
32
39
 
@@ -1,32 +1,24 @@
1
+ const localhost = /^https?:\/\/localhost(:\d+)?$/;
2
+
1
3
  // Based on https://expressjs.com/en/resources/middleware/cors.html#configuration-options
2
- export default function cors(configOrigin, origin = "") {
4
+ export default function cors(config, origin = "") {
3
5
  origin = origin.toLowerCase();
4
6
 
5
7
  // When it's true, reflect the origin
6
- if (configOrigin === true) return origin || null;
8
+ if (config === true) return origin || null;
7
9
 
8
10
  // A star should always return a star
9
- if (configOrigin === "*") return "*";
11
+ if (config === "*") return "*";
10
12
 
11
13
  // No origin, it's okay since that means we don't need CORS
12
14
  if (!origin) return null;
13
15
 
14
16
  // Coming from localhost
15
- if (/^https?:\/\/localhost(:\d+)?$/.test(origin)) {
16
- return origin;
17
- }
17
+ if (localhost.test(origin)) return origin;
18
18
 
19
- if (
20
- configOrigin
21
- .toLowerCase()
22
- .split(/\s*,\s*/g)
23
- .includes(origin)
24
- ) {
25
- return origin;
26
- }
19
+ const arr = Array.isArray(config) ? config : config.split(/\s*,\s*/g);
20
+ if (arr.includes(origin)) return origin;
27
21
 
28
- console.warn(
29
- `CORS: Origin "${origin}" not allowed. Allowed origins: ${configOrigin}`,
30
- );
22
+ console.warn(`CORS: Origin "${origin}" not allowed. Allowed "${config}"`);
31
23
  return null;
32
24
  }
@@ -0,0 +1,64 @@
1
+ import server from "../index.js";
2
+
3
+ const origin = "http://localhost:3000/";
4
+
5
+ describe("cors", () => {
6
+ it("can simply enable the cors", async () => {
7
+ const cors = "*";
8
+ const { headers } = await server({ cors })
9
+ .get("/", () => 200)
10
+ .test()
11
+ .get("/", { headers: { origin } });
12
+
13
+ expect(headers).toEqual({
14
+ "access-control-allow-origin": "*",
15
+ "access-control-allow-headers": "*",
16
+ "access-control-allow-methods": "GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS",
17
+ });
18
+ });
19
+
20
+ it("can disable the cors", async () => {
21
+ const cors = false;
22
+ const { headers } = await server({ cors })
23
+ .get("/", () => 200)
24
+ .test()
25
+ .get("/", { headers: { origin } });
26
+ expect(headers["access-control-allow-origin"]).toBe(undefined);
27
+ });
28
+
29
+ it("gets the wildcard without the origin", async () => {
30
+ const cors = "*";
31
+ const { headers } = await server({ cors })
32
+ .get("/", () => 200)
33
+ .test()
34
+ .get("/");
35
+ expect(headers["access-control-allow-origin"]).toBe("*");
36
+ });
37
+
38
+ it("gets the origin with true", async () => {
39
+ const cors = true;
40
+ const { headers } = await server({ cors })
41
+ .get("/", () => 200)
42
+ .test()
43
+ .get("/", { headers: { origin } });
44
+ expect(headers["access-control-allow-origin"]).toBe(origin);
45
+ });
46
+
47
+ it("gets the correct origin with multiple as string", async () => {
48
+ const cors = "https://a.com/,https://b.com/";
49
+ const { headers } = await server({ cors })
50
+ .get("/", () => 200)
51
+ .test()
52
+ .get("/", { headers: { origin: "https://b.com/" } });
53
+ expect(headers["access-control-allow-origin"]).toBe("https://b.com/");
54
+ });
55
+
56
+ it("gets the correct origin with multiple as array", async () => {
57
+ const cors = ["https://a.com/", "https://b.com/"];
58
+ const { headers } = await server({ cors })
59
+ .get("/", () => 200)
60
+ .test()
61
+ .get("/", { headers: { origin: "https://b.com/" } });
62
+ expect(headers["access-control-allow-origin"]).toBe("https://b.com/");
63
+ });
64
+ });
package/src/index.js CHANGED
@@ -224,7 +224,7 @@ server.prototype.test = function () {
224
224
  const fetch = async (path, options = {}) => {
225
225
  if (!options.headers) options.headers = {};
226
226
  if (options.body && typeof options.body !== "string") {
227
- options.headers["content-type"] = "application/json; charset=utf-8";
227
+ options.headers["content-type"] = "application/json";
228
228
  options.body = JSON.stringify(options.body);
229
229
  }
230
230
  if (cookie && !options.headers.cookie) {
package/src/index.test.js CHANGED
@@ -75,13 +75,13 @@ describe("simple post works", () => {
75
75
  const { body, status, headers } = await api.post("/", "New Data");
76
76
  expect(status).toBe(201);
77
77
  expect(body).toBe("New Data");
78
- expect(headers["content-type"]).toBe("text/plain; charset=utf-8");
78
+ expect(headers["content-type"]).toBe("text/plain");
79
79
  });
80
80
 
81
81
  it("will return JSON", async () => {
82
82
  const { body, status, headers } = await api.post("/", { hello: "world" });
83
83
  expect(status).toBe(201);
84
84
  expect(body).toEqual({ hello: "world" });
85
- expect(headers["content-type"]).toBe("application/json; charset=utf-8");
85
+ expect(headers["content-type"]).toBe("application/json");
86
86
  });
87
87
  });
@@ -44,11 +44,11 @@ export default async function parseResponse(out, ctx) {
44
44
  // Set the proper CORS headers
45
45
  const origin = cors(ctx.options.cors.origin, ctx.headers.origin);
46
46
  if (origin) {
47
- headers.set("Access-Control-Allow-Methods", ctx.options.cors.methods);
48
- headers.set("Access-Control-Allow-Headers", ctx.options.cors.headers);
49
- headers.set("Access-Control-Allow-Origin", origin);
47
+ out.headers.set("Access-Control-Allow-Origin", origin);
48
+ out.headers.set("Access-Control-Allow-Methods", ctx.options.cors.methods);
49
+ out.headers.set("Access-Control-Allow-Headers", ctx.options.cors.headers);
50
50
  if (ctx.options.cors.credentials) {
51
- headers.set("Access-Control-Allow-Credentials", "true");
51
+ out.headers.set("Access-Control-Allow-Credentials", "true");
52
52
  }
53
53
  }
54
54
  }
package/src/reply.js CHANGED
@@ -56,7 +56,7 @@ Reply.prototype.cookies = function (cookies) {
56
56
  // FINAL
57
57
  Reply.prototype.json = function (body) {
58
58
  return this.headers({
59
- "content-type": "application/json; charset=utf-8",
59
+ "content-type": "application/json",
60
60
  }).send(JSON.stringify(body));
61
61
  };
62
62
 
@@ -95,9 +95,7 @@ Reply.prototype.send = function (body = "") {
95
95
  // Not yet set, so infer the type from type of string
96
96
  if (!this.res.headers["content-type"]) {
97
97
  const isHtml = body.startsWith("<");
98
- this.res.headers["content-type"] = isHtml
99
- ? "text/html; charset=utf-8"
100
- : "text/plain; charset=utf-8";
98
+ this.res.headers["content-type"] = isHtml ? "text/html" : "text/plain";
101
99
  }
102
100
 
103
101
  const headers = this.generateHeaders();
package/src/url.test.js CHANGED
@@ -9,7 +9,7 @@ describe("can match the url", () => {
9
9
 
10
10
  const { body, headers } = await api.get("/hello");
11
11
  expect(body).toEqual({ id: "hello" });
12
- expect(headers["content-type"]).toEqual("application/json; charset=utf-8");
12
+ expect(headers["content-type"]).toEqual("application/json");
13
13
  });
14
14
 
15
15
  it("but it doesn't if it's a use", async () => {
@@ -21,6 +21,6 @@ describe("can match the url", () => {
21
21
 
22
22
  const { body, headers, ...rest } = await api.get("/hello");
23
23
  expect(body).toEqual({ id: "hello" });
24
- expect(headers["content-type"]).toEqual("application/json; charset=utf-8");
24
+ expect(headers["content-type"]).toEqual("application/json");
25
25
  });
26
26
  });