spiceflow 1.1.8 → 1.1.10
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 +177 -92
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js.map +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +9 -13
- package/dist/client/index.js.map +1 -1
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/utils.js.map +1 -1
- package/dist/client/ws.d.ts.map +1 -1
- package/dist/client/ws.js +1 -3
- package/dist/client/ws.js.map +1 -1
- package/dist/client.test.js +1 -1
- package/dist/client.test.js.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/cors.d.ts.map +1 -1
- package/dist/cors.js.map +1 -1
- package/dist/cors.test.js.map +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/middleware.test.js.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +1 -1
- package/dist/openapi.js.map +1 -1
- package/dist/openapi.test.js.map +1 -1
- package/dist/simple.benchmark.d.ts +2 -0
- package/dist/simple.benchmark.d.ts.map +1 -0
- package/dist/{benchmark.benchmark.js → simple.benchmark.js} +1 -1
- package/dist/simple.benchmark.js.map +1 -0
- package/dist/spiceflow.d.ts.map +1 -1
- package/dist/spiceflow.js +14 -2
- package/dist/spiceflow.js.map +1 -1
- package/dist/spiceflow.test.js.map +1 -1
- package/dist/static-node.d.ts +4 -0
- package/dist/static-node.d.ts.map +1 -0
- package/dist/static-node.js +35 -0
- package/dist/static-node.js.map +1 -0
- package/dist/static.benchmark.d.ts +2 -0
- package/dist/static.benchmark.d.ts.map +1 -0
- package/dist/static.benchmark.js +19 -0
- package/dist/static.benchmark.js.map +1 -0
- package/dist/static.d.ts +28 -0
- package/dist/static.d.ts.map +1 -0
- package/dist/static.js +181 -0
- package/dist/static.js.map +1 -0
- package/dist/stream.test.js +1 -1
- package/dist/stream.test.js.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/types.test.js +3 -7
- package/dist/types.test.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/zod.test.js.map +1 -1
- package/package.json +1 -1
- package/src/client/errors.ts +17 -17
- package/src/client/index.ts +437 -469
- package/src/client/types.ts +168 -191
- package/src/client/utils.ts +5 -5
- package/src/client/ws.ts +87 -89
- package/src/client.test.ts +176 -183
- package/src/context.ts +82 -82
- package/src/cors.test.ts +38 -38
- package/src/cors.ts +87 -92
- package/src/error.ts +13 -13
- package/src/middleware.test.ts +201 -201
- package/src/openapi.test.ts +97 -97
- package/src/openapi.ts +365 -365
- package/src/simple.benchmark.ts +16 -0
- package/src/spiceflow.test.ts +461 -467
- package/src/spiceflow.ts +1132 -1161
- package/src/static-node.ts +38 -0
- package/src/static.benchmark.ts +22 -0
- package/src/static.ts +240 -0
- package/src/stream.test.ts +310 -310
- package/src/types.test.ts +46 -50
- package/src/types.ts +698 -701
- package/src/utils.ts +79 -79
- package/src/zod.test.ts +64 -64
- package/dist/benchmark.benchmark.d.ts +0 -2
- package/dist/benchmark.benchmark.d.ts.map +0 -1
- package/dist/benchmark.benchmark.js.map +0 -1
- package/src/benchmark.benchmark.ts +0 -16
package/src/utils.ts
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
1
|
// deno-lint-ignore no-explicit-any
|
|
2
2
|
export const deepFreeze = (value: any) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
4
|
+
if (value[key] && typeof value[key] === 'object') {
|
|
5
|
+
deepFreeze(value[key])
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return Object.freeze(value)
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export const req = (path: string, options?: RequestInit) =>
|
|
12
|
-
|
|
12
|
+
new Request(`http://localhost${path}`, options)
|
|
13
13
|
|
|
14
14
|
export function isAsyncIterable(obj: any): obj is AsyncGenerator<any> {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
return (
|
|
16
|
+
typeof obj === 'object' &&
|
|
17
|
+
typeof obj.next === 'function' &&
|
|
18
|
+
typeof obj.return === 'function' &&
|
|
19
|
+
typeof obj.throw === 'function' &&
|
|
20
|
+
typeof obj.return === 'function'
|
|
21
|
+
)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function sleep(ms: number) {
|
|
25
|
-
|
|
25
|
+
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export const StatusMap = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
29
|
+
Continue: 100,
|
|
30
|
+
'Switching Protocols': 101,
|
|
31
|
+
Processing: 102,
|
|
32
|
+
'Early Hints': 103,
|
|
33
|
+
OK: 200,
|
|
34
|
+
Created: 201,
|
|
35
|
+
Accepted: 202,
|
|
36
|
+
'Non-Authoritative Information': 203,
|
|
37
|
+
'No Content': 204,
|
|
38
|
+
'Reset Content': 205,
|
|
39
|
+
'Partial Content': 206,
|
|
40
|
+
'Multi-Status': 207,
|
|
41
|
+
'Already Reported': 208,
|
|
42
|
+
'Multiple Choices': 300,
|
|
43
|
+
'Moved Permanently': 301,
|
|
44
|
+
Found: 302,
|
|
45
|
+
'See Other': 303,
|
|
46
|
+
'Not Modified': 304,
|
|
47
|
+
'Temporary Redirect': 307,
|
|
48
|
+
'Permanent Redirect': 308,
|
|
49
|
+
'Bad Request': 400,
|
|
50
|
+
Unauthorized: 401,
|
|
51
|
+
'Payment Required': 402,
|
|
52
|
+
Forbidden: 403,
|
|
53
|
+
'Not Found': 404,
|
|
54
|
+
'Method Not Allowed': 405,
|
|
55
|
+
'Not Acceptable': 406,
|
|
56
|
+
'Proxy Authentication Required': 407,
|
|
57
|
+
'Request Timeout': 408,
|
|
58
|
+
Conflict: 409,
|
|
59
|
+
Gone: 410,
|
|
60
|
+
'Length Required': 411,
|
|
61
|
+
'Precondition Failed': 412,
|
|
62
|
+
'Payload Too Large': 413,
|
|
63
|
+
'URI Too Long': 414,
|
|
64
|
+
'Unsupported Media Type': 415,
|
|
65
|
+
'Range Not Satisfiable': 416,
|
|
66
|
+
'Expectation Failed': 417,
|
|
67
|
+
"I'm a teapot": 418,
|
|
68
|
+
'Misdirected Request': 421,
|
|
69
|
+
'Unprocessable Content': 422,
|
|
70
|
+
Locked: 423,
|
|
71
|
+
'Failed Dependency': 424,
|
|
72
|
+
'Too Early': 425,
|
|
73
|
+
'Upgrade Required': 426,
|
|
74
|
+
'Precondition Required': 428,
|
|
75
|
+
'Too Many Requests': 429,
|
|
76
|
+
'Request Header Fields Too Large': 431,
|
|
77
|
+
'Unavailable For Legal Reasons': 451,
|
|
78
|
+
'Internal Server Error': 500,
|
|
79
|
+
'Not Implemented': 501,
|
|
80
|
+
'Bad Gateway': 502,
|
|
81
|
+
'Service Unavailable': 503,
|
|
82
|
+
'Gateway Timeout': 504,
|
|
83
|
+
'HTTP Version Not Supported': 505,
|
|
84
|
+
'Variant Also Negotiates': 506,
|
|
85
|
+
'Insufficient Storage': 507,
|
|
86
|
+
'Loop Detected': 508,
|
|
87
|
+
'Not Extended': 510,
|
|
88
|
+
'Network Authentication Required': 511,
|
|
89
89
|
} as const
|
|
90
90
|
|
|
91
91
|
export const InvertedStatusMap = Object.fromEntries(
|
|
92
|
-
|
|
92
|
+
Object.entries(StatusMap).map(([k, v]) => [v, k]),
|
|
93
93
|
) as {
|
|
94
|
-
|
|
94
|
+
[K in keyof StatusMap as StatusMap[K]]: K
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
export type StatusMap = typeof StatusMap
|
|
@@ -103,8 +103,8 @@ export type InvertedStatusMap = typeof InvertedStatusMap
|
|
|
103
103
|
* @param HTTP status code to send,
|
|
104
104
|
*/
|
|
105
105
|
export const redirect = (
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
url: string,
|
|
107
|
+
status: 301 | 302 | 303 | 307 | 308 = 302,
|
|
108
108
|
) => Response.redirect(url, status)
|
|
109
109
|
|
|
110
110
|
export type redirect = typeof redirect
|
package/src/zod.test.ts
CHANGED
|
@@ -5,69 +5,69 @@ import { req } from './utils.js'
|
|
|
5
5
|
import { z } from 'zod'
|
|
6
6
|
|
|
7
7
|
test('body is parsed as json', async () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
let name = ''
|
|
9
|
+
const res = await new Spiceflow()
|
|
10
|
+
.state('id', '')
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
12
|
+
.post(
|
|
13
|
+
'/post',
|
|
14
|
+
async (c) => {
|
|
15
|
+
const body = await c.request.json()
|
|
16
|
+
name = body.name
|
|
17
|
+
// @ts-expect-error
|
|
18
|
+
body.nonExistingField
|
|
19
|
+
return {
|
|
20
|
+
name,
|
|
21
|
+
nameEcho: body.name,
|
|
22
|
+
// add: 3,
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
body: z.object({
|
|
27
|
+
name: z.string(),
|
|
28
|
+
}),
|
|
29
|
+
response: z.object({
|
|
30
|
+
name: z.string(),
|
|
31
|
+
nameEcho: z.string(),
|
|
32
|
+
}),
|
|
33
|
+
},
|
|
34
|
+
)
|
|
35
|
+
.post(
|
|
36
|
+
'/post2',
|
|
37
|
+
async (c) => {
|
|
38
|
+
const body = await c.request.json()
|
|
39
|
+
name = body.name
|
|
40
|
+
// @ts-expect-error
|
|
41
|
+
body.nonExistingField
|
|
42
|
+
return {
|
|
43
|
+
name,
|
|
44
|
+
nameEcho: body.name,
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
body: z.object({
|
|
49
|
+
name: z.string(),
|
|
50
|
+
}),
|
|
51
|
+
response: {
|
|
52
|
+
200: z.object({
|
|
53
|
+
name: z.string(),
|
|
54
|
+
nameEcho: z.string(),
|
|
55
|
+
}),
|
|
56
|
+
400: z.object({
|
|
57
|
+
errorMessage: z.string(),
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
)
|
|
62
|
+
.handle(
|
|
63
|
+
req('/post', {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: {
|
|
66
|
+
'content-type': 'application/json',
|
|
67
|
+
},
|
|
68
|
+
body: JSON.stringify({ name: 'John' }),
|
|
69
|
+
}),
|
|
70
|
+
)
|
|
71
|
+
expect(res.status).toBe(200)
|
|
72
|
+
expect(await res.json()).toEqual({ name: 'John', nameEcho: 'John' })
|
|
73
73
|
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"benchmark.benchmark.d.ts","sourceRoot":"","sources":["../src/benchmark.benchmark.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"benchmark.benchmark.js","sourceRoot":"","sources":["../src/benchmark.benchmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAE9B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,KAAK,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;IAC3C,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAA;IAE3B,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAAA;IACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;AACF,CAAC,CAAC,CAAA"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { bench } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { Spiceflow } from './spiceflow.js'
|
|
4
|
-
|
|
5
|
-
bench('Spiceflow basic routing', async () => {
|
|
6
|
-
const app = new Spiceflow()
|
|
7
|
-
|
|
8
|
-
app.get('/hello', () => {
|
|
9
|
-
return { message: 'Hello, World!' }
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
const request = new Request('http://localhost/hello')
|
|
13
|
-
for (let i = 0; i < 10000; i++) {
|
|
14
|
-
await app.handle(request)
|
|
15
|
-
}
|
|
16
|
-
})
|