Skip to content

Commit 26e07b8

Browse files
committed
initial commit
0 parents  commit 26e07b8

40 files changed

Lines changed: 1412 additions & 0 deletions

.github/workflows/npm-publish.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: NPM Package
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
jobs:
8+
publish-npm:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
- uses: oven-sh/setup-bun@v2
13+
with:
14+
bun-version: latest
15+
registry-url: https://registry.npmjs.org/
16+
- run: bun install --frozen-lockfile
17+
- run: bun run build
18+
- run: npm publish
19+
env:
20+
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# dependencies (bun install)
2+
node_modules
3+
4+
# output
5+
out
6+
dist
7+
*.tgz
8+
9+
# code coverage
10+
coverage
11+
*.lcov
12+
13+
# logs
14+
logs
15+
_.log
16+
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
17+
18+
# dotenv environment variable files
19+
.env
20+
.env.development.local
21+
.env.test.local
22+
.env.production.local
23+
.env.local
24+
25+
# caches
26+
.eslintcache
27+
.cache
28+
*.tsbuildinfo
29+
30+
# IntelliJ based IDEs
31+
.idea
32+
33+
# Finder (MacOS) folder config
34+
.DS_Store

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Orkhan Karimov <karimovok1@gmail.com> (https://github.com/kerimovok)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

bun.lock

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "http-essentials",
3+
"version": "1.0.0",
4+
"description": "HTTP statuses, phrases, and exceptions",
5+
"main": "dist/index.js",
6+
"module": "dist/index.js",
7+
"types": "dist/index.d.ts",
8+
"sideEffects": false,
9+
"files": ["dist"],
10+
"keywords": ["http"],
11+
"author": "Orkhan Karimov <karimovok1@gmail.com> (https://github.com/kerimovok)",
12+
"homepage": "https://github.com/honestjs/http-essentials",
13+
"license": "MIT",
14+
"repository": {
15+
"type": "git",
16+
"url": "git+https://github.com/honestjs/http-essentials.git"
17+
},
18+
"publishConfig": {
19+
"registry": "https://registry.npmjs.org"
20+
},
21+
"devDependencies": {
22+
"@types/bun": "latest"
23+
},
24+
"peerDependencies": {
25+
"typescript": "^5"
26+
},
27+
"type": "module",
28+
"scripts": {
29+
"clean": "rm -rf dist",
30+
"build": "bun run clean && bun build ./src/index.ts --outdir=dist --target=node --minify && bun run build:types",
31+
"build:types": "tsc --emitDeclarationOnly --declaration --outDir dist"
32+
}
33+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { HttpStatus } from '@/enums';
2+
import type { Type } from '@/interfaces';
3+
4+
import {
5+
BadGatewayException,
6+
BadRequestException,
7+
ConflictException,
8+
ForbiddenException,
9+
GatewayTimeoutException,
10+
GoneException,
11+
ImATeapotException,
12+
InternalServerErrorException,
13+
MethodNotAllowedException,
14+
NotAcceptableException,
15+
NotFoundException,
16+
NotImplementedException,
17+
PreconditionFailedException,
18+
RequestTimeoutException,
19+
RequestTooLongException,
20+
ServiceUnavailableException,
21+
UnauthorizedException,
22+
UnprocessableEntityException,
23+
UnsupportedMediaTypeException,
24+
} from '@/exceptions';
25+
26+
27+
/**
28+
* Union type of all error HTTP status codes
29+
*/
30+
export type ErrorHttpStatusCode =
31+
| HttpStatus.BAD_GATEWAY
32+
| HttpStatus.BAD_REQUEST
33+
| HttpStatus.CONFLICT
34+
| HttpStatus.FORBIDDEN
35+
| HttpStatus.GATEWAY_TIMEOUT
36+
| HttpStatus.GONE
37+
| HttpStatus.IM_A_TEAPOT
38+
| HttpStatus.INTERNAL_SERVER_ERROR
39+
| HttpStatus.METHOD_NOT_ALLOWED
40+
| HttpStatus.NOT_ACCEPTABLE
41+
| HttpStatus.NOT_FOUND
42+
| HttpStatus.NOT_IMPLEMENTED
43+
| HttpStatus.REQUEST_TOO_LONG
44+
| HttpStatus.PRECONDITION_FAILED
45+
| HttpStatus.REQUEST_TIMEOUT
46+
| HttpStatus.SERVICE_UNAVAILABLE
47+
| HttpStatus.UNAUTHORIZED
48+
| HttpStatus.UNPROCESSABLE_ENTITY
49+
| HttpStatus.UNSUPPORTED_MEDIA_TYPE;
50+
51+
/**
52+
* Mapping of HTTP status codes to their corresponding exception classes
53+
*/
54+
export const HttpErrorByCode: Record<ErrorHttpStatusCode, Type<unknown>> = {
55+
[HttpStatus.BAD_GATEWAY]: BadGatewayException,
56+
[HttpStatus.BAD_REQUEST]: BadRequestException,
57+
[HttpStatus.CONFLICT]: ConflictException,
58+
[HttpStatus.FORBIDDEN]: ForbiddenException,
59+
[HttpStatus.GATEWAY_TIMEOUT]: GatewayTimeoutException,
60+
[HttpStatus.GONE]: GoneException,
61+
[HttpStatus.IM_A_TEAPOT]: ImATeapotException,
62+
[HttpStatus.INTERNAL_SERVER_ERROR]: InternalServerErrorException,
63+
[HttpStatus.METHOD_NOT_ALLOWED]: MethodNotAllowedException,
64+
[HttpStatus.NOT_ACCEPTABLE]: NotAcceptableException,
65+
[HttpStatus.NOT_FOUND]: NotFoundException,
66+
[HttpStatus.NOT_IMPLEMENTED]: NotImplementedException,
67+
[HttpStatus.REQUEST_TOO_LONG]: RequestTooLongException,
68+
[HttpStatus.PRECONDITION_FAILED]: PreconditionFailedException,
69+
[HttpStatus.REQUEST_TIMEOUT]: RequestTimeoutException,
70+
[HttpStatus.SERVICE_UNAVAILABLE]: ServiceUnavailableException,
71+
[HttpStatus.UNAUTHORIZED]: UnauthorizedException,
72+
[HttpStatus.UNPROCESSABLE_ENTITY]: UnprocessableEntityException,
73+
[HttpStatus.UNSUPPORTED_MEDIA_TYPE]: UnsupportedMediaTypeException,
74+
};
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { HttpPhrase, HttpStatus } from '@/enums';
2+
3+
export const httpPhraseByStatus: Record<HttpStatus, HttpPhrase> = {
4+
[HttpStatus.ACCEPTED]: HttpPhrase.ACCEPTED,
5+
[HttpStatus.BAD_GATEWAY]: HttpPhrase.BAD_GATEWAY,
6+
[HttpStatus.BAD_REQUEST]: HttpPhrase.BAD_REQUEST,
7+
[HttpStatus.CONFLICT]: HttpPhrase.CONFLICT,
8+
[HttpStatus.CONTINUE]: HttpPhrase.CONTINUE,
9+
[HttpStatus.CREATED]: HttpPhrase.CREATED,
10+
[HttpStatus.EXPECTATION_FAILED]: HttpPhrase.EXPECTATION_FAILED,
11+
[HttpStatus.FAILED_DEPENDENCY]: HttpPhrase.FAILED_DEPENDENCY,
12+
[HttpStatus.FORBIDDEN]: HttpPhrase.FORBIDDEN,
13+
[HttpStatus.GATEWAY_TIMEOUT]: HttpPhrase.GATEWAY_TIMEOUT,
14+
[HttpStatus.GONE]: HttpPhrase.GONE,
15+
[HttpStatus.HTTP_VERSION_NOT_SUPPORTED]: HttpPhrase.HTTP_VERSION_NOT_SUPPORTED,
16+
[HttpStatus.IM_A_TEAPOT]: HttpPhrase.IM_A_TEAPOT,
17+
[HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE]: HttpPhrase.INSUFFICIENT_SPACE_ON_RESOURCE,
18+
[HttpStatus.INSUFFICIENT_STORAGE]: HttpPhrase.INSUFFICIENT_STORAGE,
19+
[HttpStatus.INTERNAL_SERVER_ERROR]: HttpPhrase.INTERNAL_SERVER_ERROR,
20+
[HttpStatus.LENGTH_REQUIRED]: HttpPhrase.LENGTH_REQUIRED,
21+
[HttpStatus.LOCKED]: HttpPhrase.LOCKED,
22+
[HttpStatus.METHOD_FAILURE]: HttpPhrase.METHOD_FAILURE,
23+
[HttpStatus.METHOD_NOT_ALLOWED]: HttpPhrase.METHOD_NOT_ALLOWED,
24+
[HttpStatus.MOVED_PERMANENTLY]: HttpPhrase.MOVED_PERMANENTLY,
25+
[HttpStatus.MOVED_TEMPORARILY]: HttpPhrase.MOVED_TEMPORARILY,
26+
[HttpStatus.MULTI_STATUS]: HttpPhrase.MULTI_STATUS,
27+
[HttpStatus.MULTIPLE_CHOICES]: HttpPhrase.MULTIPLE_CHOICES,
28+
[HttpStatus.NETWORK_AUTHENTICATION_REQUIRED]: HttpPhrase.NETWORK_AUTHENTICATION_REQUIRED,
29+
[HttpStatus.NO_CONTENT]: HttpPhrase.NO_CONTENT,
30+
[HttpStatus.NON_AUTHORITATIVE_INFORMATION]: HttpPhrase.NON_AUTHORITATIVE_INFORMATION,
31+
[HttpStatus.NOT_ACCEPTABLE]: HttpPhrase.NOT_ACCEPTABLE,
32+
[HttpStatus.NOT_FOUND]: HttpPhrase.NOT_FOUND,
33+
[HttpStatus.NOT_IMPLEMENTED]: HttpPhrase.NOT_IMPLEMENTED,
34+
[HttpStatus.NOT_MODIFIED]: HttpPhrase.NOT_MODIFIED,
35+
[HttpStatus.OK]: HttpPhrase.OK,
36+
[HttpStatus.PARTIAL_CONTENT]: HttpPhrase.PARTIAL_CONTENT,
37+
[HttpStatus.PAYMENT_REQUIRED]: HttpPhrase.PAYMENT_REQUIRED,
38+
[HttpStatus.PERMANENT_REDIRECT]: HttpPhrase.PERMANENT_REDIRECT,
39+
[HttpStatus.PRECONDITION_FAILED]: HttpPhrase.PRECONDITION_FAILED,
40+
[HttpStatus.PRECONDITION_REQUIRED]: HttpPhrase.PRECONDITION_REQUIRED,
41+
[HttpStatus.PROCESSING]: HttpPhrase.PROCESSING,
42+
[HttpStatus.EARLY_HINTS]: HttpPhrase.EARLY_HINTS,
43+
[HttpStatus.UPGRADE_REQUIRED]: HttpPhrase.UPGRADE_REQUIRED,
44+
[HttpStatus.PROXY_AUTHENTICATION_REQUIRED]: HttpPhrase.PROXY_AUTHENTICATION_REQUIRED,
45+
[HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE]: HttpPhrase.REQUEST_HEADER_FIELDS_TOO_LARGE,
46+
[HttpStatus.REQUEST_TIMEOUT]: HttpPhrase.REQUEST_TIMEOUT,
47+
[HttpStatus.REQUEST_TOO_LONG]: HttpPhrase.REQUEST_TOO_LONG,
48+
[HttpStatus.REQUEST_URI_TOO_LONG]: HttpPhrase.REQUEST_URI_TOO_LONG,
49+
[HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE]: HttpPhrase.REQUESTED_RANGE_NOT_SATISFIABLE,
50+
[HttpStatus.RESET_CONTENT]: HttpPhrase.RESET_CONTENT,
51+
[HttpStatus.SEE_OTHER]: HttpPhrase.SEE_OTHER,
52+
[HttpStatus.SERVICE_UNAVAILABLE]: HttpPhrase.SERVICE_UNAVAILABLE,
53+
[HttpStatus.SWITCHING_PROTOCOLS]: HttpPhrase.SWITCHING_PROTOCOLS,
54+
[HttpStatus.TEMPORARY_REDIRECT]: HttpPhrase.TEMPORARY_REDIRECT,
55+
[HttpStatus.TOO_MANY_REQUESTS]: HttpPhrase.TOO_MANY_REQUESTS,
56+
[HttpStatus.UNAUTHORIZED]: HttpPhrase.UNAUTHORIZED,
57+
[HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS]: HttpPhrase.UNAVAILABLE_FOR_LEGAL_REASONS,
58+
[HttpStatus.UNPROCESSABLE_ENTITY]: HttpPhrase.UNPROCESSABLE_ENTITY,
59+
[HttpStatus.UNSUPPORTED_MEDIA_TYPE]: HttpPhrase.UNSUPPORTED_MEDIA_TYPE,
60+
[HttpStatus.USE_PROXY]: HttpPhrase.USE_PROXY,
61+
[HttpStatus.MISDIRECTED_REQUEST]: HttpPhrase.MISDIRECTED_REQUEST,
62+
};
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { HttpPhrase, HttpStatus } from '@/enums';
2+
3+
export const httpStatusByPhrase: Record<HttpPhrase, HttpStatus> = {
4+
[HttpPhrase.ACCEPTED]: HttpStatus.ACCEPTED,
5+
[HttpPhrase.BAD_GATEWAY]: HttpStatus.BAD_GATEWAY,
6+
[HttpPhrase.BAD_REQUEST]: HttpStatus.BAD_REQUEST,
7+
[HttpPhrase.CONFLICT]: HttpStatus.CONFLICT,
8+
[HttpPhrase.CONTINUE]: HttpStatus.CONTINUE,
9+
[HttpPhrase.CREATED]: HttpStatus.CREATED,
10+
[HttpPhrase.EXPECTATION_FAILED]: HttpStatus.EXPECTATION_FAILED,
11+
[HttpPhrase.FAILED_DEPENDENCY]: HttpStatus.FAILED_DEPENDENCY,
12+
[HttpPhrase.FORBIDDEN]: HttpStatus.FORBIDDEN,
13+
[HttpPhrase.GATEWAY_TIMEOUT]: HttpStatus.GATEWAY_TIMEOUT,
14+
[HttpPhrase.GONE]: HttpStatus.GONE,
15+
[HttpPhrase.HTTP_VERSION_NOT_SUPPORTED]: HttpStatus.HTTP_VERSION_NOT_SUPPORTED,
16+
[HttpPhrase.IM_A_TEAPOT]: HttpStatus.IM_A_TEAPOT,
17+
[HttpPhrase.INSUFFICIENT_SPACE_ON_RESOURCE]: HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE,
18+
[HttpPhrase.INSUFFICIENT_STORAGE]: HttpStatus.INSUFFICIENT_STORAGE,
19+
[HttpPhrase.INTERNAL_SERVER_ERROR]: HttpStatus.INTERNAL_SERVER_ERROR,
20+
[HttpPhrase.LENGTH_REQUIRED]: HttpStatus.LENGTH_REQUIRED,
21+
[HttpPhrase.LOCKED]: HttpStatus.LOCKED,
22+
[HttpPhrase.METHOD_FAILURE]: HttpStatus.METHOD_FAILURE,
23+
[HttpPhrase.METHOD_NOT_ALLOWED]: HttpStatus.METHOD_NOT_ALLOWED,
24+
[HttpPhrase.MOVED_PERMANENTLY]: HttpStatus.MOVED_PERMANENTLY,
25+
[HttpPhrase.MOVED_TEMPORARILY]: HttpStatus.MOVED_TEMPORARILY,
26+
[HttpPhrase.MULTI_STATUS]: HttpStatus.MULTI_STATUS,
27+
[HttpPhrase.MULTIPLE_CHOICES]: HttpStatus.MULTIPLE_CHOICES,
28+
[HttpPhrase.NETWORK_AUTHENTICATION_REQUIRED]: HttpStatus.NETWORK_AUTHENTICATION_REQUIRED,
29+
[HttpPhrase.NO_CONTENT]: HttpStatus.NO_CONTENT,
30+
[HttpPhrase.NON_AUTHORITATIVE_INFORMATION]: HttpStatus.NON_AUTHORITATIVE_INFORMATION,
31+
[HttpPhrase.NOT_ACCEPTABLE]: HttpStatus.NOT_ACCEPTABLE,
32+
[HttpPhrase.NOT_FOUND]: HttpStatus.NOT_FOUND,
33+
[HttpPhrase.NOT_IMPLEMENTED]: HttpStatus.NOT_IMPLEMENTED,
34+
[HttpPhrase.NOT_MODIFIED]: HttpStatus.NOT_MODIFIED,
35+
[HttpPhrase.OK]: HttpStatus.OK,
36+
[HttpPhrase.PARTIAL_CONTENT]: HttpStatus.PARTIAL_CONTENT,
37+
[HttpPhrase.PAYMENT_REQUIRED]: HttpStatus.PAYMENT_REQUIRED,
38+
[HttpPhrase.PERMANENT_REDIRECT]: HttpStatus.PERMANENT_REDIRECT,
39+
[HttpPhrase.PRECONDITION_FAILED]: HttpStatus.PRECONDITION_FAILED,
40+
[HttpPhrase.PRECONDITION_REQUIRED]: HttpStatus.PRECONDITION_REQUIRED,
41+
[HttpPhrase.PROCESSING]: HttpStatus.PROCESSING,
42+
[HttpPhrase.EARLY_HINTS]: HttpStatus.EARLY_HINTS,
43+
[HttpPhrase.UPGRADE_REQUIRED]: HttpStatus.UPGRADE_REQUIRED,
44+
[HttpPhrase.PROXY_AUTHENTICATION_REQUIRED]: HttpStatus.PROXY_AUTHENTICATION_REQUIRED,
45+
[HttpPhrase.REQUEST_HEADER_FIELDS_TOO_LARGE]: HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE,
46+
[HttpPhrase.REQUEST_TIMEOUT]: HttpStatus.REQUEST_TIMEOUT,
47+
[HttpPhrase.REQUEST_TOO_LONG]: HttpStatus.REQUEST_TOO_LONG,
48+
[HttpPhrase.REQUEST_URI_TOO_LONG]: HttpStatus.REQUEST_URI_TOO_LONG,
49+
[HttpPhrase.REQUESTED_RANGE_NOT_SATISFIABLE]: HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE,
50+
[HttpPhrase.RESET_CONTENT]: HttpStatus.RESET_CONTENT,
51+
[HttpPhrase.SEE_OTHER]: HttpStatus.SEE_OTHER,
52+
[HttpPhrase.SERVICE_UNAVAILABLE]: HttpStatus.SERVICE_UNAVAILABLE,
53+
[HttpPhrase.SWITCHING_PROTOCOLS]: HttpStatus.SWITCHING_PROTOCOLS,
54+
[HttpPhrase.TEMPORARY_REDIRECT]: HttpStatus.TEMPORARY_REDIRECT,
55+
[HttpPhrase.TOO_MANY_REQUESTS]: HttpStatus.TOO_MANY_REQUESTS,
56+
[HttpPhrase.UNAUTHORIZED]: HttpStatus.UNAUTHORIZED,
57+
[HttpPhrase.UNAVAILABLE_FOR_LEGAL_REASONS]: HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS,
58+
[HttpPhrase.UNPROCESSABLE_ENTITY]: HttpStatus.UNPROCESSABLE_ENTITY,
59+
[HttpPhrase.UNSUPPORTED_MEDIA_TYPE]: HttpStatus.UNSUPPORTED_MEDIA_TYPE,
60+
[HttpPhrase.USE_PROXY]: HttpStatus.USE_PROXY,
61+
[HttpPhrase.MISDIRECTED_REQUEST]: HttpStatus.MISDIRECTED_REQUEST,
62+
};

src/constants/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './http-error-by-code.constant';
2+
export * from './http-phrase-by-status.constant';
3+
export * from './http-status-by-phrase.constant';
4+

0 commit comments

Comments
 (0)