spiceflow 1.1.7 → 1.1.9

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 (61) hide show
  1. package/README.md +177 -92
  2. package/dist/benchmark.benchmark.js.map +1 -1
  3. package/dist/client/errors.d.ts.map +1 -1
  4. package/dist/client/errors.js.map +1 -1
  5. package/dist/client/index.d.ts.map +1 -1
  6. package/dist/client/index.js +8 -12
  7. package/dist/client/index.js.map +1 -1
  8. package/dist/client/types.d.ts.map +1 -1
  9. package/dist/client/utils.js.map +1 -1
  10. package/dist/client/ws.d.ts.map +1 -1
  11. package/dist/client/ws.js +1 -3
  12. package/dist/client/ws.js.map +1 -1
  13. package/dist/client.test.js.map +1 -1
  14. package/dist/context.d.ts.map +1 -1
  15. package/dist/cors.d.ts.map +1 -1
  16. package/dist/cors.js.map +1 -1
  17. package/dist/cors.test.js.map +1 -1
  18. package/dist/error.d.ts.map +1 -1
  19. package/dist/error.js.map +1 -1
  20. package/dist/middleware.test.js +65 -0
  21. package/dist/middleware.test.js.map +1 -1
  22. package/dist/openapi.d.ts.map +1 -1
  23. package/dist/openapi.js +1 -1
  24. package/dist/openapi.js.map +1 -1
  25. package/dist/openapi.test.js.map +1 -1
  26. package/dist/spiceflow.d.ts.map +1 -1
  27. package/dist/spiceflow.js +12 -5
  28. package/dist/spiceflow.js.map +1 -1
  29. package/dist/spiceflow.test.js.map +1 -1
  30. package/dist/stream.test.js +6 -6
  31. package/dist/stream.test.js.map +1 -1
  32. package/dist/types.d.ts +1 -1
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/types.js.map +1 -1
  35. package/dist/types.test.js +56 -6
  36. package/dist/types.test.js.map +1 -1
  37. package/dist/utils.d.ts.map +1 -1
  38. package/dist/utils.js.map +1 -1
  39. package/dist/zod.test.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/benchmark.benchmark.ts +8 -8
  42. package/src/client/errors.ts +17 -17
  43. package/src/client/index.ts +437 -469
  44. package/src/client/types.ts +168 -191
  45. package/src/client/utils.ts +5 -5
  46. package/src/client/ws.ts +87 -89
  47. package/src/client.test.ts +176 -183
  48. package/src/context.ts +82 -82
  49. package/src/cors.test.ts +38 -38
  50. package/src/cors.ts +87 -92
  51. package/src/error.ts +13 -13
  52. package/src/middleware.test.ts +221 -149
  53. package/src/openapi.test.ts +97 -97
  54. package/src/openapi.ts +365 -365
  55. package/src/spiceflow.test.ts +461 -467
  56. package/src/spiceflow.ts +1117 -1157
  57. package/src/stream.test.ts +310 -310
  58. package/src/types.test.ts +59 -39
  59. package/src/types.ts +698 -701
  60. package/src/utils.ts +79 -79
  61. package/src/zod.test.ts +64 -64
package/src/cors.test.ts CHANGED
@@ -4,47 +4,47 @@ import { cors } from './cors.js'
4
4
  import { Spiceflow } from './spiceflow.js'
5
5
 
6
6
  function request(path, method = 'GET') {
7
- return new Request(`http://localhost/${path}`, {
8
- method,
9
- headers: {
10
- Origin: 'http://example.com',
11
- },
12
- })
7
+ return new Request(`http://localhost/${path}`, {
8
+ method,
9
+ headers: {
10
+ Origin: 'http://example.com',
11
+ },
12
+ })
13
13
  }
