Skip to content

Commit 29cf0b9

Browse files
committed
FIX:
fix 'cannot set headers after they are sent to the client' error
1 parent e65b78a commit 29cf0b9

File tree

4 files changed

+100
-47
lines changed

4 files changed

+100
-47
lines changed

lib/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import { NextApiRequest, NextApiResponse } from "next/types";
22
declare type ControllerMethods = {
33
[k: string]: (req: NextApiRequest, res: NextApiResponse) => void;
44
};
5-
export declare function Controller(path: string, paths?: ControllerMethods): (req: NextApiRequest, res: NextApiResponse) => void;
5+
export declare function Controller(path: string, paths?: ControllerMethods): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
66
export {};

lib/index.js

Lines changed: 88 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,54 +10,102 @@ var __assign = (this && this.__assign) || function () {
1010
};
1111
return __assign.apply(this, arguments);
1212
};
13+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15+
return new (P || (P = Promise))(function (resolve, reject) {
16+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19+
step((generator = generator.apply(thisArg, _arguments || [])).next());
20+
});
21+
};
22+
var __generator = (this && this.__generator) || function (thisArg, body) {
23+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25+
function verb(n) { return function (v) { return step([n, v]); }; }
26+
function step(op) {
27+
if (f) throw new TypeError("Generator is already executing.");
28+
while (_) try {
29+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30+
if (y = 0, t) op = [op[0] & 2, t.value];
31+
switch (op[0]) {
32+
case 0: case 1: t = op; break;
33+
case 4: _.label++; return { value: op[1], done: false };
34+
case 5: _.label++; y = op[1]; op = [0]; continue;
35+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
36+
default:
37+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41+
if (t[2]) _.ops.pop();
42+
_.trys.pop(); continue;
43+
}
44+
op = body.call(thisArg, _);
45+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47+
}
48+
};
1349
Object.defineProperty(exports, "__esModule", { value: true });
1450
exports.Controller = void 0;
1551
function Controller(path, paths) {
52+
var _this = this;
1653
if (paths === void 0) { paths = {}; }
17-
return function (req, res) {
18-
var handled = false;
19-
var _a = req.url, url = _a === void 0 ? "" : _a;
20-
var urlWithourQueryParams = url.split("?")[0];
21-
var urlParts = urlWithourQueryParams.split("/");
22-
var handlePathUrl = "/api" + path;
23-
var _loop_1 = function (path_1) {
24-
var _b = path_1.split(" "), method = _b[0], handleUrl = _b[1];
25-
var $handleUrl = handlePathUrl + handleUrl.split("?")[0];
26-
var handleParts = $handleUrl.split("/");
27-
var finalHandler = [];
28-
var finalQuery = {};
29-
handleParts.forEach(function (handlePart, i) {
30-
if (handlePart.startsWith("[") && handlePart.endsWith("]")) {
31-
var withoutBrackets = handlePart.replace(/\[|\]/g, "");
32-
finalQuery[withoutBrackets] = urlParts[i];
33-
finalHandler.push(urlParts[i]);
34-
}
35-
else {
36-
finalHandler.push(handlePart);
37-
}
38-
});
39-
if (finalHandler.join("/") === urlParts.join("/") && !handled) {
40-
var withQ = __assign(__assign({}, req.query), finalQuery);
41-
if (req.method === method) {
42-
req.query = withQ;
43-
paths[path_1](req, res);
44-
handled = true;
54+
var handled = false;
55+
return function (req, res) { return __awaiter(_this, void 0, void 0, function () {
56+
var _a, url, urlWithourQueryParams, urlParts, handlePathUrl, totalHandlers, _loop_1, path_1, state_1;
57+
return __generator(this, function (_b) {
58+
_a = req.url, url = _a === void 0 ? "" : _a;
59+
urlWithourQueryParams = url.split("?")[0];
60+
urlParts = urlWithourQueryParams.split("/");
61+
handlePathUrl = "/api" + path;
62+
totalHandlers = Object.keys(paths).length;
63+
_loop_1 = function (path_1) {
64+
var _c = path_1.split(" "), method = _c[0], handleUrl = _c[1];
65+
var $handleUrl = handlePathUrl + handleUrl.split("?")[0];
66+
var handleParts = $handleUrl.split("/");
67+
var finalHandler = [];
68+
var finalQuery = {};
69+
handleParts.forEach(function (handlePart, i) {
70+
if (handlePart.startsWith("[") && handlePart.endsWith("]")) {
71+
var withoutBrackets = handlePart.replace(/\[|\]/g, "");
72+
finalQuery[withoutBrackets] = urlParts[i];
73+
finalHandler.push(urlParts[i]);
74+
}
75+
else {
76+
finalHandler.push(handlePart);
77+
}
78+
});
79+
if (finalHandler.join("/") === urlParts.join("/")) {
80+
var withQ = __assign(__assign({}, req.query), finalQuery);
81+
if (req.method === method) {
82+
req.query = withQ;
83+
paths[path_1](req, res);
84+
handled = true;
85+
return "break";
86+
}
87+
else {
88+
if (!("".concat(req.method, " ").concat(handleUrl) in paths) && !handled) {
89+
res.status(405);
90+
res.send("cannot ".concat(req.method, " ").concat(finalHandler.join("/")));
91+
}
92+
}
4593
}
4694
else {
47-
if (!("".concat(req.method, " ").concat(handleUrl) in paths)) {
48-
res.status(405);
49-
res.send("cannot ".concat(req.method, " ").concat(finalHandler.join("/")));
95+
res.status(404);
96+
res.send("Not found");
97+
if (Object.keys(paths).indexOf(path_1) < totalHandlers - 1) {
98+
return "break";
5099
}
51100
}
101+
};
102+
for (path_1 in paths) {
103+
state_1 = _loop_1(path_1);
104+
if (state_1 === "break")
105+
break;
52106
}
53-
else {
54-
res.status(404);
55-
res.send("Not found");
56-
}
57-
};
58-
for (var path_1 in paths) {
59-
_loop_1(path_1);
60-
}
61-
};
107+
return [2 /*return*/];
108+
});
109+
}); };
62110
}
63111
exports.Controller = Controller;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "next-rest-controller",
3-
"version": "0.0.2",
3+
"version": "0.0.3",
44
"description": "A REST helper for Next apis",
55
"main": "lib/index.js",
66
"repository": "https://github.com/atomic-state/rest-next",

src/index.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ type ControllerMethods = {
55
}
66

77
export function Controller(path: string, paths: ControllerMethods = {}) {
8-
return (req: NextApiRequest, res: NextApiResponse) => {
9-
let handled = false
8+
let handled = false
9+
return async (req: NextApiRequest, res: NextApiResponse) => {
1010
const { url = "" } = req
1111
const [urlWithourQueryParams] = url.split("?")
1212

1313
const urlParts = urlWithourQueryParams.split("/")
1414

1515
const handlePathUrl = "/api" + path
1616

17+
const totalHandlers = Object.keys(paths).length
18+
1719
for (let path in paths) {
1820
const [method, handleUrl] = path.split(" ")
1921

@@ -37,24 +39,27 @@ export function Controller(path: string, paths: ControllerMethods = {}) {
3739
}
3840
})
3941

40-
if (finalHandler.join("/") === urlParts.join("/") && !handled) {
42+
if (finalHandler.join("/") === urlParts.join("/")) {
4143
const withQ = { ...req.query, ...finalQuery }
4244

4345
if (req.method === method) {
4446
req.query = withQ
4547

4648
paths[path](req, res)
47-
4849
handled = true
50+
break
4951
} else {
50-
if (!(`${req.method} ${handleUrl}` in paths)) {
52+
if (!(`${req.method} ${handleUrl}` in paths) && !handled) {
5153
res.status(405)
5254
res.send(`cannot ${req.method} ${finalHandler.join("/")}`)
5355
}
5456
}
5557
} else {
5658
res.status(404)
5759
res.send(`Not found`)
60+
if (Object.keys(paths).indexOf(path) < totalHandlers - 1) {
61+
break
62+
}
5863
}
5964
}
6065
}

0 commit comments

Comments
 (0)