volter 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -1
- package/biome.json +40 -0
- package/index.ts +182 -0
- package/package.json +19 -51
- package/session.ts +37 -0
- package/tsconfig.json +29 -0
- package/utils.ts +142 -0
- package/global.d.ts +0 -3
- package/volter.d.ts +0 -80
package/README.md
CHANGED
|
@@ -1 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# volter
|
|
2
|
+
|
|
3
|
+
To install dependencies:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun install
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
To run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun run index.ts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This project was created using `bun init` in bun v1.2.21. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
|
package/biome.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": false,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": false
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"ignoreUnknown": false
|
|
10
|
+
},
|
|
11
|
+
"formatter": {
|
|
12
|
+
"enabled": true,
|
|
13
|
+
"indentStyle": "tab"
|
|
14
|
+
},
|
|
15
|
+
"linter": {
|
|
16
|
+
"enabled": true,
|
|
17
|
+
"rules": {
|
|
18
|
+
"recommended": true
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"javascript": {
|
|
22
|
+
"formatter": {
|
|
23
|
+
"quoteStyle": "double",
|
|
24
|
+
"semicolons": "asNeeded",
|
|
25
|
+
"lineWidth": 160,
|
|
26
|
+
"arrowParentheses": "asNeeded"
|
|
27
|
+
},
|
|
28
|
+
"linter": {
|
|
29
|
+
"enabled": true
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"assist": {
|
|
33
|
+
"enabled": true,
|
|
34
|
+
"actions": {
|
|
35
|
+
"source": {
|
|
36
|
+
"organizeImports": "off"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
package/index.ts
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { RedisClient, SocketAddress } from "bun"
|
|
2
|
+
import { createID } from "./utils"
|
|
3
|
+
import type { BunSQLDatabase } from "drizzle-orm/bun-sql"
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
interface Request {
|
|
7
|
+
ip: SocketAddress
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export namespace Volter {
|
|
12
|
+
export namespace Cache {
|
|
13
|
+
export interface Options {
|
|
14
|
+
expiry?: number
|
|
15
|
+
limit?: number
|
|
16
|
+
/** FIFO */
|
|
17
|
+
max?: number
|
|
18
|
+
}
|
|
19
|
+
export interface KV {
|
|
20
|
+
value: string
|
|
21
|
+
getch: number
|
|
22
|
+
expiry?: NodeJS.Timeout
|
|
23
|
+
limit?: number
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class Cache {
|
|
27
|
+
constructor(options?: Cache.Options) {
|
|
28
|
+
this.expiry = options?.expiry
|
|
29
|
+
this.limit = options?.limit
|
|
30
|
+
this.max = options?.max
|
|
31
|
+
}
|
|
32
|
+
expiry?: number
|
|
33
|
+
limit?: number
|
|
34
|
+
max?: number
|
|
35
|
+
hasher = new Bun.CryptoHasher("sha256")
|
|
36
|
+
store: { [x: string]: Cache.KV } = {}
|
|
37
|
+
hash(password: string): string {
|
|
38
|
+
return this.hasher.update(password).digest("base64")
|
|
39
|
+
}
|
|
40
|
+
pop(): void {
|
|
41
|
+
const keys = Object.keys(this.store)
|
|
42
|
+
delete this.store[keys[keys.length - 1]]
|
|
43
|
+
}
|
|
44
|
+
has(key: string): boolean {
|
|
45
|
+
return this.store[key] !== undefined
|
|
46
|
+
}
|
|
47
|
+
get(key: string): string | null {
|
|
48
|
+
if (this.store[key] !== undefined) {
|
|
49
|
+
const record = this.store[key]
|
|
50
|
+
this.store[key].getch += 1
|
|
51
|
+
if (record.limit !== undefined) {
|
|
52
|
+
if (record.getch >= record.limit) {
|
|
53
|
+
delete this.store[key]
|
|
54
|
+
return null
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return record.value
|
|
58
|
+
}
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
set(key: string, value: string, expiry?: number, limit?: number): boolean {
|
|
62
|
+
if (this.max !== undefined && this.size() >= this.max) this.pop()
|
|
63
|
+
this.store[key] = {
|
|
64
|
+
value,
|
|
65
|
+
getch: 0,
|
|
66
|
+
limit: limit ?? this.limit,
|
|
67
|
+
expiry: expiry
|
|
68
|
+
? setTimeout(() => delete this.store[key], expiry * 1000)
|
|
69
|
+
: this.expiry
|
|
70
|
+
? setTimeout(() => delete this.store[key], this.expiry * 1000)
|
|
71
|
+
: undefined,
|
|
72
|
+
}
|
|
73
|
+
return true
|
|
74
|
+
}
|
|
75
|
+
del(key: string): boolean {
|
|
76
|
+
if (this.store[key]) {
|
|
77
|
+
if (this.store[key].expiry !== undefined) {
|
|
78
|
+
clearTimeout(this.store[key].expiry)
|
|
79
|
+
} else {
|
|
80
|
+
delete this.store[key]
|
|
81
|
+
}
|
|
82
|
+
return true
|
|
83
|
+
}
|
|
84
|
+
return false
|
|
85
|
+
}
|
|
86
|
+
clear(): void {
|
|
87
|
+
this.store = {}
|
|
88
|
+
}
|
|
89
|
+
size(): number {
|
|
90
|
+
return Object.keys(this.store).length
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface RatelimitOptions {
|
|
95
|
+
redis: RedisClient
|
|
96
|
+
limit: number
|
|
97
|
+
duration: number
|
|
98
|
+
max: number
|
|
99
|
+
}
|
|
100
|
+
export interface RatelimitResult {
|
|
101
|
+
success: boolean
|
|
102
|
+
remaining: number
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export class Ratelimit {
|
|
106
|
+
private redis: RedisClient
|
|
107
|
+
private limiter: number
|
|
108
|
+
private duration: number
|
|
109
|
+
private max: number
|
|
110
|
+
|
|
111
|
+
constructor(options: RatelimitOptions) {
|
|
112
|
+
this.redis = options.redis
|
|
113
|
+
this.limiter = options.limit
|
|
114
|
+
this.duration = options.duration
|
|
115
|
+
this.max = options.max
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async limit(identifier: string): Promise<RatelimitResult> {
|
|
119
|
+
const blocked = await this.redis.exists(`ratelimited:${identifier}`)
|
|
120
|
+
if (blocked) {
|
|
121
|
+
return {
|
|
122
|
+
success: false,
|
|
123
|
+
remaining: 0,
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const key = `ratelimit:${identifier}`
|
|
128
|
+
|
|
129
|
+
const count = await this.redis.incr(key)
|
|
130
|
+
if (count === 1) {
|
|
131
|
+
await this.redis.expire(key, this.duration)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (count >= this.max) {
|
|
135
|
+
await this.redis.set(`ratelimited:${identifier}`, "1")
|
|
136
|
+
await this.redis.expire(`ratelimited:${identifier}`, this.limiter)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
success: true,
|
|
141
|
+
remaining: this.max - count,
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface SessionsOptions {
|
|
147
|
+
redis: RedisClient
|
|
148
|
+
db: BunSQLDatabase
|
|
149
|
+
}
|
|
150
|
+
export class Sessions {
|
|
151
|
+
constructor(options: SessionsOptions) {
|
|
152
|
+
this.redis = options.redis
|
|
153
|
+
this.db = options.db
|
|
154
|
+
}
|
|
155
|
+
redis: RedisClient
|
|
156
|
+
db: BunSQLDatabase
|
|
157
|
+
async create(id: string) {
|
|
158
|
+
const session = createID()
|
|
159
|
+
const lookup = hash(session)
|
|
160
|
+
await this.redis.set(`session:${lookup}`, id, "EX", 2592000) // 30 days
|
|
161
|
+
return session
|
|
162
|
+
} // create
|
|
163
|
+
async validate(token: string) {
|
|
164
|
+
const lookup = hash(token)
|
|
165
|
+
// todo: login
|
|
166
|
+
return await this.redis.get(`session:${lookup}`)
|
|
167
|
+
} // read
|
|
168
|
+
async rotate(token: string) {
|
|
169
|
+
const isValid = await this.validate(token)
|
|
170
|
+
if (!isValid) return undefined
|
|
171
|
+
await this.revoke(token)
|
|
172
|
+
return await this.create(token)
|
|
173
|
+
}
|
|
174
|
+
async revoke(token: string) {
|
|
175
|
+
const lookup = hash(token)
|
|
176
|
+
await this.redis.del(`session:${lookup}`)
|
|
177
|
+
return true
|
|
178
|
+
} // delete
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export default Volter
|
package/package.json
CHANGED
|
@@ -1,53 +1,21 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"csstype": "^3.1.3",
|
|
22
|
-
"elysia": "latest",
|
|
23
|
-
"showdown": "^2.1.0",
|
|
24
|
-
"typescript": "latest",
|
|
25
|
-
"undici-types": "^5.26.5"
|
|
26
|
-
},
|
|
27
|
-
"exports": {
|
|
28
|
-
".": {
|
|
29
|
-
"import": "./src/volter.ts",
|
|
30
|
-
"require": "./src/volter.ts",
|
|
31
|
-
"types": "./volter.d.ts"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
"scripts": {
|
|
35
|
-
"udp": "bun src/udp.ts",
|
|
36
|
-
"ftp": "bun src/ftp.ts",
|
|
37
|
-
"test": "bun tests/index.test.ts",
|
|
38
|
-
"test:j": "bun tests/json.test.ts"
|
|
39
|
-
},
|
|
40
|
-
"repository": {
|
|
41
|
-
"type": "git",
|
|
42
|
-
"url": "invalid"
|
|
43
|
-
},
|
|
44
|
-
"keywords": [
|
|
45
|
-
"JavaScript",
|
|
46
|
-
"Framework"
|
|
47
|
-
],
|
|
48
|
-
"author": "Modlin Inc",
|
|
49
|
-
"license": "MIT",
|
|
50
|
-
"directories": {
|
|
51
|
-
"test": "tests"
|
|
52
|
-
}
|
|
2
|
+
"name": "volter",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Secure, lightweight, and user-friendly modern JavaScript toolchain optimized for performance and minimalism.",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"module": "index.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"devDependencies": {
|
|
9
|
+
"@types/bun": "latest"
|
|
10
|
+
},
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"typescript": "^5"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@paralleldrive/cuid2": "^2.2.2",
|
|
16
|
+
"@signalapp/libsignal-client": "^0.79.1",
|
|
17
|
+
"chalk": "^5.6.0",
|
|
18
|
+
"drizzle-orm": "^0.44.5",
|
|
19
|
+
"zod": "^4.1.7"
|
|
20
|
+
}
|
|
53
21
|
}
|
package/session.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { getRandomValues, randomBytes } from "node:crypto"
|
|
2
|
+
|
|
3
|
+
function pad(input: string) {
|
|
4
|
+
const result: string[] = []
|
|
5
|
+
for (let i = 0; i < input.length; i++) {
|
|
6
|
+
result.push(input[i] as string)
|
|
7
|
+
if ((i + 1) % 4 === 0 && i !== input.length - 1) {
|
|
8
|
+
result.push("-")
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return result.join("")
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function randomID() {
|
|
15
|
+
const session = randomBytes(16).toHex()
|
|
16
|
+
|
|
17
|
+
return pad(session)
|
|
18
|
+
}
|
|
19
|
+
export function randomPN(): string {
|
|
20
|
+
const MAX = 100_000_000
|
|
21
|
+
const LIMIT = Math.floor(0x1_0000_0000 / MAX) * MAX
|
|
22
|
+
const buf = new Uint32Array(1)
|
|
23
|
+
|
|
24
|
+
let v: number
|
|
25
|
+
while (true) {
|
|
26
|
+
getRandomValues(buf)
|
|
27
|
+
v = buf[0] as number
|
|
28
|
+
if (v < LIMIT) break
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const padded = (v % MAX).toString().padStart(8, "0")
|
|
32
|
+
return `${padded.slice(0, 4)} ${padded.slice(4)}`
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
do {
|
|
36
|
+
console.log(randomID())
|
|
37
|
+
} while (true)
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Environment setup & latest features
|
|
4
|
+
"lib": ["ESNext"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "Preserve",
|
|
7
|
+
"moduleDetection": "force",
|
|
8
|
+
"jsx": "react-jsx",
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
|
|
11
|
+
// Bundler mode
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
|
|
17
|
+
// Best practices
|
|
18
|
+
"strict": true,
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noUncheckedIndexedAccess": true,
|
|
22
|
+
"noImplicitOverride": true,
|
|
23
|
+
|
|
24
|
+
// Some stricter flags (disabled by default)
|
|
25
|
+
"noUnusedLocals": false,
|
|
26
|
+
"noUnusedParameters": false,
|
|
27
|
+
"noPropertyAccessFromIndexSignature": false
|
|
28
|
+
}
|
|
29
|
+
}
|
package/utils.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { privateDecrypt, publicEncrypt, randomInt } from "node:crypto"
|
|
2
|
+
import os from "node:os"
|
|
3
|
+
import chalk from "chalk"
|
|
4
|
+
import cuid2 from "@paralleldrive/cuid2"
|
|
5
|
+
|
|
6
|
+
export const pin = z.string().min(6).max(6).regex(/\d{6}/)
|
|
7
|
+
|
|
8
|
+
export function createPIN(): string {
|
|
9
|
+
return randomInt(0, 1000000).toString().padStart(6, "0")
|
|
10
|
+
}
|
|
11
|
+
export const createID = cuid2.init({ length: 32 })
|
|
12
|
+
|
|
13
|
+
const hasher = new Bun.CryptoHasher("sha256")
|
|
14
|
+
export function hash(password: string): string {
|
|
15
|
+
return hasher.update(password).digest("hex")
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function timestamp(): string
|
|
19
|
+
export function timestamp(date: Date): string
|
|
20
|
+
export function timestamp(date?: Date): string {
|
|
21
|
+
if (!date) date = new Date()
|
|
22
|
+
return date.toISOString().slice(0, 19).replace("T", " ")
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function log(...message: unknown[]) {
|
|
26
|
+
console.log(chalk.gray(timestamp()), ...message)
|
|
27
|
+
}
|
|
28
|
+
export function error(...message: unknown[]) {
|
|
29
|
+
console.error(chalk.red(timestamp()), ...message)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function input(prompt: string = chalk.black("> ")) {
|
|
33
|
+
await Bun.stdout.write(prompt)
|
|
34
|
+
for await (const line of console) {
|
|
35
|
+
return line
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type HTTPLog = {
|
|
40
|
+
timestamp: string
|
|
41
|
+
method: string
|
|
42
|
+
url: string
|
|
43
|
+
IP: string
|
|
44
|
+
request_id?: string
|
|
45
|
+
service?: string
|
|
46
|
+
level: "info" | "warn" | "error"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Returns a structured JSON log of the request
|
|
51
|
+
*/
|
|
52
|
+
export function formatRequest(req: Request): HTTPLog {
|
|
53
|
+
return {
|
|
54
|
+
timestamp: new Date().toISOString(),
|
|
55
|
+
method: req.method,
|
|
56
|
+
url: new URL(req.url).pathname,
|
|
57
|
+
IP: req.headers.get("x-forwarded-for") ?? "unknown",
|
|
58
|
+
request_id: req.headers.get("x-request-id") ?? "none",
|
|
59
|
+
service: "app",
|
|
60
|
+
level: "info",
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns a one-line pretty string with colors using chalk
|
|
66
|
+
*/
|
|
67
|
+
export function prettifyRequest(req: Request): string {
|
|
68
|
+
const url = chalk.white(new URL(req.url).pathname)
|
|
69
|
+
return `${chalk.gray(timestamp())} ${chalk.red(req.ip.address)} ${chalk.green(req.method)} ${url}`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface Adapter {
|
|
73
|
+
adapter: string
|
|
74
|
+
networks: Bun.SocketAddress[]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function listAdapters(): Adapter[] {
|
|
78
|
+
const interfaces = os.networkInterfaces()
|
|
79
|
+
const results: Adapter[] = []
|
|
80
|
+
|
|
81
|
+
for (const [name, infos] of Object.entries(interfaces)) {
|
|
82
|
+
if (!infos) continue
|
|
83
|
+
|
|
84
|
+
const networks: Bun.SocketAddress[] = []
|
|
85
|
+
|
|
86
|
+
for (const info of infos) {
|
|
87
|
+
if (!info.address) continue
|
|
88
|
+
|
|
89
|
+
networks.push({
|
|
90
|
+
address: info.address,
|
|
91
|
+
family: info.family,
|
|
92
|
+
port: 0,
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
results.push({
|
|
97
|
+
adapter: name,
|
|
98
|
+
networks,
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return results
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
import { generateKeyPairSync } from "node:crypto"
|
|
106
|
+
import z from "zod"
|
|
107
|
+
|
|
108
|
+
type KeyPair = {
|
|
109
|
+
public: string
|
|
110
|
+
private: string
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export async function key(): Promise<KeyPair> {
|
|
114
|
+
const { publicKey, privateKey } = generateKeyPairSync("rsa", {
|
|
115
|
+
modulusLength: 2048,
|
|
116
|
+
publicKeyEncoding: {
|
|
117
|
+
type: "spki",
|
|
118
|
+
format: "pem",
|
|
119
|
+
},
|
|
120
|
+
privateKeyEncoding: {
|
|
121
|
+
type: "pkcs8",
|
|
122
|
+
format: "pem",
|
|
123
|
+
},
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
public: publicKey,
|
|
128
|
+
private: privateKey,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function encrypt(key: string, data: string) {
|
|
133
|
+
const buffer = Buffer.from(data, "utf-8")
|
|
134
|
+
const encrypted = publicEncrypt(key, buffer)
|
|
135
|
+
return encrypted.toString("hex")
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function decrypt(key: string, encrypted: string) {
|
|
139
|
+
const buffer = Buffer.from(encrypted, "hex")
|
|
140
|
+
const decrypted = privateDecrypt(key, buffer)
|
|
141
|
+
return decrypted.toString("utf-8")
|
|
142
|
+
}
|
package/global.d.ts
DELETED
package/volter.d.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
declare module 'volter' {
|
|
2
|
-
import type { Elysia } from 'elysia'
|
|
3
|
-
import type { ConverterOptions } from 'showdown'
|
|
4
|
-
|
|
5
|
-
//! Properties //!
|
|
6
|
-
export const HTTPMethods: [
|
|
7
|
-
'ACL',
|
|
8
|
-
'BIND',
|
|
9
|
-
'CHECKOUT',
|
|
10
|
-
'CONNECT',
|
|
11
|
-
'COPY',
|
|
12
|
-
'DELETE',
|
|
13
|
-
'GET',
|
|
14
|
-
'HEAD',
|
|
15
|
-
'LINK',
|
|
16
|
-
'LOCK',
|
|
17
|
-
'M-SEARCH',
|
|
18
|
-
'MERGE',
|
|
19
|
-
'MKACTIVITY',
|
|
20
|
-
'MKCALENDAR',
|
|
21
|
-
'MKCOL',
|
|
22
|
-
'MOVE',
|
|
23
|
-
'NOTIFY',
|
|
24
|
-
'OPTIONS',
|
|
25
|
-
'PATCH',
|
|
26
|
-
'POST',
|
|
27
|
-
'PROPFIND',
|
|
28
|
-
'PROPPATCH',
|
|
29
|
-
'PURGE',
|
|
30
|
-
'PUT',
|
|
31
|
-
'REBIND',
|
|
32
|
-
'REPORT',
|
|
33
|
-
'SEARCH',
|
|
34
|
-
'SOURCE',
|
|
35
|
-
'SUBSCRIBE',
|
|
36
|
-
'TRACE',
|
|
37
|
-
'UNBIND',
|
|
38
|
-
'UNLINK',
|
|
39
|
-
'UNLOCK',
|
|
40
|
-
'UNSUBSCRIBE',
|
|
41
|
-
'ALL'
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
//! Tools //!
|
|
45
|
-
export function readFilesSync(dir: string): Generator<string>
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Markdown to HTML converter using [Showdown](https://github.com/showdownjs/showdown).
|
|
49
|
-
*
|
|
50
|
-
* [MDN Guide](https://developer.mozilla.org/en-US/docs/MDN/Writing_guidelines/Howto/Markdown_in_MDN)
|
|
51
|
-
*
|
|
52
|
-
* @param markdown as a String
|
|
53
|
-
* @param options to customize the converter
|
|
54
|
-
*/
|
|
55
|
-
export function markdown(markdown: string, options?: ConverterOptions): string
|
|
56
|
-
|
|
57
|
-
//! Interfaces & Types //!
|
|
58
|
-
export interface StaticOptions {
|
|
59
|
-
path?: string
|
|
60
|
-
prefix?: string
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export type jsExt = '.js' | '.jsx' | '.ts' | '.tsx' | '.mjs' | '.cjs'
|
|
64
|
-
|
|
65
|
-
//! Plugins //!
|
|
66
|
-
/**
|
|
67
|
-
* ElysiaJS plugin for File System Routing
|
|
68
|
-
* @param options The options to use when creating the router
|
|
69
|
-
* @param options.dir The root directory containing the files to route
|
|
70
|
-
*/
|
|
71
|
-
export function FileSystemRouter<D extends string>(options: {
|
|
72
|
-
dir: D,
|
|
73
|
-
fileExtensions?: jsExt[] | string[]
|
|
74
|
-
}): Elysia
|
|
75
|
-
|
|
76
|
-
export function staticFiles(options?: StaticOptions): Elysia
|
|
77
|
-
|
|
78
|
-
//! 3rd Party Modules //!
|
|
79
|
-
export * from '@elysiajs/cors'
|
|
80
|
-
}
|