shokupan 0.11.0 → 0.13.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 (65) hide show
  1. package/README.md +47 -1815
  2. package/dist/{analyzer-CnKnQ5KV.js → analyzer-B0fMzeIo.js} +2 -2
  3. package/dist/{analyzer-CnKnQ5KV.js.map → analyzer-B0fMzeIo.js.map} +1 -1
  4. package/dist/{analyzer-BAhvpNY_.cjs → analyzer-BOtveWL-.cjs} +2 -2
  5. package/dist/{analyzer-BAhvpNY_.cjs.map → analyzer-BOtveWL-.cjs.map} +1 -1
  6. package/dist/{analyzer.impl-CfpMu4-g.cjs → analyzer.impl-CUDO6vpn.cjs} +82 -7
  7. package/dist/analyzer.impl-CUDO6vpn.cjs.map +1 -0
  8. package/dist/{analyzer.impl-DCiqlXI5.js → analyzer.impl-DmHe92Oi.js} +82 -7
  9. package/dist/analyzer.impl-DmHe92Oi.js.map +1 -0
  10. package/dist/cli.cjs +1 -1
  11. package/dist/cli.js +1 -1
  12. package/dist/context.d.ts +40 -8
  13. package/dist/index.cjs +2876 -506
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.js +2911 -541
  17. package/dist/index.js.map +1 -1
  18. package/dist/plugins/application/api-explorer/static/theme.css +4 -0
  19. package/dist/plugins/application/auth.d.ts +5 -0
  20. package/dist/plugins/application/dashboard/fetch-interceptor.d.ts +12 -0
  21. package/dist/plugins/application/dashboard/plugin.d.ts +9 -0
  22. package/dist/plugins/application/dashboard/static/requests.js +537 -251
  23. package/dist/plugins/application/dashboard/static/tabulator.css +23 -3
  24. package/dist/plugins/application/dashboard/static/theme.css +4 -0
  25. package/dist/plugins/application/error-view/index.d.ts +14 -0
  26. package/dist/plugins/application/error-view/monkeypatch.d.ts +9 -0
  27. package/dist/plugins/application/error-view/util/source-reader.d.ts +10 -0
  28. package/dist/plugins/application/error-view/views/error.d.ts +2 -0
  29. package/dist/plugins/application/error-view/views/status.d.ts +2 -0
  30. package/dist/plugins/application/htmx/index.d.ts +39 -0
  31. package/dist/plugins/application/mcp-server/plugin.d.ts +38 -0
  32. package/dist/plugins/application/openapi/analyzer.impl.d.ts +4 -0
  33. package/dist/plugins/application/openapi/test-setup.d.ts +1 -0
  34. package/dist/plugins/application/opentelemetry/index.d.ts +33 -0
  35. package/dist/plugins/middleware/compression.d.ts +12 -2
  36. package/dist/plugins/middleware/rate-limit.d.ts +5 -0
  37. package/dist/plugins/middleware/session.d.ts +4 -4
  38. package/dist/plugins/resilience/decorators.d.ts +23 -0
  39. package/dist/plugins/resilience/factory.d.ts +5 -0
  40. package/dist/plugins/resilience/index.d.ts +2 -0
  41. package/dist/router.d.ts +25 -9
  42. package/dist/server.d.ts +22 -0
  43. package/dist/shokupan.d.ts +24 -1
  44. package/dist/util/adapter/bun.d.ts +8 -0
  45. package/dist/util/adapter/index.d.ts +4 -0
  46. package/dist/util/adapter/interface.d.ts +12 -0
  47. package/dist/util/adapter/node.d.ts +8 -0
  48. package/dist/util/adapter/wintercg.d.ts +5 -0
  49. package/dist/util/body-parser.d.ts +30 -0
  50. package/dist/util/decorators.d.ts +58 -3
  51. package/dist/util/di.d.ts +3 -8
  52. package/dist/util/env-loader.d.ts +99 -0
  53. package/dist/util/mcp-protocol.d.ts +52 -0
  54. package/dist/util/metadata.d.ts +18 -0
  55. package/dist/util/promise.d.ts +16 -0
  56. package/dist/util/request.d.ts +1 -0
  57. package/dist/util/symbol.d.ts +5 -0
  58. package/dist/util/types.d.ts +140 -3
  59. package/package.json +37 -10
  60. package/dist/analyzer.impl-CfpMu4-g.cjs.map +0 -1
  61. package/dist/analyzer.impl-DCiqlXI5.js.map +0 -1
  62. package/dist/plugins/application/dashboard/static/failures.js +0 -85
  63. package/dist/plugins/application/http-server.d.ts +0 -13
  64. package/dist/util/adapter/adapters.d.ts +0 -19
  65. package/dist/util/instrumentation.d.ts +0 -9
