spiceflow 1.0.0 → 1.0.1
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/client/index.d.ts +4 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -5
- package/dist/client/index.js.map +1 -1
- package/dist/client/types.d.ts +4 -4
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/ws.d.ts +4 -4
- package/dist/client/ws.d.ts.map +1 -1
- package/dist/client/ws.js.map +1 -1
- package/dist/client.test.js +3 -3
- package/dist/client.test.js.map +1 -1
- package/dist/elysia-fork/error.d.ts +1 -1
- package/dist/elysia-fork/error.d.ts.map +1 -1
- package/dist/elysia-fork/error.js +2 -2
- package/dist/elysia-fork/error.js.map +1 -1
- package/dist/elysia-fork/types.d.ts +14 -96
- package/dist/elysia-fork/types.d.ts.map +1 -1
- package/dist/elysia-fork/types.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/spiceflow.d.ts +22 -38
- package/dist/spiceflow.d.ts.map +1 -1
- package/dist/spiceflow.js +6 -22
- package/dist/spiceflow.js.map +1 -1
- package/dist/spiceflow.test.js +21 -21
- package/dist/spiceflow.test.js.map +1 -1
- package/dist/stream.test.js +14 -14
- package/dist/stream.test.js.map +1 -1
- package/package.json +1 -2
- package/src/client/index.ts +10 -8
- package/src/client/types.ts +4 -4
- package/src/client/ws.ts +4 -4
- package/src/client.test.ts +3 -3
- package/src/elysia-fork/context.ts +2 -2
- package/src/elysia-fork/error.ts +3 -3
- package/src/elysia-fork/types.ts +23 -124
- package/src/index.ts +2 -0
- package/src/spiceflow.test.ts +22 -22
- package/src/spiceflow.ts +40 -55
- package/src/stream.test.ts +14 -14
package/src/elysia-fork/types.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import type { BunFile, Serve, Server, WebSocketHandler } from 'bun'
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
import type {
|
|
9
8
|
TSchema,
|
|
10
9
|
TObject,
|
|
@@ -28,108 +27,7 @@ import {
|
|
|
28
27
|
ParseError,
|
|
29
28
|
ValidationError
|
|
30
29
|
} from './error'
|
|
31
|
-
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export type ElysiaConfig<
|
|
35
|
-
Prefix extends string | undefined,
|
|
36
|
-
Scoped extends boolean | undefined
|
|
37
|
-
> = {
|
|
38
|
-
/**
|
|
39
|
-
* Path prefix of the instance
|
|
40
|
-
*
|
|
41
|
-
* @default '''
|
|
42
|
-
*/
|
|
43
|
-
prefix?: Prefix
|
|
44
|
-
/**
|
|
45
|
-
* If set to true, other Elysia handler will not inherits global life-cycle, store, decorators from the current instance
|
|
46
|
-
*
|
|
47
|
-
* @default false
|
|
48
|
-
*/
|
|
49
|
-
scoped?: Scoped
|
|
50
|
-
/**
|
|
51
|
-
* Name of the instance for debugging, and plugin deduplication purpose
|
|
52
|
-
*/
|
|
53
|
-
name?: string
|
|
54
|
-
/**
|
|
55
|
-
* Seed for generating checksum for plugin deduplication
|
|
56
|
-
*
|
|
57
|
-
* @see https://elysiajs.com/essential/plugin.html#plugin-deduplication
|
|
58
|
-
*/
|
|
59
|
-
seed?: unknown
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* OpenAPI documentation (use in Swagger)
|
|
63
|
-
*
|
|
64
|
-
* @see https://swagger.io/specification/
|
|
65
|
-
*/
|
|
66
|
-
detail?: DocumentDecoration
|
|
67
|
-
/**
|
|
68
|
-
* OpenAPI tags
|
|
69
|
-
*
|
|
70
|
-
* current instance' routes with tags
|
|
71
|
-
*
|
|
72
|
-
* @see https://swagger.io/specification/#tag-object
|
|
73
|
-
*/
|
|
74
|
-
tags?: DocumentDecoration['tags']
|
|
75
|
-
/**
|
|
76
|
-
* Warm up Elysia before starting the server
|
|
77
|
-
*
|
|
78
|
-
* This will perform Ahead of Time compilation and generate code for route handlers
|
|
79
|
-
*
|
|
80
|
-
* If set to false, Elysia will perform Just in Time compilation
|
|
81
|
-
*
|
|
82
|
-
* Only required for root instance (instance which use listen) to effect
|
|
83
|
-
*
|
|
84
|
-
* ! If performing a benchmark, it's recommended to set this to `true`
|
|
85
|
-
*
|
|
86
|
-
* @default false
|
|
87
|
-
*/
|
|
88
|
-
precompile?:
|
|
89
|
-
| boolean
|
|
90
|
-
| {
|
|
91
|
-
/**
|
|
92
|
-
* Perform dynamic code generation for route handlers before starting the server
|
|
93
|
-
*
|
|
94
|
-
* @default false
|
|
95
|
-
*/
|
|
96
|
-
compose?: boolean
|
|
97
|
-
/**
|
|
98
|
-
* Perform Ahead of Time compilation for schema before starting the server
|
|
99
|
-
*
|
|
100
|
-
* @default false
|
|
101
|
-
*/
|
|
102
|
-
schema?: boolean
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// /**
|
|
106
|
-
// * Override websocket configuration
|
|
107
|
-
// *
|
|
108
|
-
// * @see https://bun.sh/docs/api/websockets
|
|
109
|
-
// */
|
|
110
|
-
// websocket?: Omit<
|
|
111
|
-
// WebSocketHandler<any>,
|
|
112
|
-
// 'open' | 'close' | 'message' | 'drain'
|
|
113
|
-
// >
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Capture more detail information for each dependencies
|
|
117
|
-
*/
|
|
118
|
-
analytic?: boolean
|
|
119
|
-
/**
|
|
120
|
-
* Enable experimental features
|
|
121
|
-
*/
|
|
122
|
-
experimental?: {}
|
|
123
|
-
/**
|
|
124
|
-
* If enabled, the handlers will run a [clean](https://github.com/sinclairzx81/typebox?tab=readme-ov-file#clean) on incoming and outgoing bodies instead of failing directly.
|
|
125
|
-
* This allows for sending unknown or disallowed properties in the bodies. These will simply be filtered out instead of failing the request.
|
|
126
|
-
* This has no effect when the schemas allow additional properties.
|
|
127
|
-
* Since this uses dynamic schema it may have an impact on performance.
|
|
128
|
-
*
|
|
129
|
-
* @default false
|
|
130
|
-
*/
|
|
131
|
-
normalize?: boolean
|
|
132
|
-
}
|
|
30
|
+
import { Spiceflow } from '../spiceflow'
|
|
133
31
|
|
|
134
32
|
|
|
135
33
|
export type MaybeArray<T> = T | T[]
|
|
@@ -715,7 +613,7 @@ export type BodyHandler<
|
|
|
715
613
|
*
|
|
716
614
|
* @example
|
|
717
615
|
* ```ts
|
|
718
|
-
* new
|
|
616
|
+
* new Spiceflow()
|
|
719
617
|
* .onParse(({ contentType, request }) => {
|
|
720
618
|
* if (contentType === 'application/json')
|
|
721
619
|
* return request.json()
|
|
@@ -752,7 +650,7 @@ export type AfterResponseHandler<
|
|
|
752
650
|
) => MaybePromise<void>
|
|
753
651
|
|
|
754
652
|
export type GracefulHandler<
|
|
755
|
-
in Instance extends
|
|
653
|
+
in Instance extends Spiceflow<any, any, any, any, any, any, any, any>
|
|
756
654
|
> = (data: Instance) => any
|
|
757
655
|
|
|
758
656
|
export type ErrorHandler<
|
|
@@ -984,8 +882,6 @@ export interface InternalRoute {
|
|
|
984
882
|
hooks: LocalHook<any, any, any, any, any, any, any>
|
|
985
883
|
}
|
|
986
884
|
|
|
987
|
-
|
|
988
|
-
|
|
989
885
|
export type ListenCallback = (server: Server) => MaybePromise<void>
|
|
990
886
|
|
|
991
887
|
export type AddPrefix<Prefix extends string, T> = {
|
|
@@ -1132,13 +1028,16 @@ export type CreateEden<
|
|
|
1132
1028
|
? _CreateEden<'index', Property>
|
|
1133
1029
|
: _CreateEden<Path, Property>
|
|
1134
1030
|
|
|
1135
|
-
export type
|
|
1031
|
+
export type ComposeSpiceflowResponse<Response, Handle> = Handle extends (
|
|
1136
1032
|
...a: any[]
|
|
1137
1033
|
) => infer A
|
|
1138
|
-
?
|
|
1139
|
-
:
|
|
1034
|
+
? _ComposeSpiceflowResponse<Response, Replace<Awaited<A>, BunFile, File>>
|
|
1035
|
+
: _ComposeSpiceflowResponse<
|
|
1036
|
+
Response,
|
|
1037
|
+
Replace<Awaited<Handle>, BunFile, File>
|
|
1038
|
+
>
|
|
1140
1039
|
|
|
1141
|
-
type
|
|
1040
|
+
type _ComposeSpiceflowResponse<Response, Handle> = Prettify<
|
|
1142
1041
|
{} extends Response
|
|
1143
1042
|
? {
|
|
1144
1043
|
200: Exclude<Handle, { [ELYSIA_RESPONSE]: any }>
|
|
@@ -1155,8 +1054,8 @@ type _ComposeElysiaResponse<Response, Handle> = Prettify<
|
|
|
1155
1054
|
: Response
|
|
1156
1055
|
>
|
|
1157
1056
|
|
|
1158
|
-
export type
|
|
1159
|
-
Instances extends
|
|
1057
|
+
export type MergeSpiceflowInstances<
|
|
1058
|
+
Instances extends Spiceflow<any, any, any, any, any, any>[] = [],
|
|
1160
1059
|
Prefix extends string = '',
|
|
1161
1060
|
Scoped extends boolean = false,
|
|
1162
1061
|
Singleton extends SingletonBase = {
|
|
@@ -1176,11 +1075,11 @@ export type MergeElysiaInstances<
|
|
|
1176
1075
|
},
|
|
1177
1076
|
Routes extends RouteBase = {}
|
|
1178
1077
|
> = Instances extends [
|
|
1179
|
-
infer Current extends
|
|
1180
|
-
...infer Rest extends
|
|
1078
|
+
infer Current extends Spiceflow<any, any, any, any, any, any>,
|
|
1079
|
+
...infer Rest extends Spiceflow<any, any, any, any, any, any>[]
|
|
1181
1080
|
]
|
|
1182
1081
|
? Current['_types']['Scoped'] extends true
|
|
1183
|
-
?
|
|
1082
|
+
? MergeSpiceflowInstances<
|
|
1184
1083
|
Rest,
|
|
1185
1084
|
Prefix,
|
|
1186
1085
|
Scoped,
|
|
@@ -1189,7 +1088,7 @@ export type MergeElysiaInstances<
|
|
|
1189
1088
|
Metadata,
|
|
1190
1089
|
Routes
|
|
1191
1090
|
>
|
|
1192
|
-
:
|
|
1091
|
+
: MergeSpiceflowInstances<
|
|
1193
1092
|
Rest,
|
|
1194
1093
|
Prefix,
|
|
1195
1094
|
Scoped,
|
|
@@ -1201,7 +1100,7 @@ export type MergeElysiaInstances<
|
|
|
1201
1100
|
? Current['_routes']
|
|
1202
1101
|
: AddPrefix<Prefix, Current['_routes']>)
|
|
1203
1102
|
>
|
|
1204
|
-
:
|
|
1103
|
+
: Spiceflow<
|
|
1205
1104
|
Prefix,
|
|
1206
1105
|
Scoped,
|
|
1207
1106
|
{
|
|
@@ -1225,13 +1124,13 @@ export type MergeElysiaInstances<
|
|
|
1225
1124
|
export type LifeCycleType = 'global' | 'local' | 'scoped'
|
|
1226
1125
|
|
|
1227
1126
|
// Exclude return error()
|
|
1228
|
-
export type
|
|
1127
|
+
export type ExcludeSpiceflowResponse<T> = Exclude<
|
|
1229
1128
|
undefined extends Awaited<T> ? Partial<Awaited<T>> : Awaited<T>,
|
|
1230
1129
|
{ [ELYSIA_RESPONSE]: any }
|
|
1231
1130
|
>
|
|
1232
1131
|
|
|
1233
1132
|
export type InferContext<
|
|
1234
|
-
T extends
|
|
1133
|
+
T extends Spiceflow<any, any, any, any, any, any, any, any>,
|
|
1235
1134
|
Path extends string = T['_types']['Prefix'],
|
|
1236
1135
|
Schema extends RouteSchema = T['_types']['Metadata']['schema']
|
|
1237
1136
|
> = Context<
|
|
@@ -1244,7 +1143,7 @@ export type InferContext<
|
|
|
1244
1143
|
>
|
|
1245
1144
|
|
|
1246
1145
|
export type InferHandler<
|
|
1247
|
-
T extends
|
|
1146
|
+
T extends Spiceflow<any, any, any, any, any, any, any, any>,
|
|
1248
1147
|
Path extends string = T['_types']['Prefix'],
|
|
1249
1148
|
Schema extends RouteSchema = T['_types']['Metadata']['schema']
|
|
1250
1149
|
> = InlineHandler<
|
|
@@ -1303,7 +1202,7 @@ export type HigherOrderFunction<
|
|
|
1303
1202
|
T extends (...arg: unknown[]) => Function = (...arg: unknown[]) => Function
|
|
1304
1203
|
> = (fn: T, request: Request) => ReturnType<T>
|
|
1305
1204
|
|
|
1306
|
-
// new
|
|
1205
|
+
// new Spiceflow()
|
|
1307
1206
|
// .wrap((fn) => {
|
|
1308
1207
|
// return fn()
|
|
1309
1208
|
// })
|
|
@@ -1387,7 +1286,7 @@ export type HTTPHeaders = Record<string, string> & {
|
|
|
1387
1286
|
|
|
1388
1287
|
// Response context
|
|
1389
1288
|
allow?: string
|
|
1390
|
-
server?: '
|
|
1289
|
+
server?: 'spiceflow' | (string & {})
|
|
1391
1290
|
|
|
1392
1291
|
// Range requests
|
|
1393
1292
|
'accept-ranges'?: string
|
|
@@ -1438,7 +1337,7 @@ export type HTTPHeaders = Record<string, string> & {
|
|
|
1438
1337
|
'x-forwarded-for'?: string
|
|
1439
1338
|
'x-forwarded-host'?: string
|
|
1440
1339
|
'x-forwarded-proto'?: string
|
|
1441
|
-
'x-powered-by'?: '
|
|
1340
|
+
'x-powered-by'?: 'spiceflow' | (string & {})
|
|
1442
1341
|
'x-request-id'?: string
|
|
1443
1342
|
'x-requested-with'?: string
|
|
1444
1343
|
'x-robots-tag'?: string
|
package/src/index.ts
ADDED
package/src/spiceflow.test.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { test, describe, expect } from 'vitest'
|
|
2
2
|
import { Type } from '@sinclair/typebox'
|
|
3
|
-
import {
|
|
3
|
+
import { Spiceflow } from './spiceflow'
|
|
4
4
|
|
|
5
5
|
test('works', async () => {
|
|
6
|
-
const res = await new
|
|
6
|
+
const res = await new Spiceflow()
|
|
7
7
|
.post('/xxx', () => 'hi')
|
|
8
8
|
.handle(new Request('http://localhost/xxx', { method: 'POST' }))
|
|
9
9
|
expect(res.status).toBe(200)
|
|
10
10
|
expect(await res.text()).toBe(JSON.stringify('hi'))
|
|
11
11
|
})
|
|
12
12
|
test('dynamic route', async () => {
|
|
13
|
-
const res = await new
|
|
13
|
+
const res = await new Spiceflow()
|
|
14
14
|
.post('/ids/:id', () => 'hi')
|
|
15
15
|
.handle(new Request('http://localhost/ids/xxx', { method: 'POST' }))
|
|
16
16
|
expect(res.status).toBe(200)
|
|
17
17
|
expect(await res.text()).toBe(JSON.stringify('hi'))
|
|
18
18
|
})
|
|
19
19
|
test('GET dynamic route', async () => {
|
|
20
|
-
const res = await new
|
|
20
|
+
const res = await new Spiceflow()
|
|
21
21
|
.get('/ids/:id', () => 'hi')
|
|
22
22
|
.handle(new Request('http://localhost/ids/xxx', { method: 'GET' }))
|
|
23
23
|
expect(res.status).toBe(200)
|
|
@@ -25,13 +25,13 @@ test('GET dynamic route', async () => {
|
|
|
25
25
|
})
|
|
26
26
|
|
|
27
27
|
test('missing route is not found', async () => {
|
|
28
|
-
const res = await new
|
|
28
|
+
const res = await new Spiceflow()
|
|
29
29
|
.get('/ids/:id', () => 'hi')
|
|
30
30
|
.handle(new Request('http://localhost/zxxx', { method: 'GET' }))
|
|
31
31
|
expect(res.status).toBe(404)
|
|
32
32
|
})
|
|
33
33
|
test('state works', async () => {
|
|
34
|
-
const res = await new
|
|
34
|
+
const res = await new Spiceflow()
|
|
35
35
|
.state('id', '')
|
|
36
36
|
.onRequest(({ store, request }) => {
|
|
37
37
|
store.id = 'xxx'
|
|
@@ -45,7 +45,7 @@ test('state works', async () => {
|
|
|
45
45
|
|
|
46
46
|
test('body is parsed as json', async () => {
|
|
47
47
|
let body
|
|
48
|
-
const res = await new
|
|
48
|
+
const res = await new Spiceflow()
|
|
49
49
|
.state('id', '')
|
|
50
50
|
|
|
51
51
|
.post('/post', (c) => {
|
|
@@ -67,7 +67,7 @@ test('body is parsed as json', async () => {
|
|
|
67
67
|
})
|
|
68
68
|
|
|
69
69
|
test('validate body works, request success', async () => {
|
|
70
|
-
const res = await new
|
|
70
|
+
const res = await new Spiceflow()
|
|
71
71
|
|
|
72
72
|
.post(
|
|
73
73
|
'/post',
|
|
@@ -96,7 +96,7 @@ test('validate body works, request success', async () => {
|
|
|
96
96
|
})
|
|
97
97
|
|
|
98
98
|
test('validate body works, request fails', async () => {
|
|
99
|
-
const res = await new
|
|
99
|
+
const res = await new Spiceflow()
|
|
100
100
|
|
|
101
101
|
.post(
|
|
102
102
|
'/post',
|
|
@@ -127,7 +127,7 @@ test('validate body works, request fails', async () => {
|
|
|
127
127
|
})
|
|
128
128
|
|
|
129
129
|
test('run onRequest', async () => {
|
|
130
|
-
const res = await new
|
|
130
|
+
const res = await new Spiceflow()
|
|
131
131
|
.onRequest(({ request }) => {
|
|
132
132
|
expect(request.method).toBe('HEAD')
|
|
133
133
|
return new Response('ok', { status: 401 })
|
|
@@ -143,7 +143,7 @@ test('run onRequest', async () => {
|
|
|
143
143
|
})
|
|
144
144
|
|
|
145
145
|
test('run onRequest', async () => {
|
|
146
|
-
const res = await new
|
|
146
|
+
const res = await new Spiceflow()
|
|
147
147
|
.onRequest(({ request }) => {
|
|
148
148
|
expect(request.method).toBe('HEAD')
|
|
149
149
|
return new Response('ok', { status: 401 })
|
|
@@ -159,7 +159,7 @@ test('run onRequest', async () => {
|
|
|
159
159
|
})
|
|
160
160
|
|
|
161
161
|
test('basPath works', async () => {
|
|
162
|
-
const res = await new
|
|
162
|
+
const res = await new Spiceflow({ basePath: '/one' })
|
|
163
163
|
.get('/ids/:id', () => 'hi')
|
|
164
164
|
.handle(new Request('http://localhost/one/ids/xxx', { method: 'GET' }))
|
|
165
165
|
expect(res.status).toBe(200)
|
|
@@ -169,16 +169,16 @@ test('basPath works', async () => {
|
|
|
169
169
|
test('use with 2 basPath works', async () => {
|
|
170
170
|
let oneOnReq = false
|
|
171
171
|
let twoOnReq = false
|
|
172
|
-
const app = await new
|
|
172
|
+
const app = await new Spiceflow()
|
|
173
173
|
.use(
|
|
174
|
-
new
|
|
174
|
+
new Spiceflow({ basePath: '/one' })
|
|
175
175
|
.onRequest(({ request }) => {
|
|
176
176
|
oneOnReq = true
|
|
177
177
|
})
|
|
178
178
|
.get('/ids/:id', ({ params }) => params.id)
|
|
179
179
|
)
|
|
180
180
|
.use(
|
|
181
|
-
new
|
|
181
|
+
new Spiceflow({ basePath: '/two' })
|
|
182
182
|
.onRequest((c) => {
|
|
183
183
|
twoOnReq = true
|
|
184
184
|
})
|
|
@@ -206,16 +206,16 @@ test('use with 2 basPath works', async () => {
|
|
|
206
206
|
})
|
|
207
207
|
|
|
208
208
|
test('use with nested basPath works', async () => {
|
|
209
|
-
const app = await new
|
|
209
|
+
const app = await new Spiceflow({ basePath: '/zero' })
|
|
210
210
|
.use(
|
|
211
|
-
new
|
|
211
|
+
new Spiceflow({ basePath: '/one' }).get(
|
|
212
212
|
'/ids/:id',
|
|
213
213
|
({ params }) => params.id
|
|
214
214
|
)
|
|
215
215
|
)
|
|
216
216
|
.use(
|
|
217
|
-
new
|
|
218
|
-
new
|
|
217
|
+
new Spiceflow({ basePath: '/two' }).use(
|
|
218
|
+
new Spiceflow({ basePath: '/nested' }).get(
|
|
219
219
|
'/ids/:id',
|
|
220
220
|
({ params }) => params.id
|
|
221
221
|
)
|
|
@@ -241,7 +241,7 @@ test('use with nested basPath works', async () => {
|
|
|
241
241
|
test('errors inside basPath works', async () => {
|
|
242
242
|
let onErrorTriggered = [] as string[]
|
|
243
243
|
let onReqTriggered = [] as string[]
|
|
244
|
-
const app = await new
|
|
244
|
+
const app = await new Spiceflow({ basePath: '/zero' })
|
|
245
245
|
.onError(({ error }) => {
|
|
246
246
|
onErrorTriggered.push('root')
|
|
247
247
|
// return new Response('root', { status: 500 })
|
|
@@ -252,7 +252,7 @@ test('errors inside basPath works', async () => {
|
|
|
252
252
|
})
|
|
253
253
|
|
|
254
254
|
.use(
|
|
255
|
-
new
|
|
255
|
+
new Spiceflow({ basePath: '/two' })
|
|
256
256
|
.onError(({ error }) => {
|
|
257
257
|
onErrorTriggered.push('two')
|
|
258
258
|
// return new Response('two', { status: 500 })
|
|
@@ -262,7 +262,7 @@ test('errors inside basPath works', async () => {
|
|
|
262
262
|
// return new Response('two', { status: 500 })
|
|
263
263
|
})
|
|
264
264
|
.use(
|
|
265
|
-
new
|
|
265
|
+
new Spiceflow({ basePath: '/nested' })
|
|
266
266
|
.onError(({ error }) => {
|
|
267
267
|
onErrorTriggered.push('nested')
|
|
268
268
|
// return new Response('nested', { status: 500 })
|