Comparing version 0.5.7 to 0.6.0
/// <reference types="node" /> | ||
import { IncomingMessage, ServerResponse } from 'http'; | ||
import { TPathname } from '../../types'; | ||
export default function sendFile(req: IncomingMessage, res: ServerResponse, asset: TPathname, contentType?: string): Promise<void>; | ||
export default function sendFile(req: IncomingMessage, res: ServerResponse, location: TPathname, contentType?: string): Promise<void>; |
@@ -19,7 +19,7 @@ "use strict"; | ||
const guess_content_type_1 = __importDefault(require("../../util/guess-content-type")); | ||
function sendFile(req, res, asset, contentType) { | ||
function sendFile(req, res, location, contentType) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const location = path_1.default.join(process.cwd(), asset); | ||
const stats = yield getStats(location); | ||
res.setHeader('Content-Type', contentType !== null && contentType !== void 0 ? contentType : (0, guess_content_type_1.default)(asset)); | ||
const asset = path_1.default.join(process.cwd(), location); | ||
const stats = yield getStats(asset); | ||
res.setHeader('Content-Type', contentType !== null && contentType !== void 0 ? contentType : (0, guess_content_type_1.default)(location)); | ||
res.setHeader('Content-Length', stats.size); | ||
@@ -32,3 +32,3 @@ if (req.method === 'HEAD') { | ||
yield new Promise((resolve, reject) => { | ||
const stream = fs_1.default.createReadStream(location); | ||
const stream = fs_1.default.createReadStream(asset); | ||
stream.pipe(res); | ||
@@ -44,3 +44,3 @@ stream.on('end', resolve); | ||
throw ex_1.default.InternalServerError(undefined, { | ||
location, | ||
location: asset, | ||
error | ||
@@ -47,0 +47,0 @@ }); |
@@ -1,10 +0,7 @@ | ||
import { TRouteData, TParams, TPathname, TPathnameWild, THandle } from '../../types'; | ||
import { TParams, TPathname, THandle } from '../../types'; | ||
declare type TStaticDirectoryOptions = { | ||
url?: TPathnameWild; | ||
dir?: TPathname; | ||
exclude?: TPathname[]; | ||
location: TPathname; | ||
contentTypes?: TParams; | ||
handles?: THandle[]; | ||
}; | ||
export default function staticDirectory(options: TStaticDirectoryOptions): TRouteData; | ||
export default function staticDirectory(options: TStaticDirectoryOptions): THandle; | ||
export {}; |
@@ -20,40 +20,17 @@ "use strict"; | ||
const validate_1 = require("../../util/validate"); | ||
const ex_1 = __importDefault(require("../tools/ex")); | ||
function staticDirectory(options) { | ||
var _a, _b; | ||
validateOptions(options); | ||
const handle = (0, modules_1.createHandle)(({ req, res, params }) => __awaiter(this, void 0, void 0, function* () { | ||
var _c, _d; | ||
const asset = path_1.default.join((_c = options.dir) !== null && _c !== void 0 ? _c : '/public', params.wild); | ||
if (isExcluded((_d = options.exclude) !== null && _d !== void 0 ? _d : [], asset)) { | ||
throw ex_1.default.NotFound(); | ||
} | ||
yield (0, send_file_1.default)(req, res, asset, (0, guess_content_type_1.default)(asset, options.contentTypes)); | ||
return (0, modules_1.createHandle)(({ req, res, params }) => __awaiter(this, void 0, void 0, function* () { | ||
const location = path_1.default.join(options.location, params.wild); | ||
const contentType = (0, guess_content_type_1.default)(location, options.contentTypes); | ||
yield (0, send_file_1.default)(req, res, location, contentType); | ||
})); | ||
return (0, modules_1.createRoute)({ | ||
method: 'GET', | ||
url: (_a = options.url) !== null && _a !== void 0 ? _a : '/**', | ||
handles: [...(_b = options.handles) !== null && _b !== void 0 ? _b : [], handle] | ||
}); | ||
} | ||
exports.default = staticDirectory; | ||
function validateOptions(options) { | ||
var _a; | ||
(0, validate_1.validateExists)(options, 'Static directory options'); | ||
(0, validate_1.validateObject)(options, 'Static directory options'); | ||
(0, validate_1.validatePathname)(options.url, 'Static directory options.url', true); | ||
(0, validate_1.validatePathname)(options.dir, 'Static directory options.dir'); | ||
(0, validate_1.validateArray)(options.exclude, 'Static directory options.exclude'); | ||
(0, validate_1.validateExists)(options.location, 'Static directory options.location'); | ||
(0, validate_1.validatePathname)(options.location, 'Static directory options.location'); | ||
(0, validate_1.validateObject)(options.contentTypes, 'Static directory options.contentTypes', 'string'); | ||
(0, validate_1.validateArray)(options.handles, 'Static directory handles', 'function'); | ||
for (const value of (_a = options.exclude) !== null && _a !== void 0 ? _a : []) { | ||
(0, validate_1.validatePathname)(value, 'Static directory options.exclude'); | ||
} | ||
} | ||
function isExcluded(values, asset) { | ||
for (const value of values) { | ||
if (asset.startsWith(value)) | ||
return true; | ||
} | ||
return false; | ||
} |
@@ -1,9 +0,7 @@ | ||
import { THandle, TPathname, TRouteData } from '../../types'; | ||
import { THandle, TPathname } from '../../types'; | ||
declare type TStaticFileOptions = { | ||
url?: TPathname; | ||
asset: TPathname; | ||
location: TPathname; | ||
contentType?: string; | ||
handles?: THandle[]; | ||
}; | ||
export default function staticFile(options: TStaticFileOptions): TRouteData; | ||
export default function staticFile(options: TStaticFileOptions): THandle; | ||
export {}; |
@@ -19,12 +19,6 @@ "use strict"; | ||
function staticFile(options) { | ||
var _a; | ||
validateOptions(options); | ||
const handle = (0, modules_1.createHandle)(({ req, res }) => __awaiter(this, void 0, void 0, function* () { | ||
yield (0, send_file_1.default)(req, res, options.asset, options.contentType); | ||
return (0, modules_1.createHandle)(({ req, res }) => __awaiter(this, void 0, void 0, function* () { | ||
yield (0, send_file_1.default)(req, res, options.location, options.contentType); | ||
})); | ||
return (0, modules_1.createRoute)({ | ||
method: 'GET', | ||
url: options.url, | ||
handles: [...(_a = options.handles) !== null && _a !== void 0 ? _a : [], handle] | ||
}); | ||
} | ||
@@ -35,7 +29,5 @@ exports.default = staticFile; | ||
(0, validate_1.validateObject)(options, 'Static file options'); | ||
(0, validate_1.validatePathname)(options.url, 'Static file url'); | ||
(0, validate_1.validateExists)(options.asset, 'Static file asset'); | ||
(0, validate_1.validatePathname)(options.asset, 'Static file asset'); | ||
(0, validate_1.validateContentType)(options.contentType, 'Static file contentType'); | ||
(0, validate_1.validateArray)(options.handles, 'Static file handles', 'function'); | ||
(0, validate_1.validateExists)(options.location, 'Static file options.location'); | ||
(0, validate_1.validatePathname)(options.location, 'Static file options.location'); | ||
(0, validate_1.validateContentType)(options.contentType, 'Static file options.contentType'); | ||
} |
{ | ||
"name": "kequapp", | ||
"version": "0.5.7", | ||
"version": "0.6.0", | ||
"description": "Non-intrusive Node JavaScript web app framework", | ||
@@ -5,0 +5,0 @@ "main": "dist/main.js", |
@@ -687,9 +687,6 @@ <img alt="kequapp" src="https://github.com/Kequc/kequapp/blob/0.2-wip/logo.png?raw=true" width="142" height="85" /> | ||
| ---- | ---- | ---- | | ||
| **url** | *Pathname* | `'/**'` | | ||
| **dir** | *Local* | `'/public'` | | ||
| **exclude** | *Exclusions* | `[]` | | ||
| **location \*** | *Local* | | | ||
| **contentTypes** | *Additions* | `{}` | | ||
| **handles** | *Sequence* | `[]` | | ||
Pairs a `url` with a static directory. | ||
Pairs a `wild` parameter with a static directory relative to the root of our project. | ||
@@ -699,20 +696,46 @@ ```javascript | ||
const staticAssets = staticDirectory({ | ||
location: '/my-assets-dir', | ||
contentTypes: { | ||
'.3gp': 'audio/3gpp' | ||
} | ||
}); | ||
createApp({ | ||
routes: [ | ||
staticDirectory({ | ||
{ | ||
method: 'GET', | ||
url: '/assets/**', | ||
dir: '/my-assets-dir', | ||
exclude: ['/my-assets-dir/private'], | ||
contentTypes: { | ||
'.3gp': 'audio/3gpp' | ||
} | ||
}) | ||
handles: [staticAssets] | ||
} | ||
] | ||
); | ||
}); | ||
``` | ||
The `url` must end with `'/**'` capturing all possible paths. | ||
The `url` should end with `'/**'` capturing all possible paths. | ||
Exclusions can be provided if we want to ignore some files or directories using `exclude`. A `'Content-Type'` header is guessed based on every asset's file extension. If there are assets in the directory with unusual file extensions then additional `contentTypes` may be provided. | ||
A `'Content-Type'` header is guessed based on every asset's file extension. If there are assets in the directory with unusual file extensions then additional `contentTypes` may be provided. Exclusions can be provided if we want to ignore certain requests, or headers for assets can be set by using a handle. | ||
```javascript | ||
// staticDirectory | ||
const setupAssets = createHandle(({ res, params }) => { | ||
if (params.wild === 'secret.txt') { | ||
throw Ex.NotFound(); | ||
} | ||
res.setHeader('Cache-Control', 'max-age=604800'); | ||
}); | ||
createApp({ | ||
routes: [ | ||
{ | ||
method: 'GET', | ||
url: '/assets/**', | ||
handles: [setupAssets, staticAssets] | ||
} | ||
] | ||
}); | ||
``` | ||
# # staticFile() | ||
@@ -726,8 +749,6 @@ | ||
| ---- | ---- | ---- | | ||
| **asset \*** | *Local* | | | ||
| **url** | *Pathname* | `'/'` | | ||
| **location \*** | *Local* | | | ||
| **contentType** | *Content type* | | | ||
| **handles** | *Sequence* | `[]` | | ||
Pairs a `url` and a local file. This asset will be delivered to the client. | ||
Delivers a static asset to the client. | ||
@@ -737,8 +758,13 @@ ```javascript | ||
const serveDb = staticFile({ | ||
location: '/db/my-db.json' | ||
}); | ||
createApp({ | ||
routes: [ | ||
staticFile({ | ||
{ | ||
method: 'GET', | ||
url: '/db.json', | ||
asset: '/db/my-db.json' | ||
}) | ||
handles: [serveDb] | ||
} | ||
] | ||
@@ -765,2 +791,6 @@ ); | ||
const serveDb = createHandle(async ({ req, res }) => { | ||
await sendFile(req, res, '/db/my-db.json'); | ||
}); | ||
createApp({ | ||
@@ -771,5 +801,3 @@ routes: [ | ||
url: '/db.json' | ||
handles: [async ({ req, res }) => { | ||
await sendFile(req, res, '/db/my-db.json'); | ||
}], | ||
handles: [serveDb], | ||
} | ||
@@ -776,0 +804,0 @@ ] |
900
117465
2201