spiceflow 0.0.7 → 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.
Files changed (151) hide show
  1. package/README.md +1 -171
  2. package/dist/client/errors.d.ts +7 -0
  3. package/dist/client/errors.d.ts.map +1 -0
  4. package/dist/client/errors.js +18 -0
  5. package/dist/client/errors.js.map +1 -0
  6. package/dist/client/index.d.ts +15 -0
  7. package/dist/client/index.d.ts.map +1 -0
  8. package/dist/client/index.js +376 -0
  9. package/dist/client/index.js.map +1 -0
  10. package/dist/client/types.d.ts +87 -0
  11. package/dist/client/types.d.ts.map +1 -0
  12. package/dist/client/types.js +2 -0
  13. package/dist/client/types.js.map +1 -0
  14. package/dist/client/utils.d.ts +2 -0
  15. package/dist/client/utils.d.ts.map +1 -0
  16. package/dist/client/utils.js +9 -0
  17. package/dist/client/utils.js.map +1 -0
  18. package/dist/client/ws.d.ts +15 -0
  19. package/dist/client/ws.d.ts.map +1 -0
  20. package/dist/client/ws.js +51 -0
  21. package/dist/client/ws.js.map +1 -0
  22. package/dist/client.test.d.ts +2 -0
  23. package/dist/client.test.d.ts.map +1 -0
  24. package/dist/client.test.js +237 -0
  25. package/dist/client.test.js.map +1 -0
  26. package/dist/elysia-fork/context.d.ts +87 -0
  27. package/dist/elysia-fork/context.d.ts.map +1 -0
  28. package/dist/elysia-fork/context.js +2 -0
  29. package/dist/elysia-fork/context.js.map +1 -0
  30. package/dist/elysia-fork/error.d.ts +246 -0
  31. package/dist/elysia-fork/error.d.ts.map +1 -0
  32. package/dist/elysia-fork/error.js +195 -0
  33. package/dist/elysia-fork/error.js.map +1 -0
  34. package/dist/elysia-fork/types.d.ts +570 -0
  35. package/dist/elysia-fork/types.d.ts.map +1 -0
  36. package/dist/elysia-fork/types.js +3 -0
  37. package/dist/elysia-fork/types.js.map +1 -0
  38. package/dist/elysia-fork/utils.d.ts +134 -0
  39. package/dist/elysia-fork/utils.d.ts.map +1 -0
  40. package/dist/elysia-fork/utils.js +70 -0
  41. package/dist/elysia-fork/utils.js.map +1 -0
  42. package/dist/index.d.ts +2 -7
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +1 -22
  45. package/dist/index.js.map +1 -1
  46. package/dist/spiceflow.d.ts +237 -0
  47. package/dist/spiceflow.d.ts.map +1 -0
  48. package/dist/spiceflow.js +484 -0
  49. package/dist/spiceflow.js.map +1 -0
  50. package/dist/spiceflow.test.d.ts +2 -0
  51. package/dist/spiceflow.test.d.ts.map +1 -0
  52. package/dist/spiceflow.test.js +225 -0
  53. package/dist/spiceflow.test.js.map +1 -0
  54. package/dist/stream.test.d.ts +2 -0
  55. package/dist/stream.test.d.ts.map +1 -0
  56. package/dist/stream.test.js +286 -0
  57. package/dist/stream.test.js.map +1 -0
  58. package/dist/types.d.ts +1 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +2 -0
  61. package/dist/types.js.map +1 -0
  62. package/dist/utils.d.ts +4 -20
  63. package/dist/utils.d.ts.map +1 -1
  64. package/dist/utils.js +17 -46
  65. package/dist/utils.js.map +1 -1
  66. package/package.json +12 -37
  67. package/src/client/errors.ts +21 -0
  68. package/src/client/index.ts +541 -0
  69. package/src/client/types.ts +233 -0
  70. package/src/client/utils.ts +7 -0
  71. package/src/client/ws.ts +99 -0
  72. package/src/client.test.ts +235 -0
  73. package/src/elysia-fork/context.ts +196 -0
  74. package/src/elysia-fork/error.ts +293 -0
  75. package/src/elysia-fork/types.ts +1353 -0
  76. package/src/elysia-fork/utils.ts +85 -0
  77. package/src/index.ts +2 -34
  78. package/src/spiceflow.test.ts +290 -0
  79. package/src/spiceflow.ts +1251 -0
  80. package/src/stream.test.ts +342 -0
  81. package/src/types.ts +0 -0
  82. package/src/utils.ts +21 -70
  83. package/context.d.ts +0 -2
  84. package/context.js +0 -1
  85. package/dist/babel.test.d.ts +0 -2
  86. package/dist/babel.test.d.ts.map +0 -1
  87. package/dist/babel.test.js +0 -27
  88. package/dist/babel.test.js.map +0 -1
  89. package/dist/babelDebugOutputs.d.ts +0 -9
  90. package/dist/babelDebugOutputs.d.ts.map +0 -1
  91. package/dist/babelDebugOutputs.js +0 -34
  92. package/dist/babelDebugOutputs.js.map +0 -1
  93. package/dist/babelTransformRpc.d.ts +0 -19
  94. package/dist/babelTransformRpc.d.ts.map +0 -1
  95. package/dist/babelTransformRpc.js +0 -285
  96. package/dist/babelTransformRpc.js.map +0 -1
  97. package/dist/browser.d.ts +0 -8
  98. package/dist/browser.d.ts.map +0 -1
  99. package/dist/browser.js +0 -126
  100. package/dist/browser.js.map +0 -1
  101. package/dist/build.d.ts +0 -13
  102. package/dist/build.d.ts.map +0 -1
  103. package/dist/build.js +0 -230
  104. package/dist/build.js.map +0 -1
  105. package/dist/cli.d.ts +0 -3
  106. package/dist/cli.d.ts.map +0 -1
  107. package/dist/cli.js +0 -111
  108. package/dist/cli.js.map +0 -1
  109. package/dist/context-internal.d.ts +0 -20
  110. package/dist/context-internal.d.ts.map +0 -1
  111. package/dist/context-internal.js +0 -16
  112. package/dist/context-internal.js.map +0 -1
  113. package/dist/context.d.ts +0 -2
  114. package/dist/context.d.ts.map +0 -1
  115. package/dist/context.js +0 -2
  116. package/dist/context.js.map +0 -1
  117. package/dist/expose.d.ts +0 -6
  118. package/dist/expose.d.ts.map +0 -1
  119. package/dist/expose.js +0 -32
  120. package/dist/expose.js.map +0 -1
  121. package/dist/headers.d.ts +0 -2
  122. package/dist/headers.d.ts.map +0 -1
  123. package/dist/headers.js +0 -18
  124. package/dist/headers.js.map +0 -1
  125. package/dist/jsonRpc.d.ts +0 -32
  126. package/dist/jsonRpc.d.ts.map +0 -1
  127. package/dist/jsonRpc.js +0 -3
  128. package/dist/jsonRpc.js.map +0 -1
  129. package/dist/server.d.ts +0 -32
  130. package/dist/server.d.ts.map +0 -1
  131. package/dist/server.js +0 -292
  132. package/dist/server.js.map +0 -1
  133. package/headers.d.ts +0 -2
  134. package/headers.js +0 -1
  135. package/sdk-template/package.json +0 -22
  136. package/sdk-template/src/index.ts +0 -2
  137. package/sdk-template/src/v1/example.ts +0 -5
  138. package/sdk-template/src/v1/generator.ts +0 -12
  139. package/sdk-template/tsconfig.json +0 -16
  140. package/src/babel.test.ts +0 -35
  141. package/src/babelDebugOutputs.ts +0 -56
  142. package/src/babelTransformRpc.ts +0 -394
  143. package/src/browser.ts +0 -141
  144. package/src/build.ts +0 -298
  145. package/src/cli.ts +0 -132
  146. package/src/context-internal.ts +0 -36
  147. package/src/context.ts +0 -5
  148. package/src/expose.ts +0 -34
  149. package/src/headers.ts +0 -19
  150. package/src/jsonRpc.ts +0 -43
  151. package/src/server.ts +0 -384
