├── .github └── workflows │ ├── ci.yaml │ ├── cr.yaml │ └── release.yaml ├── .gitignore ├── .npmrc ├── LICENSE ├── README.md ├── client.d.ts ├── client ├── app │ ├── app.vue │ ├── assets │ │ └── main.css │ ├── components │ │ ├── app-footer.vue │ │ ├── fileIcon.vue │ │ ├── header-info.vue │ │ ├── shiki.vue │ │ └── ui │ │ │ ├── collapsible.vue │ │ │ └── tooltip.vue │ ├── composables │ │ └── shiki.ts │ ├── layouts │ │ └── default.vue │ ├── pages │ │ ├── index.vue │ │ └── inspector.vue │ └── tailwind.config.mjs ├── nuxt.config.ts ├── package.json ├── public │ └── favicon.svg ├── server │ └── routes │ │ ├── launchEditor.ts │ │ └── ws │ │ └── inspector.ts ├── shared │ └── types.ts └── tsconfig.json ├── docs ├── .vitepress │ ├── assets │ │ └── icons │ │ │ ├── farm.svg │ │ │ └── rspack.svg │ ├── components │ │ ├── DefaultTag.vue │ │ ├── HomePage.vue │ │ └── TypeTag.vue │ ├── config.ts │ ├── enUS.ts │ ├── theme │ │ ├── Layout.vue │ │ ├── index.ts │ │ └── style.css │ ├── types.d.ts │ └── zhCN.ts ├── components.d.ts ├── features │ ├── custom-prefix.md │ ├── highlight.md │ ├── inspector.md │ ├── launch-editor.md │ └── pass-logs.md ├── guide │ ├── configurations.md │ ├── getting-started.md │ └── migration.md ├── index.md ├── package.json ├── public │ ├── features │ │ ├── extend-name.png │ │ ├── highlight-dark.png │ │ ├── highlight.png │ │ ├── inspect.png │ │ └── prefix.png │ ├── logo.svg │ └── og.png ├── troubleshooting.md ├── uno.config.ts └── zh-CN │ ├── features │ ├── custom-prefix.md │ ├── highlight.md │ ├── inspector.md │ ├── launch-editor.md │ └── pass-logs.md │ ├── guide │ ├── configurations.md │ ├── getting-started.md │ └── migration.md │ ├── index.md │ └── troubleshooting.md ├── eslint.config.js ├── examples ├── astro │ ├── .gitignore │ ├── astro.config.mjs │ ├── package.json │ ├── public │ │ └── favicon.svg │ └── src │ │ ├── components │ │ └── Client.astro │ │ ├── env.d.ts │ │ ├── layouts │ │ └── Layout.astro │ │ └── pages │ │ └── index.astro ├── farm-vue │ ├── .gitignore │ ├── farm.config.ts │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.vue │ │ ├── env.d.ts │ │ └── index.ts │ ├── tsconfig.json │ └── tsconfig.node.json ├── nextjs │ ├── .gitignore │ ├── app │ │ ├── layout.tsx │ │ └── page.tsx │ ├── next.config.js │ ├── package.json │ └── tsconfig.json ├── nuxt │ ├── .gitignore │ ├── .npmrc │ ├── README.md │ ├── app.vue │ ├── nuxt.config.ts │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── server │ │ ├── api │ │ │ └── test.ts │ │ └── tsconfig.json │ ├── tsconfig.json │ └── utils │ │ ├── hello.js │ │ └── hello.ts ├── rspack │ ├── .gitignore │ ├── index.html │ ├── package.json │ ├── rspack.config.js │ └── src │ │ ├── App.vue │ │ ├── assets │ │ ├── rspack.svg │ │ └── vue.svg │ │ ├── components │ │ └── HelloWorld.vue │ │ ├── main.js │ │ └── style.css ├── solid-start │ ├── .gitignore │ ├── README.md │ ├── app.config.ts │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── app.css │ │ ├── app.tsx │ │ ├── components │ │ │ ├── Counter.css │ │ │ └── Counter.tsx │ │ ├── entry-client.tsx │ │ ├── entry-server.tsx │ │ ├── global.d.ts │ │ └── routes │ │ │ ├── [...404].tsx │ │ │ ├── about.tsx │ │ │ ├── api │ │ │ └── test.ts │ │ │ └── index.tsx │ └── tsconfig.json ├── svelte │ ├── .gitignore │ ├── .npmrc │ ├── README.md │ ├── package.json │ ├── src │ │ ├── app.d.ts │ │ ├── app.html │ │ ├── lib │ │ │ └── index.ts │ │ └── routes │ │ │ ├── +page.svelte │ │ │ └── test │ │ │ └── +server.js │ ├── static │ │ └── favicon.png │ ├── svelte.config.js │ ├── tsconfig.json │ └── vite.config.ts ├── vite-vue3 │ ├── .gitignore │ ├── env.d.ts │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── App.vue │ │ ├── jsLog.js │ │ ├── main.ts │ │ └── tsLog.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts └── vue3-cli │ ├── .browserslistrc │ ├── .gitignore │ ├── .npmrc │ ├── README.md │ ├── babel.config.js │ ├── package.json │ ├── public │ ├── favicon.ico │ └── index.html │ ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── HelloWorld.vue │ ├── main.ts │ └── shims-vue.d.ts │ ├── tsconfig.json │ └── vue.config.js ├── package.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── src ├── astro.ts ├── core │ ├── constants.ts │ ├── dir.ts │ ├── options │ │ ├── resolve.ts │ │ └── type.ts │ ├── server │ │ ├── filePathMap.ts │ │ ├── health.ts │ │ ├── index.ts │ │ ├── launchEditor.ts │ │ ├── send.ts │ │ ├── serveStatic.ts │ │ └── ws │ │ │ ├── inspector.ts │ │ │ └── passLogs.ts │ ├── transform │ │ ├── compilers │ │ │ ├── index.ts │ │ │ ├── sfc.ts │ │ │ ├── svelte.ts │ │ │ └── vanilla.ts │ │ └── index.ts │ └── utils │ │ ├── codegen.ts │ │ ├── common.ts │ │ ├── index.ts │ │ ├── state.ts │ │ ├── themes.ts │ │ ├── virtualModules.ts │ │ └── walker.ts ├── esbuild.ts ├── farm.ts ├── helper.ts ├── index.ts ├── nuxt.ts ├── rollup.ts ├── rspack.ts ├── types.ts ├── vite.ts └── webpack.ts ├── test ├── __snapshots__ │ ├── comment.test.ts.snap │ ├── options.test.ts.snap │ └── transform.test.ts.snap ├── comment.test.ts ├── filePathMap.test.ts ├── fixtures │ ├── comments.ts │ ├── option.ts │ └── transform.ts ├── options.test.ts ├── themes.test.ts └── transform.test.ts ├── tsconfig.json └── tsdown.config.ts /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | lint: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Set node 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: 22.x 21 | 22 | - name: Setup 23 | run: npm i -g @antfu/ni 24 | 25 | - name: Install 26 | run: nci 27 | 28 | - name: Lint 29 | run: nr lint 30 | 31 | test: 32 | runs-on: ${{ matrix.os }} 33 | 34 | strategy: 35 | matrix: 36 | node: [20.x, 22.x] 37 | os: [ubuntu-latest, windows-latest, macos-latest] 38 | fail-fast: false 39 | 40 | steps: 41 | - uses: actions/checkout@v3 42 | - name: Set node ${{ matrix.node }} 43 | uses: actions/setup-node@v3 44 | with: 45 | node-version: ${{ matrix.node }} 46 | 47 | - name: Setup 48 | run: npm i -g @antfu/ni 49 | 50 | - name: Install 51 | run: nci 52 | 53 | - name: Build 54 | run: nr build 55 | 56 | - name: Test 57 | run: nr test 58 | -------------------------------------------------------------------------------- /.github/workflows/cr.yaml: -------------------------------------------------------------------------------- 1 | name: CR 2 | 3 | on: 4 | push: 5 | pull_request: 6 | branches: [main] 7 | paths-ignore: 8 | - '.github/**' 9 | - 'tests/**' 10 | - 'docs/**' 11 | - '*.md' 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Set node 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: 22.x 23 | 24 | - name: Setup 25 | run: npm i -g @antfu/ni 26 | 27 | - name: Install 28 | run: nci 29 | 30 | - name: Build 31 | run: nr build 32 | 33 | - run: nlx pkg-pr-new publish 34 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | steps: 14 | - uses: actions/checkout@v3 15 | with: 16 | fetch-depth: 0 17 | 18 | - uses: actions/setup-node@v3 19 | with: 20 | node-version: lts/* 21 | 22 | - run: npx changelogithub 23 | env: 24 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE 81 | .idea 82 | .DS_Store 83 | 84 | docs/.vitepress/cache 85 | .vercel 86 | 87 | .output 88 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | ignore-workspace-root-check=true 2 | shamefully-hoist=true 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-PRESENT yuyinws 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.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 | 8 | 9 | 10 | 11 | 12 |

13 | 14 |

15 | 16 | 17 | 18 |

19 | 20 |

21 | 22 | 📜 Documentation 23 | 24 |

25 | 26 | https://github.com/user-attachments/assets/767fd181-4122-49c8-8a01-72d3d43dbe94 27 | 28 | ## Features 29 | 30 | - 🎨 Highlight Output 31 | - 📝 Prefix and Suffix 32 | - 🔦 Launch Editor 33 | - 🚚 Pass Logs 34 | - 🔍 Console Inspector 35 | 36 | ## ❤️ Credits 37 | 38 | Thanks these awesome project: 39 | 40 | [babel-plugin-enhance-log](https://github.com/baozouai/babel-plugin-enhance-log) 41 | 42 | [turbo-console-log](https://github.com/Chakroun-Anas/turbo-console-log) 43 | 44 | [vite-plugin-console-line](https://github.com/lq9958/vite-plugin-console-line) 45 | 46 | [vite-plugin-terminal](https://github.com/patak-dev/vite-plugin-terminal) 47 | 48 | [Nuxt's server logs feature](https://nuxt.com/blog/v3-11#better-logging) 49 | -------------------------------------------------------------------------------- /client.d.ts: -------------------------------------------------------------------------------- 1 | declare module '~console' 2 | declare module '~console/theme-detect' 3 | declare module '~console/vue-devtools' 4 | -------------------------------------------------------------------------------- /client/app/app.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /client/app/assets/main.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | @custom-variant dark (&:where(.dark-mode, .dark-mode *)); 3 | @config "../tailwind.config.mjs"; 4 | 5 | 6 | html.dark-mode .shiki, 7 | html.dark-mode .shiki span { 8 | color: var(--shiki-dark) !important; 9 | background-color: #091a28!important; 10 | /* Optional, if you also want font styles */ 11 | font-style: var(--shiki-dark-font-style) !important; 12 | font-weight: var(--shiki-dark-font-weight) !important; 13 | text-decoration: var(--shiki-dark-text-decoration) !important; 14 | } 15 | 16 | body { 17 | background-color: #fff; 18 | color: rgba(0,0,0,0.8); 19 | } 20 | .dark-mode body { 21 | background-color: #091a28; 22 | color: #ebf4f1; 23 | } 24 | .sepia-mode body { 25 | background-color: #f1e7d0; 26 | color: #433422; 27 | } 28 | 29 | .i-btn { 30 | @apply py-2 px-3 text-sm rounded-lg border border-gray-200 dark:border-gray-700 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-200 cursor-pointer text-gray-600; 31 | } 32 | 33 | .i-filter-btn { 34 | @apply px-2 py-1 text-sm rounded-full border border-gray-200 dark:border-gray-700 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-200 cursor-pointer text-gray-600 flex items-center gap-1; 35 | } 36 | 37 | .i-filter-btn-active { 38 | @apply bg-gray-50 dark:bg-gray-800 text-gray-800 dark:text-gray-300; 39 | } 40 | -------------------------------------------------------------------------------- /client/app/components/app-footer.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 17 | -------------------------------------------------------------------------------- /client/app/components/fileIcon.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 32 | -------------------------------------------------------------------------------- /client/app/components/header-info.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 24 | -------------------------------------------------------------------------------- /client/app/components/shiki.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 18 | -------------------------------------------------------------------------------- /client/app/components/ui/collapsible.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 46 | -------------------------------------------------------------------------------- /client/app/components/ui/tooltip.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 22 | -------------------------------------------------------------------------------- /client/app/composables/shiki.ts: -------------------------------------------------------------------------------- 1 | import js from '@shikijs/langs/javascript' 2 | import VitesseDark from '@shikijs/themes/vitesse-dark' 3 | import VitesseLight from '@shikijs/themes/vitesse-light' 4 | import { createHighlighterCoreSync } from 'shiki/core' 5 | import { createJavaScriptRegexEngine } from 'shiki/engine/javascript' 6 | 7 | export const shiki = createHighlighterCoreSync({ 8 | themes: [ 9 | VitesseLight, 10 | VitesseDark, 11 | ], 12 | langs: [js], 13 | engine: createJavaScriptRegexEngine(), 14 | }) 15 | -------------------------------------------------------------------------------- /client/app/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /client/app/pages/index.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 79 | -------------------------------------------------------------------------------- /client/app/tailwind.config.mjs: -------------------------------------------------------------------------------- 1 | import { blackA, grass, green, mauve } from '@radix-ui/colors' 2 | 3 | /** @type {import('tailwindcss').Config} */ 4 | module.exports = { 5 | content: ['./**/*.vue'], 6 | theme: { 7 | extend: { 8 | colors: { 9 | ...blackA, 10 | ...green, 11 | ...grass, 12 | ...mauve, 13 | }, 14 | }, 15 | }, 16 | plugins: [], 17 | } 18 | -------------------------------------------------------------------------------- /client/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import tailwindcss from '@tailwindcss/vite' 2 | import { defineNuxtConfig } from 'nuxt/config' 3 | 4 | export default defineNuxtConfig({ 5 | compatibilityDate: '2024-11-01', 6 | devtools: { enabled: true }, 7 | ssr: false, 8 | future: { 9 | compatibilityVersion: 4, 10 | }, 11 | css: ['./app/assets/main.css'], 12 | nitro: { 13 | preset: 'static', 14 | output: { 15 | dir: '../dist/client', 16 | }, 17 | experimental: { 18 | websocket: true, 19 | }, 20 | }, 21 | modules: [ 22 | 'reka-ui/nuxt', 23 | '@nuxtjs/color-mode', 24 | '@nuxt/icon', 25 | '@vueuse/nuxt', 26 | ], 27 | icon: { 28 | clientBundle: { 29 | scan: true, 30 | }, 31 | }, 32 | colorMode: { 33 | preference: 'dark', 34 | }, 35 | vite: { 36 | plugins: [ 37 | tailwindcss(), 38 | ], 39 | }, 40 | app: { 41 | head: { 42 | link: [{ rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' }], 43 | }, 44 | }, 45 | }) 46 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "type": "module", 4 | "version": "1.0.0", 5 | "private": true, 6 | "packageManager": "pnpm@10.5.2", 7 | "description": "", 8 | "author": "", 9 | "license": "ISC", 10 | "keywords": [], 11 | "main": "index.js", 12 | "scripts": { 13 | "dev": "nuxi dev", 14 | "build": "nuxi build" 15 | }, 16 | "devDependencies": { 17 | "@iconify-json/carbon": "^1.2.8", 18 | "@iconify-json/catppuccin": "^1.2.10", 19 | "@iconify-json/ph": "^1.2.2", 20 | "@iconify-json/uil": "^1.2.3", 21 | "@nuxt/icon": "^1.11.0", 22 | "@nuxtjs/color-mode": "^3.5.2", 23 | "@radix-ui/colors": "^3.0.0", 24 | "@vueuse/core": "^13.0.0", 25 | "@vueuse/nuxt": "^13.0.0", 26 | "add": "^2.0.6", 27 | "nuxt": "catalog:", 28 | "pnpm": "^10.7.0", 29 | "reka-ui": "^2.0.2", 30 | "shiki": "^3.2.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /client/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /client/server/routes/launchEditor.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(async () => { 2 | return { 3 | status: 'success', 4 | version: '1.0.0', 5 | message: 'Hello, world!', 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /client/server/routes/ws/inspector.ts: -------------------------------------------------------------------------------- 1 | const defaultMessage = { 2 | timestamp: Date.now(), 3 | expressionsMap: { 4 | 'src/App.vue': { 5 | id: '1', 6 | filePath: 7 | '/Users/yuyin/Projects/github/unplugin/unplugin-turbo-console/examples/vite-vue3/src/App.vue', 8 | expressions: [ 9 | { code: '\'from vue\'', method: 'log', line: 7, column: 2 }, 10 | ], 11 | }, 12 | 'src/jsLog.js': { 13 | id: '2', 14 | filePath: 15 | '/Users/yuyin/Projects/github/unplugin/unplugin-turbo-console/examples/vite-vue3/src/jsLog.js', 16 | expressions: [ 17 | { code: '\'from js\'', method: 'info', line: 2, column: 2 }, 18 | { code: '\'from js\'', method: 'warn', line: 4, column: 2 }, 19 | { code: '\'from js\'', method: 'error', line: 6, column: 2 }, 20 | { code: '\'from js\'', method: 'log', line: 8, column: 2 }, 21 | ], 22 | }, 23 | 'src/tsLog.ts': { 24 | id: '3', 25 | filePath: 26 | '/Users/yuyin/Projects/github/unplugin/unplugin-turbo-console/examples/vite-vue3/src/tsLog.ts', 27 | expressions: [ 28 | { code: 'abc', method: 'log', line: 3, column: 2 }, 29 | { code: 'def', method: 'log', line: 6, column: 2 }, 30 | { code: 'mno', method: 'log', line: 15, column: 8 }, 31 | ], 32 | }, 33 | }, 34 | version: '1.11.3', 35 | } 36 | 37 | export default defineWebSocketHandler({ 38 | open(peer) { 39 | peer.send(JSON.stringify(defaultMessage)) 40 | }, 41 | }) 42 | -------------------------------------------------------------------------------- /client/shared/types.ts: -------------------------------------------------------------------------------- 1 | export interface ExpressionItem { 2 | code: string 3 | method: string 4 | line: number 5 | column: number 6 | } 7 | 8 | export interface ExpressionsMap { 9 | [key: string]: { 10 | id: string 11 | filePath: string 12 | expressions: ExpressionItem[] 13 | } 14 | } 15 | export interface ExpressionsMapResponse { 16 | timestamp: number 17 | status: 'success' | 'error' 18 | expressionsMap: ExpressionsMap 19 | version: string 20 | } 21 | -------------------------------------------------------------------------------- /client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /docs/.vitepress/components/DefaultTag.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /docs/.vitepress/components/HomePage.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /docs/.vitepress/components/TypeTag.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 31 | -------------------------------------------------------------------------------- /docs/.vitepress/config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { transformerTwoslash } from '@shikijs/vitepress-twoslash' 3 | import Unocss from 'unocss/vite' 4 | import Components from 'unplugin-vue-components/vite' 5 | import { defineConfig } from 'vitepress' 6 | import { groupIconMdPlugin, groupIconVitePlugin, localIconLoader } from 'vitepress-plugin-group-icons' 7 | import { enUS } from './enUS' 8 | import { zhCN } from './zhCN' 9 | 10 | const docsLink = 'https://utc.yuy1n.io' 11 | 12 | // https://vitepress.dev/reference/site-config 13 | export default defineConfig({ 14 | locales: { 15 | 'root': { 16 | label: 'English', 17 | lang: 'en-US', 18 | ...enUS, 19 | }, 20 | 'zh-CN': { 21 | label: '简体中文', 22 | lang: 'zh-CN', 23 | link: '/zh-CN/', 24 | ...zhCN, 25 | }, 26 | }, 27 | themeConfig: { 28 | search: { 29 | provider: 'local', 30 | }, 31 | socialLinks: [ 32 | { icon: 'github', link: 'https://github.com/unplugin/unplugin-turbo-console' }, 33 | ], 34 | }, 35 | markdown: { 36 | codeTransformers: [ 37 | transformerTwoslash(), 38 | ], 39 | image: { 40 | lazyLoading: true, 41 | }, 42 | config(md) { 43 | md.use(groupIconMdPlugin) 44 | }, 45 | }, 46 | head: [ 47 | ['meta', { property: 'og:title', content: 'Unplugin Turbo Console' }], 48 | ['meta', { property: 'og:description', content: 'Improve the Developer Experience of console' }], 49 | ['meta', { property: 'og:image', content: `${docsLink}/og.png` }], 50 | ['meta', { property: 'og:type', content: 'website' }], 51 | ['meta', { property: 'og:url', content: docsLink }], 52 | ['meta', { property: 'twitter:card', content: 'summary_large_image' }], 53 | ['meta', { property: 'twitter:image', content: `${docsLink}/og.png` }], 54 | ['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }], 55 | ['meta', { name: 'theme-color', content: '#4FC08D' }], 56 | ], 57 | vite: { 58 | plugins: [ 59 | groupIconVitePlugin({ 60 | customIcon: { 61 | rspack: localIconLoader(import.meta.url, './assets/icons/rspack.svg'), 62 | farm: localIconLoader(import.meta.url, './assets/icons/farm.svg'), 63 | }, 64 | }), 65 | Unocss(), 66 | Components({ 67 | dirs: [resolve(__dirname, './components')], 68 | extensions: ['vue', 'md'], 69 | include: [/\.vue$/, /\.vue\?vue/, /\.md$/], 70 | }) as any, 71 | ], 72 | }, 73 | }) 74 | -------------------------------------------------------------------------------- /docs/.vitepress/enUS.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress' 2 | 3 | export const enUS = defineConfig({ 4 | lang: 'en-US', 5 | title: 'Unplugin Turbo Console', 6 | description: 'Improve the Developer Experience of console', 7 | themeConfig: { 8 | nav: [ 9 | { text: 'Guide', link: '/guide/getting-started', activeMatch: '/guide' }, 10 | { text: 'Features', link: '/features/highlight', activeMatch: '/features' }, 11 | ], 12 | sidebar: [ 13 | { 14 | text: 'Guide', 15 | items: [ 16 | { text: 'Getting Started', link: '/guide/getting-started' }, 17 | { text: 'Configurations', link: '/guide/configurations' }, 18 | { text: 'Migration', link: '/guide/migration' }, 19 | ], 20 | }, 21 | { 22 | text: 'Features', 23 | items: [ 24 | { text: '🎨 Highlight Output', link: '/features/highlight' }, 25 | { text: '📝 Prefix & Suffix', link: '/features/custom-prefix' }, 26 | { text: '🔦 Launch Editor', link: '/features/launch-editor' }, 27 | { text: '🚚 Pass Logs', link: '/features/pass-logs' }, 28 | { text: '🔍 Console Inspector', link: '/features/inspector' }, 29 | ], 30 | }, 31 | { 32 | text: 'Others', 33 | items: [ 34 | { text: 'Troubleshooting', link: '/troubleshooting' }, 35 | ], 36 | }, 37 | ], 38 | footer: { 39 | message: 'Made with ❤️', 40 | copyright: 41 | 'MIT License © 2023-PRESENT yuyinws', 42 | }, 43 | search: { 44 | provider: 'local', 45 | }, 46 | }, 47 | }) 48 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/Layout.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 52 | 53 | 78 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import type { EnhanceAppContext } from 'vitepress' 2 | import TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client' 3 | import Theme from 'vitepress/theme' 4 | import Layout from './Layout.vue' 5 | import './style.css' 6 | import 'uno.css' 7 | import '@shikijs/vitepress-twoslash/style.css' 8 | import 'virtual:group-icons.css' 9 | 10 | export default { 11 | ...Theme, 12 | Layout, 13 | enhanceApp({ app }: EnhanceAppContext) { 14 | app.use(TwoslashFloatingVue) 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Colors 3 | * -------------------------------------------------------------------------- */ 4 | 5 | :root { 6 | --vp-c-brand: #0e7490; 7 | --vp-c-brand-light: #0891b2; 8 | --vp-c-brand-lighter: #22d3ee; 9 | --vp-c-brand-lightest: #67e8f9; 10 | --vp-c-brand-dark: #0e7490; 11 | --vp-c-brand-darker: #164e63; 12 | --vp-c-brand-dimm: rgba(145, 71, 150, 0.08); 13 | 14 | --vp-local-search-highlight-bg: var(--vp-c-brand-light); 15 | --vp-local-search-highlight-text: var(--vp-c-bg); 16 | } 17 | 18 | /** 19 | * Component: Button 20 | * -------------------------------------------------------------------------- */ 21 | 22 | :root { 23 | --vp-button-brand-border: var(--vp-c-brand-light); 24 | --vp-button-brand-bg: var(--vp-c-brand); 25 | --vp-button-brand-hover-border: var(--vp-c-brand-light); 26 | --vp-button-brand-hover-bg: var(--vp-c-brand-light); 27 | --vp-button-brand-active-border: var(--vp-c-brand-light); 28 | --vp-button-brand-active-bg: var(--vp-button-brand-bg); 29 | --vp-button-brand-text: #eee; 30 | } 31 | 32 | /** 33 | * Component: Home 34 | * -------------------------------------------------------------------------- */ 35 | 36 | :root { 37 | --vp-home-hero-name-color: transparent; 38 | --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #4FC08D 30%, #41d1ff); 39 | 40 | --vp-home-hero-image-background-image: linear-gradient(-45deg, #4FC08D 50%, #47caff 50%); 41 | --vp-home-hero-image-filter: blur(44px); 42 | } 43 | 44 | 45 | @media (min-width: 640px) { 46 | :root { 47 | --vp-home-hero-image-filter: blur(56px); 48 | } 49 | } 50 | 51 | @media (min-width: 960px) { 52 | :root { 53 | --vp-home-hero-image-filter: blur(68px); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /docs/.vitepress/types.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | 6 | const component: DefineComponent 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /docs/.vitepress/zhCN.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress' 2 | 3 | export const zhCN = defineConfig({ 4 | lang: 'zh-CN', 5 | title: 'Unplugin Turbo Console', 6 | description: '增强 Console 的开发者体验', 7 | themeConfig: { 8 | nav: [ 9 | { text: '指南', link: '/zh-CN/guide/getting-started', activeMatch: '/zh-CN/guide' }, 10 | { text: '特性', link: '/zh-CN/features/highlight', activeMatch: '/zh-CN/features' }, 11 | ], 12 | sidebar: [ 13 | { 14 | text: '指南', 15 | items: [ 16 | { text: '入门', link: '/zh-CN/guide/getting-started' }, 17 | { text: '配置', link: '/zh-CN/guide/configurations' }, 18 | { text: '迁移', link: '/zh-CN/guide/migration' }, 19 | ], 20 | }, 21 | { 22 | text: '特性', 23 | items: [ 24 | { text: '🎨 高亮输出', link: '/zh-CN/features/highlight' }, 25 | { text: '📝 前后缀', link: '/zh-CN/features/custom-prefix' }, 26 | { text: '🔦 编辑器跳转', link: '/zh-CN/features/launch-editor' }, 27 | { text: '🚚 传递日志', link: '/zh-CN/features/pass-logs' }, 28 | { text: '🔍 Console Inspector', link: '/zh-CN/features/inspector' }, 29 | ], 30 | }, 31 | { 32 | text: '其他', 33 | items: [ 34 | { text: '常见问题', link: '/zh-CN/troubleshooting' }, 35 | ], 36 | }, 37 | ], 38 | search: { 39 | provider: 'local', 40 | options: { 41 | translations: { 42 | button: { 43 | buttonText: '搜索文档', 44 | buttonAriaLabel: '搜索文档', 45 | }, 46 | modal: { 47 | noResultsText: '没有找到结果', 48 | footer: { 49 | selectText: '选择', 50 | navigateText: '切换', 51 | closeText: '关闭', 52 | }, 53 | }, 54 | }, 55 | }, 56 | }, 57 | footer: { 58 | message: '用 ❤️ 发电', 59 | copyright: 60 | 'MIT License © 2023-PRESENT yuyinws', 61 | }, 62 | docFooter: { 63 | prev: '上一页', 64 | next: '下一页', 65 | }, 66 | outline: { 67 | label: '页面导航', 68 | }, 69 | }, 70 | }) 71 | -------------------------------------------------------------------------------- /docs/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | // Generated by unplugin-vue-components 4 | // Read more: https://github.com/vuejs/core/pull/3399 5 | // biome-ignore lint: disable 6 | export {} 7 | 8 | /* prettier-ignore */ 9 | declare module 'vue' { 10 | export interface GlobalComponents { 11 | DefaultTag: typeof import('./.vitepress/components/DefaultTag.vue')['default'] 12 | HomePage: typeof import('./.vitepress/components/HomePage.vue')['default'] 13 | RouterLink: typeof import('vue-router')['RouterLink'] 14 | RouterView: typeof import('vue-router')['RouterView'] 15 | TypeTag: typeof import('./.vitepress/components/TypeTag.vue')['default'] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /docs/features/custom-prefix.md: -------------------------------------------------------------------------------- 1 | # Prefix & Suffix 2 | 3 | By configuring the `prefix` and `suffix` options, you can customize the prefix and suffix in the Console output: 4 | 5 | ![custom-prefix](/features/prefix.png) 6 | 7 | > This feature also takes effect at build time. 8 | 9 | ## Options 10 | 11 | ```js 12 | TurboConsole({ 13 | prefix: '👇👇👇👇👇', 14 | suffix: '👆👆👆👆👆' 15 | }) 16 | ``` 17 | -------------------------------------------------------------------------------- /docs/features/highlight.md: -------------------------------------------------------------------------------- 1 | # Highlight Output 2 | 3 | Highlight Console output based on file types (such as `.js(x)`, `.ts(x)`, `.vue`, `.svelte`, `.astro`). It includes filename, line number, variable name. 4 | 5 | ![feature-highlight](/features/highlight.png) 6 | 7 | ## Expand path file name 8 | 9 | Consider having a project file directory as follows: 10 | 11 | ``` 12 | pages 13 | ├── bar 14 | │ └── index.vue 15 | ├── foo 16 | │ └── index.vue 17 | └── index.vue 18 | ``` 19 | 20 | Additionally, in every `index.vue`, there is a console statement. By default, the highlighted output will have the filename as `index.vue`, which can reduce the readability of the output. By configuring `extendedPathFileNames: ['index']`, the output can include the path information: 21 | 22 | ![extend-name](/features/extend-name.png) 23 | 24 | ## Options 25 | 26 | ```ts 27 | // Disable highlight feature 28 | TurboConsole({ 29 | highlight: false, 30 | }) 31 | 32 | // Set extended path file names 33 | TurboConsole({ 34 | highlight: { 35 | extendedPathFileNames: ['index'], 36 | }, 37 | }) 38 | ``` 39 | 40 | ## Theme Detect 41 | 42 | When the system is in dark mode, optimize the visual effect of the highlight output. 43 | 44 | ![dark](/features/highlight-dark.png) 45 | 46 | ### Options 47 | 48 | ```ts 49 | TurboConsole({ 50 | highlight: { 51 | themeDetect: true, 52 | }, 53 | }) 54 | ``` 55 | 56 | Introduce `~console/theme-detect` to your project entry file. Example: 57 | 58 | ::: code-group 59 | 60 | ```ts [Vite] 61 | // main.ts 62 | import '~console/theme-detect' 63 | ``` 64 | 65 | ```vue [Nuxt] 66 | 67 | 70 | ``` 71 | 72 | ::: 73 | 74 | > [TypeScript configuration](/guide/configurations.html#typescript) 75 | -------------------------------------------------------------------------------- /docs/features/inspector.md: -------------------------------------------------------------------------------- 1 | # Console Inspector 2 | 3 | It enables real-time monitoring of console statements and with launch editor support. 4 | 5 |