abhijanb 0.1.0 → 0.1.2

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/a/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # a
2
+
3
+ To install dependencies:
4
+
5
+ ```bash
6
+ bun install
7
+ ```
8
+
9
+ To run:
10
+
11
+ ```bash
12
+ bun run index.ts
13
+ ```
14
+
15
+ This project was created using `bun init` in bun v1.3.14. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
package/a/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { startSocket, validate } from 'abhijanb';
2
+ import express from 'express';
3
+ import z from 'zod';
4
+ const app = express();
5
+ const {server} = startSocket(app);
6
+
7
+
8
+ const schema = z.object({
9
+ name: z.string(),
10
+ age: z.number().int().positive(),
11
+ });
12
+
13
+ app.use(express.json());
14
+
15
+ app.post('/validate', (req, res) => {
16
+ const result = validate(schema, req.body);
17
+ if (result.success) {
18
+ res.json({ message: 'Validation successful', data: result.data });
19
+ } else {
20
+ res.status(400).json({ message: 'Validation failed', errors: result.errors });
21
+ }
22
+ });
23
+
24
+ server.listen(3000, () => {
25
+ console.log('Server is running on port 3000');
26
+ });
package/a/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "a",
3
+ "module": "index.ts",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "bun --watch index.ts"
8
+
9
+ },
10
+ "devDependencies": {
11
+ "@types/bun": "latest"
12
+ },
13
+ "peerDependencies": {
14
+ "typescript": "^5"
15
+ },
16
+ "dependencies": {
17
+ "abhijanb": "^0.1.1"
18
+ }
19
+ }
package/index.ts CHANGED
@@ -1,20 +1,3 @@
1
- /** Express app instanceuse for routing and middleware */
2
- export { app, server } from "./app";
3
- /** Express types — Request, Response, NextFunction */
4
- export type { Request, Response, NextFunction } from "./app";
5
- /** Express utilities — Router, json, urlencoded, expressStatic */
6
- export { Router, json, urlencoded, expressStatic } from "./app";
7
-
8
- /** Socket.IO server instance — use for `.on()` / `.emit()` */
9
- export { io, socket } from "./socket";
10
- /** Socket type — for typing event handlers */
11
- export type { Socket } from "./socket";
12
-
13
- /** Rate limiter factory: `app.use(limiter(5, 1000))` = 5min window, 1000 req/IP */
14
- export { limiter } from "./rateLimiter";
15
- /** Factory — create custom rate limiters: `rateLimit({ windowMs: 60000, max: 20 })` */
16
- export { rateLimit } from "./rateLimiter";
17
-
18
- /** Default export — Express app instance */
19
- import { app } from "./app";
20
- export default app;
1
+ /** Main entry pointre-exports everything from util/ and lib/ */
2
+ export * from "./util";
3
+ export * from "./lib";
package/lib/auth.ts ADDED
@@ -0,0 +1,71 @@
1
+ import jwt from "jsonwebtoken";
2
+ import type { Request, Response, NextFunction } from "express";
3
+
4
+ const ACCESS_SECRET = process.env.JWT_ACCESS_SECRET || "access-secret";
5
+ const REFRESH_SECRET = process.env.JWT_REFRESH_SECRET || "refresh-secret";
6
+ const ACCESS_EXPIRY = "30m";
7
+ const REFRESH_EXPIRY = "30d";
8
+
9
+ /** Sign an access token */
10
+ export function signToken(
11
+ payload: object,
12
+ options?: { secret?: string; expiresIn?: string }
13
+ ): string {
14
+ return jwt.sign(payload, options?.secret || ACCESS_SECRET, {
15
+ expiresIn: options?.expiresIn || ACCESS_EXPIRY,
16
+ });
17
+ }
18
+
19
+ /** Sign a refresh token */
20
+ export function signRefreshToken(
21
+ payload: object,
22
+ options?: { secret?: string; expiresIn?: string }
23
+ ): string {
24
+ return jwt.sign(payload, options?.secret || REFRESH_SECRET, {
25
+ expiresIn: options?.expiresIn || REFRESH_EXPIRY,
26
+ });
27
+ }
28
+
29
+ /** Verify and decode a token */
30
+ export function verifyToken<T = any>(
31
+ token: string,
32
+ options?: { secret?: string }
33
+ ): T {
34
+ return jwt.verify(token, options?.secret || ACCESS_SECRET) as T;
35
+ }
36
+
37
+ /** Refresh: verify refresh token → return new access token */
38
+ export function refreshToken(
39
+ token: string,
40
+ options?: { accessSecret?: string; refreshSecret?: string }
41
+ ): string {
42
+ const decoded = jwt.verify(
43
+ token,
44
+ options?.refreshSecret || REFRESH_SECRET
45
+ ) as jwt.JwtPayload;
46
+
47
+ const { iat, exp, ...payload } = decoded;
48
+ return signToken(payload, { secret: options?.accessSecret });
49
+ }
50
+
51
+ /** Express middleware — verifies Bearer token, attaches decoded payload to `req.user` */
52
+ export function authMiddleware(options?: { secret?: string }) {
53
+ return (req: Request, res: Response, next: NextFunction) => {
54
+ const header = req.headers.authorization;
55
+
56
+ if (!header || !header.startsWith("Bearer ")) {
57
+ res.status(401).json({ error: "Missing or invalid Authorization header" });
58
+ return;
59
+ }
60
+
61
+ const token = header.split(" ")[1];
62
+
63
+ try {
64
+ const decoded = jwt.verify(token, options?.secret || ACCESS_SECRET);
65
+ (req as any).user = decoded;
66
+ next();
67
+ } catch {
68
+ res.status(401).json({ error: "Invalid or expired token" });
69
+ }
70
+ };
71
+ }
package/lib/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ /** Start Socket.IO on an Express app: `startSocket(app)` → returns { server, io, socket } */
2
+ export { startSocket, io, socket } from "./socket";
3
+ /** Socket type — for typing event handlers */
4
+ export type { Socket } from "./socket";
5
+
6
+ /** Rate limiter factory: `app.use(limiter(5, 1000))` = 5min window, 1000 req/IP */
7
+ export { limiter } from "./rateLimiter";
8
+ /** Factory — create custom rate limiters: `rateLimit({ windowMs: 60000, max: 20 })` */
9
+ export { rateLimit } from "./rateLimiter";
10
+
11
+ /** JWT middleware — verifies Bearer token, attaches decoded payload to `req.user` */
12
+ export { authMiddleware } from "./auth";
13
+ /** Sign an access token: `signToken({ userId: 1 })` */
14
+ export { signToken } from "./auth";
15
+ /** Sign a refresh token: `signRefreshToken({ userId: 1 })` */
16
+ export { signRefreshToken } from "./auth";
17
+ /** Verify and decode a token: `verifyToken<T>(token)` */
18
+ export { verifyToken } from "./auth";
19
+ /** Refresh: verify refresh token → return new access token */
20
+ export { refreshToken } from "./auth";
package/lib/socket.ts ADDED
@@ -0,0 +1,17 @@
1
+ import http from "http";
2
+ import { Server } from "socket.io";
3
+ import type { Express } from "express";
4
+
5
+ let io: Server;
6
+ let socket: Server;
7
+
8
+ /** Start Socket.IO on an Express app: `startSocket(app)` → returns { server, io, socket } */
9
+ export function startSocket(app: Express) {
10
+ const server = http.createServer(app);
11
+ io = new Server(server);
12
+ socket = io;
13
+ return { server, io, socket };
14
+ }
15
+
16
+ export { io, socket };
17
+ export type { Socket } from "socket.io";
package/package.json CHANGED
@@ -1,22 +1,27 @@
1
1
  {
2
2
  "name": "abhijanb",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "exports": {
7
- ".": "./index.ts"
7
+ ".": "./index.ts",
8
+ "./util": "./util/index.ts",
9
+ "./lib": "./lib/index.ts"
8
10
  },
9
11
  "types": "./index.ts",
10
12
  "dependencies": {
11
- "express": "^4.21.0",
12
13
  "express-rate-limit": "^7.5.0",
13
- "socket.io": "^4.8.0"
14
+ "jsonwebtoken": "^9.0.0",
15
+ "socket.io": "^4.8.0",
16
+ "zod": "^3.22.0"
14
17
  },
15
18
  "devDependencies": {
16
19
  "@types/bun": "latest",
17
- "@types/express": "^5.0.0"
20
+ "@types/express": "^5.0.0",
21
+ "@types/jsonwebtoken": "^9.0.0"
18
22
  },
19
23
  "peerDependencies": {
24
+ "express": "^4.21.0",
20
25
  "typescript": "^5"
21
26
  }
22
27
  }
