[mod]
This commit is contained in:
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
PORT = 3000
|
PORT = 4000
|
||||||
TZ = Asia/Taipei
|
TZ = Asia/Taipei
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.DS_STORE
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# TSRPC Server
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
### Local dev server
|
||||||
|
|
||||||
|
Dev server would restart automatically when code changed.
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generate API document
|
||||||
|
|
||||||
|
Generate API document in swagger/openapi and markdown format.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm run doc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run unit Test
|
||||||
|
Execute `npm run dev` first, then execute:
|
||||||
|
```
|
||||||
|
npm run test
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
Generated
+3699
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "TSRPC_Badminton-Scoreboard-backend",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "tsrpc-cli dev",
|
||||||
|
"build": "tsrpc-cli build",
|
||||||
|
"doc": "tsrpc-cli doc",
|
||||||
|
"test": "mocha test/**/*.test.ts",
|
||||||
|
"proto": "tsrpc-cli proto",
|
||||||
|
"sync": "tsrpc-cli sync",
|
||||||
|
"api": "tsrpc-cli api"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/mocha": "^8.2.3",
|
||||||
|
"@types/node": "^15.14.9",
|
||||||
|
"mocha": "^9.2.2",
|
||||||
|
"onchange": "^7.1.0",
|
||||||
|
"ts-node": "^10.7.0",
|
||||||
|
"tsrpc-cli": "^2.4.3",
|
||||||
|
"typescript": "^4.6.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dayjs": "^1.11.1",
|
||||||
|
"dotenv": "^16.0.0",
|
||||||
|
"tsrpc": "^3.3.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { ApiCall } from "tsrpc";
|
||||||
|
import { server } from "..";
|
||||||
|
import { ReqSend, ResSend } from "../shared/protocols/PtlSend";
|
||||||
|
|
||||||
|
// This is a demo code file
|
||||||
|
// Feel free to delete it
|
||||||
|
|
||||||
|
export async function ApiSend(call: ApiCall<ReqSend, ResSend>): Promise<void> {
|
||||||
|
// Error
|
||||||
|
if (call.req.content.length === 0) {
|
||||||
|
call.error("Content is empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
|
let time: Date = new Date();
|
||||||
|
call.succ({
|
||||||
|
time: time
|
||||||
|
});
|
||||||
|
|
||||||
|
// Broadcast
|
||||||
|
server.broadcastMsg("Chat", {
|
||||||
|
content: "Chat: " + call.req.content,
|
||||||
|
time: time
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import dayjs from "dayjs";
|
||||||
|
import { ApiCall } from "tsrpc";
|
||||||
|
import { server } from "../..";
|
||||||
|
import { Reqstart, Resstart } from "../../shared/protocols/lobby/Ptlstart";
|
||||||
|
|
||||||
|
export async function Apistart(call: ApiCall<Reqstart, Resstart>): Promise<void> {
|
||||||
|
// Error
|
||||||
|
// if (call.req.content.length === 0) {
|
||||||
|
// call.error("Content is empty");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Success
|
||||||
|
let time: Date = new Date();
|
||||||
|
let dayjstime: string = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
call.logger.log(`${dayjstime} Apistart`);
|
||||||
|
call.succ({
|
||||||
|
code: 1,
|
||||||
|
data: {
|
||||||
|
time: dayjstime
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Broadcast
|
||||||
|
server.broadcastMsg("lobby/B_start", {
|
||||||
|
time: time,
|
||||||
|
data: {
|
||||||
|
content: `${dayjstime}: B_start`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import dayjs from "dayjs";
|
||||||
|
import * as path from "path";
|
||||||
|
import { WsServer } from "tsrpc";
|
||||||
|
import { serviceProto, ServiceType } from "./shared/protocols/serviceProto";
|
||||||
|
require("dotenv").config();
|
||||||
|
require("dayjs/locale/zh-tw");
|
||||||
|
dayjs.locale("zh-tw");
|
||||||
|
|
||||||
|
// Create the Server
|
||||||
|
export const server: WsServer<ServiceType> = new WsServer(serviceProto, {
|
||||||
|
port: +process.env.PORT! || 3000,
|
||||||
|
// Remove this to use binary mode (remove from the client too)
|
||||||
|
json: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize before server start
|
||||||
|
async function init(): Promise<void> {
|
||||||
|
await server.autoImplementApi(path.resolve(__dirname, "api"));
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// let time: Date = new Date();
|
||||||
|
let time: string = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
console.log(`${time} Start Server`);
|
||||||
|
// Prepare something... (e.g. connect the db)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry function
|
||||||
|
async function main(): Promise<void> {
|
||||||
|
await init();
|
||||||
|
await server.start();
|
||||||
|
}
|
||||||
|
main();
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// This is a demo code file
|
||||||
|
// Feel free to delete it
|
||||||
|
|
||||||
|
export interface MsgChat {
|
||||||
|
content: string;
|
||||||
|
time: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// This is a demo code file
|
||||||
|
// Feel free to delete it
|
||||||
|
|
||||||
|
|
||||||
|
export interface ReqSend {
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResSend {
|
||||||
|
time: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
export interface BaseRequest {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseResponse {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseConf {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseMessage {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// This is a demo code file
|
||||||
|
// Feel free to delete it
|
||||||
|
|
||||||
|
export interface MsgB_start {
|
||||||
|
data: {
|
||||||
|
content: string
|
||||||
|
};
|
||||||
|
time: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// This is a demo code file
|
||||||
|
// Feel free to delete it
|
||||||
|
|
||||||
|
export interface Reqstart { }
|
||||||
|
|
||||||
|
export interface Resstart {
|
||||||
|
code: number; // 与 TSRPC 的错误处理重复
|
||||||
|
data: {
|
||||||
|
time: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
import { ServiceProto } from 'tsrpc-proto';
|
||||||
|
import { MsgB_start } from './lobby/MsgB_start';
|
||||||
|
import { Reqstart, Resstart } from './lobby/Ptlstart';
|
||||||
|
import { MsgChat } from './MsgChat';
|
||||||
|
import { ReqSend, ResSend } from './PtlSend';
|
||||||
|
|
||||||
|
export interface ServiceType {
|
||||||
|
api: {
|
||||||
|
"lobby/start": {
|
||||||
|
req: Reqstart,
|
||||||
|
res: Resstart
|
||||||
|
},
|
||||||
|
"Send": {
|
||||||
|
req: ReqSend,
|
||||||
|
res: ResSend
|
||||||
|
}
|
||||||
|
},
|
||||||
|
msg: {
|
||||||
|
"lobby/B_start": MsgB_start,
|
||||||
|
"Chat": MsgChat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const serviceProto: ServiceProto<ServiceType> = {
|
||||||
|
"version": 1,
|
||||||
|
"services": [
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"name": "lobby/B_start",
|
||||||
|
"type": "msg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "lobby/start",
|
||||||
|
"type": "api"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "Chat",
|
||||||
|
"type": "msg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"name": "Send",
|
||||||
|
"type": "api"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"types": {
|
||||||
|
"lobby/MsgB_start/MsgB_start": {
|
||||||
|
"type": "Interface",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"name": "data",
|
||||||
|
"type": {
|
||||||
|
"type": "Interface",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"name": "content",
|
||||||
|
"type": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "time",
|
||||||
|
"type": {
|
||||||
|
"type": "Date"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lobby/Ptlstart/Reqstart": {
|
||||||
|
"type": "Interface"
|
||||||
|
},
|
||||||
|
"lobby/Ptlstart/Resstart": {
|
||||||
|
"type": "Interface",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"name": "code",
|
||||||
|
"type": {
|
||||||
|
"type": "Number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "data",
|
||||||
|
"type": {
|
||||||
|
"type": "Interface",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"name": "time",
|
||||||
|
"type": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"MsgChat/MsgChat": {
|
||||||
|
"type": "Interface",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"name": "content",
|
||||||
|
"type": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "time",
|
||||||
|
"type": {
|
||||||
|
"type": "Date"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PtlSend/ReqSend": {
|
||||||
|
"type": "Interface",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"name": "content",
|
||||||
|
"type": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PtlSend/ResSend": {
|
||||||
|
"type": "Interface",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"name": "time",
|
||||||
|
"type": {
|
||||||
|
"type": "Date"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import assert from 'assert';
|
||||||
|
import { TsrpcError, WsClient } from 'tsrpc';
|
||||||
|
import { serviceProto } from '../../src/shared/protocols/serviceProto';
|
||||||
|
|
||||||
|
// 1. EXECUTE `npm run dev` TO START A LOCAL DEV SERVER
|
||||||
|
// 2. EXECUTE `npm test` TO START UNIT TEST
|
||||||
|
|
||||||
|
describe('ApiSend', function () {
|
||||||
|
let client = new WsClient(serviceProto, {
|
||||||
|
server: 'ws://127.0.0.1:3000',
|
||||||
|
json: true,
|
||||||
|
logger: console
|
||||||
|
});
|
||||||
|
|
||||||
|
before(async function () {
|
||||||
|
let res = await client.connect();
|
||||||
|
assert.strictEqual(res.isSucc, true, 'Failed to connect to server, have you executed `npm run dev` already?');
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Success', async function () {
|
||||||
|
let ret = await client.callApi('Send', {
|
||||||
|
content: 'Test'
|
||||||
|
});
|
||||||
|
assert.ok(ret.isSucc)
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Check content is empty', async function () {
|
||||||
|
let ret = await client.callApi('Send', {
|
||||||
|
content: ''
|
||||||
|
});
|
||||||
|
assert.deepStrictEqual(ret, {
|
||||||
|
isSucc: false,
|
||||||
|
err: new TsrpcError('Content is empty')
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
after(async function () {
|
||||||
|
await client.disconnect();
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": [
|
||||||
|
"es2018"
|
||||||
|
],
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es2018",
|
||||||
|
"outDir": "dist",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"moduleResolution": "node"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
".",
|
||||||
|
"../src"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { CodeTemplate, TsrpcConfig } from "tsrpc-cli";
|
||||||
|
|
||||||
|
const tsrpcConf: TsrpcConfig = {
|
||||||
|
// Generate ServiceProto
|
||||||
|
proto: [
|
||||||
|
{
|
||||||
|
ptlDir: "src/shared/protocols", // Protocol dir
|
||||||
|
output: "src/shared/protocols/serviceProto.ts", // Path for generated ServiceProto
|
||||||
|
apiDir: "src/api", // API dir
|
||||||
|
docDir: "docs", // API documents dir
|
||||||
|
ptlTemplate: CodeTemplate.getExtendedPtl(),
|
||||||
|
// msgTemplate: CodeTemplate.getExtendedMsg(),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// Sync shared code
|
||||||
|
sync: [
|
||||||
|
{
|
||||||
|
from: "src/shared",
|
||||||
|
to: "../frontend/src/shared",
|
||||||
|
type: "symlink" // Change this to 'copy' if your environment not support symlink
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// Dev server
|
||||||
|
dev: {
|
||||||
|
autoProto: true, // Auto regenerate proto
|
||||||
|
autoSync: true, // Auto sync when file changed
|
||||||
|
autoApi: true, // Auto create API when ServiceProto updated
|
||||||
|
watch: "src", // Restart dev server when these files changed
|
||||||
|
entry: "src/index.ts", // Dev server command: node -r ts-node/register {entry}
|
||||||
|
},
|
||||||
|
// Build config
|
||||||
|
build: {
|
||||||
|
autoProto: true, // Auto generate proto before build
|
||||||
|
autoSync: true, // Auto sync before build
|
||||||
|
autoApi: true, // Auto generate API before build
|
||||||
|
outDir: "dist", // Clean this dir before build
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default tsrpcConf;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
PORT = 4000
|
||||||
|
TZ = Asia/Taipei
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
module.exports = {
|
||||||
|
require: [
|
||||||
|
'ts-node/register',
|
||||||
|
],
|
||||||
|
timeout: 999999,
|
||||||
|
exit: true,
|
||||||
|
spec: [
|
||||||
|
'./test/**/*.test.ts'
|
||||||
|
],
|
||||||
|
'preserve-symlinks': true
|
||||||
|
}
|
||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "mocha current file",
|
||||||
|
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
|
||||||
|
"args": [
|
||||||
|
"${file}"
|
||||||
|
],
|
||||||
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "ts-node current file",
|
||||||
|
"protocol": "inspector",
|
||||||
|
"args": [
|
||||||
|
"${relativeFile}"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"runtimeArgs": [
|
||||||
|
"-r",
|
||||||
|
"ts-node/register"
|
||||||
|
],
|
||||||
|
"internalConsoleOptions": "openOnSessionStart"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
FROM node
|
||||||
|
|
||||||
|
# 使用淘宝 NPM 镜像(国内机器构建推荐启用)
|
||||||
|
# RUN npm config set registry https://registry.npm.taobao.org/
|
||||||
|
|
||||||
|
# npm install
|
||||||
|
ADD package*.json /src/
|
||||||
|
WORKDIR /src
|
||||||
|
RUN npm i
|
||||||
|
|
||||||
|
# build
|
||||||
|
ADD . /src
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# clean
|
||||||
|
RUN npm prune --production
|
||||||
|
|
||||||
|
# move
|
||||||
|
RUN rm -rf /app \
|
||||||
|
&& mv dist /app \
|
||||||
|
&& mv node_modules /app/ \
|
||||||
|
&& rm -rf /src
|
||||||
|
|
||||||
|
# ENV
|
||||||
|
ENV NODE_ENV production
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
CMD node index.js
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": [
|
||||||
|
"es2018"
|
||||||
|
],
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es2018",
|
||||||
|
"outDir": "dist",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"moduleResolution": "node"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"defaultSeverity": "warning",
|
||||||
|
"rules": {
|
||||||
|
"ban": [
|
||||||
|
true,
|
||||||
|
[
|
||||||
|
"_",
|
||||||
|
"extend"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"_",
|
||||||
|
"isNull"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"_",
|
||||||
|
"isDefined"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"class-name": false,
|
||||||
|
"comment-format": [
|
||||||
|
true,
|
||||||
|
"check-space"
|
||||||
|
],
|
||||||
|
"curly": true,
|
||||||
|
"eofline": false,
|
||||||
|
"forin": false,
|
||||||
|
"indent": [
|
||||||
|
true,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"interface-name": [
|
||||||
|
true,
|
||||||
|
"never-prefix"
|
||||||
|
],
|
||||||
|
"jsdoc-format": true,
|
||||||
|
"label-position": true,
|
||||||
|
"label-undefined": true,
|
||||||
|
"max-line-length": [
|
||||||
|
false,
|
||||||
|
140
|
||||||
|
],
|
||||||
|
"no-arg": true,
|
||||||
|
"no-bitwise": false,
|
||||||
|
"no-console": [
|
||||||
|
true,
|
||||||
|
"debug",
|
||||||
|
"info",
|
||||||
|
"time",
|
||||||
|
"timeEnd",
|
||||||
|
"trace"
|
||||||
|
],
|
||||||
|
"no-construct": true,
|
||||||
|
"no-debugger": true,
|
||||||
|
"no-duplicate-key": true,
|
||||||
|
"no-duplicate-variable": true,
|
||||||
|
"no-empty": true,
|
||||||
|
// "no-eval": true,
|
||||||
|
"no-string-literal": false,
|
||||||
|
"no-trailing-comma": true,
|
||||||
|
"no-trailing-whitespace": true,
|
||||||
|
"no-unused-expression": false,
|
||||||
|
"no-unused-variable": true,
|
||||||
|
"no-unreachable": true,
|
||||||
|
"no-use-before-declare": false,
|
||||||
|
"one-line": [
|
||||||
|
true,
|
||||||
|
"check-open-brace",
|
||||||
|
"check-catch",
|
||||||
|
"check-else",
|
||||||
|
"check-whitespace"
|
||||||
|
],
|
||||||
|
"quotemark": [
|
||||||
|
true,
|
||||||
|
"double"
|
||||||
|
],
|
||||||
|
"radix": true,
|
||||||
|
"semicolon": [
|
||||||
|
true,
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"triple-equals": [
|
||||||
|
true,
|
||||||
|
"allow-null-check"
|
||||||
|
],
|
||||||
|
"typedef": [
|
||||||
|
true,
|
||||||
|
"call-signature",
|
||||||
|
"parameter",
|
||||||
|
"property-declaration",
|
||||||
|
"variable-declaration"
|
||||||
|
],
|
||||||
|
"typedef-whitespace": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"call-signature": "nospace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index-signature": "space"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"use-strict": [
|
||||||
|
true,
|
||||||
|
"check-module",
|
||||||
|
"check-function"
|
||||||
|
],
|
||||||
|
"variable-name": false,
|
||||||
|
"whitespace": [
|
||||||
|
false,
|
||||||
|
"check-branch",
|
||||||
|
"check-decl",
|
||||||
|
"check-operator",
|
||||||
|
"check-separator",
|
||||||
|
"check-type"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Vue 3 + TypeScript + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
||||||
|
|
||||||
|
## Type Support For `.vue` Imports in TS
|
||||||
|
|
||||||
|
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
|
||||||
|
|
||||||
|
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
|
||||||
|
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
|
||||||
|
|
||||||
|
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Generated
+33833
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc --noEmit && vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": "^3.22.4",
|
||||||
|
"tsrpc-browser": "^3.3.0",
|
||||||
|
"vue": "^3.2.25"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^2.3.1",
|
||||||
|
"typescript": "^4.5.4",
|
||||||
|
"vite": "^2.9.7",
|
||||||
|
"vue-tsc": "^0.34.7",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||||
|
"@typescript-eslint/parser": "^4.33.0",
|
||||||
|
"@vue/cli-plugin-babel": "^4.5.17",
|
||||||
|
"@vue/cli-plugin-eslint": "^4.5.17",
|
||||||
|
"@vue/cli-plugin-typescript": "^4.5.17",
|
||||||
|
"@vue/cli-service": "^4.5.17",
|
||||||
|
"@vue/compiler-sfc": "^3.2.33",
|
||||||
|
"@vue/eslint-config-typescript": "^7.0.0",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-plugin-vue": "^7.20.0",
|
||||||
|
"less": "^3.13.1",
|
||||||
|
"less-loader": "^5.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,23 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import Chatroom from "./Chatroom.vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "app",
|
||||||
|
components: {
|
||||||
|
Chatroom,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Chatroom title="Client #1" />
|
||||||
|
<Chatroom title="Client #2" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#app {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
<template>
|
||||||
|
<div class="Chatroom">
|
||||||
|
<header>{{ title }}</header>
|
||||||
|
<ul class="list" ref="ul">
|
||||||
|
<li v-for="(v, i) in list" :key="i">
|
||||||
|
<div class="content">{{ v.content }}</div>
|
||||||
|
<div class="time">{{ v.time.toLocaleTimeString() }}</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div> <button @click="connect">Connect</button><button @click="start">Start</button> </div>
|
||||||
|
<div class="send">
|
||||||
|
<input placeholder="Say something..." v-model="input" @keypress.enter="send" />
|
||||||
|
<button @click="send">Send</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, nextTick } from "vue";
|
||||||
|
import { getClient } from "./getClient";
|
||||||
|
import { Msgstart } from "./shared/protocols/lobby/Msgstart";
|
||||||
|
import { MsgChat } from "./shared/protocols/MsgChat";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "Chatroom",
|
||||||
|
props: {
|
||||||
|
title: String,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
input: "",
|
||||||
|
list: [] as MsgChat[],
|
||||||
|
client: getClient(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted(): void {
|
||||||
|
// Listen Msg
|
||||||
|
this.client.listenMsg("Chat", (v: MsgChat) => {
|
||||||
|
console.log("Chat")
|
||||||
|
this.list.push(v);
|
||||||
|
|
||||||
|
// Scroll the list to the bottom
|
||||||
|
nextTick(() => {
|
||||||
|
const ul = this.$refs.ul as HTMLElement;
|
||||||
|
ul.scrollTo(0, ul.scrollHeight);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen Msg
|
||||||
|
this.client.listenMsg("lobby/B_start", (v: Msgstart) => {
|
||||||
|
console.log("lobby/B_start")
|
||||||
|
let listdata: MsgChat = {
|
||||||
|
time: v.time,
|
||||||
|
content: v.data.content,
|
||||||
|
};
|
||||||
|
this.list.push(listdata);
|
||||||
|
|
||||||
|
// Scroll the list to the bottom
|
||||||
|
nextTick(() => {
|
||||||
|
const ul = this.$refs.ul as HTMLElement;
|
||||||
|
ul.scrollTo(0, ul.scrollHeight);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// When disconnected
|
||||||
|
this.client.flows.postDisconnectFlow.push((v) => {
|
||||||
|
// alert("Server disconnected");
|
||||||
|
let listdata: MsgChat = {
|
||||||
|
time: new Date(),
|
||||||
|
content: "Server disconnected",
|
||||||
|
};
|
||||||
|
this.list.push(listdata);
|
||||||
|
return v;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
async connect(): Promise<void> {
|
||||||
|
// this.client = getClient();
|
||||||
|
// let listdata: MsgChat = {
|
||||||
|
// time: new Date(),
|
||||||
|
// content: `connect`,
|
||||||
|
// };
|
||||||
|
// this.list.push(listdata);
|
||||||
|
|
||||||
|
this.client.connect().then((v) => {
|
||||||
|
if (!v.isSucc) {
|
||||||
|
// alert("= Client Connect Error =\n" + v.errMsg);
|
||||||
|
let listdata: MsgChat = {
|
||||||
|
time: new Date(),
|
||||||
|
content: "= Client Connect Error =\n" + v.errMsg,
|
||||||
|
};
|
||||||
|
this.list.push(listdata);
|
||||||
|
} else {
|
||||||
|
// alert("= Client Connect Error =\n" + v.errMsg);
|
||||||
|
let listdata: MsgChat = {
|
||||||
|
time: new Date(),
|
||||||
|
content: "Server Connect",
|
||||||
|
};
|
||||||
|
this.list.push(listdata);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async start(): Promise<void> {
|
||||||
|
let ret = await this.client.callApi("lobby/start", {});
|
||||||
|
|
||||||
|
// Error
|
||||||
|
if (!ret.isSucc) {
|
||||||
|
// alert(ret.err.message);
|
||||||
|
let listdata: MsgChat = {
|
||||||
|
time: new Date(),
|
||||||
|
content: ret.err.message,
|
||||||
|
};
|
||||||
|
this.list.push(listdata);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
|
this.input = "";
|
||||||
|
},
|
||||||
|
// Send input message
|
||||||
|
async send(): Promise<void> {
|
||||||
|
let ret = await this.client.callApi("Send", {
|
||||||
|
content: this.input,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Error
|
||||||
|
if (!ret.isSucc) {
|
||||||
|
// alert(ret.err.message);
|
||||||
|
let listdata: MsgChat = {
|
||||||
|
time: new Date(),
|
||||||
|
content: ret.err.message,
|
||||||
|
};
|
||||||
|
this.list.push(listdata);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
|
this.input = "";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
// .div .Chatroom {
|
||||||
|
// display: inline-block;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.Chatroom {
|
||||||
|
// display: inline-block;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 460px;
|
||||||
|
height: 480px;
|
||||||
|
margin: 20px;
|
||||||
|
background: #f7f7f7;
|
||||||
|
border: 1px solid #454545;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
>header {
|
||||||
|
background: #454545;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
>.send {
|
||||||
|
flex: 0 0 40px;
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid #454545;
|
||||||
|
|
||||||
|
>* {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
>input {
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
>button {
|
||||||
|
flex: 0 0 100px;
|
||||||
|
background: #215fa4;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #4b80bb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
>.list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
list-style: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
background: #f2f2f2;
|
||||||
|
|
||||||
|
>li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
line-height: 1.5em;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
>.content {
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
>.time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #4b80bb;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body>h1 {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Chatroom {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 460px;
|
||||||
|
height: 480px;
|
||||||
|
margin: 20px;
|
||||||
|
background: #f7f7f7;
|
||||||
|
border: 1px solid #454545;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-room>header {
|
||||||
|
background: #454545;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send {
|
||||||
|
flex: 0 0 40px;
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid #454545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send>* {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send>input {
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send>button {
|
||||||
|
flex: 0 0 100px;
|
||||||
|
background: #215fa4;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send>button:hover {
|
||||||
|
background: #4b80bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
list-style: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
background: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list>li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
line-height: 1.5em;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list>li>.content {
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list>li>.time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #4b80bb;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list>li:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
@@ -0,0 +1,52 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
defineProps<{ msg: string }>()
|
||||||
|
|
||||||
|
const count = ref(0)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Recommended IDE setup:
|
||||||
|
<a href="https://code.visualstudio.com/" target="_blank">VS Code</a>
|
||||||
|
+
|
||||||
|
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>See <code>README.md</code> for more information.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="https://vitejs.dev/guide/features.html" target="_blank">
|
||||||
|
Vite Docs
|
||||||
|
</a>
|
||||||
|
|
|
||||||
|
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button type="button" @click="count++">count is: {{ count }}</button>
|
||||||
|
<p>
|
||||||
|
Edit
|
||||||
|
<code>components/HelloWorld.vue</code> to test hot module replacement.
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
a {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin: 0 0.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: #eee;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #304455;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
declare module '*.vue' {
|
||||||
|
import type { DefineComponent } from 'vue'
|
||||||
|
const component: DefineComponent<{}, {}, any>
|
||||||
|
export default component
|
||||||
|
}
|
||||||
|
|
||||||
|
// TSRPC would decode ObjectId as string in frontend.
|
||||||
|
declare module 'mongodb' {
|
||||||
|
export type ObjectId = string;
|
||||||
|
export type ObjectID = string;
|
||||||
|
}
|
||||||
|
declare module 'bson' {
|
||||||
|
export type ObjectId = string;
|
||||||
|
export type ObjectID = string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { WsClient } from "tsrpc-browser";
|
||||||
|
import { serviceProto, ServiceType } from "./shared/protocols/serviceProto";
|
||||||
|
|
||||||
|
export function getClient(): WsClient<ServiceType> {
|
||||||
|
return new WsClient(serviceProto, {
|
||||||
|
server: "ws://127.0.0.1:4000",
|
||||||
|
// Remove this to use binary mode (remove from the server too)
|
||||||
|
json: true,
|
||||||
|
logger: console,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
createApp(App).mount('#app')
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
D:/Project/Test/Test_NodeJS/TSRPC_Badminton-Scoreboard/backend/src/shared
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"strict": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"sourceMap": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
],
|
||||||
|
"skipLibCheck": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.d.ts",
|
||||||
|
"src/**/*.tsx",
|
||||||
|
"src/**/*.vue"
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node"
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
base: "./",
|
||||||
|
plugins: [vue()],
|
||||||
|
server: {
|
||||||
|
port: 5000
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
// Vue project root
|
||||||
|
projects: [
|
||||||
|
'./frontend'
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user