Skip to content

Commit

Permalink
Merge pull request #14 from yracnet/v1.1.x-beta
Browse files Browse the repository at this point in the history
V1.1.x beta
  • Loading branch information
yracnet authored Dec 25, 2023
2 parents 8504737 + 74b6c95 commit 63bdc13
Show file tree
Hide file tree
Showing 44 changed files with 853 additions and 210 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
vite-plugin-api-routes-*.tgz
140 changes: 112 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export default defineConfig({
// cacheDir: ".api",
// server: "[cacheDir]/server.js",
// handler: "[cacheDir]/handler.js",
// configure: "[cacheDir]/configure.js",
// routeBase: "api",
// dirs: [{ dir: "src/api"; route: "", exclude?: ["*.txt", ".csv", "data/*.*"] }],
// include: ["**/*.js", "**/*.ts"],
Expand All @@ -138,6 +139,7 @@ export default defineConfig({
- **moduleId**: Name of the virtual module, default @api (used for imports, change if conflicts occur).
- **server**: The main file to build as the server app. [See default file.](./example/src/custom-server-example/server.ts)
- **handler**: The main file to register the API. It is called in viteServer and is the default entry. [See default file.](./example/src/custom-server-example/handler.ts)
- **configure**: The configureFile centralizes server configuration for both development (viteServer) and production (express). This file is invoked in various lifecycle hooks of the server. [See default file.](./example/src/custom-server-example/configure.ts)
- **routeBase**: Base name route for all routes. The default value is **api**.
- **dirs**: List of directories to be scanned. The default value is **[ { dir: 'src/api', route: '', exclude: []} ]**.
- **include**: Files and directories to include in the scan process. The default value is **["\\*\\*/_.js", "\\*\\*/_.ts"]**.
Expand Down Expand Up @@ -199,64 +201,146 @@ You can disable a method by setting its value to false. In the example `PATCH: f
**/src/api/index.js**

```javascript
export PING = (req, res, next)=>{
export const PING = (req, res, next)=>{
res.send({name:"Ping Service"});
}
export OTHER_POST = (req, res, next)=>{
res.send({name:"Ping Service"});
export const OTHER_POST = (req, res, next)=>{
res.send({name:"Other Service"});
}
export PATCH = (req, res, next)=>{
res.send({name:"Ping Service"});
export const PATCH = (req, res, next)=>{
res.send({name:"Path Service"});
}
```

**/src/handler.js** or see [handler.js](./example/src/custom-server-example/handler.ts)

```typescript
// @ts-nocheck
import express from "express";
import { applyRouters } from "@api/routers"; // Notice '@api', this is the moduleId!
import { applyRouters } from "@api/routers";
import * as configure from "@api/configure";

export const handler = express();

// Add JSON-Parsing
handler.use(express.json());
handler.use(express.urlencoded({ extended: true }));

applyRouters((props) => {
const { method, route, path, cb } = props;
if (handler[method]) {
if (Array.isArray(cb)) {
handler[method](route, ...cb);
configure.handlerBefore?.(handler);

applyRouters(
(props) => {
const { method, route, path, cb } = props;
if (handler[method]) {
if(Array.isArray(cb)) {
handler[method](route, ...cb);
} else {
handler[method](route, cb);
}
} else {
handler[method](route, cb);
console.log("Not Support", method, "for", route, "in", handler);
}
} else {
console.log("Not Support", method, "for", route, "in", handler);
}
});
);

configure.handlerAfter?.(handler);
```

**/src/server.ts** or see [server.ts](./example/src/custom-server-example/server.ts)

```typescript
// @ts-ignore
import { handler } from "@api/handler"; // Notice '@api', this is the moduleId!
// @ts-ignore
import { endpoints } from "@api/routers"; // Notice '@api', this is the moduleId!
import { handler } from "@api/handler";
import { endpoints } from "@api/routers";
import * as configure from "@api/configure";
import express from "express";

const { PORT = 3000, PUBLIC_DIR = "import.meta.env.PUBLIC_DIR" } = process.env;
const server = express();
server.use(express.json());
configure.serverBefore?.(server);
const { PORT = 3000, PUBLIC_DIR = "import.meta.env.PUBLIC_DIR" } = process.env;
server.use("import.meta.env.BASE", express.static(PUBLIC_DIR));
server.use("import.meta.env.BASE_API", handler);
server.listen(PORT, () => {
configure.serverAfter?.(server);
server.on("error", (error) => {
console.error(`Error at http://localhost:${PORT}`, error);
configure.serverError?.(server, error);
});
server.on("listening", () => {
console.log(`Ready at http://localhost:${PORT}`);
console.log(endpoints);
configure.serverListening?.(server, endpoints);
});
server.listen(PORT);
```

**/src/configure.ts** or see [configure.ts](./example/src/custom-server-example/configure.ts)

```typescript
import express from "express";
import { CallbackHook, StatusHook, ServerHook, HandlerHook, ViteServerHook } from "vite-plugin-api-routes/model";

export const viteServerBefore: ViteServerHook = (server, viteServer) => {
console.log("VITEJS SERVER");
server.use(express.json());
server.use(express.urlencoded({ extended: true }));
};

export const viteServerAfter: ViteServerHook = (server, viteServer) => {
};

export const serverBefore: ServerHook = (server) => {
server.use(express.json());
server.use(express.urlencoded({ extended: true }));
};

export const serverAfter: ServerHook = (server) => {
};

export const handlerBefore: HandlerHook = (handler) => {
};

export const handlerAfter: HandlerHook = (server) => {
};

export const callbackBefore: CallbackHook = (callback, route) => {
return callback;
};

export const serverListening: StatusHook = (server) => {
};

export const serverError: StatusHook = (server, error) => {
};

```

### TypeScript Support

To leverage TypeScript models within your Vite.js project, follow these steps:

#### Reference the TypeScript Definitions:

Add a reference to the TypeScript definitions file [moduleId]/types.d.ts within your vite-env.d.ts file.

src/vite-env.d.ts
```typescript
/// <reference types="vite/client" />
/// <reference types="../.api/types.d.ts" />
```

#### Utilize the TypeScript Models in Your Code:

Once you've referenced the required TypeScript definitions, you can incorporate them directly into your TypeScript code.

Incorporating a ViteServerHook model from vite-plugin-api-routes:

```typescript
import { ViteServerHook } from "vite-plugin-api-routes/model";

export const viteServerBefore: ViteServerHook = (server, viteServer) => {
console.log("VITEJS SERVER");
// Include ViteServer Config
};
```


## NOTE:

In the server file, we do not explicitly declare the basic configuration. Instead, this responsibility is delegated to the configure file, ensuring a more modular and centralized approach to server setup and initialization.

## TO DO:

- Duplicate declaration (**GET** in _/user.ts_ and _/user/index.ts_). Handler definition is required.
Expand Down
3 changes: 2 additions & 1 deletion example/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
VITE_CODE: 1234
KEY_SECRET: 123466
API_TOKEN: 123466
API_TOKEN: 123466
JWT_SECRET: F69F37EB4D1BAB673F7B5A7D41E3A
6 changes: 5 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
"build": "tsc && vite build"
},
"dependencies": {
"cookie-parser": "^1.4.6",
"dotenv": "^16.3.1",
"dotenv-local": "^1.0.0",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"vite-plugin-api-routes": "file:.."
"vite-plugin-api-routes": "..\\vite-plugin-api-routes-v1.1.0.tgz"
},
"devDependencies": {
"@types/express": "^4.17.15",
Expand Down
6 changes: 6 additions & 0 deletions example/src/api/admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createAllowRoles, assertToken } from "../middleware/sessionToken";

export default [
assertToken,
createAllowRoles(['ADMIN']),
];
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//@ts-ignore
import { createResponse } from "../../../../common/response.js";

//@ts-ignore
export const GET = (req, res, next) => {
createResponse("v2/user/[userId]/detail.ts", req, res, next);
};
createResponse("v2/post/[postId].ts", req, res, next);
};
6 changes: 6 additions & 0 deletions example/src/api/admin/post/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createResponse } from "../../../common/response.js";

//@ts-ignore
export const GET = (req, res, next) => {
createResponse("v2/post/index.ts", req, res, next);
};
12 changes: 2 additions & 10 deletions example/src/api/admin/user.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//@ts-ignore
export default (req, res, next) => {
req.copyright = "HOC FOR AUTH REQUEST - TS";
next();
};
import { createAllowRoles } from "../../middleware/sessionToken";

//@ts-ignore
export const GET = (req, res, next) => {
//res.send({ ok: true });
next();
};
export default createAllowRoles(['USER']);
7 changes: 0 additions & 7 deletions example/src/api/admin/user/[userId]/[action]/index.ts

This file was deleted.

14 changes: 1 addition & 13 deletions example/src/api/admin/user/[userId]/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,4 @@ import { createResponse } from "../../../../common/response.js";
//@ts-ignore
export const GET = (req, res, next) => {
createResponse("v2/user/[userId].ts", req, res, next);
};

//@ts-ignore
export const DELETE = (req, res, next) => {
res.clearCookie("user");
createResponse("v2/user/[userId].ts", req, res, next);
};

//@ts-ignore
export const PUT = (req, res, next) => {
res.cookie("user", "UPDATE-USER");
createResponse("v2/user/[userId].ts", req, res, next);
};
};
8 changes: 1 addition & 7 deletions example/src/api/admin/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,4 @@ import { createResponse } from "../../../common/response.js";
//@ts-ignore
export const GET = (req, res, next) => {
createResponse("v2/user/index.ts", req, res, next);
};

//@ts-ignore
export const POST = (req, res, next) => {
res.cookie("user", "NEW-USER");
createResponse("v2/user/index.ts", req, res, next);
};
};
13 changes: 9 additions & 4 deletions example/src/api/auth/login.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { NextFunction, Request, Response } from "express";
import { createResponseAsync } from "../../common/response.js";
import { createResponseAsync } from "../../common/response";
import { jwtSign } from "../../middleware/jwt";

export const POST = async (req: Request, res: Response, next: NextFunction) => {
res.cookie("auth", true);
return createResponseAsync("Logged in!", req, res, next);
export const POST = (req: Request, res: Response, next: NextFunction) => {
const token = jwtSign({
name: 'Willyams',
roles: ['ADMIN', 'USER'],
});
res.cookie('token', token, { httpOnly: false });
createResponseAsync("Logged in!", req, res, next);
};
9 changes: 1 addition & 8 deletions example/src/api/auth/logout.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import { NextFunction, Request, Response } from "express";
import { authMiddleware } from "../../common/authMiddleware.js";
import { createResponseAsync } from "../../common/response.js";

export const POST = async (req: Request, res: Response, next: NextFunction) => {
["auth", "article", "user"].forEach(name => {
["auth", "article", "user", "token"].forEach(name => {
res.clearCookie(name);
});
return createResponseAsync("Logged out!", req, res, next);
};

/* Any amount of middlewares */
/* Like this the user cannot logout if he is not logged in */
export default [
authMiddleware
]
12 changes: 0 additions & 12 deletions example/src/api/auth/protected.ts

This file was deleted.

11 changes: 0 additions & 11 deletions example/src/api/auth/status.ts

This file was deleted.

13 changes: 13 additions & 0 deletions example/src/api/auth/supplant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//@ts-ignore
import { createResponseAsync } from "../../common/response.js";
import { jwtSign } from "../../middleware/jwt";

//@ts-ignore
export const POST = (req, res, next) => {
const token = jwtSign({
name: 'User Site',
roles: ['SITE'],
});
res.cookie('token', token, { httpOnly: false });
return createResponseAsync("Changed in!", req, res, next);
};
Loading

0 comments on commit 63bdc13

Please sign in to comment.