shokupan 0.13.1 → 0.14.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 (97) hide show
  1. package/dist/{analyzer-BOtveWL-.cjs → analyzer-BZSVGTmP.cjs} +5 -4
  2. package/dist/analyzer-BZSVGTmP.cjs.map +1 -0
  3. package/dist/{analyzer-B0fMzeIo.js → analyzer-Faojwm7c.js} +5 -4
  4. package/dist/analyzer-Faojwm7c.js.map +1 -0
  5. package/dist/{analyzer.impl-CUDO6vpn.cjs → analyzer.impl-5aCqtook.cjs} +28 -11
  6. package/dist/analyzer.impl-5aCqtook.cjs.map +1 -0
  7. package/dist/{analyzer.impl-DmHe92Oi.js → analyzer.impl-COdN69gL.js} +28 -11
  8. package/dist/analyzer.impl-COdN69gL.js.map +1 -0
  9. package/dist/ast-analyzer-worker-C3jrQ8VR.js +184 -0
  10. package/dist/ast-analyzer-worker-C3jrQ8VR.js.map +1 -0
  11. package/dist/ast-analyzer-worker-D_uYkqmY.cjs +184 -0
  12. package/dist/ast-analyzer-worker-D_uYkqmY.cjs.map +1 -0
  13. package/dist/cli.cjs +1 -1
  14. package/dist/cli.js +1 -1
  15. package/dist/context.d.ts +39 -4
  16. package/dist/decorators/di.d.ts +31 -0
  17. package/dist/decorators/hooks.d.ts +28 -0
  18. package/dist/decorators/http.d.ts +60 -0
  19. package/dist/decorators/index.d.ts +8 -0
  20. package/dist/decorators/mcp.d.ts +48 -0
  21. package/dist/decorators/util/container.d.ts +36 -0
  22. package/dist/decorators/websocket.d.ts +172 -0
  23. package/dist/index-BP7v0Hiv.cjs +12216 -0
  24. package/dist/index-BP7v0Hiv.cjs.map +1 -0
  25. package/dist/index-CUNBeZKj.js +12176 -0
  26. package/dist/index-CUNBeZKj.js.map +1 -0
  27. package/dist/index.cjs +137 -10518
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.ts +1 -2
  30. package/dist/index.js +137 -10477
  31. package/dist/index.js.map +1 -1
  32. package/dist/{json-parser-COdZ0fqY.cjs → json-parser-BA0mUgMF.cjs} +3 -3
  33. package/dist/json-parser-BA0mUgMF.cjs.map +1 -0
  34. package/dist/{json-parser-B3dnQmCC.js → json-parser-BFM-SnBR.js} +3 -3
  35. package/dist/json-parser-BFM-SnBR.js.map +1 -0
  36. package/dist/knex-DDPXR-sQ.js +218 -0
  37. package/dist/knex-DDPXR-sQ.js.map +1 -0
  38. package/dist/knex-DghF-jjm.cjs +240 -0
  39. package/dist/knex-DghF-jjm.cjs.map +1 -0
  40. package/dist/level-BU87Jbus.js +184 -0
  41. package/dist/level-BU87Jbus.js.map +1 -0
  42. package/dist/level-DNFl2n-m.cjs +184 -0
  43. package/dist/level-DNFl2n-m.cjs.map +1 -0
  44. package/dist/plugins/application/api-explorer/static/explorer-client.mjs +54 -28
  45. package/dist/plugins/application/asyncapi/plugin.d.ts +1 -0
  46. package/dist/plugins/application/asyncapi/static/asyncapi-client.mjs +22 -11
  47. package/dist/plugins/application/dashboard/fetch-interceptor.d.ts +3 -1
  48. package/dist/plugins/application/dashboard/metrics-collector.d.ts +5 -3
  49. package/dist/plugins/application/dashboard/plugin.d.ts +36 -3
  50. package/dist/plugins/application/dashboard/static/requests.js +517 -53
  51. package/dist/plugins/application/dashboard/static/tabs.js +2 -2
  52. package/dist/plugins/application/error-view/index.d.ts +25 -0
  53. package/dist/plugins/application/error-view/reason-phrases.d.ts +1 -0
  54. package/dist/plugins/application/openapi/analyzer.d.ts +3 -1
  55. package/dist/plugins/application/openapi/analyzer.impl.d.ts +4 -2
  56. package/dist/router.d.ts +52 -21
  57. package/dist/shokupan.d.ts +25 -11
  58. package/dist/sqlite-CLrcTkti.js +180 -0
  59. package/dist/sqlite-CLrcTkti.js.map +1 -0
  60. package/dist/sqlite-n7FQ6Ja6.cjs +180 -0
  61. package/dist/sqlite-n7FQ6Ja6.cjs.map +1 -0
  62. package/dist/surreal-6QONU6xa.cjs +210 -0
  63. package/dist/surreal-6QONU6xa.cjs.map +1 -0
  64. package/dist/surreal-w7DeGVI-.js +188 -0
  65. package/dist/surreal-w7DeGVI-.js.map +1 -0
  66. package/dist/util/adapter/datastore/knex.d.ts +29 -0
  67. package/dist/util/adapter/datastore/level.d.ts +26 -0
  68. package/dist/util/adapter/datastore/sqlite.d.ts +24 -0
  69. package/dist/util/adapter/datastore/surreal.d.ts +29 -0
  70. package/dist/util/adapter/datastore.d.ts +59 -0
  71. package/dist/util/adapter/h3.d.ts +8 -0
  72. package/dist/util/adapter/index.d.ts +1 -0
  73. package/dist/util/ast-analyzer-worker.d.ts +77 -0
  74. package/dist/util/ast-worker-thread.d.ts +1 -0
  75. package/dist/util/cookie-parser.d.ts +6 -0
  76. package/dist/util/env-loader.d.ts +7 -0
  77. package/dist/util/html.d.ts +15 -0
  78. package/dist/util/ide.d.ts +9 -0
  79. package/dist/util/logger.d.ts +25 -0
  80. package/dist/util/query-string.d.ts +8 -0
  81. package/dist/util/response-transformer.d.ts +87 -0
  82. package/dist/util/symbol.d.ts +1 -0
  83. package/dist/util/types.d.ts +116 -42
  84. package/dist/websocket.d.ts +163 -0
  85. package/package.json +27 -1
  86. package/dist/analyzer-B0fMzeIo.js.map +0 -1
  87. package/dist/analyzer-BOtveWL-.cjs.map +0 -1
  88. package/dist/analyzer.impl-CUDO6vpn.cjs.map +0 -1
  89. package/dist/analyzer.impl-DmHe92Oi.js.map +0 -1
  90. package/dist/json-parser-B3dnQmCC.js.map +0 -1
  91. package/dist/json-parser-COdZ0fqY.cjs.map +0 -1
  92. package/dist/plugins/application/error-view/views/error.d.ts +0 -2
  93. package/dist/plugins/application/error-view/views/status.d.ts +0 -2
  94. package/dist/util/decorators.d.ts +0 -134
  95. package/dist/util/di.d.ts +0 -13
  96. /package/dist/{util → decorators/util}/metadata.d.ts +0 -0
  97. /package/dist/{util → decorators/util}/stack.d.ts +0 -0
