1
- import type { Elysia } from 'elysia'
1
+ import { NotFoundError , Elysia } from 'elysia'
2
2
3
3
import { readdir , stat } from 'fs/promises'
4
4
import { resolve , resolve as resolveFn , join } from 'path'
5
5
6
- const getFiles = async ( dir : string ) : Promise < string [ ] > => {
6
+ const listFiles = async ( dir : string ) : Promise < string [ ] > => {
7
7
const files = await readdir ( dir )
8
8
9
9
const all = await Promise . all (
@@ -12,7 +12,7 @@ const getFiles = async (dir: string): Promise<string[]> => {
12
12
const stats = await stat ( file )
13
13
14
14
return stats && stats . isDirectory ( )
15
- ? await getFiles ( file )
15
+ ? await listFiles ( file )
16
16
: [ resolve ( dir , file ) ]
17
17
} )
18
18
)
@@ -28,7 +28,8 @@ export const staticPlugin = async <Prefix extends string = '/prefix'>(
28
28
alwaysStatic = false ,
29
29
ignorePatterns = [ '.DS_Store' , '.git' , '.env' ] ,
30
30
noExtension = false ,
31
- resolve = resolveFn
31
+ resolve = resolveFn ,
32
+ headers = { }
32
33
} : {
33
34
/**
34
35
* @default "public"
@@ -74,17 +75,22 @@ export const staticPlugin = async <Prefix extends string = '/prefix'>(
74
75
* Nodejs resolve function
75
76
*/
76
77
resolve ?: ( ...pathSegments : string [ ] ) => string
78
+ /**
79
+ * Set headers
80
+ */
81
+ headers ?: Record < string , string > | undefined
77
82
} = {
78
83
assets : 'public' ,
79
84
prefix : '/public' as Prefix ,
80
85
staticLimit : 1024 ,
81
86
alwaysStatic : process . env . NODE_ENV === 'production' ,
82
87
ignorePatterns : [ ] ,
83
88
noExtension : false ,
84
- resolve : resolveFn
89
+ resolve : resolveFn ,
90
+ headers : { }
85
91
}
86
92
) => {
87
- const files = await getFiles ( resolveFn ( assets ) )
93
+ const files = await listFiles ( resolveFn ( assets ) )
88
94
89
95
if ( prefix === '/' ) prefix = '' as Prefix
90
96
@@ -97,58 +103,71 @@ export const staticPlugin = async <Prefix extends string = '/prefix'>(
97
103
} )
98
104
}
99
105
100
- return ( app : Elysia ) => {
101
- if (
102
- alwaysStatic ||
103
- ( process . env . ENV === 'production' && files . length <= staticLimit )
104
- )
105
- for ( let i = 0 ; i < files . length ; i ++ ) {
106
- const file = files [ i ]
107
- if ( shouldIgnore ( file ) ) continue
106
+ const app = new Elysia ( {
107
+ name : 'static' ,
108
+ seed : {
109
+ assets,
110
+ prefix,
111
+ staticLimit,
112
+ alwaysStatic,
113
+ ignorePatterns,
114
+ noExtension,
115
+ resolve : resolve . toString ( )
116
+ }
117
+ } )
118
+
119
+ if (
120
+ alwaysStatic ||
121
+ ( process . env . ENV === 'production' && files . length <= staticLimit )
122
+ )
123
+ for ( let i = 0 ; i < files . length ; i ++ ) {
124
+ const file = files [ i ]
125
+ if ( ! file || shouldIgnore ( file ) ) continue
108
126
109
- const response = ( ) => new Response ( Bun . file ( file ) )
110
- let fileName = file
111
- . replace ( resolve ( ) , '' )
112
- . replace ( `${ assets } /` , '' )
127
+ const response = Object . keys ( headers ) . length
128
+ ? ( ) =>
129
+ new Response ( Bun . file ( file ) , {
130
+ headers
131
+ } )
132
+ : ( ) => new Response ( Bun . file ( file ) )
113
133
114
- if ( noExtension ) {
115
- const temp = fileName . split ( '.' )
116
- temp . splice ( - 1 )
134
+ let fileName = file . replace ( resolve ( ) , '' ) . replace ( `${ assets } /` , '' )
117
135
118
- fileName = temp . join ( '.' )
119
- }
136
+ if ( noExtension ) {
137
+ const temp = fileName . split ( '.' )
138
+ temp . splice ( - 1 )
120
139
121
- app . get ( join ( prefix , fileName ) , response )
140
+ fileName = temp . join ( '.' )
122
141
}
123
- else {
124
- if (
125
- // @ts -ignore
126
- ! app . routes . find (
127
- ( { method, path } ) =>
128
- path === `${ prefix } /*` && method === 'GET'
129
- )
130
- )
131
- app . get ( `${ prefix } /*` , ( c ) => {
132
- const file = `${ assets } /${ ( c . params as any ) [ '*' ] } `
133
-
134
- if ( shouldIgnore ( file ) )
135
- return new Response ( 'NOT_FOUND' , {
136
- status : 404
137
- } )
138
-
139
- return stat ( file )
140
- . then ( ( status ) => new Response ( Bun . file ( file ) ) )
141
- . catch (
142
- ( error ) =>
143
- new Response ( 'NOT_FOUND' , {
144
- status : 404
145
- } )
146
- )
147
- } )
148
- }
149
142
150
- return app
143
+ app . get ( join ( prefix , fileName ) , response )
144
+ }
145
+ else {
146
+ if (
147
+ // @ts -ignore
148
+ ! app . routes . find (
149
+ ( { method, path } ) => path === `${ prefix } /*` && method === 'GET'
150
+ )
151
+ )
152
+ app . onError ( ( ) => { } ) . get ( `${ prefix } /*` , async ( { params } ) => {
153
+ const file = `${ assets } /${ ( params as any ) [ '*' ] } `
154
+
155
+ if ( shouldIgnore ( file ) ) throw new NotFoundError ( )
156
+
157
+ return stat ( file )
158
+ . then (
159
+ ( status ) =>
160
+ new Response ( Bun . file ( file ) , {
161
+ headers
162
+ } )
163
+ )
164
+ . catch ( ( error ) => {
165
+ throw new NotFoundError ( )
166
+ } )
167
+ } )
151
168
}
169
+
170
+ return app
152
171
}
153
172
154
173
export default staticPlugin
0 commit comments