Skip to content

Commit 6f29e61

Browse files
committed
🔧 fix: recursive macro with conflict value per status
1 parent 98e412f commit 6f29e61

File tree

5 files changed

+167
-162
lines changed

5 files changed

+167
-162
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# 1.4.25 - 12 Feb 2025
22
Bug fix:
3-
- resolve macro with conflict literal value per status
3+
- macro with conflict literal value per status
4+
- recursive macro with conflict value per status
45

56
# 1.4.24 - 11 Feb 2025
67
Feature:

example/d.ts

Lines changed: 0 additions & 71 deletions
This file was deleted.

src/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4141,7 +4141,8 @@ export default class Elysia<
41414141
>,
41424142
const MacroContext extends MacroToContext<
41434143
Metadata['macroFn'],
4144-
NoInfer<Omit<Input, keyof InputSchema>>
4144+
Omit<Input, NonResolvableMacroKey | 'as'>,
4145+
Definitions['typebox']
41454146
>,
41464147
const GuardType extends GuardSchemaType,
41474148
const AsType extends LifeCycleType,
@@ -4409,7 +4410,7 @@ export default class Elysia<
44094410
? {}
44104411
: MacroToContext<
44114412
Metadata['macroFn'],
4412-
Omit<Input, NonResolvableMacroKey>,
4413+
Omit<Input, NonResolvableMacroKey | 'as'>,
44134414
Definitions['typebox']
44144415
>,
44154416
const BeforeHandle extends MaybeArray<
@@ -5728,6 +5729,7 @@ export default class Elysia<
57285729
>
57295730
>(
57305731
path: Path,
5732+
// handler: (a: { a: MacroContext }) => any,
57315733
handler: Handle,
57325734
hook?: LocalHook<
57335735
Input,

src/types.ts

Lines changed: 125 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -988,25 +988,30 @@ type ExtractOnlyResponseFromMacro<A> =
988988
}
989989
: {}
990990

991-
export type ExtractAllResponseFromMacro<A> =
991+
type MergeResponseStatus<A> = {
992+
[status in keyof UnionToIntersect<
993+
// Must be using generic to separate literal from Box<T>
994+
A extends ElysiaCustomStatusResponse<any, any, infer Status>
995+
? { [A in Status]: 1 }
996+
: never
997+
// @ts-ignore A is checked in key computation
998+
>]: Extract<A, { code: status }>['response']
999+
}
1000+
1001+
type MergeAllStatus<T> = {
1002+
[K in T extends any ? keyof T : never]: T extends Record<K, infer V>
1003+
? V
1004+
: never
1005+
}
1006+
1007+
type ExtractAllResponseFromMacro<A> =
9921008
IsNever<A> extends true
9931009
? {}
9941010
: {
9951011
// Merge all status to single object first
996-
return: UnionToIntersect<
997-
// Must be using generic to separate literal from Box<T>
998-
A extends ElysiaCustomStatusResponse<any, any, infer Status>
999-
? { [A in Status]: 1 }
1000-
: never
1001-
> extends infer B
1002-
? // Compute each one individually
1003-
{
1004-
// @ts-ignore A is checked in B computation
1005-
[status in keyof B]: Extract<
1006-
A,
1007-
{ code: status }
1008-
>['response']
1009-
} & (Exclude<
1012+
return: Prettify<
1013+
MergeResponseStatus<A> &
1014+
(Exclude<
10101015
A,
10111016
AnyElysiaCustomStatusResponse
10121017
> extends infer A
@@ -1023,93 +1028,124 @@ export type ExtractAllResponseFromMacro<A> =
10231028
200: A
10241029
}
10251030
: {})
1026-
: Exclude<A, AnyElysiaCustomStatusResponse> extends infer A
1027-
? IsAny<A> extends true
1028-
? {}
1029-
: IsNever<A> extends true
1030-
? {}
1031-
: // FunctionArrayReturnType
1032-
NonNullable<void> extends A
1033-
? {}
1034-
: undefined extends A
1035-
? {}
1036-
: {
1037-
200: A
1038-
}
1039-
: {}
1031+
>
10401032
}
10411033

