From 49b5e67c200e95d0f36cbe9e03ee952d7ba96d1b Mon Sep 17 00:00:00 2001 From: saltyaom Date: Wed, 24 Apr 2024 19:09:18 +0700 Subject: [PATCH] :tada: feat: release 1.0.3 --- CHANGELOG.md | 6 +++++ package.json | 2 +- src/cache.ts | 22 +++++------------- src/index.ts | 63 +++++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 63 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a47305..b6dc546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +# 1.0.3 - 24 Apr 2024 +Improvement: +- [#26](https://github.com/elysiajs/elysia-static/pull/26) support system paths (windows) +- [#25](https://github.com/elysiajs/elysia-static/pull/24) add maxAge param +- add cache-control directive + # 1.0.0 - 16 Mar 2024 Change: - Add support for Elysia 1.0 diff --git a/package.json b/package.json index 179b6b0..fb11a74 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@elysiajs/static", - "version": "1.0.2", + "version": "1.0.3", "author": { "name": "saltyAom", "url": "https://github.com/SaltyAom", diff --git a/src/cache.ts b/src/cache.ts index 2f37448..8bf91ab 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -12,31 +12,22 @@ export async function isCached( if ( headers['cache-control'] && headers['cache-control'].indexOf('no-cache') !== -1 - ) { + ) return false - } // if-none-match if ('if-none-match' in headers) { const ifNoneMatch = headers['if-none-match'] - if (ifNoneMatch === '*') { - return true - } + if (ifNoneMatch === '*') return true - if (ifNoneMatch === null) { - return false - } + if (ifNoneMatch === null) return false - if (typeof etag !== 'string') { - return false - } + if (typeof etag !== 'string') return false const isMatching = ifNoneMatch === etag - if (isMatching) { - return true - } + if (isMatching) return true /** * A recipient MUST ignore If-Modified-Since if the request contains an @@ -63,9 +54,8 @@ export async function isCached( if ( lastModified !== undefined && lastModified.getTime() <= Date.parse(ifModifiedSince) - ) { + ) return true - } } return false diff --git a/src/index.ts b/src/index.ts index af7e817..cfb8056 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,18 @@ import { Elysia, NotFoundError } from 'elysia' import { readdir, stat } from 'fs/promises' -import { resolve, resolve as resolveFn, join, sep} from 'path' +import { resolve, resolve as resolveFn, join, sep } from 'path' import Cache from 'node-cache' import { generateETag, isCached } from './cache' import { Stats } from 'fs' const URL_PATH_SEP = '/' -const fileExists = (path: string) => stat(path).then(() => true, () => false) +const fileExists = (path: string) => + stat(path).then( + () => true, + () => false + ) const statCache = new Cache({ useClones: false, @@ -60,7 +64,8 @@ export const staticPlugin = async ( resolve = resolveFn, headers = {}, noCache = false, - maxAge = 0, + maxAge = 86400, + directive = 'public', indexHTML = true }: { /** @@ -125,14 +130,33 @@ export const staticPlugin = async ( */ noCache?: boolean /** - * @default 0 + * @default public + * + * directive for Cache-Control header + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#directives + */ + directive?: + | 'public' + | 'private' + | 'must-revalidate' + | 'no-cache' + | 'no-store' + | 'no-transform' + | 'proxy-revalidate' + | 'immutable' + /** + * @default 86400 * * Specifies the maximum amount of time in seconds, a resource will be considered fresh. * This freshness lifetime is calculated relative to the time of the request. * This setting helps control browser caching behavior. * A `maxAge` of 0 will prevent caching, requiring requests to validate with the server before use. */ - maxAge?: number + maxAge?: number | null + /** + * + */ /** * @default true * @@ -176,9 +200,12 @@ export const staticPlugin = async ( alwaysStatic, ignorePatterns, noExtension, + enableDecodeURI, resolve: resolve.toString(), headers, noCache, + maxAge, + directive, indexHTML } }) @@ -205,9 +232,10 @@ export const staticPlugin = async ( const file = Bun.file(filePath) const etag = await generateETag(file) - const pathName = isFSSepUnsafe ? - prefix + fileName.split(sep).join(URL_PATH_SEP) : - join(prefix, fileName) + const pathName = isFSSepUnsafe + ? prefix + fileName.split(sep).join(URL_PATH_SEP) + : join(prefix, fileName) + app.get( pathName, noCache @@ -223,7 +251,9 @@ export const staticPlugin = async ( } headers['Etag'] = etag - headers['Cache-Control'] = `public, max-age=${maxAge}` + headers['Cache-Control'] = directive + if (maxAge) + headers['Cache-Control'] += `, max-age=${maxAge}` return new Response(file, { headers @@ -247,8 +277,11 @@ export const staticPlugin = async ( } headers['Etag'] = etag - headers['Cache-Control'] = - `public, max-age=${maxAge}` + headers['Cache-Control'] = directive + if (maxAge) + headers[ + 'Cache-Control' + ] += `, max-age=${maxAge}` return new Response(file, { headers @@ -298,7 +331,9 @@ export const staticPlugin = async ( htmlCache.get( `${path}${sep}index.html` ) ?? - (await fileExists(`${path}${sep}index.html`))) + (await fileExists( + `${path}${sep}index.html` + ))) ) { if (hasCache === undefined) htmlCache.set( @@ -335,7 +370,9 @@ export const staticPlugin = async ( }) headers['Etag'] = etag - headers['Cache-Control'] = `public, max-age=${maxAge}` + headers['Cache-Control'] = directive + if (maxAge) + headers['Cache-Control'] += `, max-age=${maxAge}` return new Response(file, { headers