14
14
  describe('cors middleware', () => {
15
- const app = new Spiceflow()
16
- .state('x', 1)
17
- .use(cors())
18
- .get('/ids/:id', ({ state }) => {
19
- state.x
20
- // @ts-expect-error
21
- state.y
22
- return 'hi'
23
- })
24
- .post('/ids/:id', ({ params: { id } }) => id, {
25
- params: z.object({ id: z.string() }),
26
- })
15
+ const app = new Spiceflow()
16
+ .state('x', 1)
17
+ .use(cors())
18
+ .get('/ids/:id', ({ state }) => {
19
+ state.x
20
+ // @ts-expect-error
21
+ state.y
22
+ return 'hi'
23
+ })
24
+ .post('/ids/:id', ({ params: { id } }) => id, {
25
+ params: z.object({ id: z.string() }),
26
+ })
27
27
 
28
- test('GET request returns correct response and CORS headers', async () => {
29
- const res = await app.handle(request('ids/xxx'))
30
- expect(res.status).toBe(200)
31
- expect(await res.json()).toBe('hi')
32
- expect(res.headers.get('Access-Control-Allow-Origin')).toBe('*')
33
- })
28
+ test('GET request returns correct response and CORS headers', async () => {
29
+ const res = await app.handle(request('ids/xxx'))
30
+ expect(res.status).toBe(200)
31
+ expect(await res.json()).toBe('hi')
32
+ expect(res.headers.get('Access-Control-Allow-Origin')).toBe('*')
33
+ })
34
34
 
35
- test('OPTIONS request returns correct CORS headers', async () => {
36
- const res = await app.handle(request('ids/xxx', 'OPTIONS'))
37
- expect(res.status).toBe(204)
38
- expect(res.headers.get('Access-Control-Allow-Origin')).toBe('*')
39
- expect(res.headers.get('Access-Control-Allow-Methods')).toBe(
40
- 'GET,HEAD,PUT,POST,DELETE,PATCH',
41
- )
42
- })
35
+ test('OPTIONS request returns correct CORS headers', async () => {
36
+ const res = await app.handle(request('ids/xxx', 'OPTIONS'))
37
+ expect(res.status).toBe(204)
38
+ expect(res.headers.get('Access-Control-Allow-Origin')).toBe('*')
39
+ expect(res.headers.get('Access-Control-Allow-Methods')).toBe(
40
+ 'GET,HEAD,PUT,POST,DELETE,PATCH',
41
+ )
42
+ })
43
43
 
44
- test('POST request respects CORS and returns correct response', async () => {
45
- const res = await app.handle(request('ids/123', 'POST'))
46
- expect(res.status).toBe(200)
47
- expect(await res.json()).toBe('123')
48
- expect(res.headers.get('Access-Control-Allow-Origin')).toBe('*')
49
- })
44
+ test('POST request respects CORS and returns correct response', async () => {
45
+ const res = await app.handle(request('ids/123', 'POST'))
46
+ expect(res.status).toBe(200)
47
+ expect(await res.json()).toBe('123')
48
+ expect(res.headers.get('Access-Control-Allow-Origin')).toBe('*')
49
+ })
50
50
  })
package/src/cors.ts CHANGED
@@ -4,112 +4,107 @@ import { MiddlewareHandler } from './types.js'
4
4
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS MDN CORS documentation}
5
5
  */
6
6
  type CORSOptions = {
7
- /** Configures the Access-Control-Allow-Origin CORS header */
8
- origin: string | string[]
9
- /** Configures the Access-Control-Allow-Methods CORS header */
10
- allowMethods?: string[]
11
- /** Configures the Access-Control-Allow-Headers CORS header */
12
- allowHeaders?: string[]
13
- /** Configures the Access-Control-Max-Age CORS header */
14
- maxAge?: number
15
- /** Configures the Access-Control-Allow-Credentials CORS header */
16
- credentials?: boolean
17
- /** Configures the Access-Control-Expose-Headers CORS header */
18
- exposeHeaders?: string[]
7
+ /** Configures the Access-Control-Allow-Origin CORS header */
8
+ origin: string | string[]
9
+ /** Configures the Access-Control-Allow-Methods CORS header */
10
+ allowMethods?: string[]
11
+ /** Configures the Access-Control-Allow-Headers CORS header */
12
+ allowHeaders?: string[]
13
+ /** Configures the Access-Control-Max-Age CORS header */
14
+ maxAge?: number
15
+ /** Configures the Access-Control-Allow-Credentials CORS header */
16
+ credentials?: boolean
17
+ /** Configures the Access-Control-Expose-Headers CORS header */
18
+ exposeHeaders?: string[]
19
19
  }