@@ -16,6 +16,21 @@
16
16
  font-weight: bold;
17
17
  }
18
18
 
19
+ .tabulator-menu .tabulator-menu-separator {
20
+ border-color: var(--card-border);
21
+ }
22
+
23
+ .tabulator-popup-container {
24
+ background-color: var(--bg-card);
25
+ border: 1px solid var(--card-border);
26
+ border-radius: 4px;
27
+ color: var(--text-primary);
28
+ }
29
+
30
+ .tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover {
31
+ background-color: var(--bg-primary);
32
+ }
33
+
19
34
  .tabulator .tabulator-header .tabulator-col {
20
35
  background-color: var(--bg-card);
21
36
  border-right: 1px solid var(--card-border);
@@ -58,6 +73,7 @@
58
73
  border-bottom: 1px solid var(--card-border);
59
74
  color: var(--text-primary);
60
75
  transition: background-color 100ms ease;
76
+ min-height: unset !important;
61
77
  }
62
78
 
63
79
  /* Higher specificity to override Tabulator default themes */
@@ -72,12 +88,12 @@
72
88
  }
73
89
 
74
90
  .tabulator .tabulator-row.tabulator-selected {
75
- background-color: var(--bg-primary) !important;
91
+ background-color: var(--table-row-selected-color) !important;
76
92
  color: var(--text-primary);
77
93
  }
78
94
 
79
95
  .tabulator .tabulator-row:hover {
80
- background-color: var(--bg-primary) !important;
96
+ background-color: var(--table-row-hover-color) !important;
81
97
  color: var(--text-primary);
82
98
  cursor: pointer;
83
99
  }
@@ -85,7 +101,7 @@
85
101
  /* Cells */
86
102
  .tabulator .tabulator-row .tabulator-cell {
87
103
  border-right: 1px solid var(--card-border);
88
- padding: 10px;
104
+ padding: 6px;
89
105
  align-content: center;
90
106
  }
91
107
 
@@ -115,4 +131,8 @@
115
131
  /* Sorting Icons */
116
132
  .tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow {
117
133
  border-bottom-color: var(--text-secondary);
134
+ }
135
+
136
+ .tabulator [tabulator-field="timestamp"] {
137
+ padding: 0 4px !important;
118
138
  }
@@ -24,6 +24,7 @@
24
24
 
25
25
  --text-primary: #F0F0F0;
26
26
  --text-secondary: var(--palette-dark-accent);
27
+ --text-flavor: #ffcc80;
27
28
  --text-muted: rgba(214, 211, 209, 0.5);
28
29
 
29
30
  --primary: var(--palette-dark-primary);
@@ -34,12 +35,15 @@
34
35
  --card-border: rgba(214, 211, 209, 0.2);
35
36
 
36
37
  --table-header-border-color: rgba(214, 211, 209, 0.2);
38
+ --table-row-hover-color: #382818;
39
+ --table-row-selected-color: #48331e;
37
40
 
38
41
  --link-color: var(--palette-dark-primary);
39
42
  --link-hover: #FFCBA0;
40
43
 
41
44
  --button-bg: var(--palette-dark-primary);
42
45
  --button-text: #1A1614;
46
+
43
47
  }
44
48
 
