spiceflow 1.0.8 → 1.1.0

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 (71) hide show
  1. package/README.md +1 -1
  2. package/dist/client/index.d.ts +1 -1
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/client/types.d.ts +1 -1
  6. package/dist/client/types.d.ts.map +1 -1
  7. package/dist/client/ws.d.ts +1 -1
  8. package/dist/client/ws.d.ts.map +1 -1
  9. package/dist/client.test.js +1 -18
  10. package/dist/client.test.js.map +1 -1
  11. package/dist/{elysia-fork/context.d.ts → context.d.ts} +8 -7
  12. package/dist/context.d.ts.map +1 -0
  13. package/dist/{elysia-fork/context.js.map → context.js.map} +1 -1
  14. package/dist/error.d.ts.map +1 -0
  15. package/dist/error.js.map +1 -0
  16. package/dist/index.d.ts +1 -2
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +1 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/middleware.test.d.ts +2 -0
  21. package/dist/middleware.test.d.ts.map +1 -0
  22. package/dist/middleware.test.js +99 -0
  23. package/dist/middleware.test.js.map +1 -0
  24. package/dist/openapi.d.ts +4 -15
  25. package/dist/openapi.d.ts.map +1 -1
  26. package/dist/spiceflow.d.ts +39 -120
  27. package/dist/spiceflow.d.ts.map +1 -1
  28. package/dist/spiceflow.js +128 -165
  29. package/dist/spiceflow.js.map +1 -1
  30. package/dist/spiceflow.test.js +54 -16
  31. package/dist/spiceflow.test.js.map +1 -1
  32. package/dist/types.d.ts +406 -0
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/types.js +1 -1
  35. package/dist/types.js.map +1 -1
  36. package/dist/utils.d.ts +72 -0
  37. package/dist/utils.d.ts.map +1 -1
  38. package/dist/utils.js +69 -0
  39. package/dist/utils.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/client/index.ts +1 -3
  42. package/src/client/types.ts +6 -13
  43. package/src/client/ws.ts +1 -1
  44. package/src/client.test.ts +1 -19
  45. package/src/context.ts +128 -0
  46. package/src/index.ts +1 -2
  47. package/src/middleware.test.ts +107 -0
  48. package/src/openapi.ts +1 -1
  49. package/src/spiceflow.test.ts +74 -16
  50. package/src/spiceflow.ts +212 -385
  51. package/src/types.test.ts +1 -1
  52. package/src/types.ts +926 -0
  53. package/src/utils.ts +84 -0
  54. package/dist/elysia-fork/context.d.ts.map +0 -1
  55. package/dist/elysia-fork/error.d.ts.map +0 -1
  56. package/dist/elysia-fork/error.js.map +0 -1
  57. package/dist/elysia-fork/types.d.ts +0 -560
  58. package/dist/elysia-fork/types.d.ts.map +0 -1
  59. package/dist/elysia-fork/types.js +0 -2
  60. package/dist/elysia-fork/types.js.map +0 -1
  61. package/dist/elysia-fork/utils.d.ts +0 -73
  62. package/dist/elysia-fork/utils.d.ts.map +0 -1
  63. package/dist/elysia-fork/utils.js +0 -70
  64. package/dist/elysia-fork/utils.js.map +0 -1
  65. package/src/elysia-fork/context.ts +0 -166
  66. package/src/elysia-fork/types.ts +0 -1281
  67. package/src/elysia-fork/utils.ts +0 -85
  68. /package/dist/{elysia-fork/context.js → context.js} +0 -0
  69. /package/dist/{elysia-fork/error.d.ts → error.d.ts} +0 -0
  70. /package/dist/{elysia-fork/error.js → error.js} +0 -0
  71. /package/src/{elysia-fork/error.ts → error.ts} +0 -0