@@ -0,0 +1,163 @@
1
+ import { ServerWebSocket } from 'bun';
2
+ import { ShokupanContext } from './context';
3
+ import { $childControllers, $childRouters, $routes } from './util/symbol';
4
+ /**
5
+ * WebSocket lifecycle handlers
6
+ */
7
+ export interface WebSocketHandlers<T = any> {
8
+ /**
9
+ * Called when HTTP upgrade request is received (before WebSocket connection).
10
+ * Return false to reject the upgrade.
11
+ */
12
+ onUpgrade?: (ctx: ShokupanContext<T>) => boolean | void | Promise<boolean | void>;
13
+ /**
14
+ * Called after WebSocket connection is established.
15
+ * Return value is automatically set to both ws.data and ctx.state.
16
+ */
17
+ onOpen?: (ctx: ShokupanContext<T>, ws: ServerWebSocket<any>) => any | Promise<any>;
18
+ /**
19
+ * Called before routing to event handlers.
20
+ * Return false or throw to prevent event routing.
21
+ */
22
+ onEvent?: (ctx: ShokupanContext<T>, ws: ServerWebSocket<any>, event: string, data: any) => boolean | void | Promise<boolean | void>;
23
+ /**
24
+ * Called for every message (before event parsing/routing).
25
+ */
26
+ onMessage?: (ctx: ShokupanContext<T>, ws: ServerWebSocket<any>, message: string | Buffer) => void | Promise<void>;
27
+ /**
28
+ * Called when WebSocket connection is closed.
29
+ */
30
+ onClose?: (ctx: ShokupanContext<T>, ws: ServerWebSocket<any>, code?: number, reason?: string) => void | Promise<void>;
31
+ /**
32
+ * Called when an error occurs.
33
+ */
34
+ onError?: (ctx: ShokupanContext<T>, ws: ServerWebSocket<any>, error: Error) => void | Promise<void>;
35
+ }
36
+ /**
37
+ * Event handler function
38
+ */
39
+ export type EventHandler<T = any> = (ctx: ShokupanContext<T>, data?: any) => void | Promise<void>;
40
+ /**
41
+ * WebSocket Router for organizing WebSocket endpoints.
42
+ *
43
+ * Provides lifecycle hooks and event-based message routing.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * const wsRouter = new ShokupanWebsocketRouter();
48
+ *
49
+ * wsRouter.onUpgrade((ctx) => {
50
+ * if (!ctx.get("authorization")) return false;
51
+ * return true;
52
+ * });
53
+ *
54
+ * wsRouter.onOpen((ctx, ws) => {
55
+ * return { userId: "123" }; // Sets ws.data and ctx.state
56
+ * });
57
+ *
58
+ * wsRouter.event("chat.message", (ctx, data) => {
59
+ * ctx.broadcast("chat.message", data);
60
+ * });
61
+ *
62
+ * app.mount('/ws', wsRouter);
63
+ * ```
64
+ */
65
+ export declare class ShokupanWebsocketRouter<T = any> {
66
+ private handlers;
67
+ middleware: any[];
68
+ private events;
69
+ /**
70
+ * Register upgrade validation handler.
71
+ * Called when HTTP upgrade request is received.
72
+ * Return false to reject the upgrade.
73
+ */
74
+ onUpgrade(handler: NonNullable<WebSocketHandlers<T>['onUpgrade']>): this;
75
+ /**
76
+ * Register open handler.
77
+ * Called after WebSocket connection is established.
78
+ * Return value is automatically set to both ws.data and ctx.state.
79
+ */
80
+ onOpen(handler: NonNullable<WebSocketHandlers<T>['onOpen']>): this;
81
+ /**
82
+ * Register event middleware handler.
83
+ * Called before routing to specific event handlers.
84
+ * Return false or throw to prevent event routing.
85
+ */
86
+ onEvent(handler: NonNullable<WebSocketHandlers<T>['onEvent']>): this;
87
+ /**
88
+ * Register message handler.
89
+ * Called for every message before event parsing/routing.
90
+ */
91
+ onMessage(handler: NonNullable<WebSocketHandlers<T>['onMessage']>): this;
92
+ /**
93
+ * Register close handler.
94
+ * Called when WebSocket connection is closed.
95
+ */
96
+ onClose(handler: NonNullable<WebSocketHandlers<T>['onClose']>): this;
97
+ /**
98
+ * Register error handler.
99
+ * Called when an error occurs.
100
+ */
101
+ onError(handler: NonNullable<WebSocketHandlers<T>['onError']>): this;
102
+ /**
103
+ * Register an event handler.
104
+ *
105
+ * @param name - Event name
106
+ * @param handler - Handler function
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * router.event("chat.message", (ctx, data) => {
111
+ * ctx.broadcast("chat.message", data);
112
+ * });
113
+ * ```
114
+ */
115
+ event(name: string, handler: EventHandler<T>): this;
116
+ /**
117
+ * Get registered handlers.
118
+ * @internal
119
+ */
120
+ getHandlers(): WebSocketHandlers<T>;
121
+ /**
122
+ * Get registered events.
123
+ * @internal
124
+ */
125
+ getEvents(): Map<string, EventHandler<T>>;
126
+ /**
127
+ * Get registered event handlers.
128
+ * @internal
129
+ */
130
+ getEventHandlers(): Map<string, EventHandler<T>[]>;
131
+ /**
132
+ * Get child routers (always empty for WebSocket router).
133
+ * @internal
134
+ */
135
+ get [$childRouters](): any[];
136
+ /**
137
+ * Get local routes (always empty for WebSocket router as it handles its own routing).
138
+ * @internal
139
+ */
140
+ get [$routes](): any[];
141
+ /**
142
+ * Get child controllers (always empty).
143
+ * @internal
144
+ */
145
+ get [$childControllers](): any[];
146
+ getRoutes(): any[];
147
+ /**
148
+ * Registry Accessor to support Dashboard Graph
149
+ */
150
+ get registry(): {
151
+ metadata: any;
152
+ middleware: any[];
153
+ routes: any[];
154
+ routers: any[];
155
+ controllers: any[];
156
+ events: any[];
157
+ };
158
+ /**
159
+ * Check if this is a WebSocket router instance.
160
+ * @internal
161
+ */
162
+ static isWebSocketRouter(obj: any): obj is ShokupanWebsocketRouter;
163
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shokupan",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "Shokupan is a low-lift modern web framework for Bun.",
5
5
  "author": "Andrew G. Knackstedt",
6
6
  "publishConfig": {
@@ -60,6 +60,8 @@
60
60
  "dependencies": {
61
61
  "@clack/prompts": "^0.11.0",
62
62
  "cockatiel": "^3.2.1",
63
+ "consola": "^3.4.2",
64
+ "mrmime": "^2.0.1",
63
65
  "nanoid": "^5.1.6",
64
66
  "tslib": "^2.8.1"
65
67
  },
@@ -78,12 +80,15 @@
78
80
  "eta": "^4.0.0",
79
81
  "graphql": "^16.12.0",
80
82
  "graphql-yoga": "^5.18.0",
83
+ "h3": "^2.0.0",
81
84
  "jose": "^6.0.0",
82
85
  "js-yaml": "^4.1.1",
86
+ "knex": "^3.1.0",
83
87
  "parse-json": "^8.0.0",
84
88
  "reflect-metadata": "^0.2.0",
85
89
  "secure-json-parse": "^4.0.0",
86
90
  "socket.io": "^4.8.3",
91
+ "sqlite3": "^5.1.7",
87
92
  "surrealdb": "^2.0.0-alpha.16"
88
93
  },
89
94
  "peerDependenciesMeta": {
@@ -108,6 +113,9 @@
108
113
  "graphql-yoga": {
109
114
  "optional": true
110
115
  },
116
+ "h3": {
117
+ "optional": true
118
+ },
111
119
  "class-validator": {
112
120
  "optional": true
113
121
  },
@@ -117,6 +125,9 @@
117
125
  "jose": {
118
126
  "optional": true
119
127
  },
128
+ "knex": {
129
+ "optional": true
130
+ },
120
131
  "parse-json": {
121
132
  "optional": true
122
133
  },
@@ -150,6 +161,9 @@
150
161
  "socket.io": {
151
162
  "optional": true
152
163
  },
164
+ "sqlite3": {
165
+ "optional": true
166
+ },
153
167
  "youch": {
154
168
  "optional": true
155
169
  }
@@ -174,10 +188,12 @@
174
188
  "@types/js-yaml": "^4.0.9",
175
189
  "@types/node": "^25.0.6",
176
190
  "@types/supertest": "^6.0.3",
191
+ "abstract-level": "^3.1.1",
177
192
  "ajv": "^8.0.0",
178
193
  "ajv-formats": "^3.0.0",
179
194
  "arctic": "^3.0.0",
180
195
  "axios": "^1.13.2",
196
+ "better-sqlite3": "^12.6.2",
181
197
  "class-transformer": "^0.5.0",
182
198
  "class-validator": "^0.14.0",
183
199
  "eta": "^4.0.0",
@@ -185,16 +201,26 @@
185
201
  "get-port": "^7.1.0",
186
202
  "graphql": "^16.12.0",
187
203
  "graphql-yoga": "^5.18.0",
204
+ "h3": "2.0.1-rc.11",
188
205
  "jose": "^6.0.0",
189
206
  "js-yaml": "^4.1.1",
207
+ "knex": "^3.1.0",
208
+ "memory-level": "^3.1.0",
209
+ "mysql": "^2.18.1",
210
+ "mysql2": "^3.16.2",
211
+ "oracledb": "^6.10.0",
190
212
  "parse-json": "^8.0.0",
213
+ "pg": "^8.17.2",
214
+ "pg-query-stream": "^4.11.2",
191
215
  "preact": "^10.28.2",
192
216
  "preact-render-to-string": "^6.6.5",
193
217
  "reflect-metadata": "^0.2.0",
194
218
  "secure-json-parse": "^4.0.0",
195
219
  "socket.io": "^4.8.3",
220
+ "sqlite3": "^5.1.7",
196
221
  "supertest": "^7.2.2",
197
222
  "surrealdb": "^2.0.0-alpha.14",
223
+ "tedious": "^19.2.0",
198
224
  "typescript": "~5.9.3",
199
225
  "valibot": "^1.2.0",
200
226
  "vite": "^7.3.1",
@@ -1 +0,0 @@
1
- {"version":3,"file":"analyzer-B0fMzeIo.js","sources":["../src/plugins/application/openapi/analyzer.ts"],"sourcesContent":["\n// Re-export types used in public API\nexport type { ApplicationInstance, RouteInfo } from './analyzer.impl';\nimport type { ApplicationInstance } from './analyzer.impl';\n\n/**\n * OpenAPI Analyzer Wrapper.\n * \n * This class wraps the actual OpenAPIAnalyzer implementation to facilitate\n * lazy loading of the 'typescript' peer dependency. The actual implementation\n * and the 'typescript' module are only loaded when `analyze()` is called.\n */\nexport class OpenAPIAnalyzer {\n private analyzerImpl: any;\n\n constructor(private rootDir: string, private entrypoint?: string) { }\n\n /**\n * Main analysis entry point.\n * Dynamically imports the implementation and runs the analysis.\n */\n public async analyze(): Promise<{ applications: ApplicationInstance[]; }> {\n // Dynamic import to avoid loading 'typescript' peer dependency if not needed (e.g. at runtime)\n const { OpenAPIAnalyzer: AnalyzerImpl } = await import('./analyzer.impl');\n this.analyzerImpl = new AnalyzerImpl(this.rootDir, this.entrypoint);\n return this.analyzerImpl.analyze();\n }\n\n /**\n * Generate OpenAPI specification.\n * Must be called after analyze().\n */\n public generateOpenAPISpec(): any {\n if (!this.analyzerImpl) {\n throw new Error('Must call analyze() before generateOpenAPISpec()');\n }\n return this.analyzerImpl.generateOpenAPISpec();\n }\n}\n\n/**\n * Analyze a directory and generate OpenAPI spec\n */\nexport async function analyzeDirectory(directory: string): Promise<any> {\n const analyzer = new OpenAPIAnalyzer(directory);\n return await analyzer.analyze();\n}\n"],"names":[],"mappings":"AAYO,MAAM,gBAAgB;AAAA,EAGzB,YAAoB,SAAyB,YAAqB;AAA9C,SAAA,UAAA;AAAyB,SAAA,aAAA;AAAA,EAAuB;AAAA,EAF5D;AAAA;AAAA;AAAA;AAAA;AAAA,EAQR,MAAa,UAA6D;AAEtE,UAAM,EAAE,iBAAiB,iBAAiB,MAAM,OAAO,6BAAiB;AACxE,SAAK,eAAe,IAAI,aAAa,KAAK,SAAS,KAAK,UAAU;AAClE,WAAO,KAAK,aAAa,QAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,sBAA2B;AAC9B,QAAI,CAAC,KAAK,cAAc;AACpB,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACtE;AACA,WAAO,KAAK,aAAa,oBAAA;AAAA,EAC7B;AACJ;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"analyzer-BOtveWL-.cjs","sources":["../src/plugins/application/openapi/analyzer.ts"],"sourcesContent":["\n// Re-export types used in public API\nexport type { ApplicationInstance, RouteInfo } from './analyzer.impl';\nimport type { ApplicationInstance } from './analyzer.impl';\n\n/**\n * OpenAPI Analyzer Wrapper.\n * \n * This class wraps the actual OpenAPIAnalyzer implementation to facilitate\n * lazy loading of the 'typescript' peer dependency. The actual implementation\n * and the 'typescript' module are only loaded when `analyze()` is called.\n */\nexport class OpenAPIAnalyzer {\n private analyzerImpl: any;\n\n constructor(private rootDir: string, private entrypoint?: string) { }\n\n /**\n * Main analysis entry point.\n * Dynamically imports the implementation and runs the analysis.\n */\n public async analyze(): Promise<{ applications: ApplicationInstance[]; }> {\n // Dynamic import to avoid loading 'typescript' peer dependency if not needed (e.g. at runtime)\n const { OpenAPIAnalyzer: AnalyzerImpl } = await import('./analyzer.impl');\n this.analyzerImpl = new AnalyzerImpl(this.rootDir, this.entrypoint);\n return this.analyzerImpl.analyze();\n }\n\n /**\n * Generate OpenAPI specification.\n * Must be called after analyze().\n */\n public generateOpenAPISpec(): any {\n if (!this.analyzerImpl) {\n throw new Error('Must call analyze() before generateOpenAPISpec()');\n }\n return this.analyzerImpl.generateOpenAPISpec();\n }\n}\n\n/**\n * Analyze a directory and generate OpenAPI spec\n */\nexport async function analyzeDirectory(directory: string): Promise<any> {\n const analyzer = new OpenAPIAnalyzer(directory);\n return await analyzer.analyze();\n}\n"],"names":[],"mappings":";;AAYO,MAAM,gBAAgB;AAAA,EAGzB,YAAoB,SAAyB,YAAqB;AAA9C,SAAA,UAAA;AAAyB,SAAA,aAAA;AAAA,EAAuB;AAAA,EAF5D;AAAA;AAAA;AAAA;AAAA;AAAA,EAQR,MAAa,UAA6D;AAEtE,UAAM,EAAE,iBAAiB,iBAAiB,MAAM,QAAA,QAAA,EAAA,KAAA,MAAA,QAAO,8BAAiB,CAAA;AACxE,SAAK,eAAe,IAAI,aAAa,KAAK,SAAS,KAAK,UAAU;AAClE,WAAO,KAAK,aAAa,QAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,sBAA2B;AAC9B,QAAI,CAAC,KAAK,cAAc;AACpB,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACtE;AACA,WAAO,KAAK,aAAa,oBAAA;AAAA,EAC7B;AACJ;;"}