mirror of
https://github.com/lush2020/edgetunnel.git
synced 2026-03-24 00:48:39 +08:00
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -1,5 +1,9 @@
|
||||
{
|
||||
"deno.codeLens.implementations": true,
|
||||
"deno.codeLens.references": true,
|
||||
"deno.enablePaths": ["apps/deno-bypass", "apps/deno-vless"]
|
||||
"deno.enablePaths": [
|
||||
"apps/deno-bypass",
|
||||
"apps/deno-vless/src/deno",
|
||||
"apps/deno-vless/src/main.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
|
||||
18
apps/deno-vless/index.html
Normal file
18
apps/deno-vless/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Edge Tunnel VLESS Deno</title>
|
||||
<base href="/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/index.tsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,16 +0,0 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'deno-vless',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
},
|
||||
},
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': 'ts-jest',
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||
coverageDirectory: '../../coverage/apps/deno-vless',
|
||||
};
|
||||
15
apps/deno-vless/postcss.config.js
Normal file
15
apps/deno-vless/postcss.config.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const { join } = require('path');
|
||||
|
||||
// Note: If you use library-specific PostCSS/Tailwind configuration then you should remove the `postcssConfig` build
|
||||
// option from your application's configuration (i.e. project.json).
|
||||
//
|
||||
// See: https://nx.dev/guides/using-tailwind-css-in-react#step-4:-applying-configuration-to-libraries
|
||||
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {
|
||||
config: join(__dirname, 'tailwind.config.js'),
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
@@ -4,16 +4,53 @@
|
||||
"sourceRoot": "apps/deno-vless/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"run": {
|
||||
"executor": "nx:run-commands",
|
||||
"build": {
|
||||
"executor": "@nrwl/vite:build",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"defaultConfiguration": "production",
|
||||
"options": {
|
||||
"command": "deno run --allow-net --allow-env --allow-write apps/deno-vless/src/main.ts "
|
||||
"outputPath": "apps/deno-vless/src/client"
|
||||
},
|
||||
"configurations": {
|
||||
"development": {},
|
||||
"production": {}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/vite:dev-server",
|
||||
"defaultConfiguration": "development",
|
||||
"options": {
|
||||
"buildTarget": "deno-vless:build"
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"buildTarget": "deno-vless:build:development",
|
||||
"hmr": true
|
||||
},
|
||||
"production": {
|
||||
"buildTarget": "deno-vless:build:production",
|
||||
"hmr": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-deno": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"command": "deno run --allow-net --allow-write --allow-env --watch apps/deno-vless/src/main.ts "
|
||||
"command": "deno run --allow-net --allow-read --allow-write --allow-env --watch apps/deno-vless/src/main.ts"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nrwl/vite:test",
|
||||
"outputs": ["{projectRoot}/coverage"],
|
||||
"options": {
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["apps/deno-vless/**/*.{ts,tsx,js,jsx}"]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
BIN
apps/deno-vless/public/favicon.ico
Normal file
BIN
apps/deno-vless/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
17
apps/deno-vless/src/app/app.spec.tsx
Normal file
17
apps/deno-vless/src/app/app.spec.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import App from './app';
|
||||
|
||||
describe('App', () => {
|
||||
it('should render successfully', () => {
|
||||
const { baseElement } = render(<App />);
|
||||
|
||||
expect(baseElement).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have a greeting as the title', () => {
|
||||
const { getByText } = render(<App />);
|
||||
|
||||
expect(getByText(/Welcome test-app/gi)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
175
apps/deno-vless/src/app/app.tsx
Normal file
175
apps/deno-vless/src/app/app.tsx
Normal file
@@ -0,0 +1,175 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { ExclamationTriangleIcon } from '@heroicons/react/20/solid';
|
||||
import QRCode from 'qrcode';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { validate as uuidValidate } from 'uuid';
|
||||
export function App() {
|
||||
const [text, setText] = useState('');
|
||||
function handleShare(text: string) {
|
||||
setText(text);
|
||||
}
|
||||
return (
|
||||
<div className="flex flex-col h-screen">
|
||||
<Warning></Warning>
|
||||
<div className="flex flex-col items-center h-full">
|
||||
<QRcodeImg text={text}></QRcodeImg>
|
||||
<Actions handleShare={handleShare}></Actions>
|
||||
<Anything handleShare={handleShare}></Anything>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ClipboardCopy(text: string) {}
|
||||
function QRcodeImg({ text }: { text: string }) {
|
||||
const [codeImg, setcodeImg] = useState('');
|
||||
const [copy, setCopy] = useState(false);
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (text) {
|
||||
const dataURL = await QRCode.toDataURL(text);
|
||||
setcodeImg(dataURL);
|
||||
}
|
||||
})();
|
||||
}, [text]);
|
||||
|
||||
async function copyText() {
|
||||
await navigator.clipboard.writeText(text);
|
||||
setCopy(true);
|
||||
setTimeout(() => {
|
||||
setCopy(false);
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col border border-blue-300 overflow-hidden w-[400px] h-[400px] justify-start items-center">
|
||||
<img
|
||||
src={codeImg}
|
||||
width="350"
|
||||
height="350"
|
||||
alt="code"
|
||||
className="border-spacing-1"
|
||||
/>
|
||||
<div className="flex flex-grow w-full bg-gray-200">
|
||||
<span className="flex-grow ">{text}</span>
|
||||
<div className="w-6 h-6 ml-auto">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
onClick={copyText}
|
||||
className={`w-6 h-6 hover:cursor-pointer hover:border hover:border-indigo-500 ${
|
||||
copy ? 'hidden' : 'block'
|
||||
}`}
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M8.25 7.5V6.108c0-1.135.845-2.098 1.976-2.192.373-.03.748-.057 1.123-.08M15.75 18H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08M15.75 18.75v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5A3.375 3.375 0 006.375 7.5H5.25m11.9-3.664A2.251 2.251 0 0015 2.25h-1.5a2.251 2.251 0 00-2.15 1.586m5.8 0c.065.21.1.433.1.664v.75h-6V4.5c0-.231.035-.454.1-.664M6.75 7.5H4.875c-.621 0-1.125.504-1.125 1.125v12c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V16.5a9 9 0 00-9-9z"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
className={`w-6 h-6 hover:border hover:border-indigo-500 ${
|
||||
copy ? 'block bg-green-300' : 'hidden'
|
||||
}`}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
function Anything({ handleShare }: { handleShare: (text: string) => void }) {
|
||||
const [text, setText] = useState('');
|
||||
return (
|
||||
<div className="mt-4 w-60">
|
||||
<label
|
||||
htmlFor="comment"
|
||||
className="block text-sm font-medium text-gray-700"
|
||||
>
|
||||
随意要分享的内容
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<textarea
|
||||
rows={4}
|
||||
name="comment"
|
||||
id="comment"
|
||||
className="block w-full border border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
value={text}
|
||||
onChange={(e) => setText(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end mt-2">
|
||||
<button
|
||||
onClick={() => handleShare(text)}
|
||||
type="submit"
|
||||
className="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-transparent rounded-md shadow-sm hover:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
>
|
||||
分享
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Actions({ handleShare }: { handleShare: (text: string) => void }) {
|
||||
function getPageURL() {
|
||||
return window.location.href;
|
||||
}
|
||||
function getVlessURL() {
|
||||
const url = new URL(window.location.href);
|
||||
const uuid = url.pathname.split('/').find(uuidValidate);
|
||||
return `vless://${uuid}@${url.hostname}:443?encryption=none&security=tls&type=ws#deno-vless`;
|
||||
}
|
||||
return (
|
||||
<span className="inline-flex rounded-md shadow-sm isolate">
|
||||
<button
|
||||
onClick={() => handleShare(getPageURL())}
|
||||
type="button"
|
||||
className="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-l-md hover:border-indigo-500 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
||||
>
|
||||
分享本页
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleShare(getVlessURL())}
|
||||
type="button"
|
||||
className="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 hover:bg-gray-50 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
||||
>
|
||||
分享 V2ray
|
||||
</button>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function Warning() {
|
||||
return (
|
||||
<div className="flex justify-center p-4 rounded-md bg-yellow-50">
|
||||
<div className="flex">
|
||||
<div className="flex-shrink-0">
|
||||
<ExclamationTriangleIcon
|
||||
className="w-5 h-5 text-red-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h3 className="text-sm font-medium text-yellow-800">注意!!</h3>
|
||||
<div className="mt-2 text-sm text-yellow-700">
|
||||
<p>泄露本页面就等于泄露你的设置。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
1
apps/deno-vless/src/client/assets/index.d7b429b2.css
Normal file
1
apps/deno-vless/src/client/assets/index.d7b429b2.css
Normal file
File diff suppressed because one or more lines are too long
47
apps/deno-vless/src/client/assets/index.e8995bcc.js
Normal file
47
apps/deno-vless/src/client/assets/index.e8995bcc.js
Normal file
File diff suppressed because one or more lines are too long
BIN
apps/deno-vless/src/client/favicon.ico
Normal file
BIN
apps/deno-vless/src/client/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
20
apps/deno-vless/src/client/index.html
Normal file
20
apps/deno-vless/src/client/index.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Edge Tunnel VLESS Deno</title>
|
||||
<base href="/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<script type="module" crossorigin src="/assets/index.e8995bcc.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index.d7b429b2.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
37
apps/deno-vless/src/deno/client.ts
Normal file
37
apps/deno-vless/src/deno/client.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {
|
||||
serveDir,
|
||||
serveFile,
|
||||
} from 'https://deno.land/std@0.167.0/http/file_server.ts';
|
||||
async function serveClient(req: Request, basePath: string) {
|
||||
for await (const entry of Deno.readDir('.')) {
|
||||
console.log(entry);
|
||||
}
|
||||
const pathname = new URL(req.url).pathname;
|
||||
if (pathname.startsWith('/assets')) {
|
||||
return await serveDir(req, {
|
||||
fsRoot: `${Deno.cwd()}/apps/deno-vless/src/client`,
|
||||
});
|
||||
}
|
||||
if (pathname.includes(basePath)) {
|
||||
return await serveFile(
|
||||
req,
|
||||
`${Deno.cwd()}/apps/deno-vless/src/client/index.html`
|
||||
);
|
||||
// Do dynamic responses
|
||||
// const indexHtml = await Deno.readFile(`${Deno.cwd()}/client/index.html`);
|
||||
// return new Response(indexHtml, {
|
||||
// headers: {
|
||||
// 'content-type': 'text/html; charset=utf-8',
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
return new Response(``, {
|
||||
status: 404,
|
||||
headers: {
|
||||
'content-type': 'text/html; charset=utf-8',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export { serveClient };
|
||||
@@ -1,3 +0,0 @@
|
||||
export const environment = {
|
||||
production: true,
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
export const environment = {
|
||||
production: false,
|
||||
};
|
||||
13
apps/deno-vless/src/index.tsx
Normal file
13
apps/deno-vless/src/index.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import { StrictMode } from 'react';
|
||||
import * as ReactDOM from 'react-dom/client';
|
||||
import App from './app/app';
|
||||
import './styles.css';
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
root.render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
);
|
||||
@@ -1,17 +1,14 @@
|
||||
import { serve } from 'https://deno.land/std@0.167.0/http/server.ts';
|
||||
import { parse, stringify, validate } from 'https://jspm.dev/uuid';
|
||||
import { chunk, join } from 'https://jspm.dev/lodash-es';
|
||||
import { serveClient } from './deno/client.ts';
|
||||
|
||||
const userID = Deno.env.get('UUID');
|
||||
|
||||
if (!validate(userID)) {
|
||||
console.log('not valid userID');
|
||||
}
|
||||
const userID = Deno.env.get('UUID') || '';
|
||||
|
||||
const handler = async (req: Request): Promise<Response> => {
|
||||
const upgrade = req.headers.get('upgrade') || '';
|
||||
if (upgrade.toLowerCase() != 'websocket') {
|
||||
return new Response("request isn't trying to upgrade to websocket.");
|
||||
return await serveClient(req, userID);
|
||||
}
|
||||
const { socket, response } = Deno.upgradeWebSocket(req);
|
||||
let remoteConnection: Deno.TcpConn;
|
||||
|
||||
3
apps/deno-vless/src/styles.css
Normal file
3
apps/deno-vless/src/styles.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind components;
|
||||
@tailwind base;
|
||||
@tailwind utilities;
|
||||
17
apps/deno-vless/tailwind.config.js
Normal file
17
apps/deno-vless/tailwind.config.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const { createGlobPatternsForDependencies } = require('@nrwl/react/tailwind');
|
||||
const { join } = require('path');
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
join(
|
||||
__dirname,
|
||||
'{src,pages,components}/**/*!(*.stories|*.spec).{ts,tsx,html}'
|
||||
),
|
||||
...createGlobPatternsForDependencies(__dirname),
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
@@ -2,9 +2,21 @@
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
"files": [
|
||||
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||
"../../node_modules/@nrwl/react/typings/image.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.test.jsx"
|
||||
],
|
||||
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": false,
|
||||
"esModuleInterop": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"types": ["vite/client"]
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
@@ -9,5 +16,6 @@
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
],
|
||||
"extends": "../../tsconfig.base.json"
|
||||
}
|
||||
|
||||
@@ -2,8 +2,22 @@
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
"types": ["vitest/globals", "node"]
|
||||
},
|
||||
"include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"files": [
|
||||
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||
"../../node_modules/@nrwl/react/typings/image.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
26
apps/deno-vless/vite.config.ts
Normal file
26
apps/deno-vless/vite.config.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/// <reference types="vitest" />
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import viteTsConfigPaths from 'vite-tsconfig-paths';
|
||||
|
||||
export default defineConfig({
|
||||
server: {
|
||||
port: 4200,
|
||||
host: 'localhost',
|
||||
},
|
||||
plugins: [
|
||||
react(),
|
||||
viteTsConfigPaths({
|
||||
root: '../../',
|
||||
}),
|
||||
],
|
||||
|
||||
test: {
|
||||
globals: true,
|
||||
cache: {
|
||||
dir: '../../node_modules/.vitest',
|
||||
},
|
||||
environment: 'jsdom',
|
||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
},
|
||||
});
|
||||
@@ -39,5 +39,11 @@ https://raw.githubusercontent.com/zizifn/edgetunnel/main/doc/deno-deploy2.gif
|
||||
|
||||
## 项目地址
|
||||
|
||||
点击 View 项目会自动打开。
|
||||
记住项目地址,并且**留意返回的网站内容**,是否有提供缺少关键配置。
|
||||
点击 View 项目会自动打开。一开始返回 `404`. 不要慌张, 把你设置的 `UUID` 添加到 URL 后面。
|
||||
|
||||
下面是示例,请把 URL 和 UUID 换成自己的。
|
||||
`https://xxxxxx.deno.dev/015897c1-663d-4b2a-9f90-053b189cdc47`。
|
||||
|
||||
如果出现下面的界面,都代表一切正常。
|
||||
|
||||

|
||||
|
||||
BIN
doc/index.jpg
Normal file
BIN
doc/index.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
20
nx.json
20
nx.json
@@ -32,5 +32,23 @@
|
||||
],
|
||||
"sharedGlobals": []
|
||||
},
|
||||
"defaultProject": "edge-bypass-client"
|
||||
"defaultProject": "edge-bypass-client",
|
||||
"generators": {
|
||||
"@nrwl/react": {
|
||||
"application": {
|
||||
"style": "css",
|
||||
"linter": "eslint",
|
||||
"bundler": "vite",
|
||||
"babel": true
|
||||
},
|
||||
"component": {
|
||||
"style": "css"
|
||||
},
|
||||
"library": {
|
||||
"style": "css",
|
||||
"linter": "eslint",
|
||||
"unitTestRunner": "vitest"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9457
package-lock.json
generated
9457
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
39
package.json
39
package.json
@@ -9,30 +9,61 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.7.5",
|
||||
"@heroicons/react": "^2.0.13",
|
||||
"commander": "^9.4.1",
|
||||
"qrcode": "^1.5.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"tslib": "^2.3.0",
|
||||
"undici": "^5.13.0"
|
||||
"undici": "^5.13.0",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nrwl/cli": "15.2.4",
|
||||
"@nrwl/cypress": "^15.3.3",
|
||||
"@nrwl/eslint-plugin-nx": "15.2.4",
|
||||
"@nrwl/jest": "15.2.4",
|
||||
"@nrwl/jest": "^15.3.3",
|
||||
"@nrwl/linter": "15.2.4",
|
||||
"@nrwl/node": "15.2.4",
|
||||
"@nrwl/react": "15.3.3",
|
||||
"@nrwl/vite": "15.3.3",
|
||||
"@nrwl/webpack": "^15.3.3",
|
||||
"@nrwl/workspace": "15.2.4",
|
||||
"@testing-library/react": "13.4.0",
|
||||
"@types/jest": "28.1.1",
|
||||
"@types/node": "^18.11.10",
|
||||
"@types/node": "18.11.9",
|
||||
"@types/qrcode": "^1.5.0",
|
||||
"@types/react": "18.0.25",
|
||||
"@types/react-dom": "18.0.9",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
||||
"@typescript-eslint/parser": "^5.36.1",
|
||||
"@vitejs/plugin-react": "^2.2.0",
|
||||
"@vitest/coverage-c8": "~0.25.3",
|
||||
"@vitest/ui": "^0.9.3",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"eslint": "~8.15.0",
|
||||
"eslint-config-prettier": "8.1.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
"eslint-plugin-react": "7.31.11",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"jest": "28.1.1",
|
||||
"jest-environment-jsdom": "28.1.1",
|
||||
"jsdom": "~20.0.3",
|
||||
"nx": "15.2.4",
|
||||
"pkg": "^5.8.0",
|
||||
"postcss": "^8.4.20",
|
||||
"prettier": "^2.6.2",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"tailwindcss": "^3.2.4",
|
||||
"ts-jest": "28.0.5",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "~4.8.2"
|
||||
"typescript": "~4.8.2",
|
||||
"vite": "^3.0.5",
|
||||
"vite-plugin-eslint": "^1.6.0",
|
||||
"vite-tsconfig-paths": "^4.0.1",
|
||||
"vitest": "^0.25.1"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user