20
20
 
21
21
  export const cors = (options?: CORSOptions): MiddlewareHandler => {
22
- const defaults: CORSOptions = {
23
- origin: '*',
24
- allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'],
25
- allowHeaders: [],
26
- exposeHeaders: [],
27
- }
28
- const opts = {
29
- ...defaults,
30
- ...options,
31
- }
22
+ const defaults: CORSOptions = {
23
+ origin: '*',
24
+ allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'],
25
+ allowHeaders: [],
26
+ exposeHeaders: [],
27
+ }
28
+ const opts = {
29
+ ...defaults,
30
+ ...options,
31
+ }
32
32
 
33
- const findAllowOrigin = ((optsOrigin) => {
34
- if (typeof optsOrigin === 'string') {
35
- return () => optsOrigin
36
- } else if (typeof optsOrigin === 'function') {
37
- return optsOrigin
38
- } else {
39
- return (origin: string) =>
40
- optsOrigin.includes(origin) ? origin : optsOrigin[0]
41
- }
42
- })(opts.origin)
33
+ const findAllowOrigin = ((optsOrigin) => {
34
+ if (typeof optsOrigin === 'string') {
35
+ return () => optsOrigin
36
+ } else if (typeof optsOrigin === 'function') {
37
+ return optsOrigin
38
+ } else {
39
+ return (origin: string) =>
40
+ optsOrigin.includes(origin) ? origin : optsOrigin[0]
41
+ }
42
+ })(opts.origin)
43
43
 
44
- return async function cors(c, next) {
45
- let response = await next()
44
+ return async function cors(c, next) {
45
+ let response = await next()
46
46
 
47
- function set(key: string, value: string) {
48
- response.headers.set(key, value)
49
- }
47
+ function set(key: string, value: string) {
48
+ response.headers.set(key, value)
49
+ }
50
50
 
51
- const allowOrigin = findAllowOrigin(
52
- c.request.headers.get('origin') || '',
53
- )
54
- if (allowOrigin) {
55
- set('Access-Control-Allow-Origin', allowOrigin)
56
- }
51
+ const allowOrigin = findAllowOrigin(c.request.headers.get('origin') || '')
52
+ if (allowOrigin) {
53
+ set('Access-Control-Allow-Origin', allowOrigin)
54
+ }
57
55
 
58
- // Suppose the server sends a response with an Access-Control-Allow-Origin value with an explicit origin (rather than the "*" wildcard).
59
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
60
- if (opts.origin !== '*') {
61
- const existingVary = c.request.headers.get('Vary')
56
+ // Suppose the server sends a response with an Access-Control-Allow-Origin value with an explicit origin (rather than the "*" wildcard).
57
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
58
+ if (opts.origin !== '*') {
59
+ const existingVary = c.request.headers.get('Vary')
62
60
 
63
- if (existingVary) {
64
- set('Vary', existingVary)
65
- } else {
66
- set('Vary', 'Origin')
67
- }
68
- }
61
+ if (existingVary) {
62
+ set('Vary', existingVary)
63
+ } else {
64
+ set('Vary', 'Origin')
65
+ }
66
+ }
69
67
 
70
- if (opts.credentials) {
71
- set('Access-Control-Allow-Credentials', 'true')
72
- }
68
+ if (opts.credentials) {
69
+ set('Access-Control-Allow-Credentials', 'true')
70
+ }
73
71
 
74
- if (opts.exposeHeaders?.length) {
75
- set('Access-Control-Expose-Headers', opts.exposeHeaders.join(','))
76
- }
72
+ if (opts.exposeHeaders?.length) {
73
+ set('Access-Control-Expose-Headers', opts.exposeHeaders.join(','))
74
+ }
77
75
 
78
- if (c.request.method === 'OPTIONS') {
79
- if (opts.maxAge != null) {
80
- set('Access-Control-Max-Age', opts.maxAge.toString())
81
- }
76
+ if (c.request.method === 'OPTIONS') {
77
+ if (opts.maxAge != null) {
78
+ set('Access-Control-Max-Age', opts.maxAge.toString())
79
+ }
82
80
 
83
- if (opts.allowMethods?.length) {
84
- set('Access-Control-Allow-Methods', opts.allowMethods.join(','))
85
- }
81
+ if (opts.allowMethods?.length) {
82
+ set('Access-Control-Allow-Methods', opts.allowMethods.join(','))
83
+ }
86
84
 
87
- let headers = opts.allowHeaders
88
- if (!headers?.length) {
89
- const requestHeaders = c.request.headers.get(
90
- 'Access-Control-Request-Headers',
91
- )
92
- if (requestHeaders) {
93
- headers = requestHeaders.split(/\s*,\s*/)
94
- }
95
- }
96
- if (headers?.length) {
97
- set('Access-Control-Allow-Headers', headers.join(','))
98
- c.request.headers.append(
99
- 'Vary',
100
- 'Access-Control-Request-Headers',
101
- )
102
- }
85
+ let headers = opts.allowHeaders
86
+ if (!headers?.length) {
87
+ const requestHeaders = c.request.headers.get(
88
+ 'Access-Control-Request-Headers',
89
+ )
90
+ if (requestHeaders) {
91
+ headers = requestHeaders.split(/\s*,\s*/)
92
+ }
93
+ }
94
+ if (headers?.length) {
95
+ set('Access-Control-Allow-Headers', headers.join(','))
96
+ c.request.headers.append('Vary', 'Access-Control-Request-Headers')
97
+ }
103
98
 
104
- response.headers.delete('Content-Length')
105
- response.headers.delete('Content-Type')
99
+ response.headers.delete('Content-Length')
100
+ response.headers.delete('Content-Type')
106
101
 
107
- return new Response(null, {
108
- headers: response.headers,
109
- status: 204,
110
- statusText: response.statusText,
111
- })
112
- }
113
- return response
114
- }
102
+ return new Response(null, {
103
+ headers: response.headers,
104
+ status: 204,
105
+ statusText: response.statusText,
106
+ })
107
+ }
108
+ return response
109
+ }
115
110
  }
