shokupan 0.2.0 → 0.4.4

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 (59) hide show
  1. package/README.md +197 -24
  2. package/dist/benchmarking/advanced-cases/elysia.d.ts +1 -0
  3. package/dist/benchmarking/advanced-cases/express.d.ts +1 -0
  4. package/dist/benchmarking/advanced-cases/fastify.d.ts +1 -0
  5. package/dist/benchmarking/advanced-cases/hapi.d.ts +1 -0
  6. package/dist/benchmarking/advanced-cases/hono.d.ts +1 -0
  7. package/dist/benchmarking/advanced-cases/koa.d.ts +1 -0
  8. package/dist/benchmarking/advanced-cases/nest.d.ts +1 -0
  9. package/dist/benchmarking/advanced-cases/shokupan.d.ts +1 -0
  10. package/dist/benchmarking/advanced-data.d.ts +33 -0
  11. package/dist/benchmarking/advanced-runner.d.ts +1 -0
  12. package/dist/benchmarking/advanced-worker.d.ts +0 -0
  13. package/dist/benchmarking/cases/elysia.d.ts +1 -0
  14. package/dist/benchmarking/cases/express.d.ts +1 -0
  15. package/dist/benchmarking/cases/fastify.d.ts +1 -0
  16. package/dist/benchmarking/cases/hapi.d.ts +1 -0
  17. package/dist/benchmarking/cases/hono.d.ts +1 -0
  18. package/dist/benchmarking/cases/koa.d.ts +1 -0
  19. package/dist/benchmarking/cases/nest.d.ts +1 -0
  20. package/dist/benchmarking/cases/shokupan.d.ts +1 -0
  21. package/dist/benchmarking/data.d.ts +15 -0
  22. package/dist/benchmarking/quick_bench.d.ts +1 -0
  23. package/dist/benchmarking/runner.d.ts +1 -0
  24. package/dist/benchmarking/worker.d.ts +0 -0
  25. package/dist/buntest.d.ts +1 -0
  26. package/dist/cli.cjs +1 -1
  27. package/dist/cli.js +1 -1
  28. package/dist/context.d.ts +17 -7
  29. package/dist/decorators.d.ts +47 -0
  30. package/dist/index.cjs +939 -385
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.js +931 -379
  33. package/dist/index.js.map +1 -1
  34. package/dist/{openapi-analyzer-BTExMLX4.js → openapi-analyzer-BtIaHIfe.js} +11 -6
  35. package/dist/openapi-analyzer-BtIaHIfe.js.map +1 -0
  36. package/dist/{openapi-analyzer-BN0wFCML.cjs → openapi-analyzer-D9YB3IkV.cjs} +11 -6
  37. package/dist/openapi-analyzer-D9YB3IkV.cjs.map +1 -0
  38. package/dist/plugins/auth.d.ts +1 -1
  39. package/dist/plugins/debugview/plugin.d.ts +7 -12
  40. package/dist/plugins/failed-request-recorder.d.ts +14 -0
  41. package/dist/plugins/idempotency/plugin.d.ts +14 -0
  42. package/dist/plugins/openapi-validator.d.ts +28 -0
  43. package/dist/plugins/rate-limit.d.ts +3 -1
  44. package/dist/plugins/serve-static.d.ts +2 -3
  45. package/dist/router/trie.d.ts +14 -0
  46. package/dist/router.d.ts +60 -4
  47. package/dist/{server-adapter-CnQFr4P7.js → server-adapter-BWrEJbKL.js} +5 -5
  48. package/dist/server-adapter-BWrEJbKL.js.map +1 -0
  49. package/dist/{server-adapter-BD6oKEto.cjs → server-adapter-fVKP60e0.cjs} +5 -5
  50. package/dist/server-adapter-fVKP60e0.cjs.map +1 -0
  51. package/dist/shokupan.d.ts +14 -3
  52. package/dist/types.d.ts +100 -4
  53. package/dist/util/cpu-monitor.d.ts +11 -0
  54. package/dist/util/stack.d.ts +8 -0
  55. package/package.json +12 -5
  56. package/dist/openapi-analyzer-BN0wFCML.cjs.map +0 -1
  57. package/dist/openapi-analyzer-BTExMLX4.js.map +0 -1
  58. package/dist/server-adapter-BD6oKEto.cjs.map +0 -1
  59. package/dist/server-adapter-CnQFr4P7.js.map +0 -1
