@server/next 0.25.10 → 0.27.0

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.
Files changed (63) hide show
  1. package/index.js +2005 -0
  2. package/package.json +17 -13
  3. package/readme.md +1 -0
  4. package/src/{helpers/jsx.js → jsx/jsx-dev-runtime.js} +32 -17
  5. package/src/{helpers/jsx.test.jsx → jsx/jsx-runtime.test.jsx} +1 -1
  6. package/src/ServerError.js +0 -27
  7. package/src/auth/NoSession.js +0 -19
  8. package/src/auth/auth-cookie.test.js +0 -42
  9. package/src/auth/auth-token.test.js +0 -110
  10. package/src/auth/auth.js +0 -62
  11. package/src/auth/index.js +0 -104
  12. package/src/auth/index.test.js +0 -133
  13. package/src/auth/logout.js +0 -20
  14. package/src/auth/providers/email.js +0 -145
  15. package/src/auth/providers/github.js +0 -84
  16. package/src/auth/providers/index.js +0 -4
  17. package/src/auth/session.js +0 -18
  18. package/src/auth/updateUser.js +0 -6
  19. package/src/auth/user.js +0 -9
  20. package/src/context/node.js +0 -68
  21. package/src/context/parseBody.js +0 -107
  22. package/src/context/parseBody.test.js +0 -60
  23. package/src/context/parseCookies.js +0 -9
  24. package/src/context/winter.js +0 -46
  25. package/src/errors/index.js +0 -36
  26. package/src/helpers/StatusError.js +0 -6
  27. package/src/helpers/bucket.js +0 -89
  28. package/src/helpers/bucket.test.js +0 -51
  29. package/src/helpers/color.js +0 -30
  30. package/src/helpers/config.js +0 -64
  31. package/src/helpers/cookies.test.js +0 -23
  32. package/src/helpers/cors.js +0 -24
  33. package/src/helpers/cors.test.js +0 -64
  34. package/src/helpers/createCookies.js +0 -16
  35. package/src/helpers/createId.js +0 -51
  36. package/src/helpers/define.js +0 -18
  37. package/src/helpers/getMachine.js +0 -26
  38. package/src/helpers/handleRequest.js +0 -34
  39. package/src/helpers/index.js +0 -11
  40. package/src/helpers/iterate.js +0 -8
  41. package/src/helpers/parseHeaders.js +0 -15
  42. package/src/helpers/toWeb.js +0 -15
  43. package/src/helpers/types.js +0 -81
  44. package/src/helpers/validate.js +0 -34
  45. package/src/index.d.ts +0 -198
  46. package/src/index.js +0 -268
  47. package/src/index.test.js +0 -87
  48. package/src/index.types.ts +0 -28
  49. package/src/middle/assets.js +0 -17
  50. package/src/middle/assets.test.js +0 -10
  51. package/src/middle/index.js +0 -7
  52. package/src/middle/openapi.js +0 -147
  53. package/src/middle/timer.js +0 -14
  54. package/src/parseResponse.js +0 -111
  55. package/src/pathPattern.js +0 -47
  56. package/src/pathPattern.test.js +0 -99
  57. package/src/polyfill.js +0 -18
  58. package/src/reply.js +0 -153
  59. package/src/router.js +0 -53
  60. package/src/router.test.js +0 -57
  61. package/src/session.test.js +0 -65
  62. package/src/test/toSucceed.js +0 -64
  63. package/src/url.test.js +0 -26
