Skip to content

Commit dc624f5

Browse files
committed
Initial commit
0 parents  commit dc624f5

File tree

8 files changed

+198
-0
lines changed

8 files changed

+198
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
yarn.lock

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Dany Beltran
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

lib/index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { NextApiRequest, NextApiResponse } from "next/types";
2+
declare type ControllerMethods = {
3+
[k: string]: (req: NextApiRequest, res: NextApiResponse) => void;
4+
};
5+
export declare function Controller(paths?: ControllerMethods): (req: NextApiRequest, res: NextApiResponse) => void;
6+
export {};

lib/index.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"use strict";
2+
var __assign = (this && this.__assign) || function () {
3+
__assign = Object.assign || function(t) {
4+
for (var s, i = 1, n = arguments.length; i < n; i++) {
5+
s = arguments[i];
6+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7+
t[p] = s[p];
8+
}
9+
return t;
10+
};
11+
return __assign.apply(this, arguments);
12+
};
13+
Object.defineProperty(exports, "__esModule", { value: true });
14+
exports.Controller = void 0;
15+
function Controller(paths) {
16+
if (paths === void 0) { paths = {}; }
17+
return function (req, res) {
18+
var _a = req.url, url = _a === void 0 ? "" : _a;
19+
var urlWithourQueryParams = url.split("?")[0];
20+
var urlParts = urlWithourQueryParams.split("/");
21+
var handlePathUrl = "/api/" + __dirname.split("/api/").at(-1);
22+
var _loop_1 = function (path) {
23+
var _b = path.split(" "), method = _b[0], handleUrl = _b[1];
24+
var $handleUrl = handlePathUrl + handleUrl.split("?")[0];
25+
var handleParts = $handleUrl.split("/");
26+
if (handleParts.length === urlParts.length) {
27+
var finalHandler_1 = [];
28+
var finalQuery_1 = {};
29+
handleParts.forEach(function (handlePart, i) {
30+
if (handlePart.startsWith("[") && handlePart.endsWith("]")) {
31+
var withoutBrackets = handlePart.replace(/\[|\]/g, "");
32+
finalQuery_1[withoutBrackets] = urlParts[i];
33+
finalHandler_1.push(urlParts[i]);
34+
}
35+
else {
36+
finalHandler_1.push(handlePart);
37+
}
38+
});
39+
if (finalHandler_1.join("/") === urlParts.join("/")) {
40+
var withQ = __assign(__assign({}, req.query), finalQuery_1);
41+
if (req.method === method) {
42+
req.query = withQ;
43+
paths[path](req, res);
44+
}
45+
else {
46+
res.status(405);
47+
res.send("Cannot ".concat(req.method, " ").concat(url));
48+
}
49+
}
50+
return "break";
51+
}
52+
else {
53+
res.status(404);
54+
res.send("Not found");
55+
return "break";
56+
}
57+
};
58+
for (var path in paths) {
59+
var state_1 = _loop_1(path);
60+
if (state_1 === "break")
61+
break;
62+
}
63+
};
64+
}
65+
exports.Controller = Controller;

package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "rest-next",
3+
"version": "0.0.1",
4+
"description": "A REST helper for Next apis",
5+
"main": "lib/index.js",
6+
"repository": "https://github.com/atomic-state/rest-next",
7+
"author": "danybeltran",
8+
"license": "MIT",
9+
"private": false,
10+
"peerDependencies": {
11+
"next": "^12.1.6"
12+
},
13+
"devDependencies": {
14+
"@types/next": "^9.0.0",
15+
"@types/node": "^17.0.43",
16+
"typescript": "^4.7.3"
17+
}
18+
}

src/index.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { NextApiRequest, NextApiResponse } from "next/types"
2+
3+
type ControllerMethods = {
4+
[k: string]: (req: NextApiRequest, res: NextApiResponse) => void
5+
}
6+
7+
export function Controller(paths: ControllerMethods = {}) {
8+
return (req: NextApiRequest, res: NextApiResponse) => {
9+
const { url = "" } = req
10+
const [urlWithourQueryParams] = url.split("?")
11+
12+
const urlParts = urlWithourQueryParams.split("/")
13+
14+
const handlePathUrl = "/api/" + __dirname.split("/api/").at(-1)
15+
16+
for (let path in paths) {
17+
const [method, handleUrl] = path.split(" ")
18+
19+
let $handleUrl = handlePathUrl + handleUrl.split("?")[0]
20+
21+
const handleParts = $handleUrl.split("/")
22+
23+
if (handleParts.length === urlParts.length) {
24+
let finalHandler: string[] = []
25+
26+
let finalQuery: any = {}
27+
28+
handleParts.forEach((handlePart, i) => {
29+
if (handlePart.startsWith("[") && handlePart.endsWith("]")) {
30+
const withoutBrackets = handlePart.replace(/\[|\]/g, "")
31+
32+
finalQuery[withoutBrackets] = urlParts[i]
33+
34+
finalHandler.push(urlParts[i] as never)
35+
} else {
36+
finalHandler.push(handlePart as never)
37+
}
38+
})
39+
40+
if (finalHandler.join("/") === urlParts.join("/")) {
41+
const withQ = { ...req.query, ...finalQuery }
42+
43+
if (req.method === method) {
44+
req.query = withQ
45+
46+
paths[path](req, res)
47+
} else {
48+
res.status(405)
49+
50+
res.send(`Cannot ${req.method} ${url}`)
51+
}
52+
}
53+
break
54+
} else {
55+
res.status(404)
56+
57+
res.send("Not found")
58+
59+
break
60+
}
61+
}
62+
}
63+
}

tsconfig.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"compilerOptions": {
3+
// "watch": true,
4+
"outDir": "./lib",
5+
"module": "commonjs",
6+
"esModuleInterop": true,
7+
"target": "es5",
8+
"lib": ["es6", "es2019"],
9+
"sourceMap": false,
10+
"allowJs": true,
11+
"moduleResolution": "node",
12+
"rootDir": "src",
13+
"noImplicitReturns": true,
14+
"noImplicitThis": true,
15+
"noImplicitAny": true,
16+
"strictNullChecks": true,
17+
"declaration": true
18+
},
19+
"include": ["src"],
20+
"exclude": ["node_modules"],
21+
"types": ["node"]
22+
}

0 commit comments

Comments
 (0)