package/README.md CHANGED
@@ -1,33 +1,35 @@
1
1
  # Shokupan 🍞
2
2
 
3
- > A low-lift modern web framework for Bun
3
+ > A delightful, type-safe web framework for Bun
4
4
 
5
- Shokupan is a high-performance, feature-rich web framework built specifically for Bun. It combines the familiarity of Express.js with modern NestJS-style architecture (Dependency Injection, Controllers) and seamless compatibility with the vast ecosystem of Express plugins — all while maintaining exceptional performance and built-in OpenAPI support.
5
+ **Built for Developer Experience**
6
+ Shokupan is designed to make building APIs delightful again. With zero-config defaults, instant startup times, and full type safety out of the box, you can focus on building your product, not configuring your framework.
6
7
 
7
8
  ### Note: Shokupan is still in alpha and is not guaranteed to be stable. Please use with caution. We will be adding more features and APIs in the future. Please file an issue if you find any bugs or have suggestions for improvement.
8
9
 
9
10
  ## ✨ Features
10
11
 
11
- - 🚀 **Built for Bun** - Native [Bun](https://bun.sh/) performance with optimized routing
12
- - 🎯 **TypeScript First** - Full type safety with decorators and generics
13
- - 📝 **Auto OpenAPI** - Generate [OpenAPI](https://www.openapis.org/) specs automatically from routes
14
- - 🔌 **Rich Plugin System** - CORS, Sessions, Auth, Validation, Rate Limiting, and more
15
- - 🌐 **Flexible Routing** - Express-style routes or decorator-based controllers
16
- - 🔀 **Express Compatible** - Works with [Express](https://expressjs.com/) middleware patterns
17
- - 📊 **Built-in Telemetry** - [OpenTelemetry](https://opentelemetry.io/) instrumentation out of the box
18
- - 🔐 **OAuth2 Support** - GitHub, Google, Microsoft, Apple, Auth0, Okta
19
- - **Multi-validator Support** - Zod, Ajv, TypeBox, Valibot
20
- - 📚 **OpenAPI Docs** - Beautiful OpenAPI documentation with [Scalar](https://scalar.dev/)
21
- - **Short shift** - Very simple migration from [Express](https://expressjs.com/) or [NestJS](https://nestjs.com/) to Shokupan
12
+ - 🎯 **TypeScript First** - End-to-end type safety with decorators and generics. No manual types needed.
13
+ - 🛠️ **Zero Config** - Works effectively out of the box. No complex setup or boilerplate.
14
+ - 🚀 **Built for Bun** - Native [Bun](https://bun.sh/) performance with instant startup.
15
+ - 🔍 **Debug Dashboard** - Visual inspector for your routes, middleware, and request flow.
16
+ - 📝 **Auto OpenAPI** - Generate [OpenAPI](https://www.openapis.org/) specs automatically from routes.
17
+ - 🔌 **Rich Plugin System** - CORS, Sessions, Auth, Validation, Rate Limiting, and more.
18
+ - 🌐 **Flexible Routing** - Express-style routes or decorator-based controllers.
19
+ - 🔀 **Express Compatible** - Works with [Express](https://expressjs.com/) middleware patterns.
20
+ - 📊 **Built-in Telemetry** - [OpenTelemetry](https://opentelemetry.io/) instrumentation out of the box.
21
+ - 🔐 **OAuth2 Support** - GitHub, Google, Microsoft, Apple, Auth0, Okta.
22
+ - **Multi-validator Support** - Zod, Ajv, TypeBox, Valibot.
23
+ - 📚 **OpenAPI Docs** - Beautiful OpenAPI documentation with [Scalar](https://scalar.dev/).
24
+ - ⏩ **Short shift** - Very simple migration from [Express](https://expressjs.com/) or [NestJS](https://nestjs.com/) to Shokupan.
22
25
 
23
- ## 📦 Installation
26
+ ![Shokupan Debug Dashboard](docs/src/assets/debug_dashboard_overview.png)
24
27
 
25
- ```bash
26
- bun add shokupan
27
- ```
28
28
 
29
29
  ## 🚀 Quick Start
30
30
 
31
+ > Bun and TypeScript are recommended for Shokupan, though it also supports Node.js and standard JavaScript.
32
+
31
33
  ```typescript
32
34
  import { Shokupan } from 'shokupan';
33
35
 
@@ -829,6 +831,119 @@ app.mount('/docs', new ScalarPlugin({
829
831
 
830
832
  The Scalar plugin automatically generates OpenAPI documentation from your routes and controllers!
831
833
 
834
+ ### Proxy
835
+
836
+ Create a reverse proxy to forward requests to another server:
837
+
838
+ ```typescript
839
+ import { Proxy } from 'shokupan';
840
+
841
+ app.use('/api/v1', Proxy({
842
+ target: 'https://api.example.com',
843
+ changeOrigin: true,
844
+ pathRewrite: (path) => path.replace('/api/v1', ''),
845
+ headers: {
846
+ 'X-Custom-Header': 'Proxy'
847
+ }
848
+ }));
849
+
850
+ // Proxy WebSockets
851
+ app.use('/socket', Proxy({
852
+ target: 'ws://ws.example.com',
853
+ ws: true
854
+ }));
855
+ ```
856
+
857
+ ### OpenAPI Validator
858
+
859
+ Validate incoming requests against your generated OpenAPI specification:
860
+
861
+ ```typescript
862
+ import { enableOpenApiValidation } from 'shokupan';
863
+
864
+ const app = new Shokupan({ enableOpenApiGen: true });
865
+
866
+ // Enable validation middleware
867
+ // This validates Body, Query, Params, and Headers against your OpenAPI definitions
868
+ enableOpenApiValidation(app);
869
+
870
+ app.post('/users', {
871
+ parameters: [
872
+ { name: 'apiKey', in: 'header', required: true, schema: { type: 'string' } }
873
+ ],
874
+ requestBody: {
875
+ content: {
876
+ 'application/json': {
877
+ schema: {
878
+ type: 'object',
879
+ required: ['name'],
880
+ properties: {
881
+ name: { type: 'string', minLength: 3 }
882
+ }
883
+ }
884
+ }
885
+ }
886
+ }
887
+ }, (ctx) => {
888
+ return { success: true };
889
+ });
890
+
891
+ // Invalid requests will throw a ValidationError (400 Bad Request)
892
+ ```
893
+
894
+ ### Idempotency
895
+
896
+ Ensure that multiple identical requests do not result in different outcomes (e.g., duplicate payments). This middleware caches the response of the first request and returns it for subsequent requests with the same idempotency key.
897
+
898
+ ```typescript
899
+ import { Idempotency } from 'shokupan';
900
+
901
+ app.post('/payments',
902
+ Idempotency({
903
+ header: 'Idempotency-Key', // default
904
+ ttl: 24 * 60 * 60 * 1000 // default 24h
905
+ }),
906
+ async (ctx) => {
907
+ // Process payment...
908
+ return { status: 'charged' };
909
+ }
910
+ );
911
+ ```
912
+
913
+ ### Failed Request Recorder
914
+
915
+ Automatically record failed requests (500s) for debugging and replay purposes.
916
+
917
+ ```typescript
918
+ import { FailedRequestRecorder } from 'shokupan';
919
+
920
+ app.use(FailedRequestRecorder({
921
+ maxCapacity: 1000,
922
+ ttl: 86400000 // 1 day
923
+ }));
924
+ ```
925
+
926
+ This works great when combined with the Debug Dashboard.
927
+
928
+ ### Debug Dashboard
929
+
930
+ A visual dashboard to inspect your application, view metrics, analyze the middleware graph, and replay failed requests.
931
+
932
+ ```typescript
933
+ import { DebugDashboard } from 'shokupan/plugins/debugview';
934
+
935
+ // Mount the dashboard
936
+ app.mount('/debug', new DebugDashboard({
937
+ retentionMs: 2 * 60 * 60 * 1000, // Keep 2 hours of logs
938
+ getRequestHeaders: () => ({
939
+ 'Authorization': 'Bearer ...' // Headers to using when replaying requests and accessing data APIs
940
+ })
941
+ }));
942
+
943
+ // Available at http://localhost:3000/debug
944
+ ```
945
+
946
+
832
947
  ## 🚀 Advanced Features
833
948
 
834
949
  ### Dependency Injection
@@ -999,8 +1114,40 @@ provider.addSpanProcessor(
999
1114
  provider.register();
1000
1115
  ```
1001
1116
 
1117
+ ### Server Factory (Node.js & Deno)
1118
+
1119
+ Run Shokupan on Node.js or Deno using the server adapter:
1120
+
1121
+ ```typescript
1122
+ import { Shokupan, createHttpServer } from 'shokupan';
1123
+
1124
+ const app = new Shokupan({
1125
+ // Use Node.js http module
1126
+ serverFactory: createHttpServer()
1127
+ });
1128
+
1129
+ app.get('/', () => ({ message: 'Running on Node!' }));
1130
+
1131
+ app.listen(3000);
1132
+ ```
1133
+
1134
+ ### Automatic Backpressure
1135
+
1136
+ Protect your server from overload by shedding load when CPU usage is high:
1137
+
1138
+ ```typescript
1139
+ const app = new Shokupan({
1140
+ // Monitor CPU and reject requests when usage > 80%
1141
+ autoBackpressureFeedback: true,
1142
+ autoBackpressureLevel: 80
1143
+ });
1144
+ ```
1145
+
1146
+ When the threshold is reached, the server will return `429 Too Many Requests`.
1147
+
1002
1148
  ## 📦 Migration Guides
1003
1149
 
1150
+
1004
1151
  ### From Express
1005
1152
 
1006
1153
  Shokupan is designed to feel familiar to Express developers. Here's how to migrate:
@@ -1397,6 +1544,10 @@ app.use(useExpress(compression()));
1397
1544
  ## 🧪 Testing
1398
1545
 
1399
1546
  Shokupan applications are easy to test using Bun's built-in test runner.
1547
+ It can directly pass requests to the application or a router without requiring the
1548
+ server to fully start, bind to a port or listen for connections. This makes mocking
1549
+ the server unnecessary and allows for faster and more reliable testing. Additionally
1550
+ you can directly test authenticated endpoints without the need for a session or cookie.
1400
1551
 
1401
1552
  ```typescript
1402
1553
  import { describe, it, expect } from 'bun:test';
@@ -1427,13 +1578,13 @@ Since Shokupan is built on Bun, deployment is straightforward.
1427
1578
  ### Using Bun
1428
1579
 
1429
1580
  ```bash
1430
- bun run src/index.ts
1581
+ bun run src/main.ts
1431
1582
  ```
1432
1583
 
1433
1584
  ### Docker
1434
1585
 
1435
1586
  ```dockerfile
1436
- FROM oven/bun:1
1587
+ FROM oven/bun:1-alpine
1437
1588
 
1438
1589
  WORKDIR /app
1439
1590
 
@@ -1442,7 +1593,7 @@ RUN bun install --production
1442
1593
 
1443
1594
  EXPOSE 3000
1444
1595
 
1445
- CMD ["bun", "run", "src/index.ts"]
1596
+ CMD ["bun", "run", "src/main.ts"]
1446
1597
  ```
1447
1598
 
1448
1599
  ## 🛠️ CLI Tools
@@ -1530,6 +1681,14 @@ const app = new Shokupan(config?: ShokupanConfig);
1530
1681
  - `hostname?: string` - Hostname (default: "localhost")
1531
1682
  - `development?: boolean` - Development mode (default: auto-detect)
1532
1683
  - `enableAsyncLocalStorage?: boolean` - Enable async context tracking
1684
+ - `enableTracing?: boolean` - Enable OpenTelemetry tracing
1685
+ - `enableOpenApiGen?: boolean` - Enable OpenAPI spec generation (default: true)
1686
+ - `controllersOnly?: boolean` - If true, only allows controllers, disabling app.get/post/etc (default: false)
1687
+ - `requestTimeout?: number` - Global request timeout (ms)
1688
+ - `readTimeout?: number` - Request body read timeout (ms)
1689
+ - `serverFactory?: ServerFactory` - Custom server factory (for Node.js/Deno support)
1690
+ - `autoBackpressureFeedback?: boolean` - Enable automatic load shedding based on CPU usage
1691
+ - `autoBackpressureLevel?: number` - CPU usage % threshold for backpressure (default: 60)
1533
1692
  - `logger?: Logger` - Custom logger instance
1534
1693
 
1535
1694
  **Methods:**
@@ -1551,7 +1710,13 @@ const app = new Shokupan(config?: ShokupanConfig);
1551
1710
 
1552
1711
  ### ShokupanRouter Class
1553
1712
 
1554
- Router for grouping routes.
1713
+ Router for grouping operations, applying middleware, and mounting controllers. Additionally
1714
+ they are effective for creating sub-applications that are independently tested. Routers can
1715
+ have OpenAPI spec applied to all endpoints of the router. Additionally they can be mounted
1716
+ onto the main application or other routers.
1717
+
1718
+ When a router is mounted to an app, if you are using the DebugView plugin you will be able to
1719
+ see it under the Registry tab and the Graph tab.
1555
1720
 
1556
1721
  ```typescript
1557
1722
  const router = new ShokupanRouter(config?: ShokupanRouteConfig);
@@ -1592,6 +1757,13 @@ Request context object.
1592
1757
  - `state: Record<string, any>` - Shared state object
1593
1758
  - `session: any` - Session data (with session plugin)
1594
1759
  - `response: ShokupanResponse` - Response builder
1760
+ - `ip: string` - Client IP address
1761
+ - `hostname: string` - Hostname (e.g. "localhost")
1762
+ - `host: string` - Host (e.g. "localhost:3000")
1763
+ - `protocol: string` - Protocol (http/https)
1764
+ - `secure: boolean` - Whether the request is secure over HTTPS
1765
+ - `origin: string` - Origin URL
1766
+ - `signal: AbortSignal` - Request abort signal (for standard fetch requests)
1595
1767
 
1596
1768
  **Methods:**
1597
1769
  - `set(name: string, value: string): ShokupanContext` - Set a response header
@@ -1602,6 +1774,7 @@ Request context object.
1602
1774
  - `json(data: any, status?: number): ShokupanContext` - Return JSON response
1603
1775
  - `text(data: string, status?: number): ShokupanContext` - Return text response
1604
1776
  - `html(data: string, status?: number): ShokupanContext` - Return HTML response
1777
+ - `jsx(element: any): ShokupanContext` - Render a JSX element
1605
1778
  - `redirect(url: string, status?: number): ShokupanContext` - Redirect response
1606
1779
  - `file(path: string, fileOptions?: BlobPropertyBag, responseOptions?: ResponseInit): Response` - Return file response
1607
1780
 
@@ -1639,7 +1812,6 @@ Container.clear();
1639
1812
  - 🚧 **Framework Plugins** - Drop-in adapters for [Express](https://expressjs.com/), [Koa](https://koajs.com/), and [Elysia](https://elysiajs.com/)
1640
1813
  - 🚧 **Enhanced WebSockets** - Event support and HTTP simulation
1641
1814
  - 🚧 **Benchmarks** - Comprehensive performance comparisons
1642
- - 🚧 **Scaling** - Automatic clustering support
1643
1815
  - 🚧 **RPC Support** - [tRPC](https://trpc.io/) and [gRPC](https://grpc.io/) integration
1644
1816
  - 🚧 **Binary Formats** - [Protobuf](https://protobuf.dev/) and [MessagePack](https://msgpack.org/) support
1645
1817
  - 🚧 **Reliability** - Circuit breaker pattern for resilience
@@ -1652,7 +1824,7 @@ Contributions are welcome! Please feel free to submit a Pull Request.
1652
1824
  1. Fork the repository
1653
1825
  2. Create your feature branch (`git checkout -b feature/amazing-feature`)
1654
1826
  3. Commit your changes (`git commit -m 'Add some amazing feature'`)
1655
- 4. Push to the branch (`git push origin feature/amazing-feature`)
1827
+ 4. Publish the branch (`git push origin feature/amazing-feature`)
1656
1828
  5. Open a Pull Request
1657
1829
 
1658
1830
  ## 📝 License
@@ -1664,7 +1836,8 @@ MIT License - see the [LICENSE](LICENSE) file for details.
1664
1836
  - Inspired by [Express](https://expressjs.com/), [Koa](https://koajs.com/), [NestJS](https://nestjs.com/), and [Elysia](https://elysiajs.com/)
1665
1837
  - Built for the amazing [Bun](https://bun.sh/) runtime
1666
1838
  - Powered by [Arctic](https://github.com/pilcrowonpaper/arctic) for OAuth2 support
1839
+ - Tests and Benchmarks created with Antigravity
1667
1840
 
1668
1841
  ---
1669
1842
 
1670
- **Made with 🍞 by the Shokupan team**
1843
+ **Made with ❤️ by the Shokupan team**
@@ -0,0 +1 @@
1
+ export declare function startAdvanced(port: number, scenario: string): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function startAdvanced(port: number, scenario: string): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function startAdvanced(port: number, scenario: string): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function startAdvanced(port: number, scenario: string): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function startAdvanced(port: number, scenario: string): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function startAdvanced(port: number, scenario: string): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function startAdvanced(port: number, scenario: string): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function startAdvanced(port: number, scenario: string): Promise<() => Promise<void>>;
@@ -0,0 +1,33 @@
1
+ export declare const LARGE_JSON: {
2
+ total: number;
3
+ items: any[];
4
+ metadata: {
5
+ generated: string;
6
+ size: string;
7
+ purpose: string;
8
+ };
9
+ };
10
+ export declare const LARGE_REQUEST_BODY: string;
11
+ export declare const LARGE_HEADERS: Record<string, string>;
12
+ /**
13
+ * Calculate MD5 hash of a string
14
+ */
15
+ export declare function md5(input: string): string;
16
+ /**
17
+ * Serialize request data for hashing
18
+ */
19
+ export declare function serializeRequest(url: string, headers: Record<string, string>, body: string): string;
20
+ /**
21
+ * Get the actual byte size of the LARGE_JSON
22
+ */
23
+ export declare function getLargeJSONSize(): number;
24
+ /**
25
+ * Smaller compressible response (100KB) for compression testing
26
+ */
27
+ export declare const COMPRESSIBLE_JSON: {
28
+ data: {
29
+ id: number;
30
+ text: string;
31
+ timestamp: string;
32
+ }[];
33
+ };
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1 @@
1
+ export declare function start(port: number): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function start(port: number): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function start(port: number): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function start(port: number): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function start(port: number): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function start(port: number): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function start(port: number): Promise<() => Promise<void>>;
@@ -0,0 +1 @@
1
+ export declare function start(port: number): Promise<() => Promise<void>>;
@@ -0,0 +1,15 @@
1
+ export declare const MEDIUM_JSON: {
2
+ id: number;
3
+ name: string;
4
+ timestamp: string;
5
+ tags: string[];
6
+ nested: {
7
+ layer1: {
8
+ layer2: {
9
+ value: string;
10
+ numbers: number[];
11
+ };
12
+ };
13
+ };
14
+ description: string;
15
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1 @@
1
+ export {};
package/dist/cli.cjs CHANGED
@@ -4,7 +4,7 @@ const p = require("@clack/prompts");
4
4
  const fs = require("node:fs");
5
5
  const path = require("node:path");
6
6
  const promises = require("node:timers/promises");
7
- const openapiAnalyzer = require("./openapi-analyzer-BN0wFCML.cjs");
7
+ const openapiAnalyzer = require("./openapi-analyzer-D9YB3IkV.cjs");
8
8
  function _interopNamespaceDefault(e) {
9
9
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
10
10
  if (e) {
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import * as p from "@clack/prompts";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { setTimeout } from "node:timers/promises";
6
- import { analyzeDirectory } from "./openapi-analyzer-BTExMLX4.js";
6
+ import { analyzeDirectory } from "./openapi-analyzer-BtIaHIfe.js";
7
7
  const templates = {
8
8
  controller: (name) => `import { Controller, Get, Ctx } from 'shokupan';
9
9
  import { ShokupanContext } from 'shokupan';
package/dist/context.d.ts CHANGED
@@ -9,18 +9,30 @@ export interface HandlerStackItem {
9
9
  file: string;
10
10
  line: number;
11
11
  stateChanges?: Record<string, any>;
12
+ startTime?: number;
13
+ duration?: number;
14
+ }
15
+ export interface DebugCollector {
16
+ trackStep(id: string | undefined, type: string, duration: number, status: 'success' | 'error', error?: any): void;
17
+ trackEdge(fromId: string | undefined, toId: string | undefined): void;
18
+ setNode(id: string): void;
19
+ getCurrentNode(): string | undefined;
12
20
  }
13
21
  export declare class ShokupanContext<State extends Record<string, any> = Record<string, any>> {
14
22
  readonly request: ShokupanRequest<any>;
15
- readonly server?: Server;
23
+ readonly server?: Server<any>;
16
24
  readonly app?: Shokupan;
25
+ readonly signal?: AbortSignal;
17
26
  private _url;
18
27
  params: Record<string, string>;
19
28
  state: State;
20
29
  handlerStack: HandlerStackItem[];
21
30
  readonly response: ShokupanResponse;
31
+ _debug?: DebugCollector;
22
32
  _finalResponse?: Response;
23
- constructor(request: ShokupanRequest<any>, server?: Server, state?: State, app?: Shokupan, enableMiddlewareTracking?: boolean);
33
+ _rawBody?: string | ArrayBuffer | Uint8Array;
34
+ constructor(request: ShokupanRequest<any>, server?: Server<any>, state?: State, app?: Shokupan, signal?: AbortSignal, // Optional as it might not be provided in tests or simple creates
35
+ enableMiddlewareTracking?: boolean);
24
36
  get url(): URL;
25
37
  /**
26
38
  * Base request
@@ -37,13 +49,11 @@ export declare class ShokupanContext<State extends Record<string, any> = Record<
37
49
  /**
38
50
  * Request query params
39
51
  */
40
- get query(): {
41
- [k: string]: string;
42
- };
52
+ get query(): Record<string, any>;
43
53
  /**
44
54
  * Client IP address
45
55
  */
46
- get ip(): Bun.SocketAddress;
56
+ get ip(): any;
47
57
  /**
48
58
  * Request hostname (e.g. "localhost")
49
59
  */
@@ -126,7 +136,7 @@ export declare class ShokupanContext<State extends Record<string, any> = Record<
126
136
  /**
127
137
  * Respond with a file
128
138
  */
129
- file(path: string, fileOptions?: BlobPropertyBag, responseOptions?: ResponseInit): Response;
139
+ file(path: string, fileOptions?: BlobPropertyBag, responseOptions?: ResponseInit): Promise<Response>;
130
140
  /**
131
141
  * JSX Rendering Function
132
142
  */
@@ -1,3 +1,4 @@
1
+ import { RateLimitOptions } from './plugins/rate-limit';
1
2
  import { GuardAPISpec, MethodAPISpec, Middleware } from './types';
2
3
  /**
3
4
  * Class Decorator: Defines the base path for a controller.
@@ -7,21 +8,67 @@ export declare function Controller(path?: string): (target: any) => void;
7
8
  * Decorator: Applies middleware to a class or method.
8
9
  */
9
10
  export declare function Use(...middleware: Middleware[]): (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => void;
11
+ /**
12
+ * Decorator: Binds a parameter to the request body.
13
+ */
10
14
  export declare const Body: (name?: string) => (target: any, propertyKey: string, parameterIndex: number) => void;
15
+ /**
16
+ * Decorator: Binds a parameter to the request parameters.
17
+ */
11
18
  export declare const Param: (name?: string) => (target: any, propertyKey: string, parameterIndex: number) => void;
19
+ /**
20
+ * Decorator: Binds a parameter to the request query string.
21
+ */
12
22
  export declare const Query: (name?: string) => (target: any, propertyKey: string, parameterIndex: number) => void;
23
+ /**
24
+ * Decorator: Binds a parameter to the request headers.
25
+ */
13
26
  export declare const Headers: (name?: string) => (target: any, propertyKey: string, parameterIndex: number) => void;
27
+ /**
28
+ * Decorator: Binds a parameter to the request object.
29
+ */
14
30
  export declare const Req: (name?: string) => (target: any, propertyKey: string, parameterIndex: number) => void;
31
+ /**
32
+ * Decorator: Binds a parameter to the request context.
33
+ */
15
34
  export declare const Ctx: (name?: string) => (target: any, propertyKey: string, parameterIndex: number) => void;
16
35
  /**
17
36
  * Decorator: Overrides the OpenAPI specification for a route.
18
37
  */
19
38
  export declare function Spec(spec: MethodAPISpec | GuardAPISpec): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
39
+ /**
40
+ * Decorator: Binds a method to the GET HTTP verb.
41
+ */
20
42
  export declare const Get: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
43
+ /**
44
+ * Decorator: Binds a method to the POST HTTP verb.
45
+ */
21
46
  export declare const Post: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
47
+ /**
48
+ * Decorator: Binds a method to the PUT HTTP verb.
49
+ */
22
50
  export declare const Put: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
51
+ /**
52
+ * Decorator: Binds a method to the DELETE HTTP verb.
53
+ */
23
54
  export declare const Delete: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
55
+ /**
56
+ * Decorator: Binds a method to the PATCH HTTP verb.
57
+ */
24
58
  export declare const Patch: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
59
+ /**
60
+ * Decorator: Binds a method to the OPTIONS HTTP verb.
61
+ */
25
62
  export declare const Options: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
63
+ /**
64
+ * Decorator: Binds a method to the HEAD HTTP verb.
65
+ */
26
66
  export declare const Head: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
67
+ /**
68
+ * Decorator: Binds a method to ANY HTTP verb.
69
+ */
27
70
  export declare const All: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
71
+ /**
72
+ * Decorator: Applies a rate limit to a class or method.
73
+ */
74
+ export declare function RateLimit(options: RateLimitOptions): (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => void;