├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ └── test.yml ├── .gitignore ├── .prettierrc.json ├── .vscode ├── extensions.json └── settings.json ├── LICENSE.txt ├── README-zh-Hant.md ├── README.md ├── bun.lockb ├── package.json ├── preview ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .prettierrc.json ├── bun.lockb ├── package.json ├── src-client │ ├── app.vue │ ├── composables │ │ └── eden.ts │ ├── nuxt.config.ts │ ├── server │ │ ├── api │ │ │ └── hello.ts │ │ └── tsconfig.json │ └── tsconfig.json ├── src-server │ └── index.ts └── tsconfig.json ├── src ├── index.ts └── preset │ ├── entry.ts │ └── nitro.config.ts └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint:recommended", 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended" 6 | ], 7 | "parser": "@typescript-eslint/parser", 8 | "plugins": ["@typescript-eslint"], 9 | "root": true, 10 | "overrides": [ 11 | { 12 | "files": ["**/*.vue"], 13 | "extends": ["@nuxtjs/eslint-config-typescript"] 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue Report 問題回報 3 | about: Providing a detailed report of the issue can help us fix it faster, thank you. 詳細回報問題,能協助我們更快修正,謝謝。 4 | title: '[Issue Report] Title [問題回報] 標題' 5 | labels: '🐞 Bug 臭蟲' 6 | assignees: 'trylovetom' 7 | --- 8 | 9 | ## Expected Result 預期結果 10 | 11 | Describe how you think it should work. Example: The website language should automatically detect the browser language and change accordingly. 12 | 13 | 描述你覺得它應該這麼運作的。範例:網站語言應該要自動偵測瀏覽器語言而做更換。 14 | 15 | ## Actual Result 實際結果 16 | 17 | How does it work currently? It's recommended to provide relevant screenshots or GIF videos. Example: The browser language is set to English, but the display is in Traditional Chinese. 18 | 19 | 結果它怎麼運作?建議提供相關的截圖或是 GIF 影片。範例:目前瀏覽器語言設定為英文,但是顯示繁體中文語言。 20 | 21 | ## Steps to Reproduce 如何還原問題 22 | 23 | Use simple steps so that others can also reproduce the issue. Example: 1. Google Chrome language default is Chinese. 2. Change the browser language to English from settings. 3. Reload the website. 24 | 25 | 用簡單的步驟,讓其他人也可以重現問題。範例: 1. Google Chrome 語言預設為中文。 2. 從設定瀏覽器語言為英文。 3. 重新載入網站。 26 | 27 | ## Environment 環境 28 | 29 | The more detailed your operating environment description, the better. Example: 30 | iOS mobile version of Chrome, version XXX. 31 | 32 | 描述你的運作環境越詳細越好。範例: 33 | iOS 手機版 Chrome,版本 XXX。 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 功能開發 3 | about: Describe the feature in detail to facilitate a smoother and more organized development process. 詳細描述功能,讓開發過程更加順利有條理。 4 | title: '[Feature Request] Title [功能開發] 標題' 5 | labels: '🤔 New Feature 新功能' 6 | assignees: 'trylovetom' 7 | --- 8 | 9 | ## Statement 聲明 10 | 11 | Explain whether the current feature is finalized or if there are any uncertainties, etc. This is mainly to alert the reader to important aspects and also to protect yourself. Example: This feature is still under discussion, please contact the author for any modifications or errors, thank you. 12 | 13 | 說明目前功能是否定案,或是哪些地方還不夠明確等等,主要是用來提示閱讀的人該注意的地方,也可保護自己。範例:本功能尚在討論中,如有修改或是錯誤,煩請聯絡作者,謝謝。 14 | 15 | ## Scenario 場景 16 | 17 | Describe the scenarios in which the feature will be used. Simple template: "Who" needs "what" for "what reason"; Example: This project needs multilingual capabilities to serve customers in China and the United States. 18 | 19 | 說明功能使用在什麼樣的場景,簡易範本:「誰」需要「什麼」,為了「什麼」;範例:本專案為了服務中國與美國客戶,需要多國語系功能。 20 | 21 | ## Description 描述 22 | 23 | Describe the structure and details of the feature, the easier to understand the better, recommend using diagrams and text for assistance. Example: 24 | 25 | 描述功能的架構與細節,越容易理解越好,建議圖文輔助。範例: 26 | 27 | ```txt 28 | 標題:多國語系功能 29 | 描述: 30 | **語系功能** 31 | 透過定義不同的語系檔案,提供網站不同的語言版本。 32 | 33 | **自動切換語系** 34 | 偵測瀏覽器語系,切換不同的語言。 35 | 36 | **需支援語系** 37 | 繁體中文 zh-TW(預設) 38 | 簡體中文 zh-CN 39 | 英文 en-US 40 | ``` 41 | 42 | ```txt 43 | Title: Multilingual Functionality 44 | Description: 45 | **Languages** 46 | Provide different language versions of the website by defining different language files. 47 | 48 | **Automatic Language Switching** 49 | Detect the browser's language setting and switch to the corresponding language. 50 | 51 | **Languages to be Supported** 52 | Traditional Chinese zh-TW (default) 53 | Simplified Chinese zh-CN 54 | English en-US 55 | ``` 56 | 57 | ## Non-Goals 非目標 58 | 59 | Explain what this feature does not need to do to prevent misunderstandings. Example: The multilingual feature only needs to have a pre-established structure and support for Traditional Chinese. 60 | 61 | 說明此功能不需要做的地方,避免閱讀的人多想。範例:多國語系功能只需要做預先架構,支援繁體中文即可。 62 | 63 | ## Notes 附註 64 | 65 | Describe the technology used for this feature, how it is implemented, design drafts, etc. Example: Use the nuxt-i18n module to implement multilingual functionality. 66 | 67 | 說明此功能使用什麼技術,如何實現與設計稿等等附註。範例:使用 nuxt-i18n 模組來實作多國語系功能。 68 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## This Section Can Be Deleted 此段段落可刪除 2 | 3 | Please write the title in the following format [Type of Change] Title. The more detailed the description, the better the understanding of the risks involved in merging this PR. Thank you. 4 | Additionally, you can submit for review even if it's incomplete, to get assistance from others online. 5 | 6 | 標題請依照以下格式撰寫 `[更動種類] 標題`。描述越詳細越能了解,合併此 PR 的風險,謝謝。 7 | 另外,未完成的情況下也可以提交審核,讓大家可以在線上協助你。 8 | 9 | ## Description 描述 10 | 11 | Describe what this PR primarily does, providing related screenshots or GIF videos is recommended. Example: This PR fixes the issue where the multilingual system could not automatically detect and switch the browser language. The issue originated from a bug in the old version of the module on iOS mobile. Therefore, the module was updated and the corresponding configuration files were modified. 12 | 13 | 這 PR 主要做了什麼事情,建議提供相關的截圖或是 GIF 影片。範例:此 PR 修正了多國語系,無法自動偵測瀏覽器語言而更換的的問題。原因發生於舊版本模組在 iOS 手機版上有 Bug。所以更新了模組並修改了相對應的設定檔案。 14 | 15 | ## Related Issue 關聯 Issue 16 | 17 | Which Issue is this related to, use #1 to associate it. You can use Close #1 to indicate the action after the PR is merged. 18 | 19 | 與哪個 Issue 有相關,使用 `#1` 井字號做關聯。可以使用 `Close #1`,來標示 PR 合併後的操作。 20 | 21 | ## Type of Change 更動種類 22 | 23 | Tick the type of change, and modify the title and labels according to the type. You can add options yourself. 24 | 25 | 勾選更動的種類,並依照種類修改標題與標籤,可自行增加選項。 26 | 27 | - [ ] Bug Fix 問題修正 28 | - [ ] Feature Development 功能開發 29 | - [ ] Breaking Update 破壞性更新 30 | 31 | ## Changed Files 更動項目 32 | 33 | List the files you changed, you can use this command git diff origin/main --name-only to list all changed files. Attention! If there is a breaking update, it must be marked, and the affected range described. Example: 34 | 35 | - Installed a new version of the i18n module 36 | - **Updated i18n configuration file**: Breaking update, adjusted the structure of the configuration file, old versions of the file will not be supported. 37 | 38 | 你動了哪些項目,可使此指令 `git diff origin/main --name-only` 列出所有更動檔案。注意!如果有破壞性更新,一定要標記出來,且要描述受影響範圍。範例: 39 | 40 | - 安裝新版的 i18n 模組 41 | - **更新 i18n 設定檔案**:破壞性更新,調整了設定檔案的結構,舊版的設定檔案將不支援。 42 | 43 | ## Self-Check 自我檢查 44 | 45 | The following are items that must be checked before merging the PR, assisted by CI. 46 | 47 | 以下為合併 PR 前必須檢查的項目,CI 協助檢查。 48 | 49 | - [ ] My code adheres to the project style 我的程式碼遵守了專案風格 50 | - [ ] I have updated the corresponding documents 我已經更新了相對應的文件 51 | - [ ] My code has been tested and passed 我的程式碼已經被測試且通過了 52 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | # push to main branch 5 | push: 6 | branches: [main] 7 | 8 | # any pull request 9 | pull_request: 10 | 11 | # daily 12 | schedule: 13 | - cron: '00 16 * * *' # 00:00 in taipei (utc+8) 14 | 15 | jobs: 16 | build: 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | node-version: [1.x.x, latest] 21 | os: [ubuntu-latest, macos-latest] 22 | 23 | runs-on: ${{ matrix.os }} 24 | 25 | steps: 26 | - name: Checkout Git Source 27 | uses: actions/checkout@v4 28 | 29 | - name: Use Bun ${{ matrix.node-version }} 30 | uses: oven-sh/setup-bun@v1 31 | with: 32 | bun-version: ${{ matrix.node-version }} 33 | 34 | - name: Install Dependencies 35 | run: bun install 36 | 37 | - name: Lint Your Code 38 | run: bun run tool:lint 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | 15 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 16 | 17 | # Runtime data 18 | 19 | pids 20 | _.pid 21 | _.seed 22 | \*.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | 30 | coverage 31 | \*.lcov 32 | 33 | # nyc test coverage 34 | 35 | .nyc_output 36 | 37 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 38 | 39 | .grunt 40 | 41 | # Bower dependency directory (https://bower.io/) 42 | 43 | bower_components 44 | 45 | # node-waf configuration 46 | 47 | .lock-wscript 48 | 49 | # Compiled binary addons (https://nodejs.org/api/addons.html) 50 | 51 | build/Release 52 | 53 | # Dependency directories 54 | 55 | node_modules/ 56 | jspm_packages/ 57 | 58 | # Snowpack dependency directory (https://snowpack.dev/) 59 | 60 | web_modules/ 61 | 62 | # TypeScript cache 63 | 64 | \*.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | 68 | .npm 69 | 70 | # Optional eslint cache 71 | 72 | .eslintcache 73 | 74 | # Optional stylelint cache 75 | 76 | .stylelintcache 77 | 78 | # Microbundle cache 79 | 80 | .rpt2_cache/ 81 | .rts2_cache_cjs/ 82 | .rts2_cache_es/ 83 | .rts2_cache_umd/ 84 | 85 | # Optional REPL history 86 | 87 | .node_repl_history 88 | 89 | # Output of 'npm pack' 90 | 91 | \*.tgz 92 | 93 | # Yarn Integrity file 94 | 95 | .yarn-integrity 96 | 97 | # dotenv environment variable files 98 | 99 | .env 100 | .env.development.local 101 | .env.test.local 102 | .env.production.local 103 | .env.local 104 | 105 | # parcel-bundler cache (https://parceljs.org/) 106 | 107 | .cache 108 | .parcel-cache 109 | 110 | # Next.js build output 111 | 112 | .next 113 | out 114 | 115 | # Nuxt.js build / generate output 116 | 117 | .nuxt 118 | dist 119 | 120 | # Gatsby files 121 | 122 | .cache/ 123 | 124 | # Comment in the public line in if your project uses Gatsby and not Next.js 125 | 126 | # https://nextjs.org/blog/next-9-1#public-directory-support 127 | 128 | # public 129 | 130 | # vuepress build output 131 | 132 | .vuepress/dist 133 | 134 | # vuepress v2.x temp and cache directory 135 | 136 | .temp 137 | .cache 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.\* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | # Nuxt dev/build outputs 178 | .output 179 | .data 180 | .nuxt 181 | .nitro 182 | .cache 183 | dist 184 | 185 | # Node dependencies 186 | node_modules 187 | 188 | # Logs 189 | logs 190 | *.log 191 | 192 | # Misc 193 | .DS_Store 194 | .fleet 195 | .idea 196 | 197 | # Local env files 198 | .env 199 | .env.* 200 | !.env.example 201 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "jsxSingleQuote": true, 5 | "trailingComma": "none" 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "streetsidesoftware.code-spell-checker", 5 | "oven.bun-vscode", 6 | "vue.volar" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-2050 CHANG, TZU-YEN 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. 22 | -------------------------------------------------------------------------------- /README-zh-Hant.md: -------------------------------------------------------------------------------- 1 | # elysiajs-nuxt 2 | 3 | > 輕鬆地整合 elysia 與 nuxt,支援 @nuxt/devtools 與 @elysiajs/eden 歐! 4 | 5 | **Demo** 6 | 7 | https://github.com/nuxt/nuxt/assets/13268073/d5c96902-698f-482a-8360-9f657ab40eba 8 | 9 | ## 使用 10 | 11 | ### 開發環境 12 | 13 | 1. 安裝套件 14 | 15 | ```sh 16 | # 目前僅支援 Bun 17 | bun add elysiajs-nuxt 18 | bun add nuxt elysia --dev 19 | ``` 20 | 21 | 2. 設定 nuxt.config.ts 22 | 23 | ```ts 24 | // src-client/nuxt.config.ts 25 | export default defineNuxtConfig({ 26 | // 必要設定! 27 | nitro: { preset: import.meta.resolveSync('elysiajs-nuxt/preset') }, 28 | // 必要設定! 29 | vite: { server: { origin: 'localhost:3000' } } 30 | }) 31 | ``` 32 | 33 | 3. 使用 elysiajs-nuxt 為 plugin 34 | 35 | ```ts 36 | // src-server/index.ts 37 | import { Elysia } from 'elysia' 38 | import elysiaNuxt from 'elysiajs-nuxt' 39 | 40 | new Elysia().use(elysiaNuxt).listen(5566) 41 | ``` 42 | 43 | 4. 同時啟動開發服務器,客戶端(nuxt) 與服務器(elysia) 44 | 45 | ```sh 46 | # 服務器 47 | bun run --watch src-server 48 | ``` 49 | 50 | ```sh 51 | # 客戶端 52 | bun --bun nuxt dev src-client/index.ts 53 | ``` 54 | 55 | ### 產品環境 56 | 57 | 1. 編譯客戶端 58 | 59 | ```ts 60 | bun --bun nuxt build src-client 61 | ``` 62 | 63 | 2. 啟動服務器 64 | 65 | ```sh 66 | # 環境變數為必要設定 67 | NODE_ENV=production bun run src-server/index.ts 68 | ``` 69 | 70 | ### 範例參考 71 | 72 | - [preview](/preview) 73 | 74 | ## 作者 75 | 76 | - [張子晏](https://github.com/trylovetom) 77 | 78 | ## 語言 79 | 80 | - [English](./README.md) 81 | - [繁體中文](./README-zh-Hant.md) 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # elysiajs-nuxt 2 | 3 | > Easily integrates elysia with nuxt, now supporting @nuxt/devtools and @elysiajs/eden! 4 | 5 | **Demo** 6 | 7 | https://github.com/nuxt/nuxt/assets/13268073/d5c96902-698f-482a-8360-9f657ab40eba 8 | 9 | ## Usage 10 | 11 | ### Development Environment 12 | 13 | 1. install packages 14 | 15 | ```sh 16 | # currently only supports Bun 17 | bun add elysiajs-nuxt 18 | bun add nuxt elysia --dev 19 | ``` 20 | 21 | 2. configure nuxt.config.ts 22 | 23 | ```ts 24 | // src-client/nuxt.config.ts 25 | export default defineNuxtConfig({ 26 | // mandatory configuration! 27 | nitro: { preset: import.meta.resolveSync('elysiajs-nuxt/preset') }, 28 | // mandatory configuration! 29 | vite: { server: { origin: 'localhost:3000' } } 30 | }) 31 | ``` 32 | 33 | 3. use elysiajs-nuxt as a plugin 34 | 35 | ```ts 36 | // src-server/index.ts 37 | import { Elysia } from 'elysia' 38 | import elysiaNuxt from 'elysiajs-nuxt' 39 | 40 | new Elysia().use(elysiaNuxt).listen(5566) 41 | ``` 42 | 43 | 4. simultaneously start dev servers, both client(nuxt) and server(elysia) 44 | 45 | ```sh 46 | # server 47 | bun run --watch src-server 48 | ``` 49 | 50 | ```sh 51 | # client 52 | bun --bun nuxt dev src-client/index.ts 53 | ``` 54 | 55 | ### Production Environment 56 | 57 | 1. compile the Client 58 | 59 | ```ts 60 | bun --bun nuxt build src-client 61 | ``` 62 | 63 | 2. start the Server 64 | 65 | ```sh 66 | # mandatory configuration! 67 | NODE_ENV=production bun run src-server/index.ts 68 | ``` 69 | 70 | ### Example 71 | 72 | - [preview](/preview) 73 | 74 | ## Author 75 | 76 | - [CHANG, TZU-YEN](https://github.com/trylovetom) 77 | 78 | ## Languages 79 | 80 | - [English](./README.md) 81 | - [繁體中文](./README-zh-Hant.md) 82 | -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trylovetom/elysiajs-nuxt/1fdea431171519c40af7c3fdfadb82dd9cc692f3/bun.lockb -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elysiajs-nuxt", 3 | "version": "0.3.11", 4 | "license": "MIT", 5 | "author": "CHANG, TZU-YEN (https://github.com/trylovetom)", 6 | "homepage": "https://github.com/trylovetom/elysiajs-nuxt", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/trylovetom/elysiajs-nuxt.git" 10 | }, 11 | "type": "module", 12 | "exports": { 13 | ".": "./src/index.ts", 14 | "./preset": "./src/preset/nitro.config.ts" 15 | }, 16 | "module": "src/index.ts", 17 | "scripts": { 18 | "postinstall": "prettier-package-json --write package.json", 19 | "tool:fmt": "prettier-package-json --write ./package.json && prettier '**/*' --write --ignore-unknown && eslint '**/*.{js,jsx,ts,tsx,vue}' --fix", 20 | "tool:lint": "prettier '**/*' --check --ignore-unknown && eslint '**/*.{js,jsx,ts,tsx,vue}'" 21 | }, 22 | "peerDependencies": { 23 | "elysia": "^0.8.9", 24 | "nuxt": "^3.9.3", 25 | "typescript": "^5.3.3" 26 | }, 27 | "devDependencies": { 28 | "@nuxtjs/eslint-config-typescript": "^12.1.0", 29 | "@types/bun": "latest", 30 | "@typescript-eslint/eslint-plugin": "^6.19.1", 31 | "@typescript-eslint/parser": "^6.19.1", 32 | "elysia": "^0.8.9", 33 | "eslint": "^8.56.0", 34 | "eslint-config-prettier": "^9.1.0", 35 | "eslint-plugin-prettier": "^5.1.3", 36 | "nitropack": "^2.8.1", 37 | "nuxt": "^3.9.3", 38 | "prettier": "^3.2.4", 39 | "prettier-package-json": "^2.8.0", 40 | "typescript": "^5.3.3" 41 | }, 42 | "keywords": [ 43 | "bun", 44 | "elysia", 45 | "elysiajs", 46 | "frontend", 47 | "http", 48 | "nuxt", 49 | "nuxtjs", 50 | "server", 51 | "web" 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /preview/.eslintignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | 15 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 16 | 17 | # Runtime data 18 | 19 | pids 20 | _.pid 21 | _.seed 22 | \*.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | 30 | coverage 31 | \*.lcov 32 | 33 | # nyc test coverage 34 | 35 | .nyc_output 36 | 37 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 38 | 39 | .grunt 40 | 41 | # Bower dependency directory (https://bower.io/) 42 | 43 | bower_components 44 | 45 | # node-waf configuration 46 | 47 | .lock-wscript 48 | 49 | # Compiled binary addons (https://nodejs.org/api/addons.html) 50 | 51 | build/Release 52 | 53 | # Dependency directories 54 | 55 | node_modules/ 56 | jspm_packages/ 57 | 58 | # Snowpack dependency directory (https://snowpack.dev/) 59 | 60 | web_modules/ 61 | 62 | # TypeScript cache 63 | 64 | \*.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | 68 | .npm 69 | 70 | # Optional eslint cache 71 | 72 | .eslintcache 73 | 74 | # Optional stylelint cache 75 | 76 | .stylelintcache 77 | 78 | # Microbundle cache 79 | 80 | .rpt2_cache/ 81 | .rts2_cache_cjs/ 82 | .rts2_cache_es/ 83 | .rts2_cache_umd/ 84 | 85 | # Optional REPL history 86 | 87 | .node_repl_history 88 | 89 | # Output of 'npm pack' 90 | 91 | \*.tgz 92 | 93 | # Yarn Integrity file 94 | 95 | .yarn-integrity 96 | 97 | # dotenv environment variable files 98 | 99 | .env 100 | .env.development.local 101 | .env.test.local 102 | .env.production.local 103 | .env.local 104 | 105 | # parcel-bundler cache (https://parceljs.org/) 106 | 107 | .cache 108 | .parcel-cache 109 | 110 | # Next.js build output 111 | 112 | .next 113 | out 114 | 115 | # Nuxt.js build / generate output 116 | 117 | .nuxt 118 | dist 119 | 120 | # Gatsby files 121 | 122 | .cache/ 123 | 124 | # Comment in the public line in if your project uses Gatsby and not Next.js 125 | 126 | # https://nextjs.org/blog/next-9-1#public-directory-support 127 | 128 | # public 129 | 130 | # vuepress build output 131 | 132 | .vuepress/dist 133 | 134 | # vuepress v2.x temp and cache directory 135 | 136 | .temp 137 | .cache 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.\* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | # Nuxt dev/build outputs 178 | .output 179 | .data 180 | .nuxt 181 | .nitro 182 | .cache 183 | dist 184 | 185 | # Node dependencies 186 | node_modules 187 | 188 | # Logs 189 | logs 190 | *.log 191 | 192 | # Misc 193 | .DS_Store 194 | .fleet 195 | .idea 196 | 197 | # Local env files 198 | .env 199 | .env.* 200 | !.env.example 201 | 202 | # Database 203 | data/ 204 | -------------------------------------------------------------------------------- /preview/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint:recommended", 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended" 6 | ], 7 | "parser": "@typescript-eslint/parser", 8 | "plugins": ["@typescript-eslint"], 9 | "root": true, 10 | "overrides": [ 11 | { 12 | "files": ["src-client/**/*.{js,jsx,ts,tsx,vue}"], 13 | "extends": [ 14 | "@nuxtjs/eslint-config-typescript", 15 | "plugin:prettier/recommended" 16 | ] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /preview/.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | 15 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 16 | 17 | # Runtime data 18 | 19 | pids 20 | _.pid 21 | _.seed 22 | \*.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | 30 | coverage 31 | \*.lcov 32 | 33 | # nyc test coverage 34 | 35 | .nyc_output 36 | 37 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 38 | 39 | .grunt 40 | 41 | # Bower dependency directory (https://bower.io/) 42 | 43 | bower_components 44 | 45 | # node-waf configuration 46 | 47 | .lock-wscript 48 | 49 | # Compiled binary addons (https://nodejs.org/api/addons.html) 50 | 51 | build/Release 52 | 53 | # Dependency directories 54 | 55 | node_modules/ 56 | jspm_packages/ 57 | 58 | # Snowpack dependency directory (https://snowpack.dev/) 59 | 60 | web_modules/ 61 | 62 | # TypeScript cache 63 | 64 | \*.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | 68 | .npm 69 | 70 | # Optional eslint cache 71 | 72 | .eslintcache 73 | 74 | # Optional stylelint cache 75 | 76 | .stylelintcache 77 | 78 | # Microbundle cache 79 | 80 | .rpt2_cache/ 81 | .rts2_cache_cjs/ 82 | .rts2_cache_es/ 83 | .rts2_cache_umd/ 84 | 85 | # Optional REPL history 86 | 87 | .node_repl_history 88 | 89 | # Output of 'npm pack' 90 | 91 | \*.tgz 92 | 93 | # Yarn Integrity file 94 | 95 | .yarn-integrity 96 | 97 | # dotenv environment variable files 98 | 99 | .env 100 | .env.development.local 101 | .env.test.local 102 | .env.production.local 103 | .env.local 104 | 105 | # parcel-bundler cache (https://parceljs.org/) 106 | 107 | .cache 108 | .parcel-cache 109 | 110 | # Next.js build output 111 | 112 | .next 113 | out 114 | 115 | # Nuxt.js build / generate output 116 | 117 | .nuxt 118 | dist 119 | 120 | # Gatsby files 121 | 122 | .cache/ 123 | 124 | # Comment in the public line in if your project uses Gatsby and not Next.js 125 | 126 | # https://nextjs.org/blog/next-9-1#public-directory-support 127 | 128 | # public 129 | 130 | # vuepress build output 131 | 132 | .vuepress/dist 133 | 134 | # vuepress v2.x temp and cache directory 135 | 136 | .temp 137 | .cache 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.\* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | # Nuxt dev/build outputs 178 | .output 179 | .data 180 | .nuxt 181 | .nitro 182 | .cache 183 | dist 184 | 185 | # Node dependencies 186 | node_modules 187 | 188 | # Logs 189 | logs 190 | *.log 191 | 192 | # Misc 193 | .DS_Store 194 | .fleet 195 | .idea 196 | 197 | # Local env files 198 | .env 199 | .env.* 200 | !.env.example 201 | 202 | # Database 203 | data/ 204 | -------------------------------------------------------------------------------- /preview/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "jsxSingleQuote": true, 5 | "trailingComma": "none" 6 | } 7 | -------------------------------------------------------------------------------- /preview/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trylovetom/elysiajs-nuxt/1fdea431171519c40af7c3fdfadb82dd9cc692f3/preview/bun.lockb -------------------------------------------------------------------------------- /preview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elysiajs-nuxt", 3 | "type": "module", 4 | "module": "src-server/index.ts", 5 | "scripts": { 6 | "client:build": "bun --bun nuxt build src-client", 7 | "client:dev": "bun --bun nuxt dev src-client", 8 | "postinstall": "prettier-package-json --write package.json && bun --bun nuxt prepare src-client", 9 | "server:dev": "bun --watch src-server/index.ts", 10 | "server:start": "NODE_ENV=production bun src-server/index.ts", 11 | "tool:fmt": "prettier '**/*' --write --ignore-unknown && eslint '**/*.{js,jsx,ts,tsx,vue}' --fix", 12 | "tool:lint": "prettier '**/*' --check --ignore-unknown && eslint '**/*.{js,jsx,ts,tsx,vue}'" 13 | }, 14 | "dependencies": { 15 | "elysia": "^0.8.9", 16 | "elysiajs-nuxt": "link:elysiajs-nuxt" 17 | }, 18 | "devDependencies": { 19 | "@elysiajs/eden": "^0.8.1", 20 | "@nuxt/devtools": "^1.0.8", 21 | "@nuxtjs/eslint-config-typescript": "^12.1.0", 22 | "@typescript-eslint/eslint-plugin": "^6.19.1", 23 | "@typescript-eslint/parser": "^6.19.1", 24 | "eslint": "^8.56.0", 25 | "eslint-config-prettier": "^9.1.0", 26 | "eslint-plugin-prettier": "^5.1.3", 27 | "nuxt": "^3.9.3", 28 | "prettier-package-json": "^2.8.0", 29 | "typescript": "^5.3.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /preview/src-client/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /preview/src-client/composables/eden.ts: -------------------------------------------------------------------------------- 1 | import { edenFetch } from '@elysiajs/eden' 2 | import { type Application } from '../../src-server' 3 | 4 | async function unwrapper( 5 | req: Promise<{ data: Data; error: unknown }> 6 | ): Promise | never { 7 | const res = await req 8 | 9 | if (res.error) { 10 | throw res.error 11 | } 12 | 13 | return res.data 14 | } 15 | 16 | // eden fetch 17 | function pipeline( 18 | fn1: (...args: A) => B, 19 | fn2: (b: B) => C 20 | ): (...args: A) => C { 21 | return (...args: A): C => fn2(fn1(...args)) 22 | } 23 | 24 | export const useEdenFetch = () => { 25 | const config = useRuntimeConfig() 26 | const fetchTarget = process.server 27 | ? config.fetchTarget 28 | : config.public.fetchTarget 29 | 30 | return pipeline(edenFetch(fetchTarget), unwrapper) 31 | } 32 | -------------------------------------------------------------------------------- /preview/src-client/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtConfig({ 2 | devtools: { enabled: true }, 3 | nitro: { preset: import.meta.resolveSync('elysiajs-nuxt/preset') }, 4 | vite: { server: { origin: 'localhost:3000' } }, 5 | runtimeConfig: { 6 | // same server -> 'http://localhost:port', different server -> 'https://your.domain.com' 7 | fetchTarget: 'http://localhost:5566', 8 | // same origin -> '', different origin -> 'https://your.domain.com' 9 | public: { fetchTarget: '' } 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /preview/src-client/server/api/hello.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(() => { 2 | return { hello: 'world' } 3 | }) 4 | -------------------------------------------------------------------------------- /preview/src-client/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /preview/src-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": ["./.nuxt/tsconfig.json", "../tsconfig.json"] 4 | } 5 | -------------------------------------------------------------------------------- /preview/src-server/index.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from 'elysia' 2 | import elysiaNuxt from 'elysiajs-nuxt' 3 | 4 | const detail = `[${import.meta.file}]:` 5 | const application = new Elysia() 6 | .onStart(function onStart({ server }) { 7 | const startAt = new Date() 8 | console.info( 9 | `${detail} server started at ${startAt.toISOString()} (${server?.url}).` 10 | ) 11 | }) 12 | .onStop(function onStop() { 13 | const startAt = new Date() 14 | console.info(`${detail} server stop at ${startAt.toISOString()}.`) 15 | }) 16 | .use(elysiaNuxt) 17 | .get('/api/message', () => ({ message: 'THIS IS THE WAY!' })) 18 | .listen(5566) 19 | 20 | export type Application = typeof application 21 | -------------------------------------------------------------------------------- /preview/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://bun.sh/guides/runtime/typescript 3 | "compilerOptions": { 4 | // enable latest features 5 | "lib": ["ESNext"], 6 | "target": "ESNext", 7 | "module": "ESNext", 8 | "moduleDetection": "force", 9 | "jsx": "react-jsx", // support JSX 10 | "allowJs": true, // allow importing `.js` from `.ts` 11 | 12 | // Bundler mode 13 | "moduleResolution": "bundler", 14 | "allowImportingTsExtensions": true, 15 | "verbatimModuleSyntax": true, 16 | "noEmit": true, 17 | 18 | // Best practices 19 | "strict": true, 20 | "skipLibCheck": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "noFallthroughCasesInSwitch": true, 24 | 25 | // Some stricter flags 26 | "useUnknownInCatchVariables": true, 27 | "noPropertyAccessFromIndexSignature": true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from 'elysia' 2 | import { type NitroApp } from 'nitropack' 3 | import { defineNuxtConfig } from 'nuxt/config' 4 | import { type NuxtConfig } from 'nuxt/schema' 5 | 6 | const nitroAppGlob = new Bun.Glob('**/.output/server/index.mjs') 7 | const nitroAppPath = nitroAppGlob 8 | .scanSync({ absolute: true, dot: true }) 9 | .next().value 10 | 11 | const nuxtConfigGlob = new Bun.Glob('**/nuxt.config.ts') 12 | const nuxtConfigPath = nuxtConfigGlob.scanSync({ absolute: true }).next().value 13 | 14 | export default new Elysia().all('*', async function nuxt({ request, set }) { 15 | // isProduction 16 | if (process.env.NODE_ENV === 'production') { 17 | const nitroApp: NitroApp = import.meta.require(nitroAppPath)?.default 18 | 19 | if (!nitroApp) { 20 | throw new Error(`Can't find the nitroApp from "${nitroAppPath}"`) 21 | } 22 | 23 | let body 24 | 25 | if (request.body) { 26 | body = await request.arrayBuffer() 27 | } 28 | 29 | const url = new URL(request.url) 30 | 31 | return nitroApp.localFetch(url.pathname + url.search, { 32 | host: url.hostname, 33 | protocol: url.protocol, 34 | headers: request.headers, 35 | method: request.method, 36 | redirect: request.redirect, 37 | body 38 | }) 39 | } 40 | 41 | // isDevelopment 42 | global.defineNuxtConfig = defineNuxtConfig 43 | 44 | const nuxtConfig: NuxtConfig = import.meta.require(nuxtConfigPath)?.default 45 | const origin = nuxtConfig.vite?.server?.origin 46 | 47 | if (!origin) { 48 | throw new Error(`Can't find the origin from "${nuxtConfigPath}"`) 49 | } 50 | 51 | // forward the request 52 | const url = new URL(request.url) 53 | url.host = origin 54 | 55 | if (url.pathname === '/@vite/client') { 56 | url.pathname = '/_nuxt/@vite/client' 57 | } 58 | 59 | if (url.pathname.includes('/@vite/client')) { 60 | set.redirect = url.toString() 61 | return 62 | } 63 | 64 | const req = new Request(url.toString(), request) 65 | req.headers.set('host', url.host) 66 | req.headers.set('origin', url.origin) 67 | 68 | const res = await fetch(req) 69 | 70 | if (!res.ok || !res.headers.get('content-type')?.includes('text/html')) { 71 | return res 72 | } 73 | 74 | // modify the origin 75 | const html = (await res.text()) 76 | .replaceAll('src="/_nuxt', `src="http://${origin}/_nuxt`) 77 | .replaceAll('href="/_nuxt', `href="http://${origin}/_nuxt`) 78 | .replaceAll('src="/__nuxt', `src="http://${origin}/__nuxt`) 79 | .replaceAll('href="/__nuxt', `href="http://${origin}/__nuxt`) 80 | 81 | return new Response(html, res) 82 | }) 83 | -------------------------------------------------------------------------------- /src/preset/entry.ts: -------------------------------------------------------------------------------- 1 | import '#internal/nitro/virtual/polyfill' 2 | import { nitroApp } from '#internal/nitro/app' 3 | 4 | export default nitroApp 5 | -------------------------------------------------------------------------------- /src/preset/nitro.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import type { NitroPreset } from 'nitropack' 3 | 4 | export default { 5 | preset: 'node-server', 6 | entry: fileURLToPath(new URL('./entry.ts', import.meta.url)), 7 | // https://bun.sh/docs/runtime/modules#resolution 8 | exportConditions: ['bun', 'worker', 'node', 'import', 'default'], 9 | commands: { 10 | preview: 'bun run ./server/index.mjs' 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://bun.sh/guides/runtime/typescript 3 | "compilerOptions": { 4 | // enable latest features 5 | "lib": ["ESNext"], 6 | "target": "ESNext", 7 | "module": "ESNext", 8 | "moduleDetection": "force", 9 | "jsx": "react-jsx", // support JSX 10 | "allowJs": true, // allow importing `.js` from `.ts` 11 | 12 | // Bundler mode 13 | "moduleResolution": "bundler", 14 | "allowImportingTsExtensions": true, 15 | "verbatimModuleSyntax": true, 16 | "noEmit": true, 17 | 18 | // Best practices 19 | "strict": true, 20 | "skipLibCheck": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "noFallthroughCasesInSwitch": true, 24 | 25 | // Some stricter flags 26 | "useUnknownInCatchVariables": true, 27 | "noPropertyAccessFromIndexSignature": true 28 | } 29 | } 30 | --------------------------------------------------------------------------------