@@ -0,0 +1,233 @@
1
+ /// <reference lib="dom" />
2
+ import type { Spiceflow } from '../spiceflow'
3
+ // import { EdenWS } from './ws'
4
+ // import type { IsNever, Not, Prettify } from '../types'
5
+ import { EdenFetchError } from './errors'
6
+ import { EdenWS } from './ws'
7
+
8
+ export type Prettify<T> = {
9
+ [K in keyof T]: T[K]
10
+ } & {}
11
+
12
+ export type IsNever<T> = [T] extends [never] ? true : false
13
+
14
+ type Files = File | FileList
15
+
16
+ // type Replace<RecordType, TargetType, GenericType> = {
17
+ // [K in keyof RecordType]: RecordType[K] extends TargetType
18
+ // ? GenericType
19
+ // : RecordType[K]
20
+ // }
21
+
22
+ type ReplaceBlobWithFiles<in out RecordType extends Record<string, unknown>> = {
23
+ [K in keyof RecordType]: RecordType[K] extends Blob | Blob[]
24
+ ? Files
25
+ : RecordType[K]
26
+ } & {}
27
+
28
+ type And<A extends boolean, B extends boolean> = A extends true
29
+ ? B extends true
30
+ ? true
31
+ : false
32
+ : false
33
+
34
+ type ReplaceGeneratorWithAsyncGenerator<
35
+ in out RecordType extends Record<string, unknown>
36
+ > = {
37
+ [K in keyof RecordType]: RecordType[K] extends Generator<
38
+ infer A,
39
+ infer B,
40
+ infer C
41
+ >
42
+ ? And<Not<IsNever<A>>, void extends B ? true : false> extends true
43
+ ? AsyncGenerator<A, B, C>
44
+ : And<IsNever<A>, void extends B ? false : true> extends true
45
+ ? B
46
+ : AsyncGenerator<A, B, C> | B
47
+ : RecordType[K] extends AsyncGenerator<infer A, infer B, infer C>
48
+ ? And<Not<IsNever<A>>, void extends B ? true : false> extends true
49
+ ? AsyncGenerator<A, B, C>
50
+ : And<IsNever<A>, void extends B ? false : true> extends true
51
+ ? B
52
+ : AsyncGenerator<A, B, C> | B
53
+ : RecordType[K]
54
+ } & {}
55
+
56
+ type MaybeArray<T> = T | T[]
57
+ type MaybePromise<T> = T | Promise<T>
58
+
59
+ export namespace SpiceflowClient {
60
+ interface TreatyParam {
61
+ fetch?: RequestInit
62
+ }
63
+
64
+ export type Create<
65
+ App extends Spiceflow<any, any, any, any, any, any, any, any>
66
+ > = App extends {
67
+ _routes: infer Schema extends Record<string, any>
68
+ }
69
+ ? Prettify<Sign<Schema>>
70
+ : 'Please install Spiceflow before using Eden'
71
+
72
+ export type Sign<in out Route extends Record<string, any>> = {
73
+ [K in keyof Route as K extends `:${string}`
74
+ ? never
75
+ : K]: K extends 'subscribe' // ? Websocket route
76
+ ? (undefined extends Route['subscribe']['headers']
77
+ ? { headers?: Record<string, unknown> }
78
+ : {
79
+ headers: Route['subscribe']['headers']
80
+ }) &
81
+ (undefined extends Route['subscribe']['query']
82
+ ? { query?: Record<string, unknown> }
83
+ : {
84
+ query: Route['subscribe']['query']
85
+ }) extends infer Param
86
+ ? {} extends Param
87
+ ? (options?: Param) => EdenWS<Route['subscribe']>
88
+ : (options?: Param) => EdenWS<Route['subscribe']>
89
+ : never
90
+ : Route[K] extends {
91
+ body: infer Body
92
+ headers: infer Headers
93
+ params: any
94
+ query: infer Query
95
+ response: infer Response extends Record<number, unknown>
96
+ }
97
+ ? (undefined extends Headers
98
+ ? { headers?: Record<string, unknown> }
99
+ : {
100
+ headers: Headers
101
+ }) &
102
+ (undefined extends Query
103
+ ? { query?: Record<string, unknown> }
104
+ : { query: Query }) extends infer Param
105
+ ? {} extends Param
106
+ ? undefined extends Body
107
+ ? K extends 'get' | 'head'
108
+ ? (
109
+ options?: Prettify<Param & TreatyParam>
110
+ ) => Promise<
111
+ TreatyResponse<
112
+ ReplaceGeneratorWithAsyncGenerator<Response>
113
+ >
114
+ >
115
+ : (
116
+ body?: Body,
117
+ options?: Prettify<Param & TreatyParam>
118
+ ) => Promise<
119
+ TreatyResponse<
120
+ ReplaceGeneratorWithAsyncGenerator<Response>
121
+ >
122
+ >
123
+ : (
124
+ body: Body extends Record<string, unknown>
125
+ ? ReplaceBlobWithFiles<Body>
126
+ : Body,
127
+ options?: Prettify<Param & TreatyParam>
128
+ ) => Promise<
129
+ TreatyResponse<
130
+ ReplaceGeneratorWithAsyncGenerator<Response>
131
+ >
132
+ >
133
+ : K extends 'get' | 'head'
134
+ ? (
135
+ options: Prettify<Param & TreatyParam>
136
+ ) => Promise<
137
+ TreatyResponse<
138
+ ReplaceGeneratorWithAsyncGenerator<Response>
139
+ >
140
+ >
141
+ : (
142
+ body: Body extends Record<string, unknown>
143
+ ? ReplaceBlobWithFiles<Body>
144
+ : Body,
145
+ options: Prettify<Param & TreatyParam>
146
+ ) => Promise<
147
+ TreatyResponse<
148
+ ReplaceGeneratorWithAsyncGenerator<Response>
149
+ >
150
+ >
151
+ : never
152
+ : CreateParams<Route[K]>
153
+ }
154
+
155
+ type CreateParams<Route extends Record<string, any>> = Extract<
156
+ keyof Route,
157
+ `:${string}`
158
+ > extends infer Path extends string
159
+ ? IsNever<Path> extends true
160
+ ? Prettify<Sign<Route>>
161
+ : // ! DO NOT USE PRETTIFY ON THIS LINE, OTHERWISE FUNCTION CALLING WILL BE OMITTED
162
+ (((params: {
163
+ [param in Path extends `:${infer Param}`
164
+ ? Param extends `${infer Param}?`
165
+ ? Param
166
+ : Param
167
+ : never]: string | number
168
+ }) => Prettify<Sign<Route[Path]>> & CreateParams<Route[Path]>) &
169
+ Prettify<Sign<Route>>) &
170
+ (Path extends `:${string}?`
171
+ ? CreateParams<Route[Path]>
172
+ : {})
173
+ : never
174
+
175
+ export interface Config {
176
+ fetch?: Omit<RequestInit, 'headers' | 'method'>
177
+ fetcher?: typeof fetch
178
+ headers?: MaybeArray<
179
+ | RequestInit['headers']
180
+ | ((
181
+ path: string,
182
+ options: RequestInit
183
+ ) => RequestInit['headers'] | void)
184
+ >
185
+ onRequest?: MaybeArray<
186
+ (
187
+ path: string,
188
+ options: RequestInit
189
+ ) => MaybePromise<RequestInit | void>
190
+ >
191
+ onResponse?: MaybeArray<(response: Response) => MaybePromise<unknown>>
192
+ keepDomain?: boolean
193
+ }
194
+
195
+ // type UnwrapAwaited<T extends Record<number, unknown>> = {
196
+ // [K in keyof T]: Awaited<T[K]>
197
+ // }
198
+
199
+ export type TreatyResponse<Res extends Record<number, unknown>> =
200
+ | {
201
+ data: Res[200]
202
+ error: null
203
+ response: Response
204
+ status: number
205
+ headers: RequestInit['headers']
206
+ }
207
+ | {
208
+ data: null
209
+ error: Exclude<keyof Res, 200> extends never
210
+ ? EdenFetchError<number, any>
211
+ : {
212
+ [Status in keyof Res]: EdenFetchError<
213
+ Status,
214
+ Res[Status]
215
+ >
216
+ }[Exclude<keyof Res, 200>]
217
+ response: Response
218
+ status: number
219
+ headers: RequestInit['headers']
220
+ }
221
+
222
+ export interface OnMessage<Data = unknown> extends MessageEvent {
223
+ data: Data
224
+ rawData: MessageEvent['data']
225
+ }
226
+
227
+ export type WSEvent<
228
+ K extends keyof WebSocketEventMap,
229
+ Data = unknown
230
+ > = K extends 'message' ? OnMessage<Data> : WebSocketEventMap[K]
231
+ }
232
+
233
+ export type Not<T> = T extends true ? false : true
@@ -0,0 +1,7 @@
1
+ export function parseStringifiedValue(value: string) {
2
+ try {
3
+ return JSON.parse(value)
4
+ } catch (error) {
5
+ return value
6
+ }
7
+ }
@@ -0,0 +1,99 @@
1
+ import type { InputSchema } from '../elysia-fork/types'
2
+ import type { SpiceflowClient } from './types'
3
+ import { parseStringifiedValue } from './utils'
4
+
5
+ export class EdenWS<in out Schema extends InputSchema<any> = {}> {
6
+ ws: WebSocket
7
+
8
+ constructor(public url: string) {
9
+ this.ws = new WebSocket(url)
10
+ }
11
+
12
+ send(data: Schema['body'] | Schema['body'][]) {
13
+ if (Array.isArray(data)) {
14
+ data.forEach((datum) => this.send(datum))
15
+
16
+ return this
17
+ }
18
+
19
+ this.ws.send(
20
+ typeof data === 'object' ? JSON.stringify(data) : data.toString()
21
+ )
22
+
23
+ return this
24
+ }
25
+
26
+ on<K extends keyof WebSocketEventMap>(
27
+ type: K,
28
+ listener: (event: SpiceflowClient.WSEvent<K, Schema['response']>) => void,
29
+ options?: boolean | AddEventListenerOptions
30
+ ) {
31
+ return this.addEventListener(type, listener, options)
32
+ }
33
+
34
+ off<K extends keyof WebSocketEventMap>(
35
+ type: K,
36
+ listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,
37
+ options?: boolean | EventListenerOptions
38
+ ) {
39
+ this.ws.removeEventListener(type, listener, options)
40
+
41
+ return this
42
+ }
43
+
44
+ subscribe(
45
+ onMessage: (
46
+ event: SpiceflowClient.WSEvent<'message', Schema['response']>
47
+ ) => void,
48
+ options?: boolean | AddEventListenerOptions
49
+ ) {
50
+ return this.addEventListener('message', onMessage, options)
51
+ }
52
+
53
+ addEventListener<K extends keyof WebSocketEventMap>(
54
+ type: K,
55
+ listener: (event: SpiceflowClient.WSEvent<K, Schema['response']>) => void,
56
+ options?: boolean | AddEventListenerOptions
57
+ ) {
58
+ this.ws.addEventListener(
59
+ type,
60
+ (ws) => {
61
+ if (type === 'message') {
62
+ const data = parseMessageEvent(ws as MessageEvent)
63
+
64
+ listener({
65
+ ...ws,
66
+ data
67
+ } as any)
68
+ } else listener(ws as any)
69
+ },
70
+ options
71
+ )
72
+
73
+ return this
74
+ }
75
+
76
+ removeEventListener<K extends keyof WebSocketEventMap>(
77
+ type: K,
78
+ listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,
79
+ options?: boolean | EventListenerOptions
80
+ ) {
81
+ this.off(type, listener, options)
82
+
83
+ return this
84
+ }
85
+
86
+ close() {
87
+ this.ws.close()
88
+
89
+ return this
90
+ }
91
+ }
92
+
93
+ const parseMessageEvent = (event: MessageEvent) => {
94
+ const messageString = event.data.toString()
95
+
96
+ return messageString === 'null'
97
+ ? null
98
+ : parseStringifiedValue(messageString)
99
+ }
@@ -0,0 +1,235 @@
1
+ import { createSpiceflowClient } from './client'
2
+ import { Spiceflow, t } from './spiceflow'
3
+
4
+ import { describe, expect, it } from 'vitest'
5
+
6
+ const randomObject = {
7
+ a: 'a',
8
+ b: 2,
9
+ c: true,
10
+ d: false,
11
+ e: null,
12
+ f: new Date(0)
13
+ }
14
+ const randomArray = [
15
+ 'a',
16
+ 2,
17
+ true,
18
+ false,
19
+ null,
20
+ new Date(0),
21
+ { a: 'a', b: 2, c: true, d: false, e: null, f: new Date(0) }
22
+ ]
23
+
24
+ const app = new Spiceflow()
25
+ .get('/', () => 'a')
26
+ .post('/', () => 'a')
27
+ .get('/number', () => 1)
28
+ .get('/true', () => true)
29
+ .get('/false', () => false)
30
+ .post('/array', ({ body }) => body, {
31
+ body: t.Array(t.String())
32
+ })
33
+ .post('/mirror', ({ body }) => body)
34
+ .post('/body', ({ body }) => body, {
35
+ body: t.String()
36
+ })
37
+ .delete('/empty', ({ body }) => ({ body: body ?? null }))
38
+ .post('/deep/nested/mirror', ({ body }) => body, {
39
+ body: t.Object({
40
+ username: t.String(),
41
+ password: t.String()
42
+ })
43
+ })
44
+
45
+ .use(new Spiceflow({ basePath: '/nested' }).get('/data', ({ params }) => 'hi'))
46
+ // .get('/error', ({ error }) => error("I'm a teapot", 'Kirifuji Nagisa'), {
47
+ // response: {
48
+ // 200: t.Void(),
49
+ // 418: t.Literal('Kirifuji Nagisa'),
50
+ // 420: t.Literal('Snoop Dogg')
51
+ // }
52
+ // })
53
+ .get(
54
+ '/validationError',
55
+ // @ts-expect-error
56
+ () => {
57
+ return 'this errors because validation is wrong'
58
+ },
59
+ {
60
+ response: {
61
+ 200: t.Object({
62
+ x: t.String()
63
+ })
64
+ }
65
+ }
66
+ )
67
+
68
+ .post('/date', ({ body: { date } }) => date, {
69
+ body: t.Object({
70
+ date: t.Date()
71
+ })
72
+ })
73
+ .get('/dateObject', () => ({ date: new Date() }))
74
+ .get('/redirect', ({ redirect }) => redirect('http://localhost:8083/true'))
75
+ .post(
76
+ '/redirect',
77
+ ({ redirect }) => redirect('http://localhost:8083/true'),
78
+ {
79
+ body: t.Object({
80
+ username: t.String()
81
+ })
82
+ }
83
+ )
84
+ // .get('/formdata', () => ({
85
+ // image: Bun.file('./test/kyuukurarin.mp4')
86
+ // }))
87
+
88
+ .get('/stream', function* stream() {
89
+ yield 'a'
90
+ yield 'b'
91
+ yield 'c'
92
+ })
93
+ .get('/stream-async', async function* stream() {
94
+ yield 'a'
95
+ yield 'b'
96
+ yield 'c'
97
+ })
98
+ .get('/stream-return', function* stream() {
99
+ return 'a'
100
+ })
101
+ .get('/stream-return-async', function* stream() {
102
+ return 'a'
103
+ })
104
+ .get('/id/:id?', ({ params: { id = 'unknown' } }) => id)
105
+
106
+ const client = createSpiceflowClient(app)
107
+
108
+ describe('client', () => {
109
+ it('get index', async () => {
110
+ const { data, error } = await client.index.get()
111
+
112
+ expect(data).toBe('a')
113
+ expect(error).toBeNull()
114
+ })
115
+
116
+ it('post index', async () => {
117
+ const { data, error } = await client.index.post()
118
+
119
+ expect(data).toBe('a')
120
+ expect(error).toBeNull()
121
+ })
122
+
123
+ it('parse number', async () => {
124
+ const { data } = await client.number.get()
125
+
126
+ expect(data).toEqual(1)
127
+ })
128
+
129
+ it('parse true', async () => {
130
+ const { data } = await client.true.get()
131
+
132
+ expect(data).toEqual(true)
133
+ })
134
+
135
+ it('parse false', async () => {
136
+ const { data } = await client.false.get()
137
+
138
+ expect(data).toEqual(false)
139
+ })
140
+
141
+ it.todo('parse object with date', async () => {
142
+ const { data } = await client.dateObject.get()
143
+
144
+ expect(data?.date).toBeInstanceOf(Date)
145
+ })
146
+
147
+ it('post array', async () => {
148
+ const { data } = await client.array.post(['a', 'b'])
149
+
150
+ expect(data).toEqual(['a', 'b'])
151
+ })
152
+
153
+ it('post body', async () => {
154
+ const { data } = await client.body.post('a')
155
+
156
+ expect(data).toEqual('a')
157
+ })
158
+
159
+ it('post mirror', async () => {
160
+ const body = { username: 'A', password: 'B' }
161
+
162
+ const { data } = await client.mirror.post(body)
163
+
164
+ expect(data).toEqual(body)
165
+ })
166
+
167
+ it('delete empty', async () => {
168
+ const { data } = await client.empty.delete()
169
+
170
+ expect(data).toEqual({ body: null })
171
+ })
172
+
173
+ it('post deep nested mirror', async () => {
174
+ const body = { username: 'A', password: 'B' }
175
+
176
+ const { data } = await client.deep.nested.mirror.post(body)
177
+
178
+ expect(data).toEqual(body)
179
+ })
180
+
181
+ it('get nested data', async () => {
182
+ const { data } = await client.nested.data.get()
183
+
184
+ expect(data).toEqual('hi')
185
+ })
186
+
187
+ it('stream ', async () => {
188
+ const { data } = await client.stream.get()
189
+ let all = ''
190
+ for await (const chunk of data!) {
191
+ // console.log(chunk)
192
+ all += chunk + '-'
193
+ }
194
+ expect(all).toEqual('a-b-c-')
195
+ })
196
+ it('stream async', async () => {
197
+ const { data } = await client['stream-async'].get()
198
+ let all = ''
199
+ for await (const chunk of data!) {
200
+ // console.log(chunk)
201
+ all += chunk + '-'
202
+ }
203
+ expect(all).toEqual('a-b-c-')
204
+ })
205
+
206
+ it('stream return', async () => {
207
+ const { data } = await client['stream-return'].get()
208
+ expect(data).toEqual('a')
209
+ })
210
+ it('stream return async', async () => {
211
+ const { data } = await client['stream-return-async'].get()
212
+ // console.log(data)
213
+ expect(data).toEqual('a')
214
+ })
215
+
216
+ // it('handle error', async () => {
217
+ // const { data, error } = await client.error.get()
218
+
219
+ // let value
220
+
221
+ // if (error)
222
+ // switch (error.status) {
223
+ // case 418:
224
+ // value = error.value
225
+ // break
226
+
227
+ // case 420:
228
+ // value = error.value
229
+ // break
230
+ // }
231
+
232
+ // expect(data).toBeNull()
233
+ // expect(value).toEqual('Kirifuji Nagisa')
234
+ // })
235
+ })