Skip to content

Commit 908ce68

Browse files
committed
🎉 release: 1.2.10
1 parent bc9b3b6 commit 908ce68

File tree

13 files changed

+212
-54
lines changed

13 files changed

+212
-54
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
# 1.2.10 - 5 Jan 2025
2+
Feature:
3+
- add shorthand property for macro function
4+
5+
Improvement:
6+
- use `deuri` instead of `fast-decode-uri-component`
7+
- [#985](https://github.com/elysiajs/elysia/issues/985) MaybeEmpty and Nullable should have options args
8+
9+
Bug fix:
10+
- Macro function doesn't inherits local/scoped derive and resolve in type-level
11+
112
# 1.2.9 - 28 Dec 2024
213
Bug fix:
314
- Resolve macro unintentionally return instead of assign new context

bun.lockb

-65 Bytes
Binary file not shown.

example/a.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,23 @@ import { req } from '../test/utils'
33

44
const app = new Elysia()
55
.macro({
6-
user: (enabled: boolean) => ({
7-
resolve: ({ query: { name = 'anon' } }) => ({
8-
user: {
9-
name
6+
user: {
7+
resolve({ query: { name = 'anon' } }) {
8+
return {
9+
user: {
10+
name
11+
}
1012
}
11-
})
12-
})
13+
}
14+
}
1315
})
1416
.get('/', ({ user }) => user, {
1517
user: true
1618
})
1719

1820
const [a, b] = await Promise.all([
19-
app.handle(req('/')).then((x) => x.json()),
20-
app.handle(req('/?name=hoshino')).then((x) => x.json())
21+
app.handle(req('/')).then((x) => x.text()),
22+
app.handle(req('/?name=hoshino')).then((x) => x.text())
2123
])
2224

2325
console.log(a, b)

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "elysia",
33
"description": "Ergonomic Framework for Human",
4-
"version": "1.2.9",
4+
"version": "1.2.10",
55
"author": {
66
"name": "saltyAom",
77
"url": "https://github.com/SaltyAom",
@@ -155,7 +155,7 @@
155155
"dependencies": {
156156
"@sinclair/typebox": "^0.34.13",
157157
"cookie": "^1.0.2",
158-
"fast-decode-uri-component": "^1.0.1",
158+
"deuri": "^0.0.5",
159159
"memoirist": "^0.2.0",
160160
"openapi-types": "^12.1.3"
161161
},

src/compose.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import { TypeBoxError, type TAnySchema, type TSchema } from '@sinclair/typebox'
55

66
import { parseQuery, parseQueryFromURL } from './fast-querystring'
77

8-
// @ts-ignore
9-
import decodeURIComponent from 'fast-decode-uri-component'
8+
import { decode as decodeURIComponent } from 'deuri'
109

1110
import {
1211
ELYSIA_REQUEST_ID,
@@ -777,8 +776,8 @@ export const composeHandler = ({
777776
`else\n` +
778777
`a${index}+=','\n` +
779778
`let temp\n` +
780-
`if(memory===-1)temp=decodeURIComponent(url.slice(start).replace(/\\+|%20/g,' '))\n` +
781-
`else temp=decodeURIComponent(url.slice(start, memory).replace(/\\+|%20/g,' '))\n` +
779+
`if(memory===-1)temp=decodeURIComponent(url.slice(start).replace(/\\+/g,' '))\n` +
780+
`else temp=decodeURIComponent(url.slice(start, memory).replace(/\\+/g,' '))\n` +
782781
`const charCode = temp.charCodeAt(0)\n` +
783782
`if(charCode !== 91 && charCode !== 123)\n` +
784783
`temp='"'+temp+'"'\n` +
@@ -801,10 +800,10 @@ export const composeHandler = ({
801800
`if(a${index}===undefined)` +
802801
`a${index}=[]\n` +
803802
`if(memory===-1){` +
804-
`a${index}.push(decodeURIComponent(url.slice(start)).replace(/\\+|%20/g,' '))\n` +
803+
`a${index}.push(decodeURIComponent(url.slice(start)).replace(/\\+/g,' '))\n` +
805804
`break` +
806805
`}` +
807-
`else a${index}.push(decodeURIComponent(url.slice(start, memory)).replace(/\\+|%20/g,' '))\n` +
806+
`else a${index}.push(decodeURIComponent(url.slice(start, memory)).replace(/\\+/g,' '))\n` +
808807
`memory=url.indexOf('&${key}=',memory)\n` +
809808
`if(memory===-1) break\n` +
810809
`}`
@@ -814,8 +813,8 @@ export const composeHandler = ({
814813
`if(memory!==-1){` +
815814
`const start=memory+${key.length + 2}\n` +
816815
`memory=url.indexOf('&',start)\n` +
817-
`if(memory===-1)a${index}=decodeURIComponent(url.slice(start).replace(/\\+|%20/g,' '))` +
818-
`else a${index}=decodeURIComponent(url.slice(start,memory).replace(/\\+|%20/g,' '))` +
816+
`if(memory===-1)a${index}=decodeURIComponent(url.slice(start).replace(/\\+/g,' '))` +
817+
`else a${index}=decodeURIComponent(url.slice(start,memory).replace(/\\+/g,' '))` +
819818
`if(a${index}!==undefined)` +
820819
`try{` +
821820
`a${index}=JSON.parse(a${index})` +
@@ -828,9 +827,9 @@ export const composeHandler = ({
828827
`if(memory!==-1){` +
829828
`const start=memory+${key.length + 2}\n` +
830829
`memory=url.indexOf('&',start)\n` +
831-
`if(memory===-1)a${index}=decodeURIComponent(url.slice(start).replace(/\\+|%20/g,' '))\n` +
830+
`if(memory===-1)a${index}=decodeURIComponent(url.slice(start).replace(/\\+/g,' '))\n` +
832831
`else{` +
833-
`a${index}=decodeURIComponent(url.slice(start,memory).replace(/\\+|%20/g,' '))`
832+
`a${index}=decodeURIComponent(url.slice(start,memory).replace(/\\+/g,' '))`
834833

835834
if (anyOf)
836835
fnLiteral +=
@@ -843,8 +842,8 @@ export const composeHandler = ({
843842
`if(first)first=false\n` +
844843
`else deepMemory = url.indexOf('&', start)\n` +
845844
`let value\n` +
846-
`if(deepMemory===-1)value=decodeURIComponent(url.slice(start).replace(/\\+|%20/g,' '))\n` +
847-
`else value=decodeURIComponent(url.slice(start, deepMemory).replace(/\\+|%20/g,' '))\n` +
845+
`if(deepMemory===-1)value=decodeURIComponent(url.slice(start).replace(/\\+/g,' '))\n` +
846+
`else value=decodeURIComponent(url.slice(start, deepMemory).replace(/\\+/g,' '))\n` +
848847
`const vStart=value.charCodeAt(0)\n` +
849848
`const vEnd=value.charCodeAt(value.length - 1)\n` +
850849
`if((vStart===91&&vEnd===93)||(vStart===123&&vEnd===125))\n` +

src/cookies.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { parse, serialize } from 'cookie'
22

3-
// @ts-ignore
4-
import decodeURIComponent from 'fast-decode-uri-component'
3+
import { decode as decodeURIComponent } from 'deuri'
54

65
import { isNotEmpty, unsignCookie } from './utils'
76
import { InvalidCookieSignature } from './error'
@@ -325,6 +324,8 @@ export const parseCookie = async (
325324

326325
const cookies = parse(cookieString)
327326
for (const [name, v] of Object.entries(cookies)) {
327+
if (v === undefined) continue
328+
328329
let value = decodeURIComponent(v)
329330

330331
if (sign === true || sign?.includes(name)) {

src/fast-querystring.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
3434
DEALINGS IN THE SOFTWARE.
3535
*/
3636

37-
// @ts-ignore
38-
import fastDecode from 'fast-decode-uri-component'
37+
import { decode as fastDecode } from 'deuri'
3938

4039
const plusRegex = /\+/g
4140

src/index.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3749,7 +3749,10 @@ export default class Elysia<
37493749
macro<
37503750
const NewMacro extends HookMacroFn<
37513751
Metadata['schema'],
3752-
Singleton,
3752+
Singleton & {
3753+
derive: Partial<Ephemeral['derive'] & Volatile['derive']>
3754+
resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>
3755+
},
37533756
Definitions['error']
37543757
>
37553758
>(
@@ -3784,6 +3787,15 @@ export default class Elysia<
37843787

37853788
this.extender.macros.push(hook)
37863789
} else if (typeof macro === 'object') {
3790+
for (const name of Object.keys(macro))
3791+
if (typeof macro[name] === 'object') {
3792+
const actualValue = { ...(macro[name] as Object) }
3793+
3794+
macro[name] = (v: boolean) => {
3795+
if (v === true) return actualValue
3796+
}
3797+
}
3798+
37873799
const hook: MacroQueue = {
37883800
checksum: checksum(
37893801
JSON.stringify({

src/type-system.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
TUnsafe,
99
TypeRegistry,
1010
TInteger,
11-
IntegerOptions
11+
IntegerOptions
1212
} from '@sinclair/typebox'
1313
import { TypeSystem } from '@sinclair/typebox/system'
1414
import {
@@ -326,8 +326,11 @@ type NonEmptyArray<T> = [T, ...T[]]
326326

327327
export type TEnumValue = number | string | null
328328

329-
export interface TUnionEnum<T extends NonEmptyArray<TEnumValue> | Readonly<NonEmptyArray<TEnumValue>> = [TEnumValue]>
330-
extends TSchema {
329+
export interface TUnionEnum<
330+
T extends
331+
| NonEmptyArray<TEnumValue>
332+
| Readonly<NonEmptyArray<TEnumValue>> = [TEnumValue]
333+
> extends TSchema {
331334
type?: 'number' | 'string' | 'null'
332335
[Kind]: 'UnionEnum'
333336
static: T[number]
@@ -410,7 +413,7 @@ export const ElysiaType = {
410413
)
411414
)
412415
.Decode((value) => {
413-
if(typeof value === "number") {
416+
if (typeof value === 'number') {
414417
const date = new Date(value)
415418

416419
if (!Value.Check(schema, date))
@@ -445,7 +448,7 @@ export const ElysiaType = {
445448
t.String({
446449
format: 'boolean',
447450
default: false
448-
}),
451+
})
449452
],
450453
property
451454
)
@@ -597,12 +600,13 @@ export const ElysiaType = {
597600
return [value]
598601
})
599602
.Encode((value) => value),
600-
Nullable: <T extends TSchema>(schema: T) => t.Union([schema, t.Null()]),
603+
Nullable: <T extends TSchema>(schema: T, options?: SchemaOptions) =>
604+
t.Union([schema, t.Null()], options),
601605
/**
602606
* Allow Optional, Nullable and Undefined
603607
*/
604-
MaybeEmpty: <T extends TSchema>(schema: T) =>
605-
t.Union([schema, t.Null(), t.Undefined()]),
608+
MaybeEmpty: <T extends TSchema>(schema: T, options?: SchemaOptions) =>
609+
t.Union([schema, t.Null(), t.Undefined()], options),
606610
Cookie: <T extends TProperties>(
607611
properties: T,
608612
{
@@ -637,7 +641,11 @@ export const ElysiaType = {
637641
return v
638642
},
639643
// based on https://github.com/elysiajs/elysia/issues/512#issuecomment-1980134955
640-
UnionEnum: <const T extends NonEmptyArray<TEnumValue> | Readonly<NonEmptyArray<TEnumValue>>>(
644+
UnionEnum: <
645+
const T extends
646+
| NonEmptyArray<TEnumValue>
647+
| Readonly<NonEmptyArray<TEnumValue>>
648+
>(
641649
values: T,
642650
options: SchemaOptions = {}
643651
) => {

src/types.ts

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,10 @@ export type MacroContextBlacklistKey =
625625
| 'tags'
626626
| keyof RouteSchema
627627

628+
type ReturnTypeIfPossible<T> = T extends (...args: any) => any
629+
? ReturnType<T>
630+
: T
631+
628632
// There's only resolve that can add new properties to Context
629633
export type MacroToContext<
630634
MacroFn extends BaseMacroFn = {},
@@ -646,9 +650,27 @@ export type MacroToContext<
646650
>
647651
}
648652
? key
649-
: never]: ResolveResolutions<
653+
: MacroFn[key] extends {
654+
resolve: MaybeArray<
655+
(
656+
...v: any
657+
) => MaybePromise<
658+
| Record<keyof any, unknown>
659+
| void
660+
| ElysiaCustomStatusResponse<
661+
any,
662+
any,
663+
any
664+
>
665+
>
666+
>
667+
}
668+
? true extends SelectedMacro[key]
669+
? key
670+
: never
671+
: never]: ResolveResolutions<
650672
// @ts-expect-error type is checked in key mapping
651-
Awaited<ReturnType<MacroFn[key]>['resolve']>
673+
Awaited<ReturnTypeIfPossible<MacroFn[key]>['resolve']>
652674
>
653675
} extends infer A extends Record<RecordKey, unknown>
654676
? IsNever<A[keyof A]> extends false
@@ -1318,26 +1340,40 @@ export type HookMacroFn<
13181340
in out Errors extends Record<string, Error> = {}
13191341
> = Record<
13201342
keyof any,
1321-
(...a: any) => {
1322-
parse?: MaybeArray<BodyHandler<TypedRoute, Singleton>>
1323-
transform?: MaybeArray<VoidHandler<TypedRoute, Singleton>>
1324-
beforeHandle?: MaybeArray<OptionalHandler<TypedRoute, Singleton>>
1325-
afterHandle?: MaybeArray<AfterHandler<TypedRoute, Singleton>>
1326-
error?: MaybeArray<ErrorHandler<Errors, TypedRoute, Singleton>>
1327-
mapResponse?: MaybeArray<MapResponse<TypedRoute, Singleton>>
1328-
afterResponse?: MaybeArray<AfterResponseHandler<TypedRoute, Singleton>>
1329-
resolve?: MaybeArray<ResolveHandler<TypedRoute, Singleton>>
1330-
} | void
1343+
| {
1344+
parse?: MaybeArray<BodyHandler<TypedRoute, Singleton>>
1345+
transform?: MaybeArray<VoidHandler<TypedRoute, Singleton>>
1346+
beforeHandle?: MaybeArray<OptionalHandler<TypedRoute, Singleton>>
1347+
afterHandle?: MaybeArray<AfterHandler<TypedRoute, Singleton>>
1348+
error?: MaybeArray<ErrorHandler<Errors, TypedRoute, Singleton>>
1349+
mapResponse?: MaybeArray<MapResponse<TypedRoute, Singleton>>
1350+
afterResponse?: MaybeArray<
1351+
AfterResponseHandler<TypedRoute, Singleton>
1352+
>
1353+
resolve?: MaybeArray<ResolveHandler<TypedRoute, Singleton>>
1354+
}
1355+
| ((...a: any) => {
1356+
parse?: MaybeArray<BodyHandler<TypedRoute, Singleton>>
1357+
transform?: MaybeArray<VoidHandler<TypedRoute, Singleton>>
1358+
beforeHandle?: MaybeArray<OptionalHandler<TypedRoute, Singleton>>
1359+
afterHandle?: MaybeArray<AfterHandler<TypedRoute, Singleton>>
1360+
error?: MaybeArray<ErrorHandler<Errors, TypedRoute, Singleton>>
1361+
mapResponse?: MaybeArray<MapResponse<TypedRoute, Singleton>>
1362+
afterResponse?: MaybeArray<
1363+
AfterResponseHandler<TypedRoute, Singleton>
1364+
>
1365+
resolve?: MaybeArray<ResolveHandler<TypedRoute, Singleton>>
1366+
} | void)
13311367
>
13321368

13331369
export type MacroToProperty<
13341370
in out T extends BaseMacroFn | HookMacroFn<any, any, any>
13351371
> = Prettify<{
13361372
[K in keyof T]: T[K] extends Function
13371373
? T[K] extends (a: infer Params) => any
1338-
? Params | undefined
1339-
: T[K]
1340-
: T[K]
1374+
? Params
1375+
: boolean
1376+
: boolean
13411377
}>
13421378

13431379
interface MacroOptions {

0 commit comments

Comments
 (0)