package/util/index.ts ADDED
@@ -0,0 +1,25 @@
1
+ /** Validate data against Zod schema: `validate(schema, data)` → { success, data, errors } */
2
+ export { validate } from "./validate";
3
+ export type { ValidateResult } from "./validate";
4
+
5
+ /** Response helpers: ok, created, badRequest, notFound, etc. */
6
+ export {
7
+ ok,
8
+ created,
9
+ noContent,
10
+ paginated,
11
+ badRequest,
12
+ unauthorized,
13
+ forbidden,
14
+ notFound,
15
+ conflict,
16
+ internalError,
17
+ fail,
18
+ } from "./response";
19
+
20
+ /** Response namespace: `response.ok(res, data)`, `response.created(res, data)` */
21
+ export { response } from "./response";
22
+
23
+ /** Status codes and error codes constants */
24
+ export { STATUS_CODE, ERROR_CODES } from "./response";
25
+ export type { StatusCode, ErrorCode, ApiResponse, ApiErrorResponse } from "./response";
@@ -0,0 +1,116 @@
1
+ import type { Response } from "express";
2
+
3
+ const STATUS_CODE = {
4
+ OK: 200,
5
+ CREATED: 201,
6
+ NO_CONTENT: 204,
7
+ BAD_REQUEST: 400,
8
+ UNAUTHORIZED: 401,
9
+ FORBIDDEN: 403,
10
+ NOT_FOUND: 404,
11
+ CONFLICT: 409,
12
+ INTERNAL_SERVER_ERROR: 500,
13
+ } as const;
14
+
15
+ const ERROR_CODES = {
16
+ BAD_REQUEST: "BAD_REQUEST",
17
+ UNAUTHORIZED: "UNAUTHORIZED",
18
+ FORBIDDEN: "FORBIDDEN",
19
+ NOT_FOUND: "NOT_FOUND",
20
+ CONFLICT: "CONFLICT",
21
+ INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR",
22
+ } as const;
23
+
24
+ type StatusCode = (typeof STATUS_CODE)[keyof typeof STATUS_CODE];
25
+ type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
26
+
27
+ type ApiResponse<T> = { success: true; data: T; meta?: Record<string, unknown> };
28
+ type ApiErrorResponse = { success: false; error: { code: ErrorCode; message: string; details?: unknown } };
29
+
30
+ function successResponse<T>(data: T, meta?: Record<string, unknown>): ApiResponse<T> {
31
+ return { success: true, data, ...(meta && { meta }) };
32
+ }
33
+
34
+ function errorResponse(code: ErrorCode, message: string, details?: unknown): ApiErrorResponse {
35
+ return { success: false, error: { code, message, details } };
36
+ }
37
+
38
+ export function ok<T>(res: Response, data: T, meta?: Record<string, unknown>) {
39
+ res.status(STATUS_CODE.OK).json(successResponse(data, meta));
40
+ }
41
+
42
+ export function created<T>(res: Response, data: T) {
43
+ res.status(STATUS_CODE.CREATED).json(successResponse(data));
44
+ }
45
+
46
+ export function noContent(res: Response) {
47
+ res.status(STATUS_CODE.NO_CONTENT).send();
48
+ }
49
+
50
+ export function paginated<T>(
51
+ res: Response,
52
+ items: T[],
53
+ pagination: { page: number; limit: number; totalItems: number }
54
+ ) {
55
+ res.status(STATUS_CODE.OK).json(
56
+ successResponse(items, {
57
+ pagination: {
58
+ page: pagination.page,
59
+ limit: pagination.limit,
60
+ totalItems: pagination.totalItems,
61
+ totalPages: Math.ceil(pagination.totalItems / pagination.limit),
62
+ },
63
+ })
64
+ );
65
+ }
66
+
67
+ export function fail(
68
+ res: Response,
69
+ { status, code, message, details }: { status: StatusCode; code: ErrorCode; message: string; details?: unknown }
70
+ ) {
71
+ res.status(status).json(errorResponse(code, message, details));
72
+ }
73
+
74
+ export function badRequest(res: Response, message: string, details?: unknown) {
75
+ fail(res, { status: STATUS_CODE.BAD_REQUEST, code: ERROR_CODES.BAD_REQUEST, message, details });
76
+ }
77
+
78
+ export function unauthorized(res: Response, message: string, details?: unknown) {
79
+ fail(res, { status: STATUS_CODE.UNAUTHORIZED, code: ERROR_CODES.UNAUTHORIZED, message, details });
80
+ }
81
+
82
+ export function forbidden(res: Response, message: string, details?: unknown) {
83
+ fail(res, { status: STATUS_CODE.FORBIDDEN, code: ERROR_CODES.FORBIDDEN, message, details });
84
+ }
85
+
86
+ export function notFound(res: Response, message: string, details?: unknown) {
87
+ fail(res, { status: STATUS_CODE.NOT_FOUND, code: ERROR_CODES.NOT_FOUND, message, details });
88
+ }
89
+
90
+ export function conflict(res: Response, message: string, details?: unknown) {
91
+ fail(res, { status: STATUS_CODE.CONFLICT, code: ERROR_CODES.CONFLICT, message, details });
92
+ }
93
+
94
+ export function internalError(res: Response, message: string, details?: unknown) {
95
+ fail(res, { status: STATUS_CODE.INTERNAL_SERVER_ERROR, code: ERROR_CODES.INTERNAL_SERVER_ERROR, message, details });
96
+ }
97
+
98
+ export { STATUS_CODE, ERROR_CODES };
99
+ export type { StatusCode, ErrorCode, ApiResponse, ApiErrorResponse };
100
+
101
+ /** Response helper namespace: `response.ok(res, data)`, `response.created(res, data)` */
102
+ export const response = {
103
+ ok,
104
+ created,
105
+ noContent,
106
+ paginated,
107
+ badRequest,
108
+ unauthorized,
109
+ forbidden,
110
+ notFound,
111
+ conflict,
112
+ internalError,
113
+ fail,
114
+ STATUS_CODE,
115
+ ERROR_CODES,
116
+ };
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ import type { ZodSchema, ZodError } from "zod";
3
+
4
+ type FormattedError = { field: string; message: string; code: string };
5
+
6
+ type ValidateResult<T> =
7
+ | { success: true; data: T; errors: null }
8
+ | { success: false; data: null; errors: FormattedError[] };
9
+
10
+ function formatZodErrors(error: ZodError): FormattedError[] {
11
+ return error.issues.map((issue) => ({
12
+ field: issue.path.length ? issue.path.join(".") : "root",
13
+ message: issue.message,
14
+ code: issue.code,
15
+ }));
16
+ }
17
+
18
+ /** Validate data against Zod schema → { success, data, errors } */
19
+ export function validate<T>(schema: ZodSchema<T>, data: unknown): ValidateResult<T> {
20
+ const result = schema.safeParse(data);
21
+ if (result.success) {
22
+ return { success: true, data: result.data, errors: null };
23
+ }
24
+ return { success: false, data: null, errors: formatZodErrors(result.error) };
25
+ }
26
+
27
+ export type { ValidateResult };
package/app.ts DELETED
@@ -1,14 +0,0 @@
1
- import express from "express";
2
- import http from "http";
3
-
4
- const app = express();
5
- const server = http.createServer(app);
6
-
7
- /** Express app instance — use for routing and middleware */
8
- export { app };
9
- /** HTTP server instance — used by Socket.IO */
10
- export { server };
11
- /** Express request type */
12
- export type { Request, Response, NextFunction } from "express";
13
- /** Router — create modular route handlers */
14
- export { Router, json, urlencoded, static as expressStatic } from "express";
package/socket.ts DELETED
@@ -1,10 +0,0 @@
1
- import { Server } from "socket.io";
2
- import { server } from "./app";
3
-
4
- const io = new Server(server);
5
- const socket = io;
6
-
7
- /** Socket.IO server instance — use for `.on()` / `.emit()` */
8
- export { io, socket };
9
- /** Socket type — for typing event handlers */
10
- export type { Socket } from "socket.io";
File without changes