package/src/types.ts CHANGED
@@ -0,0 +1,926 @@
1
+ // https://github.com/remorses/elysia/blob/main/src/types.ts#L6
2
+ /// <reference types="bun-types" />
3
+ import z from 'zod'
4
+
5
+ import type { BunFile, Server } from 'bun'
6
+
7
+ import type {
8
+ OptionalKind,
9
+ Static,
10
+ StaticDecode,
11
+ TObject,
12
+ TSchema,
13
+ } from '@sinclair/typebox'
14
+
15
+ import type { OpenAPIV3 } from 'openapi-types'
16
+
17
+ import { ZodObject, ZodTypeAny } from 'zod'
18
+ import type { Context, ErrorContext, MiddlewareContext } from './context.js'
19
+ import {
20
+ ELYSIA_RESPONSE,
21
+ InternalServerError,
22
+ NotFoundError,
23
+ ParseError,
24
+ ValidationError,
25
+ } from './error.js'
26
+ import { AnySpiceflow, Spiceflow } from './spiceflow.js'
27
+
28
+ export type MaybeArray<T> = T | T[]
29
+ export type MaybePromise<T> = T | Promise<T>
30
+
31
+ export type ObjectValues<T extends object> = T[keyof T]
32
+
33
+ type IsPathParameter<Part extends string> = Part extends `:${infer Parameter}`
34
+ ? Parameter
35
+ : Part extends `*`
36
+ ? '*'
37
+ : never
38
+
39
+ export type GetPathParameter<Path extends string> =
40
+ Path extends `${infer A}/${infer B}`
41
+ ? IsPathParameter<A> | GetPathParameter<B>
42
+ : IsPathParameter<Path>
43
+
44
+ export type ResolvePath<Path extends string> = Prettify<
45
+ {
46
+ [Param in GetPathParameter<Path> as Param extends `${string}?`
47
+ ? never
48
+ : Param]: string
49
+ } & {
50
+ [Param in GetPathParameter<Path> as Param extends `${infer OptionalParam}?`
51
+ ? OptionalParam
52
+ : never]?: string
53
+ }
54
+ >
55
+
56
+ // https://twitter.com/mattpocockuk/status/1622730173446557697?s=20
57
+ export type Prettify<T> = {
58
+ [K in keyof T]: T[K]
59
+ } & {}
60
+
61
+ export type Prettify2<T> = {
62
+ [K in keyof T]: Prettify<T[K]>
63
+ } & {}
64
+
65
+ export type Partial2<T> = {
66
+ [K in keyof T]?: Partial<T[K]>
67
+ }
68
+
69
+ export type NeverKey<T> = {
70
+ [K in keyof T]?: T[K]
71
+ } & {}
72
+
73
+ type IsBothObject<A, B> = A extends Record<string | number | symbol, unknown>
74
+ ? B extends Record<string | number | symbol, unknown>
75
+ ? IsClass<A> extends false
76
+ ? IsClass<B> extends false
77
+ ? true
78
+ : false
79
+ : false
80
+ : false
81
+ : false
82
+
83
+ type IsClass<V> = V extends abstract new (...args: any) => any ? true : false
84
+ type And<A, B> = A extends true ? (B extends true ? true : false) : false
85
+
86
+ export type Reconcile<
87
+ A extends Object,
88
+ B extends Object,
89
+ Override extends boolean = false,
90
+ // Detect Stack limit, eg. circular dependency
91
+ Stack extends number[] = [],
92
+ > = Stack['length'] extends 16
93
+ ? A
94
+ : Override extends true
95
+ ? {
96
+ [key in keyof A as key extends keyof B ? never : key]: A[key]
97
+ } extends infer Collision
98
+ ? {} extends Collision
99
+ ? {
100
+ [key in keyof B]: IsBothObject<
101
+ // @ts-ignore trust me bro
102
+ A[key],
103
+ B[key]
104
+ > extends true
105
+ ? Reconcile<
106
+ // @ts-ignore trust me bro
107
+ A[key],
108
+ B[key],
109
+ Override,
110
+ [0, ...Stack]
111
+ >
112
+ : B[key]
113
+ }
114
+ : Prettify<
115
+ Collision & {
116
+ [key in keyof B]: B[key]
117
+ }
118
+ >
119
+ : never
120
+ : {
121
+ [key in keyof B as key extends keyof A ? never : key]: B[key]
122
+ } extends infer Collision
123
+ ? {} extends Collision
124
+ ? {
125
+ [key in keyof A]: IsBothObject<
126
+ A[key],
127
+ // @ts-ignore trust me bro
128
+ B[key]
129
+ > extends true
130
+ ? Reconcile<
131
+ // @ts-ignore trust me bro
132
+ A[key],
133
+ // @ts-ignore trust me bro
134
+ B[key],
135
+ Override,
136
+ [0, ...Stack]
137
+ >
138
+ : A[key]
139
+ }
140
+ : Prettify<
141
+ {
142
+ [key in keyof A]: A[key]
143
+ } & Collision
144
+ >
145
+ : never
146
+
147
+ export interface SingletonBase {
148
+ store: Record<string, unknown>
149
+ }
150
+
151
+ export interface DefinitionBase {
152
+ type: Record<string, unknown>
153
+ error: Record<string, Error>
154
+ }
155
+
156
+ export type RouteBase = Record<string, unknown>
157
+
158
+ export interface MetadataBase {
159
+ schema: RouteSchema
160
+ macro: BaseMacro
161
+ macroFn: BaseMacroFn
162
+ }
163
+
164
+ export interface RouteSchema {
165
+ body?: unknown
166
+ query?: unknown
167
+ params?: unknown
168
+ response?: unknown
169
+ }
170
+
171
+ type OptionalField = {
172
+ [OptionalKind]: 'Optional'
173
+ }
174
+
175
+ export type TypeSchema = TSchema | ZodTypeAny
176
+
177
+ export type TypeObject = TObject | ZodObject<any, any, any>
178
+
179
+ export type UnwrapSchema<
180
+ Schema extends TypeSchema | string | undefined,
181
+ Definitions extends Record<string, unknown> = {},
182
+ > = undefined extends Schema
183
+ ? unknown
184
+ : Schema extends ZodTypeAny
185
+ ? z.infer<Schema>
186
+ : Schema extends TSchema
187
+ ? Schema extends OptionalField
188
+ ? Prettify<Partial<Static<Schema>>>
189
+ : StaticDecode<Schema>
190
+ : Schema extends string
191
+ ? Definitions extends Record<Schema, infer NamedSchema>
192
+ ? NamedSchema
193
+ : Definitions
194
+ : unknown
195
+
196
+ export interface UnwrapRoute<
197
+ in out Schema extends InputSchema<any>,
198
+ in out Definitions extends DefinitionBase['type'] = {},
199
+ > {
200
+ body: UnwrapSchema<Schema['body'], Definitions>
201
+ query: UnwrapSchema<Schema['query'], Definitions>
202
+ params: UnwrapSchema<Schema['params'], Definitions>
203
+ response: Schema['response'] extends TypeSchema | string
204
+ ? {
205
+ 200: CoExist<
206
+ UnwrapSchema<Schema['response'], Definitions>,
207
+ File,
208
+ BunFile
209
+ >
210
+ }
211
+ : Schema['response'] extends Record<number, TypeSchema | string>
212
+ ? {
213
+ [k in keyof Schema['response']]: CoExist<
214
+ UnwrapSchema<Schema['response'][k], Definitions>,
215
+ File,
216
+ BunFile
217
+ >
218
+ }
219
+ : unknown | void
220
+ }
221
+
222
+ export type LifeCycleEvent =
223
+ | 'start'
224
+ | 'request'
225
+ | 'parse'
226
+ | 'transform'
227
+ | 'beforeHandle'
228
+ | 'afterHandle'
229
+ | 'response'
230
+ | 'error'
231
+ | 'stop'
232
+
233
+ export type ContentType = MaybeArray<
234
+ | (string & {})
235
+ | 'none'
236
+ | 'text'
237
+ | 'json'
238
+ | 'formdata'
239
+ | 'urlencoded'
240
+ | 'arrayBuffer'
241
+ | 'text/plain'
242
+ | 'application/json'
243
+ | 'multipart/form-data'
244
+ | 'application/x-www-form-urlencoded'
245
+ >
246
+
247
+ export type HTTPMethod =
248
+ | (string & {})
249
+ | 'ACL'
250
+ | 'BIND'
251
+ | 'CHECKOUT'
252
+ | 'CONNECT'
253
+ | 'COPY'
254
+ | 'DELETE'
255
+ | 'GET'
256
+ | 'HEAD'
257
+ | 'LINK'
258
+ | 'LOCK'
259
+ | 'M-SEARCH'
260
+ | 'MERGE'
261
+ | 'MKACTIVITY'
262
+ | 'MKCALENDAR'
263
+ | 'MKCOL'
264
+ | 'MOVE'
265
+ | 'NOTIFY'
266
+ | 'OPTIONS'
267
+ | 'PATCH'
268
+ | 'POST'
269
+ | 'PROPFIND'
270
+ | 'PROPPATCH'
271
+ | 'PURGE'
272
+ | 'PUT'
273
+ | 'REBIND'
274
+ | 'REPORT'
275
+ | 'SEARCH'
276
+ | 'SOURCE'
277
+ | 'SUBSCRIBE'
278
+ | 'TRACE'
279
+ | 'UNBIND'
280
+ | 'UNLINK'
281
+ | 'UNLOCK'
282
+ | 'UNSUBSCRIBE'
283
+ | 'ALL'
284
+
285
+ export interface InputSchema<Name extends string = string> {
286
+ body?: TypeSchema | Name
287
+ query?: TypeObject | Name
288
+ params?: TypeObject | Name
289
+ response?:
290
+ | TypeSchema
291
+ | Record<number, TypeSchema>
292
+ | Name
293
+ | Record<number, Name | TypeSchema>
294
+ }
295
+
296
+ export interface MergeSchema<
297
+ in out A extends RouteSchema,
298
+ in out B extends RouteSchema,
299
+ > {
300
+ body: undefined extends A['body'] ? B['body'] : A['body']
301
+ query: undefined extends A['query'] ? B['query'] : A['query']
302
+ params: undefined extends A['params'] ? B['params'] : A['params']
303
+ response: {} extends A['response']
304
+ ? {} extends B['response']
305
+ ? {}
306
+ : B['response']
307
+ : {} extends B['response']
308
+ ? A['response']
309
+ : A['response'] & Omit<B['response'], keyof A['response']>
310
+ }
311
+
312
+ export type Handler<
313
+ in out Route extends RouteSchema = {},
314
+ in out Singleton extends SingletonBase = {
315
+ decorator: {}
316
+ store: {}
317
+ },
318
+ Path extends string = '',
319
+ > = (
320
+ context: Context<Route, Singleton, Path>,
321
+ ) => MaybePromise<
322
+ {} extends Route['response']
323
+ ? unknown
324
+ : Route['response'][keyof Route['response']]
325
+ >
326
+
327
+ export type Replace<Original, Target, With> = IsAny<Target> extends true
328
+ ? Original
329
+ : Original extends Record<string, unknown>
330
+ ? {
331
+ [K in keyof Original]: Original[K] extends Target
332
+ ? With
333
+ : Original[K]
334
+ }
335
+ : Original extends Target
336
+ ? With
337
+ : Original
338
+
339
+ export type IsAny<T> = 0 extends 1 & T ? true : false
340
+
341
+ export type CoExist<Original, Target, With> = IsAny<Target> extends true
342
+ ? Original
343
+ : Original extends Record<string, unknown>
344
+ ? {
345
+ [K in keyof Original]: Original[K] extends Target
346
+ ? Original[K] | With
347
+ : Original[K]
348
+ }
349
+ : Original extends Target
350
+ ? Original | With
351
+ : Original
352
+
353
+ export type InlineHandler<
354
+ Route extends RouteSchema = {},
355
+ Singleton extends SingletonBase = {
356
+ decorator: {}
357
+ store: {}
358
+ },
359
+ Path extends string = '',
360
+ MacroContext = {},
361
+ > = (
362
+ context: MacroContext extends Record<string | number | symbol, unknown>
363
+ ? Prettify<MacroContext & Context<Route, Singleton, Path>>
364
+ : Context<Route, Singleton, Path>,
365
+ ) =>
366
+ | Response
367
+ | MaybePromise<
368
+ {} extends Route['response']
369
+ ? unknown
370
+ :
371
+ | (Route['response'] extends { 200: any }
372
+ ? Route['response']
373
+ : string | number | boolean | Object)
374
+ | Route['response'][keyof Route['response']]
375
+ | {
376
+ [Status in keyof Route['response']]: {
377
+ _type: Record<
378
+ Status,
379
+ Route['response'][Status]
380
+ >
381
+ [ELYSIA_RESPONSE]: Status
382
+ }
383
+ }[keyof Route['response']]
384
+ >
385
+
386
+ export type OptionalHandler<
387
+ in out Route extends RouteSchema = {},
388
+ in out Singleton extends SingletonBase = {
389
+ decorator: {}
390
+ store: {}
391
+ },
392
+ Path extends string = '',
393
+ > = Handler<Route, Singleton, Path> extends (
394
+ context: infer Context,
395
+ ) => infer Returned
396
+ ? (context: Context) => Returned | MaybePromise<void>
397
+ : never
398
+
399
+ export type AfterHandler<
400
+ in out Route extends RouteSchema = {},
401
+ in out Singleton extends SingletonBase = {
402
+ decorator: {}
403
+ store: {}
404
+ },
405
+ Path extends string = '',
406
+ > = Handler<Route, Singleton, Path> extends (
407
+ context: infer Context,
408
+ ) => infer Returned
409
+ ? (
410
+ context: Prettify<
411
+ {
412
+ response: Route['response']
413
+ } & Context
414
+ >,
415
+ ) => Returned | MaybePromise<void>
416
+ : never
417
+
418
+ export type MapResponse<
419
+ in out Route extends RouteSchema = {},
420
+ in out Singleton extends SingletonBase = {
421
+ decorator: {}
422
+ store: {}
423
+ },
424
+ Path extends string = '',
425
+ > = Handler<
426
+ Omit<Route, 'response'> & {
427
+ response: MaybePromise<Response | undefined | unknown>
428
+ },
429
+ Singleton & {
430
+ derive: {
431
+ response: Route['response']
432
+ }
433
+ },
434
+ Path
435
+ >
436
+
437
+ export type VoidHandler<
438
+ in out Route extends RouteSchema = {},
439
+ in out Singleton extends SingletonBase = {
440
+ decorator: {}
441
+ store: {}
442
+ },
443
+ > = (context: Context<Route, Singleton>) => MaybePromise<void>
444
+
445
+ export type TransformHandler<
446
+ in out Route extends RouteSchema = {},
447
+ in out Singleton extends SingletonBase = {
448
+ decorator: {}
449
+ store: {}
450
+ },
451
+ BasePath extends string = '',
452
+ > = {
453
+ (
454
+ context: Prettify<
455
+ Context<
456
+ Route,
457
+ Omit<Singleton, 'resolve'> & {
458
+ resolve: {}
459
+ },
460
+ BasePath
461
+ >
462
+ >,
463
+ ): MaybePromise<void>
464
+ }
465
+
466
+ export type BodyHandler<
467
+ in out Route extends RouteSchema = {},
468
+ in out Singleton extends SingletonBase = {
469
+ decorator: {}
470
+ store: {}
471
+ },
472
+ Path extends string = '',
473
+ > = (
474
+ context: Prettify<
475
+ {
476
+ contentType: string
477
+ } & Context<Route, Singleton, Path>
478
+ >,
479
+ /**
480
+ * @deprecated
481
+ *
482
+ * use `context.contentType` instead
483
+ *
484
+ * @example
485
+ * ```ts
486
+ * new Spiceflow()
487
+ * .onParse(({ contentType, request }) => {
488
+ * if (contentType === 'application/json')
489
+ * return request.json()
490
+ * })
491
+ * ```
492
+ */
493
+ contentType: string,
494
+ ) => MaybePromise<any>
495
+
496
+ export type MiddlewareHandler<
497
+ in out Route extends RouteSchema = {},
498
+ in out Singleton extends SingletonBase = {
499
+ decorator: {}
500
+ store: {}
501
+ },
502
+ > = (
503
+ context: MiddlewareContext<Singleton>,
504
+ next: () => Promise<Response | void>,
505
+ ) => MaybePromise<Route['response'] | void>
506
+
507
+ export type AfterResponseHandler<
508
+ in out Route extends RouteSchema = {},
509
+ in out Singleton extends SingletonBase = {
510
+ decorator: {}
511
+ store: {}
512
+ },
513
+ > = (
514
+ context: Prettify<
515
+ Context<Route, Singleton> & {
516
+ response: Route['response']
517
+ }
518
+ >,
519
+ ) => MaybePromise<void>
520
+
521
+ // export type GracefulHandler<
522
+ // in Instance extends AnySpiceflow,
523
+ // > = (data: Instance) => any
524
+
525
+ export type ErrorHandler<
526
+ in out T extends Record<string, Error> = {},
527
+ in out Route extends RouteSchema = {},
528
+ in out Singleton extends SingletonBase = {
529
+ store: {}
530
+ },
531
+ > = (
532
+ context: ErrorContext<
533
+ Route,
534
+ {
535
+ store: Singleton['store']
536
+ }
537
+ > &
538
+ (
539
+ | Prettify<
540
+ {
541
+ request: Request
542
+ code: 'UNKNOWN'
543
+ error: Readonly<Error>
544
+ } & Partial<Singleton['store']>
545
+ >
546
+ | Prettify<
547
+ {
548
+ request: Request
549
+ code: 'VALIDATION'
550
+ error: Readonly<ValidationError>
551
+ } & Singleton['store']
552
+ >
553
+ | Prettify<
554
+ {
555
+ request: Request
556
+ code: 'NOT_FOUND'
557
+ error: Readonly<NotFoundError>
558
+ } & NeverKey<Singleton['store']>
559
+ >
560
+ | Prettify<
561
+ {
562
+ request: Request
563
+ code: 'PARSE'
564
+ error: Readonly<ParseError>
565
+ } & Singleton['store']
566
+ >
567
+ | Prettify<
568
+ {
569
+ request: Request
570
+ code: 'INTERNAL_SERVER_ERROR'
571
+ error: Readonly<InternalServerError>
572
+ } & Partial<Singleton['store']>
573
+ >
574
+ | Prettify<
575
+ {
576
+ [K in keyof T]: {
577
+ request: Request
578
+ code: K
579
+ error: Readonly<T[K]>
580
+ }
581
+ }[keyof T] &
582
+ Partial<Singleton['store']>
583
+ >
584
+ ),
585
+ ) => any | Promise<any>
586
+
587
+ export type Isolate<T> = {
588
+ [P in keyof T]: T[P]
589
+ }
590
+
591
+ export type DocumentDecoration = Partial<OpenAPIV3.OperationObject> & {
592
+ /**
593
+ * Pass `true` to hide route from OpenAPI/swagger document
594
+ * */
595
+ hide?: boolean
596
+ }
597
+
598
+ export type LocalHook<
599
+ LocalSchema extends InputSchema,
600
+ Schema extends RouteSchema,
601
+ Singleton extends SingletonBase,
602
+ Errors extends Record<string, Error>,
603
+ Extension extends BaseMacro,
604
+ Path extends string = '',
605
+ TypedRoute extends RouteSchema = Schema extends {
606
+ params: Record<string, unknown>
607
+ }
608
+ ? Schema
609
+ : Schema & {
610
+ params: undefined extends Schema['params']
611
+ ? ResolvePath<Path>
612
+ : Schema['params']
613
+ },
614
+ > = (LocalSchema extends {} ? LocalSchema : Isolate<LocalSchema>) &
615
+ Extension & {
616
+ detail?: DocumentDecoration
617
+ /**
618
+ * Short for 'Content-Type'
619
+ *
620
+ * Available:
621
+ * - 'none': do not parse body
622
+ * - 'text' / 'text/plain': parse body as string
623
+ * - 'json' / 'application/json': parse body as json
624
+ * - 'formdata' / 'multipart/form-data': parse body as form-data
625
+ * - 'urlencoded' / 'application/x-www-form-urlencoded: parse body as urlencoded
626
+ * - 'arraybuffer': parse body as readable stream
627
+ */
628
+ type?: ContentType
629
+ }
630
+
631
+ export type ComposedHandler = (context: Context) => MaybePromise<Response>
632
+
633
+ export interface InternalRoute {
634
+ method: HTTPMethod
635
+ path: string
636
+ composed: ComposedHandler | Response | null
637
+ handler: Handler
638
+ hooks: LocalHook<any, any, any, any, any, any, any>
639
+ }
640
+
641
+ export type ListenCallback = (server: Server) => MaybePromise<void>
642
+
643
+ export type AddPrefix<Prefix extends string, T> = {
644
+ [K in keyof T as Prefix extends string ? `${Prefix}${K & string}` : K]: T[K]
645
+ }
646
+
647
+ export type AddPrefixCapitalize<Prefix extends string, T> = {
648
+ [K in keyof T as `${Prefix}${Capitalize<K & string>}`]: T[K]
649
+ }
650
+
651
+ export type AddSuffix<Suffix extends string, T> = {
652
+ [K in keyof T as `${K & string}${Suffix}`]: T[K]
653
+ }
654
+
655
+ export type AddSuffixCapitalize<Suffix extends string, T> = {
656
+ [K in keyof T as `${K & string}${Capitalize<Suffix>}`]: T[K]
657
+ }
658
+
659
+ export type BaseMacro = Record<
660
+ string,
661
+ string | number | boolean | Object | undefined | null
662
+ >
663
+ export type BaseMacroFn = Record<string, (...a: any) => unknown>
664
+
665
+ type _CreateEden<
666
+ Path extends string,
667
+ Property extends Record<string, unknown> = {},
668
+ > = Path extends `${infer Start}/${infer Rest}`
669
+ ? {
670
+ [x in Start]: _CreateEden<Rest, Property>
671
+ }
672
+ : {
673
+ [x in Path]: Property
674
+ }
675
+
676
+ export type CreateEden<
677
+ Path extends string,
678
+ Property extends Record<string, unknown> = {},
679
+ > = Path extends `/${infer Rest}`
680
+ ? _CreateEden<Rest, Property>
681
+ : Path extends ''
682
+ ? _CreateEden<'index', Property>
683
+ : _CreateEden<Path, Property>
684
+
685
+ export type ComposeSpiceflowResponse<Response, Handle> = Handle extends (
686
+ ...a: any[]
687
+ ) => infer A
688
+ ? _ComposeSpiceflowResponse<Response, Replace<Awaited<A>, BunFile, File>>
689
+ : _ComposeSpiceflowResponse<
690
+ Response,
691
+ Replace<Awaited<Handle>, BunFile, File>
692
+ >
693
+
694
+ type _ComposeSpiceflowResponse<Response, Handle> = Prettify<
695
+ {} extends Response
696
+ ? {
697
+ 200: Exclude<Handle, { [ELYSIA_RESPONSE]: any }>
698
+ } & {
699
+ [ErrorResponse in Extract<
700
+ Handle,
701
+ { response: any }
702
+ > as ErrorResponse extends {
703
+ [ELYSIA_RESPONSE]: infer Status extends number
704
+ }
705
+ ? Status
706
+ : never]: ErrorResponse['response']
707
+ }
708
+ : Response
709
+ >
710
+
711
+ export type MergeSpiceflowInstances<
712
+ Instances extends Spiceflow<any, any, any, any, any, any>[] = [],
713
+ Prefix extends string = '',
714
+ Scoped extends boolean = false,
715
+ Singleton extends SingletonBase = {
716
+ decorator: {}
717
+ store: {}
718
+ },
719
+ Definitions extends DefinitionBase = {
720
+ type: {}
721
+ error: {}
722
+ },
723
+ Metadata extends MetadataBase = {
724
+ schema: {}
725
+ macro: {}
726
+ macroFn: {}
727
+ },
728
+ Routes extends RouteBase = {},
729
+ > = Instances extends [
730
+ infer Current extends Spiceflow<any, any, any, any, any, any>,
731
+ ...infer Rest extends Spiceflow<any, any, any, any, any, any>[],
732
+ ]
733
+ ? Current['_types']['Scoped'] extends true
734
+ ? MergeSpiceflowInstances<
735
+ Rest,
736
+ Prefix,
737
+ Scoped,
738
+ Singleton,
739
+ Definitions,
740
+ Metadata,
741
+ Routes
742
+ >
743
+ : MergeSpiceflowInstances<
744
+ Rest,
745
+ Prefix,
746
+ Scoped,
747
+ Singleton & Current['_types']['Singleton'],
748
+ Definitions & Current['_types']['Definitions'],
749
+ Metadata & Current['_types']['Metadata'],
750
+ Routes &
751
+ (Prefix extends ``
752
+ ? Current['_routes']
753
+ : AddPrefix<Prefix, Current['_routes']>)
754
+ >
755
+ : Spiceflow<
756
+ Prefix,
757
+ Scoped,
758
+ {
759
+ store: Prettify<Singleton['store']>
760
+ },
761
+ {
762
+ type: Prettify<Definitions['type']>
763
+ error: Prettify<Definitions['error']>
764
+ },
765
+ {
766
+ schema: Prettify<Metadata['schema']>
767
+ macro: Prettify<Metadata['macro']>
768
+ macroFn: Prettify<Metadata['macroFn']>
769
+ },
770
+ Routes
771
+ >
772
+
773
+ export type LifeCycleType = 'global' | 'local' | 'scoped'
774
+
775
+ export type UnionToIntersect<U> = (
776
+ U extends unknown ? (arg: U) => 0 : never
777
+ ) extends (arg: infer I) => 0
778
+ ? I
779
+ : never
780
+
781
+ export type ContextAppendType = 'append' | 'override'
782
+
783
+ export type HTTPHeaders = Record<string, string> & {
784
+ // Authentication
785
+ 'www-authenticate'?: string
786
+ authorization?: string
787
+ 'proxy-authenticate'?: string
788
+ 'proxy-authorization'?: string
789
+
790
+ // Caching
791
+ age?: string
792
+ 'cache-control'?: string
793
+ 'clear-site-data'?: string
794
+ expires?: string
795
+ 'no-vary-search'?: string
796
+ pragma?: string
797
+
798
+ // Conditionals
799
+ 'last-modified'?: string
800
+ etag?: string
801
+ 'if-match'?: string
802
+ 'if-none-match'?: string
803
+ 'if-modified-since'?: string
804
+ 'if-unmodified-since'?: string
805
+ vary?: string
806
+
807
+ // Connection management
808
+ connection?: string
809
+ 'keep-alive'?: string
810
+
811
+ // Content negotiation
812
+ accept?: string
813
+ 'accept-encoding'?: string
814
+ 'accept-language'?: string
815
+
816
+ // Controls
817
+ expect?: string
818
+ 'max-forwards'?: string
819
+
820
+ // Cokies
821
+ cookie?: string
822
+ 'set-cookie'?: string | string[]
823
+
824
+ // CORS
825
+ 'access-control-allow-origin'?: string
826
+ 'access-control-allow-credentials'?: string
827
+ 'access-control-allow-headers'?: string
828
+ 'access-control-allow-methods'?: string
829
+ 'access-control-expose-headers'?: string
830
+ 'access-control-max-age'?: string
831
+ 'access-control-request-headers'?: string
832
+ 'access-control-request-method'?: string
833
+ origin?: string
834
+ 'timing-allow-origin'?: string
835
+
836
+ // Downloads
837
+ 'content-disposition'?: string
838
+
839
+ // Message body information
840
+ 'content-length'?: string
841
+ 'content-type'?: string
842
+ 'content-encoding'?: string
843
+ 'content-language'?: string
844
+ 'content-location'?: string
845
+
846
+ // Proxies
847
+ forwarded?: string
848
+ via?: string
849
+
850
+ // Redirects
851
+ location?: string
852
+ refresh?: string
853
+
854
+ // Request context
855
+ // from?: string
856
+ // host?: string
857
+ // referer?: string
858
+ // 'user-agent'?: string
859
+
860
+ // Response context
861
+ allow?: string
862
+ server?: 'spiceflow' | (string & {})
863
+
864
+ // Range requests
865
+ 'accept-ranges'?: string
866
+ range?: string
867
+ 'if-range'?: string
868
+ 'content-range'?: string
869
+
870
+ // Security
871
+ 'content-security-policy'?: string
872
+ 'content-security-policy-report-only'?: string
873
+ 'cross-origin-embedder-policy'?: string
874
+ 'cross-origin-opener-policy'?: string
875
+ 'cross-origin-resource-policy'?: string
876
+ 'expect-ct'?: string
877
+ 'permission-policy'?: string
878
+ 'strict-transport-security'?: string
879
+ 'upgrade-insecure-requests'?: string
880
+ 'x-content-type-options'?: string
881
+ 'x-frame-options'?: string
882
+ 'x-xss-protection'?: string
883
+
884
+ // Server-sent events
885
+ 'last-event-id'?: string
886
+ 'ping-from'?: string
887
+ 'ping-to'?: string
888
+ 'report-to'?: string
889
+
890
+ // Transfer coding
891
+ te?: string
892
+ trailer?: string
893
+ 'transfer-encoding'?: string
894
+
895
+ // Other
896
+ 'alt-svg'?: string
897
+ 'alt-used'?: string
898
+ date?: string
899
+ dnt?: string
900
+ 'early-data'?: string
901
+ 'large-allocation'?: string
902
+ link?: string
903
+ 'retry-after'?: string
904
+ 'service-worker-allowed'?: string
905
+ 'source-map'?: string
906
+ upgrade?: string
907
+
908
+ // Non-standard
909
+ 'x-dns-prefetch-control'?: string
910
+ 'x-forwarded-for'?: string
911
+ 'x-forwarded-host'?: string
912
+ 'x-forwarded-proto'?: string
913
+ 'x-powered-by'?: 'spiceflow' | (string & {})
914
+ 'x-request-id'?: string
915
+ 'x-requested-with'?: string
916
+ 'x-robots-tag'?: string
917
+ 'x-ua-compatible'?: string
918
+ }
919
+
920
+ export type JoinPath<A extends string, B extends string> = `${A}${B extends '/'
921
+ ? '/index'
922
+ : B extends ''
923
+ ? B
924
+ : B extends `/${string}`
925
+ ? B
926
+ : B}`