package/src/error.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  // ? Cloudflare worker support
2
2
  const env =
3
- // @ts-ignore
4
- typeof Bun !== 'undefined'
5
- ? // @ts-ignore
6
- Bun.env
7
- : typeof process !== 'undefined'
8
- ? process?.env
9
- : undefined
3
+ // @ts-ignore
4
+ typeof Bun !== 'undefined'
5
+ ? // @ts-ignore
6
+ Bun.env
7
+ : typeof process !== 'undefined'
8
+ ? process?.env
9
+ : undefined
10
10
 
11
11
  export const ERROR_CODE = Symbol('SpiceflowErrorCode')
12
12
  export type ERROR_CODE = typeof ERROR_CODE
@@ -17,16 +17,16 @@ export type ELYSIA_RESPONSE = typeof ELYSIA_RESPONSE
17
17
  export const isProduction = (env?.NODE_ENV ?? env?.ENV) === 'production'
18
18
 
19
19
  export class ValidationError extends Error {
20
- code = 'VALIDATION'
21
- status = 422
20
+ code = 'VALIDATION'
21
+ status = 422
22
22
  }
23
23
 
24
24
  export class ParseError extends Error {
25
- code = 'PARSE'
26
- status = 400
25
+ code = 'PARSE'
26
+ status = 400
27
27
  }
28
28
 
29
29
  export class InternalServerError extends Error {
30
- code = 'INTERNAL_SERVER_ERROR'
31
- status = 500
30
+ code = 'INTERNAL_SERVER_ERROR'
31
+ status = 500
32
32
  }