45
49
  * {
@@ -0,0 +1,14 @@
1
+ import { Shokupan } from '../../../shokupan';
2
+ import { ShokupanPlugin } from '../../../util/types';
3
+ export interface ErrorViewConfig {
4
+ /**
5
+ * Theme for syntax highlighting (default 'dark')
6
+ */
7
+ theme?: 'light' | 'dark';
8
+ }
9
+ export declare class ErrorView implements ShokupanPlugin {
10
+ private config;
11
+ name: string;
12
+ constructor(config?: ErrorViewConfig);
13
+ onInit(app: Shokupan): Promise<void>;
14
+ }
@@ -0,0 +1,9 @@
1
+ declare global {
2
+ interface Error {
3
+ timestamp?: number;
4
+ id?: string;
5
+ scope?: any;
6
+ structuredStack?: NodeJS.CallSite[];
7
+ }
8
+ }
9
+ export declare function applyMonkeyPatch(): void;
@@ -0,0 +1,10 @@
1
+ export interface SourceContext {
2
+ lines: {
3
+ line: number;
4
+ code: string;
5
+ isTarget: boolean;
6
+ }[];
7
+ startLine: number;
8
+ file: string;
9
+ }
10
+ export declare function readSourceContext(filePath: string | undefined, line: number, contextLines?: number): Promise<SourceContext | null>;
@@ -0,0 +1,2 @@
1
+ import { ShokupanContext } from '../../../../context';
2
+ export declare function renderErrorView(ctx: ShokupanContext, error: any): Promise<string>;
@@ -0,0 +1,2 @@
1
+ import { ShokupanContext } from '../../../../context';
2
+ export declare function renderStatusView(ctx: ShokupanContext, status: number, error: Error): string;
@@ -0,0 +1,39 @@
1
+ import { Shokupan } from '../../../shokupan';
2
+ import { Middleware, ShokupanPlugin } from '../../../util/types';
3
+ /**
4
+ * Extends the ShokupanContext interface with HTMX specific helpers.
5
+ */
6
+ declare module "../../../context" {
7
+ interface ShokupanContext {
8
+ /**
9
+ * Checks if the request is an HTMX request.
10
+ */
11
+ isHtmx: boolean;
12
+ /**
13
+ * Checks if the request is boosting.
14
+ */
15
+ isHtmxBoosted: boolean;
16
+ /**
17
+ * Sets the HX-Trigger header.
18
+ */
19
+ trigger(event: string | Record<string, any>, options?: {
20
+ after?: 'receive' | 'settle' | 'swap';
21
+ }): void;
22
+ /**
23
+ * Sets the HX-Push-Url header.
24
+ */
25
+ pushUrl(url: string | false): void;
26
+ /**
27
+ * Sets the HX-Redirect header.
28
+ */
29
+ htmxRedirect(url: string): void;
30
+ /**
31
+ * Sets the HX-Refresh header.
32
+ */
33
+ refresh(): void;
34
+ }
35
+ }
36
+ export declare class HtmxPlugin implements ShokupanPlugin {
37
+ onInit(app: Shokupan): Promise<void>;
38
+ middleware(): Middleware;
39
+ }
@@ -0,0 +1,38 @@
1
+ import { Shokupan } from '../../../shokupan';
2
+ import { ShokupanPlugin } from '../../../util/types';
3
+ export interface MCPServerPluginOptions {
4
+ /**
5
+ * The path to mount the MCP server to.
6
+ */
7
+ path?: string;
8
+ /**
9
+ * The root directory to scan for OpenAPI documents.
10
+ */
11
+ rootDir?: string;
12
+ /**
13
+ * Whether to allow the introspection tool.
14
+ */
15
+ allowIntrospection?: boolean;
16
+ /**
17
+ * Whether to allow tool execution.
18
+ */
19
+ allowToolExecution?: boolean;
20
+ }
21
+ /**
22
+ * Attaches an MCP server to the application.
23
+ * This MCP server is focus-designed to provide introspection and tool execution capabilities.
24
+ *
25
+ * If your application design requires anything custom, implement your own MCP server.
26
+ */
27
+ export declare class MCPServerPlugin implements ShokupanPlugin {
28
+ private options;
29
+ private router;
30
+ private analyzer;
31
+ constructor(options?: MCPServerPluginOptions);
32
+ onInit(app: Shokupan): void;
33
+ private collectAppMcpItems;
34
+ private setupRoutes;
35
+ private registerTools;
36
+ private registerResources;
37
+ private registerPrompts;
38
+ }
@@ -109,6 +109,10 @@ export declare class OpenAPIAnalyzer {
109
109
  /**
110
110
  * Main analysis entry point
111
111
  */
112
+ /**
113
+ * Main analysis entry point
114
+ */
115
+ private cachedResult?;
112
116
  /**
113
117
  * Main analysis entry point
114
118
  */
@@ -0,0 +1 @@
1
+ export declare function getSharedSpec(): Promise<any>;
@@ -0,0 +1,33 @@
1
+ import { Shokupan } from '../../../shokupan';
2
+ import { Middleware, ShokupanHandler, ShokupanPlugin } from '../../../util/types';
3
+ export interface OpenTelemetryOptions {
4
+ /**
5
+ * Service name for traces
6
+ */
7
+ serviceName?: string;
8
+ /**
9
+ * Enable auto-instrumentation
10
+ * @default true
11
+ */
12
+ enableAutoInstrumentation?: boolean;
13
+ /**
14
+ * OTLP Endpoint (e.g. http://localhost:4318)
15
+ */
16
+ otlpEndpoint?: string;
17
+ }
18
+ export declare class OpenTelemetryPlugin implements ShokupanPlugin {
19
+ private options;
20
+ private api;
21
+ private sdk;
22
+ constructor(options?: OpenTelemetryOptions);
23
+ onInit(app: Shokupan): Promise<void>;
24
+ middleware(): Middleware;
25
+ }
26
+ /**
27
+ * Wraps a middleware function with an OpenTelemetry span.
28
+ */
29
+ export declare function traceMiddleware(fn: Middleware, name?: string): Middleware;
30
+ /**
31
+ * Wraps a route handler with an OpenTelemetry span.
32
+ */
33
+ export declare function traceHandler(fn: ShokupanHandler | ((...args: any[]) => any), name: string): ShokupanHandler;
@@ -1,13 +1,23 @@
1
1
  import { Middleware } from '../../util/types';
2
2
  export interface CompressionOptions {
3
3
  /**
4
- * Minimum byte size to compress
4
+ * Minimum byte size to compress responses
5
5
  */
6
6
  threshold?: number;
7
7
  /**
8
- * Allowed algorithms
8
+ * Allowed algorithms for response compression
9
9
  */
10
10
  allowedAlgorithms?: string[];
11
+ /**
12
+ * Enable request decompression
13
+ * @default true
14
+ */
15
+ decompress?: boolean;
16
+ /**
17
+ * Maximum size of decompressed request body in bytes to prevent zipbomb style attacks
18
+ * @default 10485760 (10MB)
19
+ */
20
+ maxDecompressedSize?: number;
11
21
  }
12
22
  /**
13
23
  * Compression middleware.
@@ -49,6 +49,11 @@ export interface RateLimitOptions {
49
49
  * List of trusted proxy IPs
50
50
  */
51
51
  trustedProxies?: string[];
52
+ /**
53
+ * Interval in milliseconds to clean up expired entries.
54
+ * Defaults to windowMs.
55
+ */
56
+ cleanupInterval?: number;
52
57
  }
53
58
  /**
54
59
  * Rate limit middleware.
@@ -148,10 +148,10 @@ export declare class MemoryStore extends EventEmitter implements Store {
148
148
  export interface SessionContext {
149
149
  session: SessionData & {
150
150
  id: string;
151
- regenerate(callback: (err: any) => void): void;
152
- destroy(callback: (err: any) => void): void;
153
- reload(callback: (err: any) => void): void;
154
- save(callback: (err: any) => void): void;
151
+ regenerate(): Promise<void>;
152
+ destroy(): Promise<void>;
153
+ reload(): Promise<void>;
154
+ save(): Promise<void>;
155
155
  touch(): void;
156
156
  };
157
157
  sessionID: string;
@@ -0,0 +1,23 @@
1
+ export interface RetryOptions {
2
+ attempts?: number;
3
+ backoff?: 'constant' | 'exponential';
4
+ delay?: number;
5
+ maxDelay?: number;
6
+ }
7
+ export interface CircuitBreakerOptions {
8
+ threshold?: number;
9
+ windowDuration?: number;
10
+ resetTimeout?: number;
11
+ }
12
+ export interface ResilienceConfig {
13
+ retry?: RetryOptions;
14
+ circuitBreaker?: CircuitBreakerOptions;
15
+ timeout?: number;
16
+ bulkhead?: number;
17
+ fallback?: any | ((...args: any[]) => any);
18
+ }
19
+ export declare function Retry(options?: RetryOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
20
+ export declare function CircuitBreaker(options?: CircuitBreakerOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
21
+ export declare function Timeout(duration: number): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
22
+ export declare function Bulkhead(limit: number): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
23
+ export declare function Fallback(valueOrFn: any): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
@@ -0,0 +1,5 @@
1
+ import { IPolicy } from 'cockatiel';
2
+ import { ResilienceConfig } from './decorators';
3
+ export declare class ResilienceFactory {
4
+ static createPolicy(config: ResilienceConfig): IPolicy;
5
+ }
@@ -0,0 +1,2 @@
1
+ export * from './decorators';
2
+ export * from './factory';
package/dist/router.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ShokupanContext } from './context';
2
2
  import { Shokupan } from './shokupan';
3
- import { SurrealDatastore } from './util/datastore';
3
+ import { McpProtocol, McpPrompt } from './util/mcp-protocol';
4
4
  import { $appRoot, $childControllers, $childRouters, $isApplication, $isMounted, $isRouter, $mountPath, $parent, $routes } from './util/symbol';
5
5
  import { GuardAPISpec, HeadersInit, JSXRenderer, Method, MethodAPISpec, Middleware, OpenAPIOptions, ProcessResult, RequestOptions, RouteMetadata, RouteParams, ShokupanController, ShokupanHandler, ShokupanHooks, ShokupanRoute, ShokupanRouteConfig, StaticServeOptions } from './util/types';
6
6
  export declare const RouterRegistry: Map<string, ShokupanRouter<any>>;
@@ -95,7 +95,6 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
95
95
  get hasBeforeValidateHook(): boolean;
96
96
  get hasAfterValidateHook(): boolean;
97
97
  requestTimeout?: number;
98
- get db(): SurrealDatastore | undefined;
99
98
  private hookCache;
100
99
  private hooksInitialized;
101
100
  middleware: Middleware[];
@@ -106,12 +105,14 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
106
105
  development: boolean;
107
106
  enableAsyncLocalStorage: boolean;
108
107
  enableOpenApiGen: boolean;
108
+ enablePromiseMonkeypatch: boolean;
109
109
  blockOnOpenApiGen: boolean;
110
110
  enableAsyncApiGen: boolean;
111
111
  blockOnAsyncApiGen: boolean;
112
112
  reusePort: boolean;
113
113
  controllersOnly: boolean;
114
114
  enableTracing?: boolean;
115
+ queryParserMode?: "extended" | "simple" | "strict";
115
116
  jsonParser?: "native" | "parse-json" | "secure-json-parse";
116
117
  autoBackpressureFeedback?: boolean;
117
118
  autoBackpressureLevel?: number;
@@ -131,11 +132,12 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
131
132
  fatal: (msg: string, props: Record<string, any>) => void;
132
133
  };
133
134
  readTimeout: number;
135
+ maxBodySize?: number;
134
136
  requestTimeout: number;
135
137
  writeTimeout: number;
136
138
  renderer: JSXRenderer;
137
139
  serverFactory: import('.').ServerFactory;
138
- adapter?: "bun" | "node" | "wintercg" | import('./util/adapter/adapters').ServerAdapter;
140
+ adapter?: "bun" | "node" | "wintercg" | import('./util/adapter').ServerAdapter;
139
141
  fileSystem?: import('./util/adapter/filesystem').FileSystemAdapter;
140
142
  hooks: ShokupanHooks<Record<string, any>> | ShokupanHooks<Record<string, any>>[];
141
143
  validateStatusCodes: boolean;
@@ -173,11 +175,13 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
173
175
  spec_url: string;
174
176
  }>;
175
177
  };
178
+ defaultSecurityHeaders?: boolean | any;
176
179
  }>;
177
180
  get root(): Shokupan<any>;
178
181
  [$routes]: ShokupanRoute[];
179
182
  private trie;
180
183
  metadata?: RouteMetadata;
184
+ mcpProtocol: McpProtocol;
181
185
  private currentGuards;
182
186
  private eventHandlers;
183
187
  /**
@@ -185,7 +189,7 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
185
189
  * Middleware will run for all routes matched by this router.
186
190
  */
187
191
  use(middleware: Middleware): this;
188
- getComponentRegistry(): {
192
+ get registry(): {
189
193
  metadata: RouteMetadata;
190
194
  middleware: {
191
195
  name: string;
@@ -238,6 +242,22 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
238
242
  * Registers a lifecycle hook dynamically.
239
243
  */
240
244
  hook(name: keyof ShokupanHooks, handler: Function): this;
245
+ /**
246
+ * Registers an MCP Tool.
247
+ */
248
+ tool(name: string, schema: any, handler: Function): this;
249
+ /**
250
+ * Registers an MCP Prompt.
251
+ */
252
+ prompt(name: string, args: McpPrompt['arguments'], handler: Function): this;
253
+ /**
254
+ * Registers an MCP Resource.
255
+ */
256
+ resource(uri: string, options: {
257
+ name?: string;
258
+ description?: string;
259
+ mimeType?: string;
260
+ }, handler: Function): this;
241
261
  /**
242
262
  * Finds an event handler(s) by name.
243
263
  */
@@ -245,7 +265,7 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
245
265
  /**
246
266
  * Registers a controller instance to the router.
247
267
  */
248
- registerControllerInstance(controller: any): void;
268
+ bindController(controller: any): void;
249
269
  /**
250
270
  * Returns all registered event handlers.
251
271
  */
@@ -323,10 +343,6 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
323
343
  requestTimeout?: number;
324
344
  renderer?: JSXRenderer;
325
345
  controller?: any;
326
- metadata?: {
327
- file: string;
328
- line: number;
329
- };
330
346
  middleware?: Middleware[];
331
347
  }): this;
332
348
  /**
@@ -0,0 +1,22 @@
1
+ import { Shokupan } from './shokupan';
2
+ /**
3
+ * Shokupan Server
4
+ *
5
+ * Responsible for the lifecycle of the HTTP server (listen, stop)
6
+ * and managing the underlying adapter (Bun, Node, etc).
7
+ */
8
+ export declare class ShokupanServer {
9
+ private app;
10
+ private server?;
11
+ private adapter?;
12
+ constructor(app: Shokupan);
13
+ /**
14
+ * Starts the application server.
15
+ * @param port The port to listen on.
16
+ */
17
+ listen(port?: number): Promise<any>;
18
+ /**
19
+ * Stops the server.
20
+ */
21
+ stop(closeActiveConnections?: boolean): Promise<void>;
22
+ }
@@ -76,9 +76,11 @@ export declare class Shokupan<T = any> extends ShokupanRouter<T> {
76
76
  private asyncApiSpecPromise?;
77
77
  private composedMiddleware?;
78
78
  private cpuMonitor?;
79
- private server?;
79
+ server?: Server<any>;
80
+ private httpServer?;
80
81
  private datastore?;
81
82
  dbPromise?: Promise<any>;
83
+ private rootTrie?;
82
84
  get db(): SurrealDatastore | undefined;
83
85
  get logger(): {
84
86
  verbose: boolean;
@@ -114,6 +116,17 @@ export declare class Shokupan<T = any> extends ShokupanRouter<T> {
114
116
  * This happens after generateOpenApi() but before the server starts listening (or at least before it finishes startup if async).
115
117
  */
116
118
  onSpecAvailable(callback: (spec: any) => void | Promise<void>): this;
119
+ /**
120
+ * Starts the application server.
121
+ *
122
+ * @param port - The port to listen on. If not specified, the port from the configuration is used. If that is not specified, port 3000 is used.
123
+ * @returns The server instance.
124
+ */
125
+ /**
126
+ * Prepare the application for listening.
127
+ * Use this if you want to initialize the app without starting the server immediately.
128
+ */
129
+ start(): Promise<void>;
117
130
  /**
118
131
  * Starts the application server.
119
132
  *
@@ -155,4 +168,14 @@ export declare class Shokupan<T = any> extends ShokupanRouter<T> {
155
168
  */
156
169
  fetch(req: Request, server?: Server<any>): Promise<Response>;
157
170
  private handleRequest;
171
+ /**
172
+ * Compiles all routes into a master Trie for O(1) router lookup.
173
+ * Use this if adding routes dynamically after start (not recommended but possible).
174
+ */
175
+ compile(): void;
176
+ private flattenRoutes;
177
+ find(method: string, path: string): {
178
+ handler: import('.').ShokupanHandler<T>;
179
+ params: Record<string, string>;
180
+ };
158
181
  }
@@ -0,0 +1,8 @@
1
+ import { Server } from 'bun';
2
+ import { Shokupan } from '../../shokupan';
3
+ import { ServerAdapter } from './interface';
4
+ export declare class BunAdapter implements ServerAdapter {
5
+ private server?;
6
+ listen(port: number, app: Shokupan): Promise<Server<any>>;
7
+ stop(): Promise<void>;
8
+ }
@@ -0,0 +1,4 @@
1
+ export * from './bun';
2
+ export * from './interface';
3
+ export * from './node';
4
+ export * from './wintercg';
@@ -0,0 +1,12 @@
1
+ import { Server } from 'bun';
2
+ import { Shokupan } from '../../shokupan';
3
+ export interface ServerAdapter {
4
+ /**
5
+ * Start listening on the specified port.
6
+ */
7
+ listen(port: number, app: Shokupan): Promise<Server<any>>;
8
+ /**
9
+ * Stop the server.
10
+ */
11
+ stop?(): Promise<void>;
12
+ }
@@ -0,0 +1,8 @@
1
+ import { Server } from 'bun';
2
+ import { Shokupan } from '../../shokupan';
3
+ import { ServerAdapter } from './interface';
4
+ export declare class NodeAdapter implements ServerAdapter {
5
+ private server?;
6
+ listen(port: number, app: Shokupan): Promise<Server<any>>;
7
+ stop(): Promise<void>;
8
+ }
@@ -0,0 +1,5 @@
1
+ import { Shokupan } from '../../shokupan';
2
+ import { ServerAdapter } from './interface';
3
+ export declare class WinterCGAdapter implements ServerAdapter {
4
+ listen(port: number, app: Shokupan): Promise<any>;
5
+ }
@@ -0,0 +1,30 @@
1
+ import { ShokupanRequest } from './request';
2
+ import { ShokupanConfig } from './types';
3
+ /**
4
+ * Utility class for parsing request bodies.
5
+ * Handles size limits, parsing, and caching logic detached from the Context.
6
+ */
7
+ export declare class BodyParser {
8
+ /**
9
+ * Parses the body of a request based on Content-Type header.
10
+ * @param req The ShokupanRequest object
11
+ * @param config Application configuration for limits and parser options
12
+ * @returns The parsed body or throws an error
13
+ */
14
+ static parse(req: ShokupanRequest<any>, config?: ShokupanConfig): Promise<{
15
+ type: string;
16
+ body: any;
17
+ }>;
18
+ /**
19
+ * Parsing helper for JSON
20
+ */
21
+ static parseJson(req: ShokupanRequest<any>, parserType: 'native' | 'parse-json' | 'secure-json-parse', maxBodySize: number): Promise<any>;
22
+ /**
23
+ * Parsing helper for FormData
24
+ */
25
+ static parseFormData(req: ShokupanRequest<any>, maxBodySize: number): Promise<FormData>;
26
+ /**
27
+ * Reads raw body as string with size enforcement
28
+ */
29
+ static readRawBody(req: ShokupanRequest<any>, maxBodySize: number): Promise<string>;
30
+ }