@@ -1,147 +0,0 @@
1
- import fsp from "node:fs/promises";
2
-
3
- const entities = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" };
4
- const encode = (str = "") => {
5
- if (typeof str === "number") str = String(str);
6
- if (typeof str !== "string") return ""; // nullify not-strings
7
- return str.replace(/[&<>"]/g, (tag) => entities[tag]);
8
- };
9
-
10
- const getConfig = (routes) => {
11
- const config = routes.find(
12
- (r) =>
13
- typeof r !== "string" && typeof r !== "function" && typeof r === "object",
14
- );
15
- if (!config) return {};
16
- if (config.tags) {
17
- if (typeof config.tags === "string") {
18
- config.tags = config.tags.split(/\s*\,\s*/g);
19
- }
20
- if (!Array.isArray(config.tags)) {
21
- throw new Error("invalid tags", config.tags);
22
- }
23
- config.tags = config.tags.map((t) => t.trim());
24
- }
25
- return config;
26
- };
27
-
28
- const pkgProm = fsp
29
- .readFile("package.json", "utf-8")
30
- .then((data) => JSON.parse(data))
31
- .catch(() => ({}));
32
-
33
- const getTag = (name, fn) => {
34
- const found = fn
35
- .toString()
36
- .split("\n")
37
- .filter((l) => /\s+\/\/\s/.test(l))
38
- .map((l) => l.trim().replace("// ", ""))
39
- .find((l) => l.startsWith(name));
40
- if (!found) return "";
41
- return encode(found.replace(name, "").trim());
42
- };
43
-
44
- const getDescription = (fn) => getTag("@description", fn) || "";
45
- const getReturn = (fn) => getTag("@returns", fn) || "200 OK";
46
-
47
- const generateOpenApiPaths = (handlers) => {
48
- const paths = {};
49
-
50
- for (const [method, routes] of Object.entries(handlers)) {
51
- for (const route of routes) {
52
- const [_, path, fn, meta] = [
53
- route[0],
54
- route[1],
55
- route.find((p) => typeof p === "function"),
56
- route.find((p) => typeof p === "object"),
57
- ];
58
-
59
- const config = getConfig(route);
60
-
61
- if (typeof path !== "string" || path === "*" || !fn) continue;
62
-
63
- // Normalize path (convert ":id" to "{id}" for OpenAPI)
64
- const normalizedPath = path.replace(/:([a-zA-Z0-9_]+)/g, "{$1}");
65
-
66
- if (!paths[normalizedPath]) {
67
- paths[normalizedPath] = {};
68
- }
69
-
70
- const getTitle = (fn) => {
71
- if (!fn.name) return null;
72
- // Well, we shouldn't really rely on these, e.g. automatic names from export default
73
- const wrongNames = ["default"];
74
- if (wrongNames.includes(fn.name)) return null;
75
- if (fn.name.length <= 3) return null;
76
- if (fn.name.includes("_")) return fn.name.replaceAll("_", " ");
77
- const name = fn.name
78
- .split(/(?=[A-Z])/)
79
- .join(" ")
80
- .toLowerCase();
81
- return name[0].toUpperCase() + name.slice(1);
82
- };
83
-
84
- paths[normalizedPath][method] = {
85
- tags: config.tags,
86
- summary:
87
- config.title ||
88
- getTitle(fn) ||
89
- getTag("@title", fn) ||
90
- `${method.toUpperCase()} ${path}`,
91
- description: getDescription(fn),
92
- responses: {
93
- 200: {
94
- description: getReturn(fn),
95
- },
96
- },
97
- ...(meta
98
- ? {
99
- parameters: Object.entries(meta).map(([key, value]) => ({
100
- name: key,
101
- in: "query",
102
- required: false,
103
- schema: { type: typeof value },
104
- example: value,
105
- })),
106
- }
107
- : {}),
108
- };
109
- }
110
- }
111
-
112
- return paths;
113
- };
114
-
115
- export default async (ctx) => {
116
- const pkg = await pkgProm;
117
- const domain = pkg.homepage || ctx.url.origin;
118
- const openApi = {
119
- openapi: "3.0.0",
120
- info: {
121
- title: pkg.name || "API Documentation",
122
- version: pkg.version || "1.0.0",
123
- description: pkg.description || "",
124
- },
125
- servers: domain ? [{ url: domain }] : [],
126
- paths: generateOpenApiPaths(ctx.app.handlers),
127
- };
128
-
129
- const configuration = ctx.options.openapi.scalar || {};
130
-
131
- return `
132
- <!doctype html>
133
- <html>
134
- <head>
135
- <title>API Reference</title>
136
- <meta charset="utf-8" />
137
- <meta
138
- name="viewport"
139
- content="width=device-width, initial-scale=1" />
140
- <style>.open-api-client-button {display: none!important;}</style>
141
- </head>
142
- <body>
143
- <script id="api-reference" type="application/json" data-configuration="${encode(JSON.stringify(configuration))}">${JSON.stringify(openApi, null, 2)}</script>
144
- <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
145
- </body>
146
- </html> `;
147
- };
@@ -1,14 +0,0 @@
1
- export default function timer(ctx) {
2
- const times = [["init", performance.now()]];
3
- ctx.time = (name) => times.push([name, performance.now()]);
4
- ctx.time.times = times;
5
- ctx.time.headers = () => {
6
- const r = (t) => Math.round(t);
7
- const times = ctx.time.times;
8
- const timing = times
9
- .slice(1)
10
- .map(([name, time], i) => `${name};dur=${r(time - times[i][1])}`)
11
- .join(", ");
12
- return timing;
13
- };
14
- }
@@ -1,111 +0,0 @@
1
- import { cors, createId } from "./helpers/index.js";
2
- import { json } from "./reply.js";
3
- import ServerError from "./ServerError.js";
4
-
5
- export default async function parseResponse(out, ctx) {
6
- // undefined || null || 0 || false || ~""~ -> empty string is still 200
7
- if (!out && typeof out !== "string") return null;
8
-
9
- if (typeof out === "function") {
10
- out = await out(ctx);
11
- }
12
-
13
- if (out instanceof Blob) {
14
- out = new Response(out, { headers: { "Content-Type": blob.type } });
15
- }
16
-
17
- if (out instanceof ReadableStream) {
18
- out = new Response(out);
19
- }
20
-
21
- // A plain number is a status code
22
- if (typeof out === "number") {
23
- out = new Response(undefined, { status: out });
24
- }
25
-
26
- // A plain string will be converted to either html or plain
27
- if (typeof out === "string") {
28
- const type = /^\s*\</.test(out) ? "text/html" : "text/plain";
29
- out = new Response(out, { headers: { "content-type": type } });
30
- }
31
-
32
- // https://stackoverflow.com/a/69745650/938236
33
- if (out?.constructor === Object || Array.isArray(out)) {
34
- out = json(out);
35
- }
36
-
37
- // The output from fetch(), create a copy of it into a new response
38
- if (out instanceof Response && out.url && out.body) {
39
- out = new Response(out.body, {
40
- status: 200,
41
- headers: out.headers,
42
- });
43
- if (/^(br|gzip)$/.test(out.headers.get("content-encoding"))) {
44
- console.warn("Compression not yet supported for response");
45
- out.headers.delete("content-encoding");
46
- }
47
- }
48
-
49
- if (!(out instanceof Response)) {
50
- throw new Error(`Invalid response type ${out}`);
51
- }
52
-
53
- // Here it should be a Response
54
-
55
- // If we have CORS, set it up
56
- if (ctx.options.cors) {
57
- // Set the proper CORS headers
58
- const origin = cors(ctx.options.cors.origin, ctx.headers.origin);
59
- if (origin) {
60
- out.headers.set("Access-Control-Allow-Origin", origin);
61
- out.headers.set("Access-Control-Allow-Methods", ctx.options.cors.methods);
62
- out.headers.set("Access-Control-Allow-Headers", ctx.options.cors.headers);
63
- if (ctx.options.cors.credentials) {
64
- out.headers.set("Access-Control-Allow-Credentials", "true");
65
- }
66
- }
67
- }
68
-
69
- // Only attach the headers if the user is using the timing API
70
- // 1 item is the `init` so it doesn't count
71
- if (ctx.time.times.length > 1) {
72
- out.headers.set("Server-Timing", ctx.time.headers());
73
- }
74
-
75
- // If we have a session, we need to persist it into a cookie
76
- if (Object.keys(ctx.session || {}).length) {
77
- if (!ctx.options.session?.store) {
78
- throw ServerError.NO_STORE({});
79
- }
80
-
81
- // Persistence is based on the Token
82
- // Persistence is based on the Cookies
83
- // No session cookies, generate a _persistent_ cookie
84
- if (!ctx.cookies.session) {
85
- ctx.res.cookies.session = createId();
86
- }
87
- const id = ctx.cookies.session;
88
-
89
- // Saves the session in the session store
90
- // Note that this is async but we are totally fine deferring it
91
- ctx.options.session.store.set(id, ctx.session);
92
- }
93
-
94
- // Cookies to headers
95
- if (ctx.options.cookies) {
96
- if (Object.keys(ctx.res.cookies).length) {
97
- for (const cookie of ctx.res.cookies) {
98
- ctx.res.headers.append("set-cookie", cookie);
99
- }
100
- }
101
- }
102
-
103
- // Add the headers that are neeeded
104
- if (ctx?.res?.headers) {
105
- for (const key in ctx.res.headers) {
106
- out.headers[key] = ctx.res.headers[key];
107
- }
108
- }
109
-
110
- return out;
111
- }
@@ -1,47 +0,0 @@
1
- export default function pathPattern(pattern, path) {
2
- if (pattern === "*") return {};
3
-
4
- pattern = `/${pattern.replace(/^\//, "")}`;
5
- pattern = pattern.replace(/\/$/, "") || "/";
6
- path = path.replace(/\/$/, "") || "/";
7
-
8
- if (pattern === path) return {};
9
-
10
- const params = {};
11
- const pathParts = path.split("/").slice(1);
12
- const pattParts = pattern.split("/").slice(1);
13
- let allSame = true;
14
- for (let i = 0; i < Math.max(pathParts.length, pattParts.length); i++) {
15
- const patt = pattParts[i] || "";
16
- const part = pathParts[i] || "";
17
- const last = pattParts[pattParts.length - 1];
18
- const key = patt
19
- .replace(/^:/, "")
20
- .replace(/\?$/, "")
21
- .replace(/\(\w*\)/, "");
22
- if (patt === part) continue;
23
- if (patt.endsWith("?") && !part) continue;
24
- if (patt.startsWith(":")) {
25
- params[key] = part;
26
- if (/\(\w*\)/.test(patt)) {
27
- if (patt.includes("(number)")) {
28
- const value = Number(part);
29
- params[key] = Number.isNaN(value) ? undefined : value;
30
- }
31
- if (patt.includes("(date)")) {
32
- const value = new Date(part);
33
- params[key] = Number.isNaN(value) ? undefined : value;
34
- }
35
- }
36
- continue;
37
- }
38
- if ((!patt && last === "*" && part) || (patt === "*" && part)) {
39
- params["*"] = params["*"] || [];
40
- params["*"].push(part);
41
- continue;
42
- }
43
- allSame = false;
44
- }
45
- if (allSame) return params;
46
- return null;
47
- }
@@ -1,99 +0,0 @@
1
- import pathPattern from "./pathPattern.js";
2
-
3
- describe("pathPattern.js", () => {
4
- it("matches the same string", () => {
5
- expect(pathPattern("/", "/hello")).toEqual(null);
6
- expect(pathPattern("/hello", "/")).toEqual(null);
7
- expect(pathPattern("/hello", "/hello")).toEqual({});
8
- expect(pathPattern("/hello/world", "/hello/world")).toEqual({});
9
- });
10
-
11
- it("is trailing slash insensitive both ways", () => {
12
- expect(pathPattern("/hello", "/hello")).toEqual({});
13
- expect(pathPattern("/hello", "/hello/")).toEqual({});
14
- expect(pathPattern("/hello/", "/hello")).toEqual({});
15
- expect(pathPattern("/hello/", "/hello/")).toEqual({});
16
-
17
- expect(pathPattern("/hello/world", "/hello/world")).toEqual({});
18
- expect(pathPattern("/hello/world", "/hello/world/")).toEqual({});
19
- expect(pathPattern("/hello/world/", "/hello/world")).toEqual({});
20
- expect(pathPattern("/hello/world/", "/hello/world/")).toEqual({});
21
- });
22
-
23
- it("doesn't do partial matches", () => {
24
- expect(pathPattern("/hello", "/hello/John")).toEqual(null);
25
- expect(pathPattern("/hello/", "/hello/John")).toEqual(null);
26
- });
27
-
28
- it("can capture simple params", () => {
29
- expect(pathPattern("/:hello", "/john")).toEqual({ hello: "john" });
30
- expect(pathPattern("/hello/:there", "/hello/john")).toEqual({
31
- there: "john",
32
- });
33
- });
34
-
35
- it("will parse the params as numbers", () => {
36
- expect(pathPattern("/:id(number)", "/25")).toEqual({ id: 25 });
37
- expect(pathPattern("/:id(number)", "/25.5")).toEqual({ id: 25.5 });
38
- expect(pathPattern("/users/:id(number)", "/users/25")).toEqual({
39
- id: 25,
40
- });
41
- expect(pathPattern("/:id(date)", "/2015-01-01")).toEqual({
42
- id: new Date("2015-01-01"),
43
- });
44
- expect(pathPattern("/report/:id(date)", "/report/2015-01-01")).toEqual({
45
- id: new Date("2015-01-01"),
46
- });
47
- });
48
-
49
- it("will still match, but not parse it if it's an invalid number", () => {
50
- expect(pathPattern("/:id(number)", "/hi")).toEqual({});
51
- expect(pathPattern("/users/:id(number)", "/users/hi")).toEqual({});
52
- });
53
-
54
- it("requires a part for the asterisk", () => {
55
- expect(pathPattern("/hello/:there/*", "/hello/John")).toEqual(null);
56
- });
57
-
58
- it("can make a part optional", () => {
59
- expect(pathPattern("/:name?", "/")).toEqual({});
60
- expect(pathPattern("/hello/:name?", "/hello/")).toEqual({});
61
- expect(pathPattern("/:id(number)?", "/")).toEqual({});
62
- expect(pathPattern("/:id(date)?", "/")).toEqual({});
63
- expect(pathPattern("/:id(number)?", "/25")).toEqual({ id: 25 });
64
- expect(pathPattern("/:id(date)?", "/2015-01-01")).toEqual({
65
- id: new Date("2015-01-01"),
66
- });
67
- expect(pathPattern("/:name?", "/john")).toEqual({ name: "john" });
68
- expect(pathPattern("/:name/*?", "/john")).toEqual({ name: "john" });
69
- });
70
-
71
- it("correctly matches the asterisk as an array of parts", () => {
72
- expect(pathPattern("/*", "/john")).toEqual({ "*": ["john"] });
73
- expect(pathPattern("/*", "/john/doe")).toEqual({ "*": ["john", "doe"] });
74
- expect(pathPattern("/*/*", "/john/doe")).toEqual({ "*": ["john", "doe"] });
75
-
76
- expect(pathPattern("/hello/*", "/hello/john")).toEqual({ "*": ["john"] });
77
- expect(pathPattern("/hello/*", "/hello/john/doe")).toEqual({
78
- "*": ["john", "doe"],
79
- });
80
- expect(pathPattern("/hello/*/*", "/hello/john/doe")).toEqual({
81
- "*": ["john", "doe"],
82
- });
83
-
84
- expect(pathPattern("/:name/*", "/john/doe")).toEqual({
85
- name: "john",
86
- "*": ["doe"],
87
- });
88
-
89
- expect(pathPattern("/:name/*", "/john/doe/derek")).toEqual({
90
- name: "john",
91
- "*": ["doe", "derek"],
92
- });
93
-
94
- expect(pathPattern("/:name/*/*", "/john/doe/derek")).toEqual({
95
- name: "john",
96
- "*": ["doe", "derek"],
97
- });
98
- });
99
- });
package/src/polyfill.js DELETED
@@ -1,18 +0,0 @@
1
- // out = new Response(out, { headers: { "content-type": type } });
2
- if (typeof Response === "undefined") {
3
- global.Response = function Response(body, other = {}) {
4
- return { body, ...other };
5
- };
6
- }
7
-
8
- // Polyfill Netlify's environment variables
9
- globalThis.env = {};
10
- if (typeof Netlify !== "undefined") {
11
- Object.assign(env, Netlify.env.toObject());
12
- }
13
- if (typeof process !== "undefined") {
14
- Object.assign(env, process.env);
15
- }
16
- if (typeof import.meta.env !== "undefined") {
17
- Object.assign(env, import.meta.env);
18
- }
package/src/reply.js DELETED
@@ -1,153 +0,0 @@
1
- import fs from "node:fs/promises";
2
-
3
- import { createCookies, toWeb, types } from "./helpers/index.js";
4
-
5
- function Reply() {
6
- this.res = {
7
- headers: {},
8
- cookies: {},
9
- };
10
- }
11
-
12
- // INTERNAL
13
- Reply.prototype.generateHeaders = function () {
14
- const headers = new Headers(this.res.headers);
15
- for (const cookie of createCookies(this.res.cookies)) {
16
- headers.append("set-cookie", cookie);
17
- }
18
- return headers;
19
- };
20
-
21
- // PARTIAL
22
- Reply.prototype.status = function (status) {
23
- this.res.status = status;
24
- return this;
25
- };
26
-
27
- // `.html`, `html`, `text/html`
28
- Reply.prototype.type = function (type) {
29
- if (!type) return this;
30
- type = types[type.replace(/^\./)] || type;
31
- return this.headers({ "content-type": type });
32
- };
33
-
34
- // Prompt for download from the user side
35
- Reply.prototype.download = function (name, type) {
36
- // filename.txt and no explicit type => add headers "text/plain"
37
- if (name && !type) type = name.split(".")[1];
38
-
39
- // Add the Content-Type if there's a type
40
- if (type) this.type(type);
41
-
42
- const filename = name ? `; filename="${name}"` : "";
43
- return this.headers({ "content-disposition": `attachment${filename}` });
44
- };
45
-
46
- // Set extra headers
47
- Reply.prototype.headers = function (headers) {
48
- if (!headers || typeof headers !== "object") return this;
49
- for (const key in headers) {
50
- this.res.headers[key] = headers[key];
51
- }
52
- return this;
53
- };
54
-
55
- // Set extra cookies
56
- Reply.prototype.cookies = function (cookies) {
57
- if (!cookies || typeof cookies !== "object") return this;
58
- for (const key in cookies) {
59
- if (typeof cookies[key] === "string") {
60
- this.res.cookies[key] = { value: cookies[key] };
61
- } else {
62
- this.res.cookies[key] = cookies[key];
63
- }
64
- }
65
- return this;
66
- };
67
-
68
- // FINAL
69
- Reply.prototype.json = function (body) {
70
- return this.headers({
71
- "content-type": "application/json",
72
- }).send(JSON.stringify(body));
73
- };
74
-
75
- Reply.prototype.redirect = function (Location) {
76
- return this.headers({ Location }).status(302).send();
77
- };
78
-
79
- Reply.prototype.file = async function (path) {
80
- try {
81
- const data = await fs.readFile(path);
82
- const ext = path.split(".").pop();
83
- return this.type(ext).send(data);
84
- } catch (error) {
85
- if (error.code === "ENOENT") {
86
- return status(404).send();
87
- }
88
- throw error;
89
- }
90
- };
91
-
92
- Reply.prototype.view = async function (path) {
93
- return async (ctx) => {
94
- if (!ctx.options.views) {
95
- throw new Error("Views not enabled");
96
- }
97
- const data = await ctx.options.views.read(path);
98
- if (data) return this.type(path.split(".").pop()).send(data);
99
- return this.status(404).send();
100
- };
101
- };
102
-
103
- Reply.prototype.send = function (body = "") {
104
- const { status = 200 } = this.res;
105
-
106
- if (typeof body === "string") {
107
- // Not yet set, so infer the type from type of string
108
- if (!this.res.headers["content-type"]) {
109
- const isHtml = body.startsWith("<");
110
- this.res.headers["content-type"] = isHtml ? "text/html" : "text/plain";
111
- }
112
-
113
- const headers = this.generateHeaders();
114
- return new Response(body, { status, headers });
115
- }
116
-
117
- const name = body?.constructor?.name;
118
- if (name === "Buffer") {
119
- const headers = this.generateHeaders();
120
- return new Response(body, { status, headers });
121
- }
122
-
123
- // WebStream already, just pass it through
124
- if (name === "ReadableStream") {
125
- const headers = this.generateHeaders();
126
- return new Response(body, { status, headers });
127
- }
128
-
129
- // Node stream, convert it to web stream
130
- if (name === "PassThrough" || name === "Readable") {
131
- return new Response(toWeb(body), { status, headers });
132
- }
133
-
134
- // This is a bit loopy, send({}) => json({}) => send('{}')
135
- return this.json(body);
136
- };
137
-
138
- // INTERNAL
139
- export { Reply };
140
-
141
- // PARTIAL
142
- export const status = (...args) => new Reply().status(...args);
143
- export const headers = (...args) => new Reply().headers(...args);
144
- export const type = (...args) => new Reply().type(...args);
145
- export const download = (...args) => new Reply().download(...args);
146
- export const cookies = (...args) => new Reply().cookies(...args);
147
-
148
- // FINAL
149
- export const send = (...args) => new Reply().send(...args);
150
- export const json = (...args) => new Reply().json(...args);
151
- export const file = (...args) => new Reply().file(...args);
152
- export const redirect = (...args) => new Reply().redirect(...args);
153
- export const view = (...args) => new Reply().view(...args);
package/src/router.js DELETED
@@ -1,53 +0,0 @@
1
- export default function router() {
2
- if (!(this instanceof router)) {
3
- return new router();
4
- }
5
- this.handlers = {
6
- socket: [],
7
- get: [],
8
- head: [],
9
- post: [],
10
- put: [],
11
- patch: [],
12
- delete: [],
13
- options: [],
14
- };
15
- }
16
-
17
- // INTERNAL
18
- router.prototype.handle = function (method, path, ...middleware) {
19
- this.handlers[method].push([method, path, ...middleware]);
20
- return this;
21
- };
22
-
23
- router.prototype.socket = function (path, ...middleware) {
24
- return this.handle("socket", path, ...middleware);
25
- };
26
-
27
- router.prototype.get = function (path, ...middleware) {
28
- return this.handle("get", path, ...middleware);
29
- };
30
-
31
- router.prototype.head = function (path, ...middleware) {
32
- return this.handle("head", path, ...middleware);
33
- };
34
-
35
- router.prototype.post = function (path, ...middleware) {
36
- return this.handle("post", path, ...middleware);
37
- };
38
-
39
- router.prototype.put = function (path, ...middleware) {
40
- return this.handle("put", path, ...middleware);
41
- };
42
-
43
- router.prototype.patch = function (path, ...middleware) {
44
- return this.handle("patch", path, ...middleware);
45
- };
46
-
47
- router.prototype.del = function (path, ...middleware) {
48
- return this.handle("del", path, ...middleware);
49
- };
50
-
51
- router.prototype.options = function (path, ...middleware) {
52
- return this.handle("options", path, ...middleware);
53
- };