From cd32689b475f6e1f1937685e2ad90fafffc82f70 Mon Sep 17 00:00:00 2001
From: "Indrawan I."
Date: Thu, 14 May 2026 04:57:54 +0700
Subject: [PATCH] feat(core): hard remake with bun and elysia (#19)
* static files changes
* remake modifiers
* test case
* some docs changes
* deps and rule changes
* edit proper interfaces
* remake getServer
* @elysiajs/swagger
* remake tsconfig
* ci changes use bun
* docs changes
* feat(core): hard remake with bun and elysia
* chore(release): 8.2.0-alpha
* auto release
* ci
* update global
* chore(release): 8.2.1-alpha
* ci
---
.github/workflows/build.yml | 16 +-
.github/workflows/docker.yml | 2 +-
.github/workflows/eporner.yml | 23 +-
.github/workflows/playground.yml | 37 --
.github/workflows/pornhub.yml | 23 +-
.github/workflows/redtube.yml | 23 +-
.github/workflows/release.yml | 56 +++
.github/workflows/status.yml | 17 +-
.github/workflows/txxx.yml | 23 +-
.github/workflows/xhamster.yml | 23 +-
.github/workflows/xnxx.yml | 23 +-
.github/workflows/xvideos.yml | 23 +-
.github/workflows/youporn.yml | 23 +-
.gitignore | 3 +-
CLOSING_REMARKS.md | 2 +-
Dockerfile | 27 +-
README.md | 75 ++--
bun.lock | 365 ++++++++++++++++++
eslint.config.js | 11 +
fly.toml | 39 --
package.json | 80 ++--
resources/project/images/bnnuy.png | Bin 109198 -> 0 bytes
resources/project/images/nun.png | Bin 0 -> 34730 bytes
src/LustPress.ts | 319 +++++++--------
src/controller/eporner/epornerGet.ts | 52 +--
src/controller/eporner/epornerGetRelated.ts | 23 +-
src/controller/eporner/epornerRandom.ts | 104 ++---
src/controller/eporner/epornerSearch.ts | 101 ++---
src/controller/pornhub/pornhubGet.ts | 50 +--
src/controller/pornhub/pornhubGetRelated.ts | 50 +--
src/controller/pornhub/pornhubRandom.ts | 44 +--
src/controller/pornhub/pornhubSearch.ts | 95 ++---
src/controller/redtube/redtubeGet.ts | 51 +--
src/controller/redtube/redtubeGetRelated.ts | 68 +---
src/controller/redtube/redtubeRandom.ts | 56 +--
src/controller/redtube/redtubeSearch.ts | 79 +---
src/controller/txxx/txxxGet.ts | 39 +-
src/controller/txxx/txxxGetRelated.ts | 43 +--
src/controller/txxx/txxxRandom.ts | 33 +-
src/controller/txxx/txxxSearch.ts | 49 +--
src/controller/xhamster/xhamsterGet.ts | 50 +--
src/controller/xhamster/xhamsterGetRelated.ts | 50 +--
src/controller/xhamster/xhamsterRandom.ts | 49 +--
src/controller/xhamster/xhamsterSearch.ts | 79 +---
src/controller/xnxx/xnxxGet.ts | 50 +--
src/controller/xnxx/xnxxGetRelated.ts | 50 +--
src/controller/xnxx/xnxxRandom.ts | 58 +--
src/controller/xnxx/xnxxSearch.ts | 78 +---
src/controller/xvideos/xvideosGet.ts | 50 +--
src/controller/xvideos/xvideosGetRelated.ts | 50 +--
src/controller/xvideos/xvideosRandom.ts | 53 +--
src/controller/xvideos/xvideosSearch.ts | 79 +---
src/controller/youporn/youpornGet.ts | 50 +--
src/controller/youporn/youpornGetRelated.ts | 50 +--
src/controller/youporn/youpornRandom.ts | 51 +--
src/controller/youporn/youpornSearch.ts | 79 +---
src/index.ts | 108 +++---
src/interfaces.ts | 196 ++++++++--
src/router/endpoint.ts | 300 +++++++++-----
src/scraper/eporner/epornerGetController.ts | 4 +-
.../eporner/epornerGetRelatedController.ts | 4 +-
src/scraper/pornhub/pornhubGetController.ts | 4 +-
.../pornhub/pornhubSearchController.ts | 113 +++---
.../redtube/redtubeSearchController.ts | 135 +++----
src/scraper/xhamster/xhamsterGetController.ts | 19 +-
.../xhamster/xhamsterSearchController.ts | 113 +++---
src/scraper/xnxx/xnxxGetRelatedController.ts | 105 +++--
.../xvideos/xvideosGetRelatedController.ts | 102 +++--
.../xvideos/xvideosSearchController.ts | 129 +++----
.../youporn/youpornSearchController.ts | 4 +-
src/utils/limit-options.ts | 17 -
src/utils/logger.ts | 8 -
src/utils/modifier.ts | 4 +-
src/utils/ph-solver.ts | 83 ++++
test/lustpress.test.ts | 29 +-
tsconfig.json | 33 +-
76 files changed, 2025 insertions(+), 2581 deletions(-)
delete mode 100644 .github/workflows/playground.yml
create mode 100644 .github/workflows/release.yml
create mode 100644 bun.lock
delete mode 100644 fly.toml
delete mode 100644 resources/project/images/bnnuy.png
create mode 100644 resources/project/images/nun.png
delete mode 100644 src/utils/limit-options.ts
delete mode 100644 src/utils/logger.ts
create mode 100644 src/utils/ph-solver.ts
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 758651d..3daeb29 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,24 +10,24 @@ permissions:
contents: read
jobs:
- test:
+ build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- name: Check lint
- run: npm run lint
+ run: bun run lint
- name: Build
- run: npm run build
\ No newline at end of file
+ run: bun run build
\ No newline at end of file
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 4ec9583..39539f8 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set image name
run: echo "IMAGE_NAME=ghcr.io/$GITHUB_REPOSITORY" >> $GITHUB_ENV
diff --git a/.github/workflows/eporner.yml b/.github/workflows/eporner.yml
index d6e7370..f7ebf39 100644
--- a/.github/workflows/eporner.yml
+++ b/.github/workflows/eporner.yml
@@ -14,23 +14,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- - name: Install Playwright browsers
- run: npx playwright install --with-deps chromium
-
- - name: Build
- run: npm run build
-
- - name: Eporner test
- run: npm run test:eporner
\ No newline at end of file
+ - name: Run test
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test:eporner
\ No newline at end of file
diff --git a/.github/workflows/playground.yml b/.github/workflows/playground.yml
deleted file mode 100644
index fb24b69..0000000
--- a/.github/workflows/playground.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: Playground
-
-on:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
-
-permissions:
- contents: write
-
-jobs:
- build-and-deploy:
- concurrency: ci-${{ github.ref }}
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
- with:
- persist-credentials: false
-
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
- with:
- node-version: 24
-
- - name: Install dependencies
- run: npm install
-
- - name: Generating docs
- run: npm run build:apidoc
-
- - name: Deploy
- uses: JamesIves/github-pages-deploy-action@9d877eea73427180ae43cf98e8914934fe157a1a
- with:
- branch: gh-pages
- folder: docs
\ No newline at end of file
diff --git a/.github/workflows/pornhub.yml b/.github/workflows/pornhub.yml
index c5a10f4..30eebc8 100644
--- a/.github/workflows/pornhub.yml
+++ b/.github/workflows/pornhub.yml
@@ -14,23 +14,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- - name: Install Playwright browsers
- run: npx playwright install --with-deps chromium
-
- - name: Build
- run: npm run build
-
- - name: Pornhub test
- run: npm run test:pornhub
\ No newline at end of file
+ - name: Run test
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test:pornhub
\ No newline at end of file
diff --git a/.github/workflows/redtube.yml b/.github/workflows/redtube.yml
index 6d092c4..ee46d4f 100644
--- a/.github/workflows/redtube.yml
+++ b/.github/workflows/redtube.yml
@@ -14,23 +14,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- - name: Install Playwright browsers
- run: npx playwright install --with-deps chromium
-
- - name: Build
- run: npm run build
-
- - name: Redtube test
- run: npm run test:redtube
\ No newline at end of file
+ - name: Run test
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test:redtube
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..fb003ed
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,56 @@
+name: Release
+
+on:
+ push:
+ branches: [master]
+
+permissions:
+ contents: write
+ pull-requests: read
+
+concurrency:
+ group: release-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
+ with:
+ persist-credentials: false
+ fetch-depth: 0
+
+ - name: Set release metadata
+ id: meta
+ shell: bash
+ run: |
+ VERSION="$(jq -r .version package.json)"
+ TAG="v${VERSION}"
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
+ echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
+
+ - name: Check if tag already exists
+ id: tag_check
+ shell: bash
+ run: |
+ if git ls-remote --tags origin "refs/tags/${{ steps.meta.outputs.tag }}" | grep -q "${{ steps.meta.outputs.tag }}"; then
+ echo "exists=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "exists=false" >> "$GITHUB_OUTPUT"
+ fi
+
+ - name: Create GitHub release
+ if: steps.tag_check.outputs.exists == 'false'
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: ${{ steps.meta.outputs.tag }}
+ name: ${{ steps.meta.outputs.tag }}
+ target_commitish: master
+ generate_release_notes: true
+
+ - name: Skip release when tag exists
+ if: steps.tag_check.outputs.exists == 'true'
+ run: echo "Tag ${{ steps.meta.outputs.tag }} already exists. Skipping release creation."
\ No newline at end of file
diff --git a/.github/workflows/status.yml b/.github/workflows/status.yml
index 7451d86..e90bd82 100644
--- a/.github/workflows/status.yml
+++ b/.github/workflows/status.yml
@@ -14,20 +14,23 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- name: Build
- run: npm run build
+ run: bun run build
- name: Check status code
- run: npm run test
\ No newline at end of file
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test
\ No newline at end of file
diff --git a/.github/workflows/txxx.yml b/.github/workflows/txxx.yml
index d628a09..ec61ae1 100644
--- a/.github/workflows/txxx.yml
+++ b/.github/workflows/txxx.yml
@@ -14,23 +14,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- - name: Install Playwright browsers
- run: npx playwright install --with-deps chromium
-
- - name: Build
- run: npm run build
-
- - name: Txxx test
- run: npm run test:txxx
\ No newline at end of file
+ - name: Run test
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test:txxx
\ No newline at end of file
diff --git a/.github/workflows/xhamster.yml b/.github/workflows/xhamster.yml
index 053c580..5226e8a 100644
--- a/.github/workflows/xhamster.yml
+++ b/.github/workflows/xhamster.yml
@@ -14,23 +14,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- - name: Install Playwright browsers
- run: npx playwright install --with-deps chromium
-
- - name: Build
- run: npm run build
-
- - name: Xhamster test
- run: npm run test:xhamster
\ No newline at end of file
+ - name: Run test
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test:xhamster
\ No newline at end of file
diff --git a/.github/workflows/xnxx.yml b/.github/workflows/xnxx.yml
index 55d56a9..2b42f2b 100644
--- a/.github/workflows/xnxx.yml
+++ b/.github/workflows/xnxx.yml
@@ -14,23 +14,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- - name: Install Playwright browsers
- run: npx playwright install --with-deps chromium
-
- - name: Build
- run: npm run build
-
- - name: Xnxx test
- run: npm run test:xnxx
\ No newline at end of file
+ - name: Run test
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test:xnxx
\ No newline at end of file
diff --git a/.github/workflows/xvideos.yml b/.github/workflows/xvideos.yml
index 5a675b7..3e77f14 100644
--- a/.github/workflows/xvideos.yml
+++ b/.github/workflows/xvideos.yml
@@ -14,23 +14,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- - name: Install Playwright browsers
- run: npx playwright install --with-deps chromium
-
- - name: Build
- run: npm run build
-
- - name: Xvideos test
- run: npm run test:xvideos
\ No newline at end of file
+ - name: Run test
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test:xvideos
\ No newline at end of file
diff --git a/.github/workflows/youporn.yml b/.github/workflows/youporn.yml
index 47391fb..4c4f3fb 100644
--- a/.github/workflows/youporn.yml
+++ b/.github/workflows/youporn.yml
@@ -14,23 +14,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- - name: Setup Node
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
+ - name: Setup Bun
+ uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
- node-version: 24
+ bun-version: latest
- name: Install dependencies
- run: npm install
+ run: bun install
- - name: Install Playwright browsers
- run: npx playwright install --with-deps chromium
-
- - name: Build
- run: npm run build
-
- - name: Youporn test
- run: npm run test:youporn
\ No newline at end of file
+ - name: Run test
+ run: |
+ bun run start:dev &
+ sleep 3
+ bun run test:youporn
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 9dba34d..dc96a2b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,5 @@ p.ts
.env
.idea
CHANGELOG.md
-theme.zip
\ No newline at end of file
+theme.zip
+AGENTS.md
\ No newline at end of file
diff --git a/CLOSING_REMARKS.md b/CLOSING_REMARKS.md
index 6705f39..52b2d17 100644
--- a/CLOSING_REMARKS.md
+++ b/CLOSING_REMARKS.md
@@ -4,7 +4,7 @@ I hope you have found this project useful. All the major credit really goes to t
allows this services to operate.
Core dependencies:
-- [express](https://github.com/expressjs/express)
+- [elysia](https://elysiajs.com/)
- [cheerio](https://cheerio.js.org/)
- [keyv](https://github.com/jaredwray/keyv)
diff --git a/Dockerfile b/Dockerfile
index b565095..6a1d7fc 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,17 +1,26 @@
-FROM node:22
-
+FROM oven/bun:1.3.13-alpine AS base
WORKDIR /srv/app
-COPY package*.json ./
-RUN npm install
-
-# install browser + system deps
-RUN npx playwright install --with-deps chromium
+# 1. Install production dependencies only
+FROM base AS deps
+COPY package.json bun.lock ./
+RUN bun install --production
+# 2. Builder stage to compile TypeScript
+FROM base AS builder
+COPY package.json bun.lock ./
+RUN bun install
COPY . .
+RUN bun run build
-RUN npm run build
+# 3. Final release stage
+FROM base AS release
+COPY --from=deps /srv/app/node_modules ./node_modules
+COPY --from=builder /srv/app/build ./build
+COPY package.json ./
+# Run as non-root user
+USER bun
EXPOSE 3000
-CMD ["node", "build/src/index.js"]
\ No newline at end of file
+CMD ["bun", "run", "start"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 62d6317..4a42993 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
-Lustpress stand for Lust and **Express**, rebuild from [Jandapress](https://github.com/sinkaroid/jandapress) with completely different approach.
+Lustpress was originally named Lust and Express (legacy name) and now runs on **Bun** + **Elysia** a high-performance remake from the ground up using Bun.
The motivation of this project is to bring you an actionable data related to pornhub and other r18 sites with gather, similar design pattern, endpoint bindings, and consistent structure in mind.
Playground •
@@ -17,7 +17,7 @@ The motivation of this project is to bring you an actionable data related to por
---
-
+
- [Lustpress](#)
- [The problem](#the-problem)
@@ -32,11 +32,10 @@ The motivation of this project is to bring you an actionable data related to por
- [Playground](https://sinkaroid.github.io/lustpress)
- [Routing](#playground)
- [Status response](#status-response)
+ - [Pornhub JS Challenge Solver](#pornhub-js-challenge-solver)
- [CLosing remarks](https://github.com/sinkaroid/lustpress/blob/master/CLOSING_REMARKS.md)
- [Alternative links](https://github.com/sinkaroid/lustpress/blob/master/CLOSING_REMARKS.md#alternative-links)
- [Pronunciation](#Pronunciation)
- - [Client libraries](#client-libraries)
- - [Acknowledgements](#acknowledgements)
- [Legal](#legal)
- [Discontinued playground](#frequently-asked-questions)
- [again, discontinued playground](#frequently-asked-questions)
@@ -81,7 +80,7 @@ Some tests may fail in CI environments because certain websites restrict or bloc
## Prerequisites
- | NOTE: NodeJS 22.x or higher |
+ NOTE: Bun 1.3.13 or higher |
To handle several requests from each website, You will also need [Redis](https://redis.io/) for persistent caching, free tier is available on [Redis Labs](https://redislabs.com/), You can also choose another adapters as we using [keyv](https://github.com/jaredwray/keyv) Key-value storage with support for multiple backends. When you choosing your own adapter, all data must be stored with `` type.
@@ -90,9 +89,6 @@ To handle several requests from each website, You will also need [Redis](https:/
Rename `.env.schema` to `.env` and fill the value with your own
```bash
-# railway, fly.dev, heroku, vercel or any free service
-RAILWAY = sinkaroid
-
# default port
PORT = 3000
@@ -103,7 +99,7 @@ REDIS_URL = redis://default:somenicepassword@redis-666.c10.us-east-6-6.ec666.clo
EXPIRE_CACHE = 1
# you must identify your origin, if not set it will use default
-USER_AGENT = "lustpress/8.0.1 Node.js/22.22.0"
+USER_AGENT = "lustpress/8.2.0-alpha Bun/1.3.13"
```
### Docker
@@ -118,7 +114,7 @@ docker run -d \
-p 3028:3000 \
-e REDIS_URL='redis://default:somenicepassword@redis-666.c10.us-east-6-6.ec666.cloud.redislabs.com:1337' \
-e EXPIRE_CACHE='1' \
- -e USER_AGENT='lustpress/8.0.1 Node.js/22.22.0' \
+ -e USER_AGENT='lustpress/8.2.0-alpha Bun/1.3.13' \
ghcr.io/sinkaroid/lustpress:latest
```
@@ -127,43 +123,42 @@ docker run -d \
git clone https://github.com/sinkaroid/lustpress.git
- Install dependencies
- - `npm install / yarn install`
+ - `bun install`
- Lustpress production
- - `npm run start:prod`
+ - `bun run start:prod`
- Lustpress testing and hot reload
- - `npm run start:dev`
+ - `bun run start:dev`
-## Tests
+## Running tests
Run the following commands to execute tests for each supported source:
```bash
# Check whether all supported sites are available for scraping
-npm run test
+bun run test
# Check whether ph and (maybe the others do..) do Solving challenge in their website
-npm run test:mock
+bun run test:mock
# Run tests for individual sources
-npm run test:pornhub
-npm run test:xnxx
-npm run test:redtube
-npm run test:xvideos
-npm run test:xhamster
-npm run test:youporn
-npm run test:eporner
-npm run test:txxx
+bun run test:pornhub
+bun run test:xnxx
+bun run test:redtube
+bun run test:xvideos
+bun run test:xhamster
+bun run test:youporn
+bun run test:eporner
+bun run test:txxx
```
-
### Start the production server
-`npm run start:prod`
+`bun run start:prod`
### Running development server
-`npm run start:dev`
+`bun run start:dev`
### Generating playground like swagger from apidoc definition
-`npm run build:apidoc`
+`bun run build:apidoc`
> To running other tests, you can see object scripts in file `package.json` or modify the `lustpress.test.ts` according your needs
@@ -298,6 +293,21 @@ https://sinkaroid.github.io/lustpress/#api-txxx
HTTP/1.1 400 Bad Request
HTTP/1.1 500 Fail to get data
+## Pornhub JS Challenge Solver
+Pornhub serves a JavaScript challenge page to detect automated requests. Instead of relying on a headless browser (Playwright/Puppeteer), Lustpress solves this natively with zero external dependencies.
+
+**How it works:**
+- Fetch the index page and capture initial session cookies
+- Detect the `leastFactor` math challenge in the response HTML
+- Parse obfuscated variables (`p`, `s`) and conditional bitwise operations
+- Compute the correct `KEY` cookie value
+- Verify the solved cookie against the index
+- Cache and reuse cookies for subsequent requests, auto-refresh on expiry
+
+This approach runs in **< 1ms** compared to 5-10s with a headless browser, uses virtually no memory, and is fully **Docker-friendly** — no Chromium installation required.
+
+The solver logic lives in [`src/utils/ph-solver.ts`](src/utils/ph-solver.ts). If Pornhub changes its obfuscation pattern, update the regex patterns in that file.
+
## Frequently asked questions
**Q: The website response is slow**
> That's unfortunate, this repository was opensource already, You can host and deploy Lustpress with your own instance. Any fixes and improvements will updating to this repo.
@@ -311,14 +321,7 @@ To continue using Lustpress, please deploy and run your own self-hosted instance
`en_US` • **/lʌstˈprɛs/** — "lust" stand for this project and "press" for express.
-## Client libraries
-Seamlessly integrate with the languages you love, simplified the usage, and intelisense definitions on your IDEs
-
-- TBD
-- Or [create your own](https://github.com/sinkaroid/lustpress/edit/master/README.md)
-
-
## Legal
This tool can be freely copied, modified, altered, distributed without any attribution whatsoever. However, if you feel
like this tool deserves an attribution, mention it. It won't hurt anybody.
-> Licence: WTF.
+> Licence: WTF.
\ No newline at end of file
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 0000000..78ea4a1
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,365 @@
+{
+ "lockfileVersion": 1,
+ "configVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "lustpress",
+ "dependencies": {
+ "@elysiajs/cors": "^1.2.0",
+ "@elysiajs/swagger": "^1.2.2",
+ "@keyv/redis": "^5.1.6",
+ "cheerio": "^1.2.0",
+ "elysia": "^1.2.24",
+ "keyv": "^5.6.0",
+ },
+ "devDependencies": {
+ "@types/bun": "^1.3.13",
+ "@typescript-eslint/eslint-plugin": "^8.24.1",
+ "@typescript-eslint/parser": "^8.24.1",
+ "eslint": "^9.20.1",
+ "typescript": "^6.0.3",
+ },
+ },
+ },
+ "packages": {
+ "@borewit/text-codec": ["@borewit/text-codec@0.2.2", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="],
+
+ "@elysiajs/cors": ["@elysiajs/cors@1.4.2", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-FTCcbH35brTLigF1W7BYySRZomgI/dBEMK9BgK9RP9Nez7zmpGh4koL/Yr1BFv8nYz7CfhRvcM8d/c+XnwMaVQ=="],
+
+ "@elysiajs/swagger": ["@elysiajs/swagger@1.3.1", "", { "dependencies": { "@scalar/themes": "^0.9.52", "@scalar/types": "^0.0.12", "openapi-types": "^12.1.3", "pathe": "^1.1.2" }, "peerDependencies": { "elysia": ">= 1.3.0" } }, "sha512-LcbLHa0zE6FJKWPWKsIC/f+62wbDv3aXydqcNPVPyqNcaUgwvCajIi+5kHEU6GO3oXUCpzKaMsb3gsjt8sLzFQ=="],
+
+ "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
+
+ "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
+
+ "@eslint/config-array": ["@eslint/config-array@0.21.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.5" } }, "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw=="],
+
+ "@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
+
+ "@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
+
+ "@eslint/eslintrc": ["@eslint/eslintrc@3.3.5", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" } }, "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg=="],
+
+ "@eslint/js": ["@eslint/js@9.39.4", "", {}, "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw=="],
+
+ "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
+
+ "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
+
+ "@humanfs/core": ["@humanfs/core@0.19.2", "", { "dependencies": { "@humanfs/types": "^0.15.0" } }, "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA=="],
+
+ "@humanfs/node": ["@humanfs/node@0.16.8", "", { "dependencies": { "@humanfs/core": "^0.19.2", "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ=="],
+
+ "@humanfs/types": ["@humanfs/types@0.15.0", "", {}, "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q=="],
+
+ "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
+
+ "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
+
+ "@keyv/redis": ["@keyv/redis@5.1.6", "", { "dependencies": { "@redis/client": "^5.10.0", "cluster-key-slot": "^1.1.2", "hookified": "^1.13.0" }, "peerDependencies": { "keyv": "^5.6.0" } }, "sha512-eKvW6pspvVaU5dxigaIDZr635/Uw6urTXL3gNbY9WTR8d3QigZQT+r8gxYSEOsw4+1cCBsC4s7T2ptR0WC9LfQ=="],
+
+ "@keyv/serialize": ["@keyv/serialize@1.1.1", "", {}, "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA=="],
+
+ "@redis/client": ["@redis/client@5.12.1", "", { "dependencies": { "cluster-key-slot": "1.1.2" }, "peerDependencies": { "@node-rs/xxhash": "^1.1.0", "@opentelemetry/api": ">=1 <2" }, "optionalPeers": ["@node-rs/xxhash", "@opentelemetry/api"] }, "sha512-7aPGWeqA3uFm43o19umzdl16CEjK/JQGtSXVPevplTaOU3VJA/rseBC1QvYUz9lLDIMBimc4SW/zrW4S89BaCA=="],
+
+ "@scalar/openapi-types": ["@scalar/openapi-types@0.1.1", "", {}, "sha512-NMy3QNk6ytcCoPUGJH0t4NNr36OWXgZhA3ormr3TvhX1NDgoF95wFyodGVH8xiHeUyn2/FxtETm8UBLbB5xEmg=="],
+
+ "@scalar/themes": ["@scalar/themes@0.9.86", "", { "dependencies": { "@scalar/types": "0.1.7" } }, "sha512-QUHo9g5oSWi+0Lm1vJY9TaMZRau8LHg+vte7q5BVTBnu6NuQfigCaN+ouQ73FqIVd96TwMO6Db+dilK1B+9row=="],
+
+ "@scalar/types": ["@scalar/types@0.0.12", "", { "dependencies": { "@scalar/openapi-types": "0.1.1", "@unhead/schema": "^1.9.5" } }, "sha512-XYZ36lSEx87i4gDqopQlGCOkdIITHHEvgkuJFrXFATQs9zHARop0PN0g4RZYWj+ZpCUclOcaOjbCt8JGe22mnQ=="],
+
+ "@sinclair/typebox": ["@sinclair/typebox@0.34.49", "", {}, "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A=="],
+
+ "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
+
+ "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
+
+ "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
+
+ "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
+
+ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
+
+ "@types/node": ["@types/node@25.7.0", "", { "dependencies": { "undici-types": "~7.21.0" } }, "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg=="],
+
+ "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.59.3", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/type-utils": "8.59.3", "@typescript-eslint/utils": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.59.3", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw=="],
+
+ "@typescript-eslint/parser": ["@typescript-eslint/parser@8.59.3", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg=="],
+
+ "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.59.3", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.59.3", "@typescript-eslint/types": "^8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng=="],
+
+ "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3" } }, "sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA=="],
+
+ "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.59.3", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw=="],
+
+ "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/utils": "8.59.3", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ=="],
+
+ "@typescript-eslint/types": ["@typescript-eslint/types@8.59.3", "", {}, "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg=="],
+
+ "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.59.3", "", { "dependencies": { "@typescript-eslint/project-service": "8.59.3", "@typescript-eslint/tsconfig-utils": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg=="],
+
+ "@typescript-eslint/utils": ["@typescript-eslint/utils@8.59.3", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg=="],
+
+ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="],
+
+ "@unhead/schema": ["@unhead/schema@1.11.20", "", { "dependencies": { "hookable": "^5.5.3", "zhead": "^2.2.4" } }, "sha512-0zWykKAaJdm+/Y7yi/Yds20PrUK7XabLe9c3IRcjnwYmSWY6z0Cr19VIs3ozCj8P+GhR+/TI2mwtGlueCEYouA=="],
+
+ "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
+
+ "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
+
+ "ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="],
+
+ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
+
+ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
+
+ "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
+
+ "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
+
+ "brace-expansion": ["brace-expansion@1.1.14", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g=="],
+
+ "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
+
+ "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
+
+ "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
+
+ "cheerio": ["cheerio@1.2.0", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "encoding-sniffer": "^0.2.1", "htmlparser2": "^10.1.0", "parse5": "^7.3.0", "parse5-htmlparser2-tree-adapter": "^7.1.0", "parse5-parser-stream": "^7.1.2", "undici": "^7.19.0", "whatwg-mimetype": "^4.0.0" } }, "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg=="],
+
+ "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="],
+
+ "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="],
+
+ "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
+
+ "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
+
+ "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
+
+ "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
+
+ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
+
+ "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
+
+ "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
+
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
+
+ "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
+
+ "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
+
+ "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
+
+ "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
+
+ "elysia": ["elysia@1.4.28", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.7", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-Vrx8sBnvq8squS/3yNBzR1jBXI+SgmnmvwawPjNuEHndUe5l1jV2Gp6JJ4ulDkEB8On6bWmmuyPpA+bq4t+WYg=="],
+
+ "encoding-sniffer": ["encoding-sniffer@0.2.1", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="],
+
+ "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
+
+ "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
+
+ "eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="],
+
+ "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
+
+ "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
+
+ "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
+
+ "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="],
+
+ "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
+
+ "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
+
+ "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
+
+ "exact-mirror": ["exact-mirror@0.2.7", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-+MeEmDcLA4o/vjK2zujgk+1VTxPR4hdp23qLqkWfStbECtAq9gmsvQa3LW6z/0GXZyHJobrCnmy1cdeE7BjsYg=="],
+
+ "fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
+
+ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
+
+ "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
+
+ "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
+
+ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
+
+ "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
+
+ "file-type": ["file-type@22.0.1", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.5", "token-types": "^6.1.2", "uint8array-extras": "^1.5.0" } }, "sha512-ww5Mhre0EE+jmBvOXTmXAbEMuZE7uX4a3+oRCQFNj8w++g3ev913N6tXQz0XTXbueQ5TWQfm6BdaViEHHn8bhA=="],
+
+ "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
+
+ "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
+
+ "flatted": ["flatted@3.4.2", "", {}, "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA=="],
+
+ "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
+
+ "globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
+
+ "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
+
+ "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
+
+ "hookified": ["hookified@1.15.1", "", {}, "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg=="],
+
+ "htmlparser2": ["htmlparser2@10.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "entities": "^7.0.1" } }, "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ=="],
+
+ "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
+
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
+
+ "ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
+
+ "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
+
+ "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
+
+ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
+
+ "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
+
+ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
+
+ "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
+
+ "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
+
+ "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
+
+ "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
+
+ "keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="],
+
+ "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
+
+ "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
+
+ "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
+
+ "memoirist": ["memoirist@0.4.0", "", {}, "sha512-zxTgA0mSYELa66DimuNQDvyLq36AwDlTuVRbnQtB+VuTcKWm5Qc4z3WkSpgsFWHNhexqkIooqpv4hdcqrX5Nmg=="],
+
+ "minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
+
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+
+ "nanoid": ["nanoid@5.1.11", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg=="],
+
+ "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
+
+ "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
+
+ "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
+
+ "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
+
+ "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
+
+ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
+
+ "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
+
+ "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
+
+ "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="],
+
+ "parse5-parser-stream": ["parse5-parser-stream@7.1.2", "", { "dependencies": { "parse5": "^7.0.0" } }, "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow=="],
+
+ "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
+
+ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
+
+ "pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
+
+ "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
+
+ "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
+
+ "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
+
+ "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
+
+ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
+
+ "semver": ["semver@7.8.0", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA=="],
+
+ "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
+
+ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
+
+ "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
+
+ "strtok3": ["strtok3@10.3.5", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA=="],
+
+ "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
+
+ "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="],
+
+ "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
+
+ "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="],
+
+ "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
+
+ "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
+
+ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="],
+
+ "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
+
+ "undici": ["undici@7.25.0", "", {}, "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ=="],
+
+ "undici-types": ["undici-types@7.21.0", "", {}, "sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ=="],
+
+ "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
+
+ "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="],
+
+ "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="],
+
+ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
+
+ "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
+
+ "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
+
+ "zhead": ["zhead@2.2.4", "", {}, "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag=="],
+
+ "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
+
+ "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
+
+ "@eslint/eslintrc/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
+
+ "@scalar/themes/@scalar/types": ["@scalar/types@0.1.7", "", { "dependencies": { "@scalar/openapi-types": "0.2.0", "@unhead/schema": "^1.11.11", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "zod": "^3.23.8" } }, "sha512-irIDYzTQG2KLvFbuTI8k2Pz/R4JR+zUUSykVTbEMatkzMmVFnn1VzNSMlODbadycwZunbnL2tA27AXed9URVjw=="],
+
+ "@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="],
+
+ "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="],
+
+ "eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
+
+ "flat-cache/keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
+
+ "htmlparser2/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="],
+
+ "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
+
+ "@scalar/themes/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.2.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-waiKk12cRCqyUCWTOX0K1WEVX46+hVUK+zRPzAahDJ7G0TApvbNkuy5wx7aoUyEk++HHde0XuQnshXnt8jsddA=="],
+
+ "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="],
+
+ "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
+ }
+}
diff --git a/eslint.config.js b/eslint.config.js
index c3394fa..49a3242 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -21,6 +21,17 @@ module.exports = [
process: "readonly",
Buffer: "readonly",
console: "readonly",
+ Bun: "readonly",
+ fetch: "readonly",
+ describe: "readonly",
+ test: "readonly",
+ expect: "readonly",
+ beforeAll: "readonly",
+ afterAll: "readonly",
+ it: "readonly",
+ AbortController: "readonly",
+ setTimeout: "readonly",
+ clearTimeout: "readonly",
},
},
plugins: {
diff --git a/fly.toml b/fly.toml
deleted file mode 100644
index db24634..0000000
--- a/fly.toml
+++ /dev/null
@@ -1,39 +0,0 @@
-# fly.toml file generated for lust on 2023-04-18T12:01:37+07:00
-
-app = "lust"
-kill_signal = "SIGINT"
-kill_timeout = 5
-processes = []
-
-[env]
-
-[experimental]
- auto_rollback = true
-
-[[services]]
- autostart = true
- autostop = false
- http_checks = []
- internal_port = 3000
- processes = ["app"]
- protocol = "tcp"
- script_checks = []
- [services.concurrency]
- hard_limit = 25
- soft_limit = 20
- type = "connections"
-
- [[services.ports]]
- force_https = true
- handlers = ["http"]
- port = 80
-
- [[services.ports]]
- handlers = ["tls", "http"]
- port = 443
-
- [[services.tcp_checks]]
- grace_period = "1s"
- interval = "15s"
- restart_limit = 0
- timeout = "2s"
diff --git a/package.json b/package.json
index eb651a8..47e769b 100644
--- a/package.json
+++ b/package.json
@@ -1,34 +1,24 @@
{
"name": "lustpress",
- "version": "8.1.3-alpha",
+ "version": "8.2.1-alpha",
"description": "RESTful and experimental API for PH and other R18 websites",
- "main": "build/src/index.js",
+ "main": "src/index.ts",
"scripts": {
- "build": "rimraf build && tsc",
- "start": "node build/src/index.js",
- "test": "ts-node test/test.ts",
- "test:mock": "ts-node test/mock.ts",
- "start:prod": "npm run build && node build/src/index.js",
- "start:dev": "ts-node-dev src/index.ts",
- "start:flyctl": "flyctl deploy",
- "lint": "eslint . --ext .ts",
- "lint:fix": "eslint . --fix",
- "build:freshdoc": "rimraf docs",
- "build:apidoc": "npm run build:freshdoc && npx apidoc -i src -o docs",
- "test:pornhub": "start-server-and-test \"npm run start:dev\" 3000 \"node -r ts-node/register --test --test-name-pattern=^pornhub$ test/lustpress.test.ts\"",
- "test:xnxx": "start-server-and-test \"npm run start:dev\" 3000 \"node -r ts-node/register --test --test-name-pattern=^xnxx$ test/lustpress.test.ts\"",
- "test:redtube": "start-server-and-test \"npm run start:dev\" 3000 \"node -r ts-node/register --test --test-name-pattern=^redtube$ test/lustpress.test.ts\"",
- "test:xvideos": "start-server-and-test \"npm run start:dev\" 3000 \"node -r ts-node/register --test --test-name-pattern=^xvideos$ test/lustpress.test.ts\"",
- "test:xhamster": "start-server-and-test \"npm run start:dev\" 3000 \"node -r ts-node/register --test --test-name-pattern=^xhamster$ test/lustpress.test.ts\"",
- "test:youporn": "start-server-and-test \"npm run start:dev\" 3000 \"node -r ts-node/register --test --test-name-pattern=^youporn$ test/lustpress.test.ts\"",
- "test:eporner": "start-server-and-test \"npm run start:dev\" 3000 \"node -r ts-node/register --test --test-name-pattern=^eporner$ test/lustpress.test.ts\"",
- "test:txxx": "start-server-and-test \"npm run start:dev\" 3000 \"node -r ts-node/register --test --test-name-pattern=^txxx$ test/lustpress.test.ts\""
- },
- "apidoc": {
- "title": "Lustpress API Documentation",
- "url": "http://localhost:3000",
- "sampleUrl": "http://localhost:3000",
- "name": "Lustpress"
+ "start:dev": "bun --watch src/index.ts",
+ "build": "bun build ./src/index.ts --outdir ./build --target bun",
+ "start": "bun ./build/index.js",
+ "start:prod": "bun run build && bun ./build/index.js",
+ "test": "bun test test/lustpress.test.ts",
+ "test:pornhub": "bun test -t pornhub test/lustpress.test.ts",
+ "test:xnxx": "bun test -t xnxx test/lustpress.test.ts",
+ "test:redtube": "bun test -t redtube test/lustpress.test.ts",
+ "test:xvideos": "bun test -t xvideos test/lustpress.test.ts",
+ "test:xhamster": "bun test -t xhamster test/lustpress.test.ts",
+ "test:youporn": "bun test -t youporn test/lustpress.test.ts",
+ "test:eporner": "bun test -t eporner test/lustpress.test.ts",
+ "test:txxx": "bun test -t txxx test/lustpress.test.ts",
+ "lint": "eslint .",
+ "lint:fix": "eslint . --fix"
},
"keywords": [],
"author": "sinkaroid",
@@ -38,34 +28,22 @@
},
"license": "MIT",
"dependencies": {
+ "@elysiajs/cors": "^1.2.0",
+ "@elysiajs/swagger": "^1.2.2",
"@keyv/redis": "^5.1.6",
"cheerio": "^1.2.0",
- "cors": "^2.8.6",
- "dotenv": "^17.3.1",
- "express": "^5.2.1",
- "express-rate-limit": "^8.3.1",
- "express-slow-down": "^3.1.0",
- "keyv": "^5.6.0",
- "phin": "^3.7.1",
- "pino": "^10.3.1",
- "pino-pretty": "^13.1.3",
- "playwright": "^1.58.2"
+ "elysia": "^1.2.24",
+ "keyv": "^5.6.0"
},
"devDependencies": {
- "@types/cors": "^2.8.19",
- "@types/express": "^5.0.6",
- "@types/node": "^25.4.0",
- "@typescript-eslint/eslint-plugin": "^8.57.0",
- "@typescript-eslint/parser": "^8.57.0",
- "apidoc": "^1.2.0",
- "eslint": "^10.0.3",
- "rimraf": "^6.1.3",
- "start-server-and-test": "^2.1.5",
- "ts-node": "^10.9.2",
- "ts-node-dev": "^2.0.0",
- "typescript": "5.9.3"
+ "@types/bun": "^1.3.13",
+ "@typescript-eslint/eslint-plugin": "^8.24.1",
+ "@typescript-eslint/parser": "^8.24.1",
+ "eslint": "^9.20.1",
+ "typescript": "^6.0.3"
},
"engines": {
- "node": ">=22"
- }
+ "bun": ">=1.3.13"
+ },
+ "packageManager": "bun@1.3.13"
}
\ No newline at end of file
diff --git a/resources/project/images/bnnuy.png b/resources/project/images/bnnuy.png
deleted file mode 100644
index 96a0184e8c7a12484f8b9d89e64ab028489f5bde..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 109198
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