shokupan 0.13.0 → 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.
- package/dist/{analyzer-BOtveWL-.cjs → analyzer-BZSVGTmP.cjs} +5 -4
- package/dist/analyzer-BZSVGTmP.cjs.map +1 -0
- package/dist/{analyzer-B0fMzeIo.js → analyzer-Faojwm7c.js} +5 -4
- package/dist/analyzer-Faojwm7c.js.map +1 -0
- package/dist/{analyzer.impl-CUDO6vpn.cjs → analyzer.impl-5aCqtook.cjs} +28 -11
- package/dist/analyzer.impl-5aCqtook.cjs.map +1 -0
- package/dist/{analyzer.impl-DmHe92Oi.js → analyzer.impl-COdN69gL.js} +28 -11
- package/dist/analyzer.impl-COdN69gL.js.map +1 -0
- package/dist/ast-analyzer-worker-C3jrQ8VR.js +184 -0
- package/dist/ast-analyzer-worker-C3jrQ8VR.js.map +1 -0
- package/dist/ast-analyzer-worker-D_uYkqmY.cjs +184 -0
- package/dist/ast-analyzer-worker-D_uYkqmY.cjs.map +1 -0
- package/dist/cli.cjs +1 -1
- package/dist/cli.js +1 -1
- package/dist/context.d.ts +39 -4
- package/dist/decorators/di.d.ts +31 -0
- package/dist/decorators/hooks.d.ts +28 -0
- package/dist/decorators/http.d.ts +60 -0
- package/dist/decorators/index.d.ts +8 -0
- package/dist/decorators/mcp.d.ts +48 -0
- package/dist/decorators/util/container.d.ts +36 -0
- package/dist/decorators/websocket.d.ts +172 -0
- package/dist/index-BP7v0Hiv.cjs +12216 -0
- package/dist/index-BP7v0Hiv.cjs.map +1 -0
- package/dist/index-CUNBeZKj.js +12176 -0
- package/dist/index-CUNBeZKj.js.map +1 -0
- package/dist/index.cjs +137 -10518
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +137 -10477
- package/dist/index.js.map +1 -1
- package/dist/{json-parser-COdZ0fqY.cjs → json-parser-BA0mUgMF.cjs} +3 -3
- package/dist/json-parser-BA0mUgMF.cjs.map +1 -0
- package/dist/{json-parser-B3dnQmCC.js → json-parser-BFM-SnBR.js} +3 -3
- package/dist/json-parser-BFM-SnBR.js.map +1 -0
- package/dist/knex-DDPXR-sQ.js +218 -0
- package/dist/knex-DDPXR-sQ.js.map +1 -0
- package/dist/knex-DghF-jjm.cjs +240 -0
- package/dist/knex-DghF-jjm.cjs.map +1 -0
- package/dist/level-BU87Jbus.js +184 -0
- package/dist/level-BU87Jbus.js.map +1 -0
- package/dist/level-DNFl2n-m.cjs +184 -0
- package/dist/level-DNFl2n-m.cjs.map +1 -0
- package/dist/plugins/application/api-explorer/static/explorer-client.mjs +54 -28
- package/dist/plugins/application/asyncapi/plugin.d.ts +1 -0
- package/dist/plugins/application/asyncapi/static/asyncapi-client.mjs +22 -11
- package/dist/plugins/application/dashboard/fetch-interceptor.d.ts +3 -1
- package/dist/plugins/application/dashboard/metrics-collector.d.ts +5 -3
- package/dist/plugins/application/dashboard/plugin.d.ts +36 -3
- package/dist/plugins/application/dashboard/static/requests.js +517 -53
- package/dist/plugins/application/dashboard/static/tabs.js +2 -2
- package/dist/plugins/application/error-view/index.d.ts +25 -0
- package/dist/plugins/application/error-view/reason-phrases.d.ts +1 -0
- package/dist/plugins/application/openapi/analyzer.d.ts +3 -1
- package/dist/plugins/application/openapi/analyzer.impl.d.ts +4 -2
- package/dist/router.d.ts +56 -21
- package/dist/shokupan.d.ts +25 -11
- package/dist/sqlite-CLrcTkti.js +180 -0
- package/dist/sqlite-CLrcTkti.js.map +1 -0
- package/dist/sqlite-n7FQ6Ja6.cjs +180 -0
- package/dist/sqlite-n7FQ6Ja6.cjs.map +1 -0
- package/dist/surreal-6QONU6xa.cjs +210 -0
- package/dist/surreal-6QONU6xa.cjs.map +1 -0
- package/dist/surreal-w7DeGVI-.js +188 -0
- package/dist/surreal-w7DeGVI-.js.map +1 -0
- package/dist/util/adapter/datastore/knex.d.ts +29 -0
- package/dist/util/adapter/datastore/level.d.ts +26 -0
- package/dist/util/adapter/datastore/sqlite.d.ts +24 -0
- package/dist/util/adapter/datastore/surreal.d.ts +29 -0
- package/dist/util/adapter/datastore.d.ts +59 -0
- package/dist/util/adapter/h3.d.ts +8 -0
- package/dist/util/adapter/index.d.ts +1 -0
- package/dist/util/ast-analyzer-worker.d.ts +77 -0
- package/dist/util/ast-worker-thread.d.ts +1 -0
- package/dist/util/cookie-parser.d.ts +6 -0
- package/dist/util/env-loader.d.ts +7 -0
- package/dist/util/html.d.ts +15 -0
- package/dist/util/ide.d.ts +9 -0
- package/dist/util/logger.d.ts +25 -0
- package/dist/util/query-string.d.ts +8 -0
- package/dist/util/response-transformer.d.ts +87 -0
- package/dist/util/symbol.d.ts +1 -0
- package/dist/util/types.d.ts +116 -42
- package/dist/websocket.d.ts +163 -0
- package/package.json +27 -1
- package/dist/analyzer-B0fMzeIo.js.map +0 -1
- package/dist/analyzer-BOtveWL-.cjs.map +0 -1
- package/dist/analyzer.impl-CUDO6vpn.cjs.map +0 -1
- package/dist/analyzer.impl-DmHe92Oi.js.map +0 -1
- package/dist/json-parser-B3dnQmCC.js.map +0 -1
- package/dist/json-parser-COdZ0fqY.cjs.map +0 -1
- package/dist/plugins/application/error-view/views/error.d.ts +0 -2
- package/dist/plugins/application/error-view/views/status.d.ts +0 -2
- package/dist/util/decorators.d.ts +0 -134
- package/dist/util/di.d.ts +0 -13
- /package/dist/{util → decorators/util}/metadata.d.ts +0 -0
- /package/dist/{util → decorators/util}/stack.d.ts +0 -0
package/dist/util/types.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { OpenAPI } from '@scalar/openapi-types';
|
|
2
2
|
import { Server } from 'bun';
|
|
3
3
|
import { Server as NodeServer } from 'node:http';
|
|
4
|
-
import { ConnectOptions, Engines } from 'surrealdb';
|
|
5
4
|
import { ShokupanContext } from '../context';
|
|
6
5
|
import { ServerAdapter } from './adapter';
|
|
7
6
|
import { FileSystemAdapter } from './adapter/filesystem';
|
|
7
|
+
import { Logger } from './logger';
|
|
8
8
|
import { $isRouter } from './symbol';
|
|
9
9
|
export type HeadersInit = Headers | Record<string, string> | [string, string][];
|
|
10
10
|
export interface ShokupanPluginOptions {
|
|
@@ -43,6 +43,39 @@ type ParsePathParams<Path extends string> = Path extends `${infer _Start}:${infe
|
|
|
43
43
|
[K in Param]: string;
|
|
44
44
|
} : {};
|
|
45
45
|
export type RouteParams<Path extends string> = string extends Path ? Record<string, string> : ParsePathParams<Path> extends Record<string, never> ? Record<string, string> : ParsePathParams<Path>;
|
|
46
|
+
/**
|
|
47
|
+
* Type guard to check if a state property exists and narrow its type.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* if (hasStateProperty(ctx, 'userId')) {
|
|
52
|
+
* // ctx.state.userId is now typed as defined (not undefined)
|
|
53
|
+
* console.log(ctx.state.userId);
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function hasStateProperty<S extends Record<string, any>, K extends string>(state: S, key: K): key is K & keyof S;
|
|
58
|
+
/**
|
|
59
|
+
* Runtime assertion that a state property exists.
|
|
60
|
+
* Throws an error if the property is missing.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* requireStateProperty(ctx.state, 'userId');
|
|
65
|
+
* // Now TypeScript knows ctx.state.userId exists
|
|
66
|
+
* const id = ctx.state.userId;
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function requireStateProperty<S extends Record<string, any>, K extends keyof S>(state: S, key: K, message?: string): asserts state is S & Record<K, NonNullable<S[K]>>;
|
|
70
|
+
/**
|
|
71
|
+
* Type-safe state getter with optional default value.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const userId = getStateProperty(ctx.state, 'userId', 'anonymous');
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare function getStateProperty<S extends Record<string, any>, K extends keyof S, D = undefined>(state: S, key: K, defaultValue?: D): S[K] | D;
|
|
46
79
|
export interface RouteMetadata {
|
|
47
80
|
file: string;
|
|
48
81
|
line: number;
|
|
@@ -243,6 +276,9 @@ export declare enum RouteParamType {
|
|
|
243
276
|
export interface ServerFactory {
|
|
244
277
|
(options: any): Server<any> | Promise<Server<any>> | NodeServer | Promise<NodeServer>;
|
|
245
278
|
}
|
|
279
|
+
export interface ErrorHandler<T = any> {
|
|
280
|
+
(err: T, ctx: ShokupanContext): Response | Promise<Response>;
|
|
281
|
+
}
|
|
246
282
|
export type NextFn = () => Promise<any>;
|
|
247
283
|
export type Middleware = ((ctx: ShokupanContext<unknown>, next: NextFn) => Promise<any> | any) & {
|
|
248
284
|
isBuiltin?: boolean;
|
|
@@ -357,6 +393,10 @@ export type ShokupanRoute = {
|
|
|
357
393
|
* Middleware stack metadata for this route (Controller/Method level)
|
|
358
394
|
*/
|
|
359
395
|
middleware?: Middleware[];
|
|
396
|
+
/**
|
|
397
|
+
* Whether this route is a WebSocket route
|
|
398
|
+
*/
|
|
399
|
+
isSocket?: boolean;
|
|
360
400
|
};
|
|
361
401
|
export type ShokupanConfig<T extends Record<string, any> = Record<string, any>> = Partial<{
|
|
362
402
|
/**
|
|
@@ -412,6 +452,18 @@ export type ShokupanConfig<T extends Record<string, any> = Record<string, any>>
|
|
|
412
452
|
* @default true
|
|
413
453
|
*/
|
|
414
454
|
blockOnAsyncApiGen: boolean;
|
|
455
|
+
/**
|
|
456
|
+
* Whether to use async AST scanning with worker threads.
|
|
457
|
+
* When enabled, AST analysis runs in a separate thread to avoid blocking server startup.
|
|
458
|
+
* @default true
|
|
459
|
+
*/
|
|
460
|
+
enableAsyncAstScanning?: boolean;
|
|
461
|
+
/**
|
|
462
|
+
* Maximum time (ms) to wait for AST analysis before timing out.
|
|
463
|
+
* Only applies when enableAsyncAstScanning is true.
|
|
464
|
+
* @default 30000 (30 seconds)
|
|
465
|
+
*/
|
|
466
|
+
astAnalysisTimeout?: number;
|
|
415
467
|
/**
|
|
416
468
|
* Whether to reuse the port.
|
|
417
469
|
* @default false
|
|
@@ -461,6 +513,20 @@ export type ShokupanConfig<T extends Record<string, any> = Record<string, any>>
|
|
|
461
513
|
* @default 60
|
|
462
514
|
*/
|
|
463
515
|
autoBackpressureLevel?: number;
|
|
516
|
+
/**
|
|
517
|
+
* Whether to enable automatic content negotiation for ctx.json() and other response methods.
|
|
518
|
+
* When enabled, ctx.json() will use the response transformer registry to negotiate the best
|
|
519
|
+
* response format based on the Accept header.
|
|
520
|
+
* @default false
|
|
521
|
+
*/
|
|
522
|
+
enableAutoContentNegotiation?: boolean;
|
|
523
|
+
/**
|
|
524
|
+
* Default response transformer content type.
|
|
525
|
+
* If set, ctx.respond() and auto-negotiated ctx.json() will use this transformer
|
|
526
|
+
* when no Accept header matches or when Accept is any.
|
|
527
|
+
* @default 'application/json'
|
|
528
|
+
*/
|
|
529
|
+
defaultResponseTransformer?: string;
|
|
464
530
|
/**
|
|
465
531
|
* Whether to enable middleware and handler tracking.
|
|
466
532
|
* When enabled, `ctx.handlerStack` will be populated with the handlers the request has passed through.
|
|
@@ -479,15 +545,15 @@ export type ShokupanConfig<T extends Record<string, any> = Record<string, any>>
|
|
|
479
545
|
* This enables websocket messages to run through the HTTP server.
|
|
480
546
|
* e.g.
|
|
481
547
|
* ```json
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
548
|
+
* {
|
|
549
|
+
* "method": "POST",
|
|
550
|
+
* "path": "/api/v1/myHttpEndpoint",
|
|
551
|
+
* "headers": {},
|
|
552
|
+
* "body": {
|
|
487
553
|
* "type": "text",
|
|
488
|
-
|
|
554
|
+
* "data": "Hello, world!"
|
|
489
555
|
* }
|
|
490
|
-
|
|
556
|
+
* }
|
|
491
557
|
* ```
|
|
492
558
|
* @default false
|
|
493
559
|
*/
|
|
@@ -515,17 +581,7 @@ export type ShokupanConfig<T extends Record<string, any> = Record<string, any>>
|
|
|
515
581
|
/**
|
|
516
582
|
* Logger object.
|
|
517
583
|
*/
|
|
518
|
-
logger:
|
|
519
|
-
verbose: boolean;
|
|
520
|
-
info: (msg: string, props: Record<string, any>) => void;
|
|
521
|
-
debug: (msg: string, props: Record<string, any>) => void;
|
|
522
|
-
warning: (msg: string, props: Record<string, any>) => void;
|
|
523
|
-
error: (msg: string, props: Record<string, any>) => void;
|
|
524
|
-
/**
|
|
525
|
-
* Something fatally went wrong and the application cannot continue.
|
|
526
|
-
*/
|
|
527
|
-
fatal: (msg: string, props: Record<string, any>) => void;
|
|
528
|
-
};
|
|
584
|
+
logger: Logger;
|
|
529
585
|
/**
|
|
530
586
|
* Timeout for reading the request body (milliseconds).
|
|
531
587
|
* Maps to Bun's `idleTimeout`.
|
|
@@ -564,7 +620,7 @@ export type ShokupanConfig<T extends Record<string, any> = Record<string, any>>
|
|
|
564
620
|
* The server adapter to use.
|
|
565
621
|
* overrides `serverFactory`.
|
|
566
622
|
*/
|
|
567
|
-
adapter?: 'bun' | 'node' | 'wintercg' | ServerAdapter;
|
|
623
|
+
adapter?: 'bun' | 'node' | 'wintercg' | 'h3' | ServerAdapter;
|
|
568
624
|
/**
|
|
569
625
|
* The file system adapter to use for `ctx.file`.
|
|
570
626
|
*/
|
|
@@ -579,31 +635,19 @@ export type ShokupanConfig<T extends Record<string, any> = Record<string, any>>
|
|
|
579
635
|
*/
|
|
580
636
|
validateStatusCodes: boolean;
|
|
581
637
|
/**
|
|
582
|
-
*
|
|
638
|
+
* @deprecated Use `datastore` config instead.
|
|
583
639
|
*/
|
|
584
|
-
surreal?:
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
* @default Embedded
|
|
588
|
-
*/
|
|
589
|
-
engines?: Engines;
|
|
590
|
-
/**
|
|
591
|
-
* SurrealDB connection URL.
|
|
592
|
-
* @default 'rocksdb://database'
|
|
593
|
-
*/
|
|
594
|
-
url?: string;
|
|
595
|
-
/**
|
|
596
|
-
* SurrealDB connection options.
|
|
597
|
-
*/
|
|
598
|
-
connectOptions?: ConnectOptions;
|
|
599
|
-
/**
|
|
600
|
-
* SurrealDB namespace.
|
|
601
|
-
*/
|
|
602
|
-
namespace?: string;
|
|
640
|
+
surreal?: any;
|
|
641
|
+
datastore?: {
|
|
642
|
+
adapter: 'surreal' | 'sqlite' | 'level' | 'knex';
|
|
603
643
|
/**
|
|
604
|
-
*
|
|
644
|
+
* Options for the specific adapter.
|
|
645
|
+
* - For 'surreal', this matches SurrealAdapterOptions
|
|
646
|
+
* - For 'sqlite', this matches SqliteAdapterOptions
|
|
647
|
+
* - For 'level', this matches LevelAdapterOptions
|
|
648
|
+
* - For 'knex', this matches KnexAdapterOptions (Knex.Config)
|
|
605
649
|
*/
|
|
606
|
-
|
|
650
|
+
options?: any;
|
|
607
651
|
};
|
|
608
652
|
/**
|
|
609
653
|
* Configuration for the AI Plugin manifest (.well-known/ai-plugin.json).
|
|
@@ -651,6 +695,18 @@ export type ShokupanConfig<T extends Record<string, any> = Record<string, any>>
|
|
|
651
695
|
* @deprecated
|
|
652
696
|
*/
|
|
653
697
|
[key: string]: any;
|
|
698
|
+
/**
|
|
699
|
+
* IDE configuration for file links.
|
|
700
|
+
* Can be a specific editor name (vscode, intellij, etc.) or an autodetection mode.
|
|
701
|
+
* Overrides process.env.IDE.
|
|
702
|
+
*
|
|
703
|
+
* Options:
|
|
704
|
+
* - 'vscode', 'vscode-insiders', 'vscodium', 'cursor', 'intellij', 'sublime', 'neovim'
|
|
705
|
+
* - 'vscode.dev': Force generic vscode.dev links
|
|
706
|
+
* - 'autodetect-vscode.dev': Auto-detect git remote and generate specific vscode.dev links
|
|
707
|
+
* - 'autodetect-repo': Auto-detect git remote and generate web repository links
|
|
708
|
+
*/
|
|
709
|
+
ide?: string;
|
|
654
710
|
}>;
|
|
655
711
|
export interface RequestOptions {
|
|
656
712
|
path?: string;
|
|
@@ -717,5 +773,23 @@ export interface StaticServeOptions<T extends Record<string, any>> {
|
|
|
717
773
|
* OpenAPI specification for the static route.
|
|
718
774
|
*/
|
|
719
775
|
openapi?: MethodAPISpec;
|
|
776
|
+
/**
|
|
777
|
+
* Enable ETags for static files.
|
|
778
|
+
*/
|
|
779
|
+
etag?: boolean;
|
|
780
|
+
/**
|
|
781
|
+
* Maximum age for the cache.
|
|
782
|
+
*/
|
|
783
|
+
maxAge?: number;
|
|
784
|
+
/**
|
|
785
|
+
* Whether the file is immutable.
|
|
786
|
+
* maxAge must be set to a value > 0 for this to have any effect.
|
|
787
|
+
*/
|
|
788
|
+
immutable?: boolean;
|
|
789
|
+
/**
|
|
790
|
+
* Whether to use the cache.
|
|
791
|
+
* @default true
|
|
792
|
+
*/
|
|
793
|
+
useCache?: boolean;
|
|
720
794
|
}
|
|
721
795
|
export {};
|
|
@@ -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.
|
|
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;;"}
|