1- import type { Elysia } from 'elysia'
1+ import { NotFoundError , Elysia } from 'elysia'
22
33import { readdir , stat } from 'fs/promises'
44import { resolve , resolve as resolveFn , join } from 'path'
55
6- const getFiles = async ( dir : string ) : Promise < string [ ] > => {
6+ const listFiles = async ( dir : string ) : Promise < string [ ] > => {
77 const files = await readdir ( dir )
88
99 const all = await Promise . all (
@@ -12,7 +12,7 @@ const getFiles = async (dir: string): Promise<string[]> => {
1212 const stats = await stat ( file )
1313
1414 return stats && stats . isDirectory ( )
15- ? await getFiles ( file )
15+ ? await listFiles ( file )
1616 : [ resolve ( dir , file ) ]
1717 } )
1818 )
@@ -28,7 +28,8 @@ export const staticPlugin = async <Prefix extends string = '/prefix'>(
2828 alwaysStatic = false ,
2929 ignorePatterns = [ '.DS_Store' , '.git' , '.env' ] ,
3030 noExtension = false ,
31- resolve = resolveFn
31+ resolve = resolveFn ,
32+ headers = { }
3233 } : {
3334 /**
3435 * @default "public"
@@ -74,17 +75,22 @@ export const staticPlugin = async <Prefix extends string = '/prefix'>(
7475 * Nodejs resolve function
7576 */
7677 resolve ?: ( ...pathSegments : string [ ] ) => string
78+ /**
79+ * Set headers
80+ */
81+ headers ?: Record < string , string > | undefined
7782 } = {
7883 assets : 'public' ,
7984 prefix : '/public' as Prefix ,
8085 staticLimit : 1024 ,
8186 alwaysStatic : process . env . NODE_ENV === 'production' ,
8287 ignorePatterns : [ ] ,
8388 noExtension : false ,
84- resolve : resolveFn
89+ resolve : resolveFn ,
90+ headers : { }
8591 }
8692) => {
87- const files = await getFiles ( resolveFn ( assets ) )
93+ const files = await listFiles ( resolveFn ( assets ) )
8894
8995 if ( prefix === '/' ) prefix = '' as Prefix
9096
@@ -97,58 +103,71 @@ export const staticPlugin = async <Prefix extends string = '/prefix'>(
97103 } )
98104 }
99105
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
108126
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 ) )
113133
114- if ( noExtension ) {
115- const temp = fileName . split ( '.' )
116- temp . splice ( - 1 )
134+ let fileName = file . replace ( resolve ( ) , '' ) . replace ( `${ assets } /` , '' )
117135
118- fileName = temp . join ( '.' )
119- }
136+ if ( noExtension ) {
137+ const temp = fileName . split ( '.' )
138+ temp . splice ( - 1 )
120139
121- app . get ( join ( prefix , fileName ) , response )
140+ fileName = temp . join ( '.' )
122141 }
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- }
149142
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+ } )
151168 }
169+
170+ return app
152171}
153172
154173export default staticPlugin
0 commit comments