added doga
This commit is contained in:
21
25_02_24/node_modules/@tinyhttp/logger/LICENSE
generated
vendored
Normal file
21
25_02_24/node_modules/@tinyhttp/logger/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 v 1 r t l
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
103
25_02_24/node_modules/@tinyhttp/logger/README.md
generated
vendored
Normal file
103
25_02_24/node_modules/@tinyhttp/logger/README.md
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<div align="center">
|
||||
|
||||
# @tinyhttp/logger
|
||||
|
||||
[![npm][npm-img]][npm-url] [![GitHub Workflow Status][gh-actions-img]][github-actions] [![Coverage][cov-img]][cov-url]
|
||||
|
||||
</div>
|
||||
|
||||
Minimal and flexible HTTP logger
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
pnpm i @tinyhttp/logger
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```ts
|
||||
import { logger } from '@tinyhttp/logger'
|
||||
```
|
||||
|
||||
### `logger(options)`
|
||||
|
||||
Returns the middleware for logging HTTP requests.
|
||||
|
||||
#### Options
|
||||
|
||||
- `methods`: a list of HTTP methods to log. Defaults to `http`'s `METHODS`.
|
||||
- `timestamp.format`: timestamp format. It is consumed by the [dayjs](https://day.js.org) library. If a string is specified, it is used as a format; otherwise just enabled.
|
||||
- `output.callback`: a function that receives the log generated by the logger.
|
||||
- `output.color`: a property that determines whether the logger will generate a message with color. Useful for logging into the console; disable if logging into a file or other colorless environments.
|
||||
- `emoji`: enable emojis for HTTP status codes. See [http-status-emojis](https://github.com/bendrucker/http-status-emojis/blob/master/index.js) for a full list.
|
||||
- `ip`: log IP address.
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
import { App } from '@tinyhttp/app'
|
||||
import { logger } from '@tinyhttp/logger'
|
||||
|
||||
new App()
|
||||
.use(
|
||||
logger({
|
||||
methods: ['GET', 'POST'],
|
||||
timestamp: { format: 'HH:mm:ss' },
|
||||
output: { callback: console.log, color: false }
|
||||
})
|
||||
)
|
||||
.get('/', (req, res) => res.send('Hello world'))
|
||||
.post('/', (req, res) => res.send('Sent POST'))
|
||||
.listen(3000)
|
||||
```
|
||||
|
||||
To Log a level, use the enum `LogLevel`
|
||||
|
||||
```ts
|
||||
import { App } from '@tinyhttp/app'
|
||||
import { logger, LogLevel } from '@tinyhttp/logger'
|
||||
|
||||
new App()
|
||||
.use(
|
||||
logger({
|
||||
methods: ['GET', 'POST'],
|
||||
timestamp: { format: 'HH:mm:ss' },
|
||||
output: { callback: console.log, color: false, level: LogLevel.warn }
|
||||
})
|
||||
)
|
||||
.get('/', (req, res) => res.send('Hello world'))
|
||||
.listen(3000)
|
||||
```
|
||||
|
||||
This also includes a simple file logger. To stream to a file, simply supply the filename in the options. Supported file names innclude
|
||||
`./file.log` or `./log/tiny.log`
|
||||
|
||||
```ts
|
||||
import { App } from '@tinyhttp/app'
|
||||
import { logger } from '@tinyhttp/logger'
|
||||
|
||||
new App()
|
||||
.use(
|
||||
logger({
|
||||
methods: ['GET', 'POST'],
|
||||
timestamp: { format: 'HH:mm:ss' },
|
||||
output: { callback: console.log, color: false, filename: './log/tiny.log' }
|
||||
})
|
||||
)
|
||||
.get('/', (req, res) => res.send('Hello world'))
|
||||
.listen(3000)
|
||||
```
|
||||
|
||||
## Alternatives
|
||||
|
||||
- [@tinyhttp/logger](/mw/logger) - Simple HTTP logger for tinyhttp
|
||||
- [Pino HTTP](https://github.com/pinojs/pino-http) - high-speed HTTP logger for Node.js
|
||||
- [chrona](https://github.com/xambassador/chrona) - Simple HTTP request logger middleware for express.js inspired from koa-logger, written in typescript.
|
||||
|
||||
[npm-url]: https://npmjs.com/package/@tinyhttp/logger
|
||||
[github-actions]: https://github.com/tinyhttp/logger/actions
|
||||
[gh-actions-img]: https://img.shields.io/github/actions/workflow/status/tinyhttp/logger/ci.yml?branch=master&style=for-the-badge&color=hotpink&label=&logo=github
|
||||
[cov-img]: https://img.shields.io/coveralls/github/tinyhttp/logger?style=for-the-badge&color=hotpink
|
||||
[cov-url]: https://coveralls.io/github/tinyhttp/logger
|
||||
[npm-img]: https://img.shields.io/npm/dt/@tinyhttp/logger?style=for-the-badge&color=hotpink
|
||||
6
25_02_24/node_modules/@tinyhttp/logger/dist/filelogger.d.ts
generated
vendored
Normal file
6
25_02_24/node_modules/@tinyhttp/logger/dist/filelogger.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export declare class FileLogger {
|
||||
#private;
|
||||
private writableStream;
|
||||
constructor(filename: string);
|
||||
toFile(stringToLog: string): void;
|
||||
}
|
||||
59
25_02_24/node_modules/@tinyhttp/logger/dist/filelogger.js
generated
vendored
Normal file
59
25_02_24/node_modules/@tinyhttp/logger/dist/filelogger.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
import { accessSync, writeFileSync, createWriteStream, mkdirSync } from 'node:fs';
|
||||
import { dirname as directoryname } from 'node:path';
|
||||
export class FileLogger {
|
||||
#filename;
|
||||
#dirname;
|
||||
writableStream;
|
||||
constructor(filename) {
|
||||
this.#dirname = directoryname(filename);
|
||||
this.#filename = filename;
|
||||
this.#_stat();
|
||||
this.#_createWritableStream();
|
||||
this.#_endStream();
|
||||
}
|
||||
#fsAccess(filename, mode) {
|
||||
try {
|
||||
accessSync(filename, mode);
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#_stat() {
|
||||
//check if file exists
|
||||
if (!this.#fsAccess(this.#filename)) {
|
||||
// check if directory exists
|
||||
if (!this.#fsAccess(this.#dirname)) {
|
||||
// create the directory
|
||||
mkdirSync(this.#dirname, { recursive: true });
|
||||
}
|
||||
// create the file and write an empty string to it
|
||||
writeFileSync(this.#filename, '');
|
||||
return;
|
||||
}
|
||||
}
|
||||
#_createWritableStream() {
|
||||
this.writableStream = createWriteStream(this.#filename, { flags: 'a' });
|
||||
}
|
||||
toFile(stringToLog) {
|
||||
this.writableStream.write(stringToLog + '\n');
|
||||
}
|
||||
#_endStream() {
|
||||
process.on('exit', () => {
|
||||
this.writableStream.close();
|
||||
});
|
||||
process.on('SIGTERM', () => {
|
||||
this.writableStream.close();
|
||||
process.exit(0);
|
||||
});
|
||||
process.on('SIGINT', () => {
|
||||
this.writableStream.close();
|
||||
process.exit(0);
|
||||
});
|
||||
process.on('uncaughtException', () => {
|
||||
this.writableStream.close();
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
23
25_02_24/node_modules/@tinyhttp/logger/dist/index.d.ts
generated
vendored
Normal file
23
25_02_24/node_modules/@tinyhttp/logger/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ServerResponse as Response, IncomingMessage as Request } from 'node:http';
|
||||
export declare enum LogLevel {
|
||||
error = "error",
|
||||
warn = "warn",
|
||||
trace = "trace",
|
||||
info = "info",
|
||||
log = "log"
|
||||
}
|
||||
export interface LoggerOptions {
|
||||
methods?: string[];
|
||||
output?: {
|
||||
color: boolean;
|
||||
filename?: string;
|
||||
callback: (string: string) => void;
|
||||
level?: LogLevel;
|
||||
};
|
||||
timestamp?: boolean | {
|
||||
format?: string;
|
||||
};
|
||||
emoji?: boolean;
|
||||
ip?: boolean;
|
||||
}
|
||||
export declare const logger: (options?: LoggerOptions) => (req: Request, res: Response, next?: () => void) => void;
|
||||
81
25_02_24/node_modules/@tinyhttp/logger/dist/index.js
generated
vendored
Normal file
81
25_02_24/node_modules/@tinyhttp/logger/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
import { cyan, red, magenta, bold } from 'colorette';
|
||||
import statusEmoji from 'http-status-emojis';
|
||||
import dayjs from 'dayjs';
|
||||
import { METHODS } from 'node:http';
|
||||
import { FileLogger } from './filelogger.js';
|
||||
export var LogLevel;
|
||||
(function (LogLevel) {
|
||||
LogLevel["error"] = "error";
|
||||
LogLevel["warn"] = "warn";
|
||||
LogLevel["trace"] = "trace";
|
||||
LogLevel["info"] = "info";
|
||||
LogLevel["log"] = "log";
|
||||
})(LogLevel || (LogLevel = {}));
|
||||
const compileArgs = (args, req, res, options = {}, status, msg) => {
|
||||
const { method } = req;
|
||||
const { statusCode } = res;
|
||||
const url = req.originalUrl || req.url;
|
||||
const methods = options.methods ?? METHODS;
|
||||
const timestamp = options.timestamp ?? false;
|
||||
const emojiEnabled = options.emoji;
|
||||
const level = options.output && options.output.level ? options.output.level : null;
|
||||
if (level)
|
||||
args.push('[' + level.toUpperCase() + ']');
|
||||
if (methods.includes(method) && timestamp) {
|
||||
args.push(`${dayjs()
|
||||
.format(typeof timestamp !== 'boolean' && timestamp.format ? timestamp.format : 'HH:mm:ss')
|
||||
.toString()} - `);
|
||||
}
|
||||
if (options.ip)
|
||||
args.push(req.ip);
|
||||
if (emojiEnabled)
|
||||
args.push(statusEmoji[statusCode]);
|
||||
args.push(method);
|
||||
args.push(status || res.statusCode);
|
||||
args.push(msg || res.statusMessage);
|
||||
args.push(url);
|
||||
};
|
||||
export const logger = (options = {}) => {
|
||||
const methods = options.methods ?? METHODS;
|
||||
const output = options.output ?? { callback: console.log, color: true, level: null };
|
||||
let filelogger = null;
|
||||
if (options.output && options.output.filename) {
|
||||
filelogger = new FileLogger(options.output.filename);
|
||||
}
|
||||
return (req, res, next) => {
|
||||
res.on('finish', () => {
|
||||
const args = [];
|
||||
// every time
|
||||
if (methods.includes(req.method)) {
|
||||
const s = res.statusCode.toString();
|
||||
let stringToLog = '';
|
||||
if (!output.color) {
|
||||
compileArgs(args, req, res, options);
|
||||
const m = args.join(' ');
|
||||
stringToLog = m;
|
||||
}
|
||||
else {
|
||||
switch (s[0]) {
|
||||
case '2':
|
||||
compileArgs(args, req, res, options, cyan(bold(s)), cyan(res.statusMessage));
|
||||
stringToLog = args.join(' ');
|
||||
break;
|
||||
case '4':
|
||||
compileArgs(args, req, res, options, red(bold(s)), red(res.statusMessage));
|
||||
stringToLog = args.join(' ');
|
||||
break;
|
||||
case '5':
|
||||
compileArgs(args, req, res, options, magenta(bold(s)), magenta(res.statusMessage));
|
||||
stringToLog = args.join(' ');
|
||||
break;
|
||||
}
|
||||
}
|
||||
output.callback(stringToLog);
|
||||
if (filelogger) {
|
||||
filelogger.toFile(stringToLog);
|
||||
}
|
||||
}
|
||||
});
|
||||
next?.();
|
||||
};
|
||||
};
|
||||
71
25_02_24/node_modules/@tinyhttp/logger/package.json
generated
vendored
Normal file
71
25_02_24/node_modules/@tinyhttp/logger/package.json
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "@tinyhttp/logger",
|
||||
"version": "2.0.0",
|
||||
"type": "module",
|
||||
"description": "Minimal and flexible HTTP logger.",
|
||||
"homepage": "https://github.com/tinyhttp/logger#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tinyhttp/logger.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.18 || >=16.20"
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
},
|
||||
"./filelogger": {
|
||||
"import": "./dist/filelogger.js",
|
||||
"types": "./dist/filelogger.d.ts"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"tinyhttp",
|
||||
"node.js",
|
||||
"web framework",
|
||||
"web",
|
||||
"backend"
|
||||
],
|
||||
"author": "v1rtl",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"colorette": "^2.0.20",
|
||||
"dayjs": "^1.11.10",
|
||||
"http-status-emojis": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^18.2.0",
|
||||
"@commitlint/config-conventional": "^18.1.0",
|
||||
"@tinyhttp/app": "^2.2.0",
|
||||
"@types/node": "^20.8.9",
|
||||
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
||||
"@typescript-eslint/parser": "^6.9.0",
|
||||
"bun-types": "^1.0.7",
|
||||
"c8": "^8.0.1",
|
||||
"eslint": "^8.52.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-prettier": "^5.0.1",
|
||||
"expect": "^29.7.0",
|
||||
"husky": "^8.0.3",
|
||||
"prettier": "^3.0.3",
|
||||
"supertest-fetch": "^1.5.0",
|
||||
"tsx": "^3.14.0",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "tsx tests/index.test.ts",
|
||||
"test:coverage": "c8 tsx --test tests/index.test.ts",
|
||||
"test:report": "c8 report --reporter=text-lcov > lcov.info",
|
||||
"lint": "eslint . --ext=ts",
|
||||
"format": "prettier --check \"./**/*.{ts,md}\"",
|
||||
"format:fix": "prettier --write \"./**/*.{ts,md}\""
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user