@spfn/core 0.2.0-beta.2 → 0.2.0-beta.21
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/README.md +262 -1092
- package/dist/{boss-D-fGtVgM.d.ts → boss-DI1r4kTS.d.ts} +68 -11
- package/dist/codegen/index.d.ts +55 -8
- package/dist/codegen/index.js +179 -5
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +204 -6
- package/dist/config/index.js +44 -11
- package/dist/config/index.js.map +1 -1
- package/dist/db/index.d.ts +13 -0
- package/dist/db/index.js +92 -33
- package/dist/db/index.js.map +1 -1
- package/dist/env/index.d.ts +83 -3
- package/dist/env/index.js +83 -15
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.d.ts +95 -0
- package/dist/env/loader.js +78 -0
- package/dist/env/loader.js.map +1 -0
- package/dist/event/index.d.ts +29 -70
- package/dist/event/index.js +15 -1
- package/dist/event/index.js.map +1 -1
- package/dist/event/sse/client.d.ts +157 -0
- package/dist/event/sse/client.js +169 -0
- package/dist/event/sse/client.js.map +1 -0
- package/dist/event/sse/index.d.ts +46 -0
- package/dist/event/sse/index.js +205 -0
- package/dist/event/sse/index.js.map +1 -0
- package/dist/job/index.d.ts +54 -8
- package/dist/job/index.js +61 -12
- package/dist/job/index.js.map +1 -1
- package/dist/middleware/index.d.ts +124 -11
- package/dist/middleware/index.js +41 -7
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/index.js +37 -5
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +45 -24
- package/dist/nextjs/server.js +87 -66
- package/dist/nextjs/server.js.map +1 -1
- package/dist/route/index.d.ts +207 -14
- package/dist/route/index.js +304 -31
- package/dist/route/index.js.map +1 -1
- package/dist/route/types.d.ts +2 -31
- package/dist/router-Di7ENoah.d.ts +151 -0
- package/dist/server/index.d.ts +321 -10
- package/dist/server/index.js +798 -189
- package/dist/server/index.js.map +1 -1
- package/dist/{types-DRG2XMTR.d.ts → types-7Mhoxnnt.d.ts} +97 -4
- package/dist/types-DHQMQlcb.d.ts +305 -0
- package/docs/cache.md +133 -0
- package/docs/codegen.md +74 -0
- package/docs/database.md +346 -0
- package/docs/entity.md +539 -0
- package/docs/env.md +499 -0
- package/docs/errors.md +319 -0
- package/docs/event.md +432 -0
- package/docs/file-upload.md +717 -0
- package/docs/job.md +131 -0
- package/docs/logger.md +108 -0
- package/docs/middleware.md +337 -0
- package/docs/nextjs.md +247 -0
- package/docs/repository.md +496 -0
- package/docs/route.md +497 -0
- package/docs/server.md +429 -0
- package/package.json +19 -3
package/dist/route/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
2
|
-
import { TSchema, Static } from '@sinclair/typebox';
|
|
2
|
+
import { TSchema, Static, Kind } from '@sinclair/typebox';
|
|
3
3
|
import { Context, MiddlewareHandler, Hono } from 'hono';
|
|
4
4
|
import { ContentfulStatusCode, RedirectStatusCode } from 'hono/utils/http-status';
|
|
5
5
|
import { HttpMethod } from './types.js';
|
|
6
|
-
export { HeaderRecord, InferResponseData, RouteMeta, RouteMetadata, RouterMetadata } from './types.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Route Input Types
|
|
@@ -23,6 +22,8 @@ type RouteInput = {
|
|
|
23
22
|
query?: TSchema;
|
|
24
23
|
/** Request body (JSON) */
|
|
25
24
|
body?: TSchema;
|
|
25
|
+
/** Form data (multipart/form-data) for file uploads */
|
|
26
|
+
formData?: TSchema;
|
|
26
27
|
/** HTTP headers */
|
|
27
28
|
headers?: TSchema;
|
|
28
29
|
/** Cookies */
|
|
@@ -35,6 +36,18 @@ type RouteInput = {
|
|
|
35
36
|
* Provides structured input access and response helpers for route handlers
|
|
36
37
|
*/
|
|
37
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Paginated response structure
|
|
41
|
+
*/
|
|
42
|
+
type PaginatedResult<T> = {
|
|
43
|
+
items: T[];
|
|
44
|
+
pagination: {
|
|
45
|
+
page: number;
|
|
46
|
+
limit: number;
|
|
47
|
+
total: number;
|
|
48
|
+
totalPages: number;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
38
51
|
/**
|
|
39
52
|
* Merge input with interceptor-injected fields
|
|
40
53
|
* Server receives both client input and interceptor-injected fields
|
|
@@ -50,6 +63,7 @@ type MergedInput<TInput extends RouteInput, TInterceptor extends RouteInput> = {
|
|
|
50
63
|
params: (TInput['params'] extends TSchema ? Static<TInput['params']> : {}) & (TInterceptor['params'] extends TSchema ? Static<TInterceptor['params']> : {});
|
|
51
64
|
query: (TInput['query'] extends TSchema ? Static<TInput['query']> : {}) & (TInterceptor['query'] extends TSchema ? Static<TInterceptor['query']> : {});
|
|
52
65
|
body: (TInput['body'] extends TSchema ? Static<TInput['body']> : {}) & (TInterceptor['body'] extends TSchema ? Static<TInterceptor['body']> : {});
|
|
66
|
+
formData: (TInput['formData'] extends TSchema ? Static<TInput['formData']> : {}) & (TInterceptor['formData'] extends TSchema ? Static<TInterceptor['formData']> : {});
|
|
53
67
|
headers: (TInput['headers'] extends TSchema ? Static<TInput['headers']> : {}) & (TInterceptor['headers'] extends TSchema ? Static<TInterceptor['headers']> : {});
|
|
54
68
|
cookies: (TInput['cookies'] extends TSchema ? Static<TInput['cookies']> : {}) & (TInterceptor['cookies'] extends TSchema ? Static<TInterceptor['cookies']> : {});
|
|
55
69
|
};
|
|
@@ -94,7 +108,7 @@ type RouteBuilderContext<TInput extends RouteInput = RouteInput, TInterceptor ex
|
|
|
94
108
|
json(data: unknown, status?: ContentfulStatusCode, headers?: Record<string, string | string[]>): Response;
|
|
95
109
|
/**
|
|
96
110
|
* Return 201 Created response with optional Location header
|
|
97
|
-
* Returns data directly
|
|
111
|
+
* Returns data directly for type inference
|
|
98
112
|
*
|
|
99
113
|
* @example
|
|
100
114
|
* ```ts
|
|
@@ -103,25 +117,29 @@ type RouteBuilderContext<TInput extends RouteInput = RouteInput, TInterceptor ex
|
|
|
103
117
|
* // Response: 201 Created
|
|
104
118
|
* // Header: Location: /users/123
|
|
105
119
|
* // Body: { id: '123', name: 'John' }
|
|
120
|
+
* // Type: User (inferred from data)
|
|
106
121
|
* ```
|
|
107
122
|
*/
|
|
108
|
-
created(data:
|
|
123
|
+
created<T>(data: T, location?: string): T;
|
|
109
124
|
/**
|
|
110
125
|
* Return 202 Accepted response
|
|
111
|
-
* Returns data directly
|
|
126
|
+
* Returns data directly for type inference
|
|
112
127
|
*
|
|
113
128
|
* @example
|
|
114
129
|
* ```ts
|
|
115
130
|
* // With data
|
|
116
131
|
* return c.accepted({ jobId: '123' });
|
|
117
132
|
* // Response: 202 Accepted, Body: { jobId: '123' }
|
|
133
|
+
* // Type: { jobId: string }
|
|
118
134
|
*
|
|
119
135
|
* // Without data
|
|
120
136
|
* return c.accepted();
|
|
121
137
|
* // Response: 202 Accepted, Body: (empty)
|
|
138
|
+
* // Type: void
|
|
122
139
|
* ```
|
|
123
140
|
*/
|
|
124
|
-
accepted(
|
|
141
|
+
accepted(): void;
|
|
142
|
+
accepted<T>(data: T): T;
|
|
125
143
|
/**
|
|
126
144
|
* Return 204 No Content response (empty body)
|
|
127
145
|
*
|
|
@@ -130,9 +148,10 @@ type RouteBuilderContext<TInput extends RouteInput = RouteInput, TInterceptor ex
|
|
|
130
148
|
* await deleteUser(id);
|
|
131
149
|
* return c.noContent();
|
|
132
150
|
* // Response: 204 No Content, Body: (empty)
|
|
151
|
+
* // Type: void
|
|
133
152
|
* ```
|
|
134
153
|
*/
|
|
135
|
-
noContent():
|
|
154
|
+
noContent(): void;
|
|
136
155
|
/**
|
|
137
156
|
* Return 304 Not Modified response (empty body)
|
|
138
157
|
*
|
|
@@ -142,12 +161,13 @@ type RouteBuilderContext<TInput extends RouteInput = RouteInput, TInterceptor ex
|
|
|
142
161
|
* return c.notModified();
|
|
143
162
|
* }
|
|
144
163
|
* // Response: 304 Not Modified, Body: (empty)
|
|
164
|
+
* // Type: void
|
|
145
165
|
* ```
|
|
146
166
|
*/
|
|
147
|
-
notModified():
|
|
167
|
+
notModified(): void;
|
|
148
168
|
/**
|
|
149
169
|
* Return paginated response with metadata
|
|
150
|
-
* Returns `{ items: [...], pagination: {...} }` format
|
|
170
|
+
* Returns `{ items: [...], pagination: {...} }` format with type inference
|
|
151
171
|
*
|
|
152
172
|
* @example
|
|
153
173
|
* ```ts
|
|
@@ -163,9 +183,10 @@ type RouteBuilderContext<TInput extends RouteInput = RouteInput, TInterceptor ex
|
|
|
163
183
|
* // totalPages: 5
|
|
164
184
|
* // }
|
|
165
185
|
* // }
|
|
186
|
+
* // Type: PaginatedResult<User>
|
|
166
187
|
* ```
|
|
167
188
|
*/
|
|
168
|
-
paginated(data:
|
|
189
|
+
paginated<T>(data: T[], page: number, limit: number, total: number): PaginatedResult<T>;
|
|
169
190
|
/**
|
|
170
191
|
* Redirect to another URL
|
|
171
192
|
*
|
|
@@ -501,14 +522,46 @@ declare class RouteBuilder<TInput extends RouteInput = {}, TInterceptor extends
|
|
|
501
522
|
/**
|
|
502
523
|
* Define handler function
|
|
503
524
|
*
|
|
525
|
+
* Response type is automatically inferred from the return value.
|
|
526
|
+
* Use helper methods like `c.created()`, `c.paginated()` for proper type inference.
|
|
527
|
+
*
|
|
504
528
|
* @example
|
|
505
529
|
* ```ts
|
|
530
|
+
* // Direct return - type inferred from data
|
|
506
531
|
* route.get('/users/:id')
|
|
507
532
|
* .input({ params: Type.Object({ id: Type.String() }) })
|
|
508
533
|
* .handler(async (c) => {
|
|
509
534
|
* const { params } = await c.data();
|
|
510
|
-
*
|
|
511
|
-
*
|
|
535
|
+
* return await getUser(params.id); // Type: User
|
|
536
|
+
* })
|
|
537
|
+
*
|
|
538
|
+
* // Using c.created() - returns data with 201 status, type preserved
|
|
539
|
+
* route.post('/users')
|
|
540
|
+
* .input({ body: Type.Object({ name: Type.String() }) })
|
|
541
|
+
* .handler(async (c) => {
|
|
542
|
+
* const { body } = await c.data();
|
|
543
|
+
* return c.created(await createUser(body)); // Type: User
|
|
544
|
+
* })
|
|
545
|
+
*
|
|
546
|
+
* // Using c.paginated() - returns PaginatedResult<T>
|
|
547
|
+
* route.get('/users')
|
|
548
|
+
* .handler(async (c) => {
|
|
549
|
+
* const users = await getUsers();
|
|
550
|
+
* return c.paginated(users, 1, 20, 100); // Type: PaginatedResult<User>
|
|
551
|
+
* })
|
|
552
|
+
*
|
|
553
|
+
* // Using c.noContent() - returns void
|
|
554
|
+
* route.delete('/users/:id')
|
|
555
|
+
* .handler(async (c) => {
|
|
556
|
+
* await deleteUser(params.id);
|
|
557
|
+
* return c.noContent(); // Type: void
|
|
558
|
+
* })
|
|
559
|
+
*
|
|
560
|
+
* // Using c.json() - returns Response (type inference lost)
|
|
561
|
+
* // Use only when you need custom status codes not covered by helpers
|
|
562
|
+
* route.get('/custom')
|
|
563
|
+
* .handler(async (c) => {
|
|
564
|
+
* return c.json({ data }, 418); // Type: Response
|
|
512
565
|
* })
|
|
513
566
|
* ```
|
|
514
567
|
*/
|
|
@@ -646,6 +699,14 @@ declare function defineRouter<TRoutes extends Record<string, RouteDef<any, any,
|
|
|
646
699
|
* Registers routes defined with route.get()...handler() to Hono app
|
|
647
700
|
*/
|
|
648
701
|
|
|
702
|
+
/**
|
|
703
|
+
* Registered route information for logging
|
|
704
|
+
*/
|
|
705
|
+
interface RegisteredRoute {
|
|
706
|
+
method: HttpMethod;
|
|
707
|
+
path: string;
|
|
708
|
+
name: string;
|
|
709
|
+
}
|
|
649
710
|
/**
|
|
650
711
|
* Register routes from defineRouter() to Hono app
|
|
651
712
|
*
|
|
@@ -653,6 +714,7 @@ declare function defineRouter<TRoutes extends Record<string, RouteDef<any, any,
|
|
|
653
714
|
* @param router - Router definition
|
|
654
715
|
* @param namedMiddlewares - Optional server-level named middlewares
|
|
655
716
|
*
|
|
717
|
+
* @param collectedRoutes
|
|
656
718
|
* @example
|
|
657
719
|
* ```ts
|
|
658
720
|
* const appRouter = defineRouter({
|
|
@@ -671,7 +733,7 @@ declare function defineRouter<TRoutes extends Record<string, RouteDef<any, any,
|
|
|
671
733
|
declare function registerRoutes<TRoutes extends Record<string, RouteDef<any> | Router<any>>>(app: Hono, router: Router<TRoutes>, namedMiddlewares?: ReadonlyArray<{
|
|
672
734
|
name: string;
|
|
673
735
|
handler: MiddlewareHandler;
|
|
674
|
-
}
|
|
736
|
+
}>, collectedRoutes?: RegisteredRoute[]): RegisteredRoute[];
|
|
675
737
|
|
|
676
738
|
/**
|
|
677
739
|
* Type guard for HttpMethod
|
|
@@ -698,4 +760,135 @@ declare const Nullable: <T extends TSchema>(schema: T) => _sinclair_typebox.TUni
|
|
|
698
760
|
*/
|
|
699
761
|
declare const OptionalNullable: <T extends TSchema>(schema: T) => _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[T, _sinclair_typebox.TNull]>>;
|
|
700
762
|
|
|
701
|
-
|
|
763
|
+
/**
|
|
764
|
+
* File Schema Helpers for TypeBox
|
|
765
|
+
*
|
|
766
|
+
* Provides TypeBox schema definitions for file upload handling
|
|
767
|
+
* with optional validation constraints.
|
|
768
|
+
*/
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* File validation options
|
|
772
|
+
*/
|
|
773
|
+
interface FileSchemaOptions {
|
|
774
|
+
/**
|
|
775
|
+
* Maximum file size in bytes
|
|
776
|
+
*
|
|
777
|
+
* @example 5 * 1024 * 1024 // 5MB
|
|
778
|
+
*/
|
|
779
|
+
maxSize?: number;
|
|
780
|
+
/**
|
|
781
|
+
* Allowed MIME types
|
|
782
|
+
*
|
|
783
|
+
* @example ['image/jpeg', 'image/png', 'image/webp']
|
|
784
|
+
*/
|
|
785
|
+
allowedTypes?: string[];
|
|
786
|
+
/**
|
|
787
|
+
* Minimum file size in bytes (optional)
|
|
788
|
+
*
|
|
789
|
+
* @example 1024 // 1KB minimum
|
|
790
|
+
*/
|
|
791
|
+
minSize?: number;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* File array validation options
|
|
795
|
+
*/
|
|
796
|
+
interface FileArraySchemaOptions extends FileSchemaOptions {
|
|
797
|
+
/**
|
|
798
|
+
* Maximum number of files
|
|
799
|
+
*
|
|
800
|
+
* @example 5
|
|
801
|
+
*/
|
|
802
|
+
maxFiles?: number;
|
|
803
|
+
/**
|
|
804
|
+
* Minimum number of files (optional)
|
|
805
|
+
*
|
|
806
|
+
* @example 1
|
|
807
|
+
*/
|
|
808
|
+
minFiles?: number;
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Internal schema type with file validation metadata
|
|
812
|
+
*/
|
|
813
|
+
interface FileSchemaType extends TSchema {
|
|
814
|
+
[Kind]: 'File';
|
|
815
|
+
fileOptions?: FileSchemaOptions;
|
|
816
|
+
}
|
|
817
|
+
interface FileArraySchemaType extends TSchema {
|
|
818
|
+
[Kind]: 'FileArray';
|
|
819
|
+
fileOptions?: FileArraySchemaOptions;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Create a File schema with optional validation
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* // Basic usage (no validation)
|
|
827
|
+
* formData: Type.Object({
|
|
828
|
+
* file: FileSchema()
|
|
829
|
+
* })
|
|
830
|
+
*
|
|
831
|
+
* // With validation
|
|
832
|
+
* formData: Type.Object({
|
|
833
|
+
* avatar: FileSchema({
|
|
834
|
+
* maxSize: 5 * 1024 * 1024, // 5MB
|
|
835
|
+
* allowedTypes: ['image/jpeg', 'image/png', 'image/webp']
|
|
836
|
+
* })
|
|
837
|
+
* })
|
|
838
|
+
* ```
|
|
839
|
+
*/
|
|
840
|
+
declare function FileSchema(options?: FileSchemaOptions): FileSchemaType;
|
|
841
|
+
/**
|
|
842
|
+
* Create a File array schema with optional validation
|
|
843
|
+
*
|
|
844
|
+
* @example
|
|
845
|
+
* ```ts
|
|
846
|
+
* // Basic usage (no validation)
|
|
847
|
+
* formData: Type.Object({
|
|
848
|
+
* files: FileArraySchema()
|
|
849
|
+
* })
|
|
850
|
+
*
|
|
851
|
+
* // With validation
|
|
852
|
+
* formData: Type.Object({
|
|
853
|
+
* documents: FileArraySchema({
|
|
854
|
+
* maxSize: 10 * 1024 * 1024, // 10MB per file
|
|
855
|
+
* maxFiles: 5,
|
|
856
|
+
* allowedTypes: ['application/pdf', 'application/msword']
|
|
857
|
+
* })
|
|
858
|
+
* })
|
|
859
|
+
* ```
|
|
860
|
+
*/
|
|
861
|
+
declare function FileArraySchema(options?: FileArraySchemaOptions): FileArraySchemaType;
|
|
862
|
+
/**
|
|
863
|
+
* Create an optional File schema with validation
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* ```ts
|
|
867
|
+
* formData: Type.Object({
|
|
868
|
+
* name: Type.String(),
|
|
869
|
+
* avatar: OptionalFileSchema({
|
|
870
|
+
* maxSize: 2 * 1024 * 1024,
|
|
871
|
+
* allowedTypes: ['image/jpeg', 'image/png']
|
|
872
|
+
* })
|
|
873
|
+
* })
|
|
874
|
+
* ```
|
|
875
|
+
*/
|
|
876
|
+
declare function OptionalFileSchema(options?: FileSchemaOptions): TSchema;
|
|
877
|
+
/**
|
|
878
|
+
* Check if a schema is a File schema
|
|
879
|
+
*/
|
|
880
|
+
declare function isFileSchema(schema: TSchema): schema is FileSchemaType;
|
|
881
|
+
/**
|
|
882
|
+
* Check if a schema is a FileArray schema
|
|
883
|
+
*/
|
|
884
|
+
declare function isFileArraySchema(schema: TSchema): schema is FileArraySchemaType;
|
|
885
|
+
/**
|
|
886
|
+
* Get file options from schema
|
|
887
|
+
*/
|
|
888
|
+
declare function getFileOptions(schema: TSchema): FileSchemaOptions | FileArraySchemaOptions | undefined;
|
|
889
|
+
/**
|
|
890
|
+
* Format file size for error messages
|
|
891
|
+
*/
|
|
892
|
+
declare function formatFileSize(bytes: number): string;
|
|
893
|
+
|
|
894
|
+
export { type ExtractMiddlewareNames, FileArraySchema, type FileArraySchemaOptions, type FileArraySchemaType, FileSchema, type FileSchemaOptions, type FileSchemaType, HttpMethod, type MergedInput, type NamedMiddleware, type NamedMiddlewareFactory, Nullable, OptionalFileSchema, OptionalNullable, type PaginatedResult, type RegisteredRoute, type RouteBuilderContext, type RouteDef, type RouteHandlerFn, type RouteInput, type Router, defineMiddleware, defineMiddlewareFactory, defineRouter, formatFileSize, getFileOptions, isFileArraySchema, isFileSchema, isHttpMethod, registerRoutes, route };
|