Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@elysiajs/static

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@elysiajs/static - npm Package Compare versions

Comparing version 1.0.2 to 1.0.3

18

dist/cache.js

@@ -7,21 +7,16 @@ import { stat } from 'fs/promises';

if (headers['cache-control'] &&
headers['cache-control'].indexOf('no-cache') !== -1) {
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 === '*') {
if (ifNoneMatch === '*')
return true;
}
if (ifNoneMatch === null) {
if (ifNoneMatch === null)
return false;
}
if (typeof etag !== 'string') {
if (typeof etag !== 'string')
return false;
}
const isMatching = ifNoneMatch === etag;
if (isMatching) {
if (isMatching)
return true;
}
/**

@@ -49,5 +44,4 @@ * A recipient MUST ignore If-Modified-Since if the request contains an

if (lastModified !== undefined &&
lastModified.getTime() <= Date.parse(ifModifiedSince)) {
lastModified.getTime() <= Date.parse(ifModifiedSince))
return true;
}
}

@@ -54,0 +48,0 @@ return false;

@@ -7,20 +7,15 @@ "use strict";

if (headers['cache-control'] &&
headers['cache-control'].indexOf('no-cache') !== -1) {
headers['cache-control'].indexOf('no-cache') !== -1)
return false;
}
if ('if-none-match' in headers) {
const ifNoneMatch = headers['if-none-match'];
if (ifNoneMatch === '*') {
if (ifNoneMatch === '*')
return true;
}
if (ifNoneMatch === null) {
if (ifNoneMatch === null)
return false;
}
if (typeof etag !== 'string') {
if (typeof etag !== 'string')
return false;
}
const isMatching = ifNoneMatch === etag;
if (isMatching) {
if (isMatching)
return true;
}
return false;

@@ -37,5 +32,4 @@ }

if (lastModified !== undefined &&
lastModified.getTime() <= Date.parse(ifModifiedSince)) {
lastModified.getTime() <= Date.parse(ifModifiedSince))
return true;
}
}

@@ -42,0 +36,0 @@ return false;

import { Elysia } from 'elysia';
export declare const staticPlugin: <Prefix extends string = "/prefix">({ assets, prefix, staticLimit, alwaysStatic, ignorePatterns, noExtension, enableDecodeURI, resolve, headers, noCache, indexHTML }?: {
export declare const staticPlugin: <Prefix extends string = "/prefix">({ assets, prefix, staticLimit, alwaysStatic, ignorePatterns, noExtension, enableDecodeURI, resolve, headers, noCache, maxAge, directive, indexHTML }?: {
assets?: string | undefined;

@@ -13,2 +13,4 @@ prefix?: Prefix | undefined;

noCache?: boolean | undefined;
directive?: "no-cache" | "public" | "private" | "must-revalidate" | "no-store" | "no-transform" | "proxy-revalidate" | "immutable" | undefined;
maxAge?: number | null | undefined;
indexHTML?: boolean | undefined;

@@ -15,0 +17,0 @@ }) => Promise<Elysia<"", false, {

@@ -12,2 +12,3 @@ "use strict";

const cache_1 = require("./cache");
const URL_PATH_SEP = '/';
const fileExists = (path) => (0, promises_1.stat)(path).then(() => true, () => false);

@@ -35,3 +36,3 @@ const statCache = new node_cache_1.default({

const all = await Promise.all(files.map(async (name) => {
const file = dir + '/' + name;
const file = dir + path_1.sep + name;
const stats = await (0, promises_1.stat)(file);

@@ -44,3 +45,3 @@ return stats && stats.isDirectory()

};
const staticPlugin = async ({ assets = 'public', prefix = '/public', staticLimit = 1024, alwaysStatic = false, ignorePatterns = ['.DS_Store', '.git', '.env'], noExtension = false, enableDecodeURI = false, resolve = path_1.resolve, headers = {}, noCache = false, indexHTML = true } = {
const staticPlugin = async ({ assets = 'public', prefix = '/public', staticLimit = 1024, alwaysStatic = false, ignorePatterns = ['.DS_Store', '.git', '.env'], noExtension = false, enableDecodeURI = false, resolve = path_1.resolve, headers = {}, noCache = false, maxAge = 86400, directive = 'public', indexHTML = true } = {
assets: 'public',

@@ -59,3 +60,4 @@ prefix: '/public',

const files = await listFiles((0, path_1.resolve)(assets));
if (prefix === '/')
const isFSSepUnsafe = path_1.sep !== URL_PATH_SEP;
if (prefix === URL_PATH_SEP)
prefix = '';

@@ -81,5 +83,8 @@ const shouldIgnore = (file) => {

noExtension,
enableDecodeURI,
resolve: resolve.toString(),
headers,
noCache,
maxAge,
directive,
indexHTML

@@ -96,3 +101,3 @@ }

.replace(resolve(), '')
.replace(`${assets}/`, '');
.replace(`${assets}${path_1.sep}`, '');
if (noExtension) {

@@ -105,3 +110,6 @@ const temp = fileName.split('.');

const etag = await (0, cache_1.generateETag)(file);
app.get((0, path_1.join)(prefix, fileName), noCache
const pathName = isFSSepUnsafe
? prefix + fileName.split(path_1.sep).join(URL_PATH_SEP)
: (0, path_1.join)(prefix, fileName);
app.get(pathName, noCache
? new Response(file, {

@@ -118,3 +126,5 @@ headers

headers['Etag'] = etag;
headers['Cache-Control'] = 'public, max-age=0';
headers['Cache-Control'] = directive;
if (maxAge !== null)
headers['Cache-Control'] += `, max-age=${maxAge}`;
return new Response(file, {

@@ -124,4 +134,4 @@ headers

});
if (indexHTML && fileName.endsWith('/index.html'))
app.get((0, path_1.join)(prefix, fileName.replace('/index.html', '')), noCache
if (indexHTML && pathName.endsWith('/index.html'))
app.get((0, path_1.join)(prefix, pathName.replace('/index.html', '')), noCache
? new Response(file, {

@@ -131,3 +141,3 @@ headers

: async ({ headers: reqHeaders }) => {
if (await (0, cache_1.isCached)(reqHeaders, etag, filePath)) {
if (await (0, cache_1.isCached)(reqHeaders, etag, pathName)) {
return new Response(null, {

@@ -139,3 +149,5 @@ status: 304,

headers['Etag'] = etag;
headers['Cache-Control'] = 'public, max-age=0';
headers['Cache-Control'] = directive;
if (maxAge !== null)
headers['Cache-Control'] += `, max-age=${maxAge}`;
return new Response(file, {

@@ -149,5 +161,8 @@ headers

app.onError(() => { }).get(`${prefix}/*`, async ({ params, headers: reqHeaders }) => {
const path = enableDecodeURI
let path = enableDecodeURI
? decodeURI(`${assets}/${decodeURI(params['*'])}`)
: `${assets}/${params['*']}`;
if (isFSSepUnsafe) {
path = path.replace(URL_PATH_SEP, path_1.sep);
}
if (shouldIgnore(path))

@@ -167,11 +182,11 @@ throw new elysia_1.NotFoundError();

(hasCache =
htmlCache.get(`${path}/index.html`) ??
(await fileExists(`${path}/index.html`)))) {
htmlCache.get(`${path}${path_1.sep}index.html`) ??
(await fileExists(`${path}${path_1.sep}index.html`)))) {
if (hasCache === undefined)
htmlCache.set(`${path}/index.html`, true);
file = Bun.file(`${path}/index.html`);
htmlCache.set(`${path}${path_1.sep}index.html`, true);
file = Bun.file(`${path}${path_1.sep}index.html`);
}
else {
if (indexHTML && hasCache === undefined)
htmlCache.set(`${path}/index.html`, false);
htmlCache.set(`${path}${path_1.sep}index.html`, false);
throw new elysia_1.NotFoundError();

@@ -194,3 +209,5 @@ }

headers['Etag'] = etag;
headers['Cache-Control'] = 'public, max-age=0';
headers['Cache-Control'] = directive;
if (maxAge !== null)
headers['Cache-Control'] += `, max-age=${maxAge}`;
return new Response(file, {

@@ -197,0 +214,0 @@ headers

import { Elysia } from 'elysia';
export declare const staticPlugin: <Prefix extends string = "/prefix">({ assets, prefix, staticLimit, alwaysStatic, ignorePatterns, noExtension, enableDecodeURI, resolve, headers, noCache, indexHTML }?: {
export declare const staticPlugin: <Prefix extends string = "/prefix">({ assets, prefix, staticLimit, alwaysStatic, ignorePatterns, noExtension, enableDecodeURI, resolve, headers, noCache, maxAge, directive, indexHTML }?: {
/**

@@ -65,2 +65,22 @@ * @default "public"

/**
* @default public
*
* directive for Cache-Control header
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#directives
*/
directive?: "no-cache" | "public" | "private" | "must-revalidate" | "no-store" | "no-transform" | "proxy-revalidate" | "immutable" | undefined;
/**
* @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 | null | undefined;
/**
*
*/
/**
* @default true

@@ -67,0 +87,0 @@ *

import { Elysia, NotFoundError } from 'elysia';
import { readdir, stat } from 'fs/promises';
import { resolve, resolve as resolveFn, join } from 'path';
import { resolve, resolve as resolveFn, join, sep } from 'path';
import Cache from 'node-cache';
import { generateETag, isCached } from './cache';
const URL_PATH_SEP = '/';
const fileExists = (path) => stat(path).then(() => true, () => false);

@@ -28,3 +29,3 @@ const statCache = new Cache({

const all = await Promise.all(files.map(async (name) => {
const file = dir + '/' + name;
const file = dir + sep + name;
const stats = await stat(file);

@@ -37,3 +38,3 @@ return stats && stats.isDirectory()

};
export const staticPlugin = async ({ assets = 'public', prefix = '/public', staticLimit = 1024, alwaysStatic = false, ignorePatterns = ['.DS_Store', '.git', '.env'], noExtension = false, enableDecodeURI = false, resolve = resolveFn, headers = {}, noCache = false, indexHTML = true } = {
export const staticPlugin = async ({ assets = 'public', prefix = '/public', staticLimit = 1024, alwaysStatic = false, ignorePatterns = ['.DS_Store', '.git', '.env'], noExtension = false, enableDecodeURI = false, resolve = resolveFn, headers = {}, noCache = false, maxAge = 86400, directive = 'public', indexHTML = true } = {
assets: 'public',

@@ -52,3 +53,4 @@ prefix: '/public',

const files = await listFiles(resolveFn(assets));
if (prefix === '/')
const isFSSepUnsafe = sep !== URL_PATH_SEP;
if (prefix === URL_PATH_SEP)
prefix = '';

@@ -74,5 +76,8 @@ const shouldIgnore = (file) => {

noExtension,
enableDecodeURI,
resolve: resolve.toString(),
headers,
noCache,
maxAge,
directive,
indexHTML

@@ -89,3 +94,3 @@ }

.replace(resolve(), '')
.replace(`${assets}/`, '');
.replace(`${assets}${sep}`, '');
if (noExtension) {

@@ -98,3 +103,6 @@ const temp = fileName.split('.');

const etag = await generateETag(file);
app.get(join(prefix, fileName), noCache
const pathName = isFSSepUnsafe
? prefix + fileName.split(sep).join(URL_PATH_SEP)
: join(prefix, fileName);
app.get(pathName, noCache
? new Response(file, {

@@ -111,3 +119,5 @@ headers

headers['Etag'] = etag;
headers['Cache-Control'] = 'public, max-age=0';
headers['Cache-Control'] = directive;
if (maxAge !== null)
headers['Cache-Control'] += `, max-age=${maxAge}`;
return new Response(file, {

@@ -117,4 +127,4 @@ headers

});
if (indexHTML && fileName.endsWith('/index.html'))
app.get(join(prefix, fileName.replace('/index.html', '')), noCache
if (indexHTML && pathName.endsWith('/index.html'))
app.get(join(prefix, pathName.replace('/index.html', '')), noCache
? new Response(file, {

@@ -124,3 +134,3 @@ headers

: async ({ headers: reqHeaders }) => {
if (await isCached(reqHeaders, etag, filePath)) {
if (await isCached(reqHeaders, etag, pathName)) {
return new Response(null, {

@@ -132,3 +142,5 @@ status: 304,

headers['Etag'] = etag;
headers['Cache-Control'] = 'public, max-age=0';
headers['Cache-Control'] = directive;
if (maxAge !== null)
headers['Cache-Control'] += `, max-age=${maxAge}`;
return new Response(file, {

@@ -142,5 +154,10 @@ headers

app.onError(() => { }).get(`${prefix}/*`, async ({ params, headers: reqHeaders }) => {
const path = enableDecodeURI
let path = enableDecodeURI
? decodeURI(`${assets}/${decodeURI(params['*'])}`)
: `${assets}/${params['*']}`;
// Handle varying filepath separators
if (isFSSepUnsafe) {
path = path.replace(URL_PATH_SEP, sep);
}
// Note that path must match the system separator
if (shouldIgnore(path))

@@ -160,11 +177,11 @@ throw new NotFoundError();

(hasCache =
htmlCache.get(`${path}/index.html`) ??
(await fileExists(`${path}/index.html`)))) {
htmlCache.get(`${path}${sep}index.html`) ??
(await fileExists(`${path}${sep}index.html`)))) {
if (hasCache === undefined)
htmlCache.set(`${path}/index.html`, true);
file = Bun.file(`${path}/index.html`);
htmlCache.set(`${path}${sep}index.html`, true);
file = Bun.file(`${path}${sep}index.html`);
}
else {
if (indexHTML && hasCache === undefined)
htmlCache.set(`${path}/index.html`, false);
htmlCache.set(`${path}${sep}index.html`, false);
throw new NotFoundError();

@@ -187,3 +204,5 @@ }

headers['Etag'] = etag;
headers['Cache-Control'] = 'public, max-age=0';
headers['Cache-Control'] = directive;
if (maxAge !== null)
headers['Cache-Control'] += `, max-age=${maxAge}`;
return new Response(file, {

@@ -190,0 +209,0 @@ headers

{
"name": "@elysiajs/static",
"version": "1.0.2",
"version": "1.0.3",
"author": {

@@ -5,0 +5,0 @@ "name": "saltyAom",

@@ -15,5 +15,4 @@ import { BunFile } from 'bun'

headers['cache-control'].indexOf('no-cache') !== -1
) {
)
return false
}

@@ -24,19 +23,11 @@ // 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

@@ -68,5 +59,4 @@ /**

lastModified.getTime() <= Date.parse(ifModifiedSince)
) {
)
return true
}
}

@@ -73,0 +63,0 @@

import { Elysia, NotFoundError } from 'elysia'
import { readdir, stat } from 'fs/promises'
import { resolve, resolve as resolveFn, join } from 'path'
import { resolve, resolve as resolveFn, join, sep } from 'path'
import Cache from 'node-cache'

@@ -10,3 +10,8 @@

const fileExists = (path: string) => stat(path).then(() => true, () => false)
const URL_PATH_SEP = '/'
const fileExists = (path: string) =>
stat(path).then(
() => true,
() => false
)

@@ -39,3 +44,3 @@ const statCache = new Cache({

files.map(async (name) => {
const file = dir + '/' + name
const file = dir + sep + name
const stats = await stat(file)

@@ -64,2 +69,4 @@

noCache = false,
maxAge = 86400,
directive = 'public',
indexHTML = true

@@ -129,2 +136,30 @@ }: {

/**
* @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 | null
/**
*
*/
/**
* @default true

@@ -150,4 +185,5 @@ *

const files = await listFiles(resolveFn(assets))
const isFSSepUnsafe = sep !== URL_PATH_SEP
if (prefix === '/') prefix = '' as Prefix
if (prefix === URL_PATH_SEP) prefix = '' as Prefix

@@ -172,5 +208,8 @@ const shouldIgnore = (file: string) => {

noExtension,
enableDecodeURI,
resolve: resolve.toString(),
headers,
noCache,
maxAge,
directive,
indexHTML

@@ -190,3 +229,3 @@ }

.replace(resolve(), '')
.replace(`${assets}/`, '')
.replace(`${assets}${sep}`, '')

@@ -203,4 +242,8 @@ if (noExtension) {

const pathName = isFSSepUnsafe
? prefix + fileName.split(sep).join(URL_PATH_SEP)
: join(prefix, fileName)
app.get(
join(prefix, fileName),
pathName,
noCache

@@ -219,3 +262,5 @@ ? new Response(file, {

headers['Etag'] = etag
headers['Cache-Control'] = 'public, max-age=0'
headers['Cache-Control'] = directive
if (maxAge !== null)
headers['Cache-Control'] += `, max-age=${maxAge}`

@@ -228,5 +273,5 @@ return new Response(file, {

if (indexHTML && fileName.endsWith('/index.html'))
if (indexHTML && pathName.endsWith('/index.html'))
app.get(
join(prefix, fileName.replace('/index.html', '')),
join(prefix, pathName.replace('/index.html', '')),
noCache

@@ -237,3 +282,3 @@ ? new Response(file, {

: async ({ headers: reqHeaders }) => {
if (await isCached(reqHeaders, etag, filePath)) {
if (await isCached(reqHeaders, etag, pathName)) {
return new Response(null, {

@@ -246,3 +291,7 @@ status: 304,

headers['Etag'] = etag
headers['Cache-Control'] = 'public, max-age=0'
headers['Cache-Control'] = directive
if (maxAge !== null)
headers[
'Cache-Control'
] += `, max-age=${maxAge}`

@@ -264,6 +313,11 @@ return new Response(file, {

async ({ params, headers: reqHeaders }) => {
const path = enableDecodeURI
let path = enableDecodeURI
? decodeURI(`${assets}/${decodeURI(params['*'])}`)
: `${assets}/${params['*']}`
// Handle varying filepath separators
if (isFSSepUnsafe) {
path = path.replace(URL_PATH_SEP, sep)
}
// Note that path must match the system separator
if (shouldIgnore(path)) throw new NotFoundError()

@@ -291,17 +345,19 @@

htmlCache.get<boolean>(
`${path}/index.html`
`${path}${sep}index.html`
) ??
(await fileExists(`${path}/index.html`)))
(await fileExists(
`${path}${sep}index.html`
)))
) {
if (hasCache === undefined)
htmlCache.set(
`${path}/index.html`,
`${path}${sep}index.html`,
true
)
file = Bun.file(`${path}/index.html`)
file = Bun.file(`${path}${sep}index.html`)
} else {
if (indexHTML && hasCache === undefined)
htmlCache.set(
`${path}/index.html`,
`${path}${sep}index.html`,
false

@@ -331,3 +387,5 @@ )

headers['Etag'] = etag
headers['Cache-Control'] = 'public, max-age=0'
headers['Cache-Control'] = directive
if (maxAge !== null)
headers['Cache-Control'] += `, max-age=${maxAge}`

@@ -334,0 +392,0 @@ return new Response(file, {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc