bun-platform-kit 1.0.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 (54) hide show
  1. package/README.md +82 -0
  2. package/dist/BunKitServer.d.ts +31 -0
  3. package/dist/BunKitServer.js +173 -0
  4. package/dist/BunKitStandardServer.d.ts +18 -0
  5. package/dist/BunKitStandardServer.js +53 -0
  6. package/dist/abstract/ServerModule.d.ts +7 -0
  7. package/dist/abstract/ServerModule.js +12 -0
  8. package/dist/abstract/ServerService.d.ts +6 -0
  9. package/dist/abstract/ServerService.js +9 -0
  10. package/dist/abstract/ServerTypes.d.ts +78 -0
  11. package/dist/abstract/ServerTypes.js +7 -0
  12. package/dist/abstract/index.d.ts +3 -0
  13. package/dist/abstract/index.js +19 -0
  14. package/dist/adapters/BunAdapter.d.ts +12 -0
  15. package/dist/adapters/BunAdapter.js +1165 -0
  16. package/dist/adapters/index.d.ts +1 -0
  17. package/dist/adapters/index.js +17 -0
  18. package/dist/controllers/ReportFinanceController.d.ts +0 -0
  19. package/dist/controllers/ReportFinanceController.js +1 -0
  20. package/dist/decorators/Controller.d.ts +2 -0
  21. package/dist/decorators/Controller.js +13 -0
  22. package/dist/decorators/DecoratorGuards.d.ts +1 -0
  23. package/dist/decorators/DecoratorGuards.js +14 -0
  24. package/dist/decorators/Handlers.d.ts +18 -0
  25. package/dist/decorators/Handlers.js +35 -0
  26. package/dist/decorators/MetadataKeys.d.ts +6 -0
  27. package/dist/decorators/MetadataKeys.js +10 -0
  28. package/dist/decorators/Parameters.d.ts +24 -0
  29. package/dist/decorators/Parameters.js +41 -0
  30. package/dist/decorators/Use.d.ts +3 -0
  31. package/dist/decorators/Use.js +26 -0
  32. package/dist/decorators/index.d.ts +5 -0
  33. package/dist/decorators/index.js +21 -0
  34. package/dist/index.d.ts +10 -0
  35. package/dist/index.js +27 -0
  36. package/dist/modules/ControllersModule.d.ts +11 -0
  37. package/dist/modules/ControllersModule.js +138 -0
  38. package/dist/modules/CorsModule.d.ts +12 -0
  39. package/dist/modules/CorsModule.js +89 -0
  40. package/dist/modules/FileUploadModule.d.ts +21 -0
  41. package/dist/modules/FileUploadModule.js +20 -0
  42. package/dist/modules/RateLimitModule.d.ts +18 -0
  43. package/dist/modules/RateLimitModule.js +61 -0
  44. package/dist/modules/RequestContextModule.d.ts +18 -0
  45. package/dist/modules/RequestContextModule.js +52 -0
  46. package/dist/modules/SecurityModule.d.ts +11 -0
  47. package/dist/modules/SecurityModule.js +65 -0
  48. package/dist/modules/index.d.ts +6 -0
  49. package/dist/modules/index.js +22 -0
  50. package/dist/testing/createDecoratedTestApp.d.ts +19 -0
  51. package/dist/testing/createDecoratedTestApp.js +49 -0
  52. package/dist/testing/index.d.ts +1 -0
  53. package/dist/testing/index.js +17 -0
  54. package/package.json +57 -0
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateLimitModule = void 0;
4
+ const abstract_1 = require("../abstract");
5
+ class RateLimitModule extends abstract_1.BaseServerModule {
6
+ constructor(limiterOptions) {
7
+ super();
8
+ this.name = "RateLimit";
9
+ this.priority = -70;
10
+ this.limiterOptions = limiterOptions || {
11
+ windowMs: 8 * 60 * 1000, // 8 minutes
12
+ limit: 100,
13
+ standardHeaders: true,
14
+ legacyHeaders: false,
15
+ };
16
+ }
17
+ getModuleName() {
18
+ return this.name;
19
+ }
20
+ init(app, context) {
21
+ app.use(createRateLimitMiddleware(this.limiterOptions));
22
+ }
23
+ }
24
+ exports.RateLimitModule = RateLimitModule;
25
+ const createRateLimitMiddleware = (options) => {
26
+ const windowMsOption = options?.windowMs;
27
+ const windowMs = typeof windowMsOption === "number" ? windowMsOption : 8 * 60 * 1000;
28
+ const legacyMax = options?.max;
29
+ const limitOption = options?.limit ?? legacyMax;
30
+ const limit = typeof limitOption === "number" ? limitOption : 100;
31
+ const hits = new Map();
32
+ return (req, res, next) => {
33
+ const key = req.ip || String(req.headers?.["x-forwarded-for"] || "unknown");
34
+ const now = Date.now();
35
+ const existing = hits.get(key);
36
+ if (!existing || existing.expiresAt <= now) {
37
+ hits.set(key, { count: 1, expiresAt: now + windowMs });
38
+ }
39
+ else {
40
+ existing.count += 1;
41
+ }
42
+ const current = hits.get(key);
43
+ const remaining = Math.max(0, limit - current.count);
44
+ if (options?.standardHeaders) {
45
+ res.set("ratelimit-limit", String(limit));
46
+ res.set("ratelimit-remaining", String(remaining));
47
+ res.set("ratelimit-reset", String(Math.ceil(current.expiresAt / 1000)));
48
+ }
49
+ if (current.count > limit) {
50
+ const message = typeof options?.message === "string" ||
51
+ (typeof options?.message === "object" && options?.message)
52
+ ? options.message
53
+ : undefined;
54
+ res.status(429).json(message || {
55
+ message: "Too many requests, please try again later.",
56
+ });
57
+ return;
58
+ }
59
+ next();
60
+ };
61
+ };
@@ -0,0 +1,18 @@
1
+ import { BaseServerModule } from "../abstract";
2
+ import { ServerApp, ServerContext } from "../abstract";
3
+ export declare class RequestContextModule extends BaseServerModule {
4
+ name: string;
5
+ priority: number;
6
+ init(app: ServerApp, _context?: ServerContext): void;
7
+ getModuleName(): string;
8
+ }
9
+ interface Context {
10
+ requestId: string;
11
+ }
12
+ declare class RequestContext {
13
+ private static storage;
14
+ static get currentContext(): Context | undefined;
15
+ static get requestId(): string | undefined;
16
+ static run(context: Context, callback: () => void): void;
17
+ }
18
+ export { RequestContext };
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequestContext = exports.RequestContextModule = void 0;
4
+ const abstract_1 = require("../abstract");
5
+ const async_hooks_1 = require("async_hooks");
6
+ class RequestContextModule extends abstract_1.BaseServerModule {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.name = "RequestContext";
10
+ this.priority = -50;
11
+ }
12
+ init(app, _context) {
13
+ const requestContextMiddleware = async (req, _res, next) => {
14
+ const incomingRequestId = req.headers["x-request-id"];
15
+ const requestId = (Array.isArray(incomingRequestId)
16
+ ? incomingRequestId[0]
17
+ : incomingRequestId) || (await createRequestId());
18
+ req.requestId = requestId;
19
+ RequestContext.run({ requestId }, () => {
20
+ next();
21
+ });
22
+ };
23
+ app.use(requestContextMiddleware);
24
+ }
25
+ getModuleName() {
26
+ return this.name;
27
+ }
28
+ }
29
+ exports.RequestContextModule = RequestContextModule;
30
+ class RequestContext {
31
+ // Obtiene el contexto actual
32
+ static get currentContext() {
33
+ return this.storage.getStore();
34
+ }
35
+ // Obtiene el requestId actual del contexto
36
+ static get requestId() {
37
+ return this.currentContext?.requestId;
38
+ }
39
+ // Inicializa el contexto
40
+ static run(context, callback) {
41
+ this.storage.run(context, callback);
42
+ }
43
+ }
44
+ exports.RequestContext = RequestContext;
45
+ RequestContext.storage = new async_hooks_1.AsyncLocalStorage();
46
+ const createRequestId = async () => {
47
+ const cryptoObj = globalThis.crypto;
48
+ if (cryptoObj?.randomUUID) {
49
+ return cryptoObj.randomUUID();
50
+ }
51
+ return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
52
+ };
@@ -0,0 +1,11 @@
1
+ import { BaseServerModule } from "../abstract";
2
+ import { ServerApp, ServerContext } from "../abstract";
3
+ import type { HelmetOptions } from "helmet";
4
+ export declare class SecurityModule extends BaseServerModule {
5
+ name: string;
6
+ priority: number;
7
+ private readonly helmetOptions;
8
+ constructor(helmetOptions?: HelmetOptions);
9
+ getModuleName(): string;
10
+ init(app: ServerApp, context?: ServerContext): void;
11
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SecurityModule = void 0;
4
+ const abstract_1 = require("../abstract");
5
+ class SecurityModule extends abstract_1.BaseServerModule {
6
+ constructor(helmetOptions) {
7
+ super();
8
+ this.name = "Security";
9
+ this.priority = -80;
10
+ this.helmetOptions = helmetOptions || {
11
+ contentSecurityPolicy: false,
12
+ crossOriginEmbedderPolicy: false,
13
+ crossOriginOpenerPolicy: false,
14
+ crossOriginResourcePolicy: false,
15
+ dnsPrefetchControl: true,
16
+ frameguard: { action: "deny" },
17
+ hidePoweredBy: true,
18
+ ieNoOpen: true,
19
+ noSniff: true,
20
+ originAgentCluster: true,
21
+ permittedCrossDomainPolicies: false,
22
+ referrerPolicy: { policy: "no-referrer" },
23
+ };
24
+ }
25
+ getModuleName() {
26
+ return this.name;
27
+ }
28
+ init(app, context) {
29
+ app.use(createSecurityMiddleware(this.helmetOptions));
30
+ }
31
+ }
32
+ exports.SecurityModule = SecurityModule;
33
+ const createSecurityMiddleware = (options) => {
34
+ return (_req, res, next) => {
35
+ const frameguard = options?.frameguard;
36
+ if (frameguard && typeof frameguard === "object" && "action" in frameguard) {
37
+ const action = frameguard.action;
38
+ if (action) {
39
+ res.set("x-frame-options", action.toUpperCase());
40
+ }
41
+ }
42
+ if (options?.ieNoOpen !== false) {
43
+ res.set("x-download-options", "noopen");
44
+ }
45
+ if (options?.noSniff !== false) {
46
+ res.set("x-content-type-options", "nosniff");
47
+ }
48
+ if (options?.originAgentCluster) {
49
+ res.set("origin-agent-cluster", "?1");
50
+ }
51
+ if (options?.permittedCrossDomainPolicies === false) {
52
+ res.set("x-permitted-cross-domain-policies", "none");
53
+ }
54
+ const referrerPolicy = options?.referrerPolicy;
55
+ if (referrerPolicy && typeof referrerPolicy === "object" && "policy" in referrerPolicy) {
56
+ res.set("referrer-policy", Array.isArray(referrerPolicy.policy)
57
+ ? referrerPolicy.policy.join(",")
58
+ : referrerPolicy.policy);
59
+ }
60
+ if (options?.dnsPrefetchControl) {
61
+ res.set("x-dns-prefetch-control", "on");
62
+ }
63
+ next();
64
+ };
65
+ };
@@ -0,0 +1,6 @@
1
+ export * from "./CorsModule";
2
+ export * from "./ControllersModule";
3
+ export * from "./FileUploadModule";
4
+ export * from "./RateLimitModule";
5
+ export * from "./RequestContextModule";
6
+ export * from "./SecurityModule";
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./CorsModule"), exports);
18
+ __exportStar(require("./ControllersModule"), exports);
19
+ __exportStar(require("./FileUploadModule"), exports);
20
+ __exportStar(require("./RateLimitModule"), exports);
21
+ __exportStar(require("./RequestContextModule"), exports);
22
+ __exportStar(require("./SecurityModule"), exports);
@@ -0,0 +1,19 @@
1
+ import type { BunKitServer } from "../BunKitServer";
2
+ import { ControllersModule } from "../modules";
3
+ import { BaseServerService, ServerApp } from "../abstract";
4
+ import { BunKitStandardServerOptions } from "../BunKitStandardServer";
5
+ type ControllerClass<T = any> = new (...args: any[]) => T;
6
+ export interface DecoratedTestAppOptions {
7
+ controllers?: ControllerClass[];
8
+ controllersModule?: ControllersModule;
9
+ port?: number;
10
+ services?: BaseServerService[];
11
+ standardOptions?: BunKitStandardServerOptions;
12
+ }
13
+ export interface DecoratedTestAppResult {
14
+ app: ServerApp;
15
+ server: BunKitServer;
16
+ stop: () => Promise<void>;
17
+ }
18
+ export declare function createDecoratedTestApp(options: DecoratedTestAppOptions): Promise<DecoratedTestAppResult>;
19
+ export {};
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDecoratedTestApp = createDecoratedTestApp;
4
+ const BunKitStandardServer_1 = require("../BunKitStandardServer");
5
+ const modules_1 = require("../modules");
6
+ const mergeOptions = (base, override) => {
7
+ if (!override) {
8
+ return base;
9
+ }
10
+ const mergedServices = [
11
+ ...(base.services ?? []),
12
+ ...(override.services ?? []),
13
+ ];
14
+ return {
15
+ adapter: override.adapter ?? base.adapter,
16
+ services: mergedServices.length ? mergedServices : undefined,
17
+ modules: {
18
+ ...(base.modules ?? {}),
19
+ ...(override.modules ?? {}),
20
+ },
21
+ };
22
+ };
23
+ async function createDecoratedTestApp(options) {
24
+ const { controllers = [], controllersModule, port = 0, services, standardOptions, } = options;
25
+ const moduleInstance = controllersModule ?? new modules_1.ControllersModule(controllers);
26
+ const baseOptions = {
27
+ services,
28
+ modules: {
29
+ cors: false,
30
+ security: false,
31
+ rateLimit: false,
32
+ },
33
+ };
34
+ const mergedOptions = mergeOptions(baseOptions, standardOptions);
35
+ const server = (0, BunKitStandardServer_1.BunKitStandardServer)(port, moduleInstance, {
36
+ ...mergedOptions,
37
+ });
38
+ await server.initialize();
39
+ return {
40
+ app: server.getApp(),
41
+ server,
42
+ stop: async () => {
43
+ const serverInstance = server.getServer();
44
+ if (serverInstance) {
45
+ await new Promise((resolve) => serverInstance.close(() => resolve()));
46
+ }
47
+ },
48
+ };
49
+ }
@@ -0,0 +1 @@
1
+ export * from "./createDecoratedTestApp";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./createDecoratedTestApp"), exports);
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "bun-platform-kit",
3
+ "author": "angel bejarano / angel.bejarano@jaspesoft.com",
4
+ "version": "1.0.0",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "bun run tsc -p tsconfig.json",
12
+ "clean": "rm -rf dist",
13
+ "prepare": "bun run build",
14
+ "prebuild": "bun run clean",
15
+ "format": "bun run prettier --write .",
16
+ "format:check": "bun run prettier --check .",
17
+ "typecheck": "bun run tsc --noEmit",
18
+ "prepack": "bun run build",
19
+ "test": "bun test",
20
+ "test:watch": "bun test --watch",
21
+ "test:coverage": "bun test --coverage"
22
+ },
23
+ "keywords": [
24
+ "server",
25
+ "framework",
26
+ "modular",
27
+ "decorators",
28
+ "platform",
29
+ "bun"
30
+ ],
31
+ "license": "MIT",
32
+ "dependencies": {
33
+ "cors": "^2.8.5",
34
+ "helmet": "^8.1.0",
35
+ "reflect-metadata": "^0.2.2"
36
+ },
37
+ "devDependencies": {
38
+ "@semantic-release/changelog": "^6.0.3",
39
+ "@semantic-release/git": "^10.0.1",
40
+ "@types/cors": "^2.8.19",
41
+ "bun-types": "^1.3.5",
42
+ "prettier": "^3.6.2",
43
+ "semantic-release": "^25.0.2",
44
+ "typescript": "^5.9.3"
45
+ },
46
+ "engines": {
47
+ "bun": ">=1.3.5"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/abejarano/bun-platform-kit.git"
52
+ },
53
+ "publishConfig": {
54
+ "registry": "https://registry.npmjs.org",
55
+ "access": "public"
56
+ }
57
+ }