1042-
// There's only resolve that can add new properties to Context
1034+
type FlattenMacroResponse<T> = T extends object
1035+
? '_' extends keyof T
1036+
? MergeFlattenMacroResponse<
1037+
Omit<T, '_'>,
1038+
FlattenMacroResponse<MergeAllStatus<T['_']>>
1039+
>
1040+
: T
1041+
: T
1042+
1043+
type MergeFlattenMacroResponse<A, B> = {
1044+
[K in keyof A | keyof B]: K extends keyof A
1045+
? K extends keyof B
1046+
? A[K] | B[K]
1047+
: A[K]
1048+
: K extends keyof B
1049+
? B[K]
1050+
: never
1051+
}
1052+
type UnionMacroContext<A> = UnionToIntersect<{
1053+
[K in Exclude<keyof A, 'return'>]: A[K]
1054+
}> & {
1055+
// @ts-ignore Allow recursive Macro.return without collapse into
1056+
return: { _: A['return'] }
1057+
}
1058+
10431059
export type MacroToContext<
10441060
in out MacroFn extends Macro = {},
10451061
in out SelectedMacro extends BaseMacro = {},
10461062
in out Definitions extends DefinitionBase['typebox'] = {},
10471063
in out R extends 1[] = []
10481064
> = Prettify<
1049-
{} extends SelectedMacro
1065+
InnerMacroToContext<
1066+
MacroFn,
1067+
Pick<SelectedMacro, Extract<keyof MacroFn, keyof SelectedMacro>>,
1068+
Definitions,
1069+
R
1070+
> extends infer A
1071+
? {
1072+
[K in Exclude<keyof A, 'return'>]: A[K]
1073+
} & Prettify<{
1074+
// @ts-ignore
1075+
return: FlattenMacroResponse<A['return']>
1076+
}>
1077+
: {}
1078+
>
1079+
1080+
// There's only resolve that can add new properties to Context
1081+
type InnerMacroToContext<
1082+
MacroFn extends Macro = {},
1083+
SelectedMacro extends BaseMacro = {},
1084+
Definitions extends DefinitionBase['typebox'] = {},
1085+
R extends 1[] = []
1086+
> = {} extends SelectedMacro
1087+
? {}
1088+
: R['length'] extends 15
10501089
? {}
1051-
: R['length'] extends 15
1052-
? {}
1053-
: UnionToIntersect<
1054-
{
1055-
[key in keyof SelectedMacro]: ReturnTypeIfPossible<
1056-
MacroFn[key],
1057-
SelectedMacro[key]
1058-
> extends infer Value
1059-
? {
1060-
resolve: ExtractResolveFromMacro<
1061-
Extract<
1062-
Exclude<
1063-
FunctionArrayReturnType<
1064-
// @ts-ignore Trust me bro
1065-
Value['resolve']
1066-
>,
1067-
AnyElysiaCustomStatusResponse
1090+
: UnionMacroContext<
1091+
{
1092+
[key in keyof SelectedMacro]: ReturnTypeIfPossible<
1093+
MacroFn[key],
1094+
SelectedMacro[key]
1095+
> extends infer Value
1096+
? {
1097+
resolve: ExtractResolveFromMacro<
1098+
Extract<
1099+
Exclude<
1100+
FunctionArrayReturnType<
1101+
// @ts-ignore Trust me bro
1102+
Value['resolve']
10681103
>,
1069-
Record<any, unknown>
1070-
>
1104+
AnyElysiaCustomStatusResponse
1105+
>,
1106+
Record<any, unknown>
1107+
>
1108+
>
1109+
} & UnwrapMacroSchema<
1110+
// @ts-ignore Trust me bro
1111+
Value,
1112+
Definitions
1113+
> &
1114+
ExtractAllResponseFromMacro<
1115+
FunctionArrayReturnTypeNonNullable<
1116+
// @ts-expect-error type is checked in key mapping
1117+
Value['beforeHandle']
10711118
>
1072-
} & UnwrapMacroSchema<
1073-
// @ts-ignore Trust me bro
1074-
Value,
1075-
Definitions
10761119
> &
1077-
ExtractAllResponseFromMacro<
1078-
FunctionArrayReturnTypeNonNullable<
1079-
// @ts-expect-error type is checked in key mapping
1080-
Value['beforeHandle']
1081-
>
1082-
> &
1083-
ExtractAllResponseFromMacro<
1084-
FunctionArrayReturnTypeNonNullable<
1085-
// @ts-expect-error type is checked in key mapping
1086-
Value['afterHandle']
1087-
>
1088-
> &
1089-
ExtractAllResponseFromMacro<
1120+
ExtractAllResponseFromMacro<
1121+
FunctionArrayReturnTypeNonNullable<
10901122
// @ts-expect-error type is checked in key mapping
1091-
FunctionArrayReturnType<Value['error']>
1092-
> &
1093-
ExtractOnlyResponseFromMacro<
1094-
FunctionArrayReturnTypeNonNullable<
1095-
// @ts-expect-error type is checked in key mapping
1096-
Value['resolve']
1097-
>
1098-
> &
1099-
MacroToContext<
1100-
MacroFn,
1101-
// @ts-ignore trust me bro
1102-
Pick<
1103-
Value,
1104-
Extract<keyof MacroFn, keyof Value>
1105-
>,
1106-
Definitions,
1107-
[...R, 1]
1123+
Value['afterHandle']
11081124
>
1109-
: {}
1110-
}[keyof SelectedMacro]
1111-
>
1112-
>
1125+
> &
1126+
ExtractAllResponseFromMacro<
1127+
// @ts-expect-error type is checked in key mapping
1128+
FunctionArrayReturnType<Value['error']>
1129+
> &
1130+
ExtractOnlyResponseFromMacro<
1131+
FunctionArrayReturnTypeNonNullable<
1132+
// @ts-expect-error type is checked in key mapping
1133+
Value['resolve']
1134+
>
1135+
> &
1136+
InnerMacroToContext<
1137+
MacroFn,
1138+
// @ts-ignore trust me bro
1139+
Pick<
1140+
Value,
1141+
Extract<keyof MacroFn, keyof Value>
1142+
>,
1143+
Definitions,
1144+
[...R, 1]
1145+
>
1146+
: {}
1147+
}[keyof SelectedMacro]
1148+
>
11131149

11141150
type UnwrapMacroSchema<
11151151
T extends Partial<InputSchema<any>>,
@@ -1766,6 +1802,7 @@ export type AnyBaseHookLifeCycle = BaseHookLifeCycle<any, any, any, any>
17661802
export type NonResolvableMacroKey =
17671803
| keyof AnyBaseHookLifeCycle
17681804
| keyof InputSchema
1805+
| 'resolve'
17691806

17701807
interface RouteSchemaWithResolvedMacro extends RouteSchema {
17711808
response: PossibleResponse

0 commit comments

Comments
 (0)