feat: add trpc openapi and swagger ui
This commit is contained in:
parent
4f58c7f5eb
commit
d183b8ca6f
@ -1,8 +1,9 @@
|
||||
# postgresql url
|
||||
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
|
||||
|
||||
# Whether allow register user
|
||||
# Whether allow feature
|
||||
ALLOW_REGISTER=
|
||||
ALLOW_OPENAPI=
|
||||
|
||||
# For analyze tianji self
|
||||
WEBSITE_ID=
|
||||
|
@ -8,6 +8,7 @@ services:
|
||||
DATABASE_URL: postgresql://tianji:tianji@db:5432/tianji
|
||||
JWT_SECRET: replace-me-with-a-random-string
|
||||
ALLOW_REGISTER: "false"
|
||||
ALLOW_OPENAPI: "true"
|
||||
depends_on:
|
||||
- postgres
|
||||
restart: always
|
||||
|
@ -11,6 +11,7 @@
|
||||
"build:server": "tsc -p tsconfig.server.json",
|
||||
"build:tracker": "ts-node scripts/build-tracker.ts",
|
||||
"build:geo": "ts-node scripts/build-geo.ts",
|
||||
"postinstall": "pnpm db:generate",
|
||||
"check:type": "tsc --noEmit --skipLibCheck --module esnext",
|
||||
"db:push": "prisma db push",
|
||||
"db:generate": "prisma generate",
|
||||
@ -69,6 +70,8 @@
|
||||
"socket.io": "^4.7.2",
|
||||
"socket.io-client": "^4.7.2",
|
||||
"str2int": "^1.1.0",
|
||||
"swagger-ui-express": "^5.0.0",
|
||||
"trpc-openapi": "^1.2.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"uuid": "^9.0.0",
|
||||
"vite-express": "^0.10.0",
|
||||
@ -92,6 +95,7 @@
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/request-ip": "^0.0.38",
|
||||
"@types/swagger-ui-express": "^4.1.5",
|
||||
"@types/tar": "^6.1.5",
|
||||
"@vitejs/plugin-react": "^4.0.4",
|
||||
"autoprefixer": "^10.4.15",
|
||||
|
167
pnpm-lock.yaml
167
pnpm-lock.yaml
@ -151,6 +151,12 @@ dependencies:
|
||||
str2int:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
swagger-ui-express:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0(express@4.18.2)
|
||||
trpc-openapi:
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(@trpc/server@10.38.4)(zod@3.22.2)
|
||||
ts-node:
|
||||
specifier: ^10.9.1
|
||||
version: 10.9.1(@types/node@18.17.12)(typescript@5.2.2)
|
||||
@ -216,6 +222,9 @@ devDependencies:
|
||||
'@types/request-ip':
|
||||
specifier: ^0.0.38
|
||||
version: 0.0.38
|
||||
'@types/swagger-ui-express':
|
||||
specifier: ^4.1.5
|
||||
version: 4.1.5
|
||||
'@types/tar':
|
||||
specifier: ^6.1.5
|
||||
version: 6.1.5
|
||||
@ -2181,6 +2190,13 @@ packages:
|
||||
'@types/node': 18.17.12
|
||||
dev: true
|
||||
|
||||
/@types/swagger-ui-express@4.1.5:
|
||||
resolution: {integrity: sha512-MRvm1OCzIR321glc/4tP34wRVmsupgLzs6XIq50CFp0CJUzxbpDsrhJxEBMQfoO46ixrlCiw3QXxEs5HHxYI8Q==}
|
||||
dependencies:
|
||||
'@types/express': 4.17.17
|
||||
'@types/serve-static': 1.15.2
|
||||
dev: true
|
||||
|
||||
/@types/tar@6.1.5:
|
||||
resolution: {integrity: sha512-qm2I/RlZij5RofuY7vohTpYNaYcrSQlN2MyjucQc7ZweDwaEWkdN/EeNh6e9zjK6uEm6PwjdMXkcj05BxZdX1Q==}
|
||||
dependencies:
|
||||
@ -2739,6 +2755,15 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/co-body@6.1.0:
|
||||
resolution: {integrity: sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==}
|
||||
dependencies:
|
||||
inflation: 2.1.0
|
||||
qs: 6.11.0
|
||||
raw-body: 2.5.1
|
||||
type-is: 1.6.18
|
||||
dev: false
|
||||
|
||||
/color-convert@0.5.3:
|
||||
resolution: {integrity: sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==}
|
||||
dev: false
|
||||
@ -2835,6 +2860,11 @@ packages:
|
||||
/concat-map@0.0.1:
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
|
||||
/consola@3.2.3:
|
||||
resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
|
||||
engines: {node: ^14.18.0 || >=16.10.0}
|
||||
dev: false
|
||||
|
||||
/content-disposition@0.5.4:
|
||||
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@ -2855,6 +2885,10 @@ packages:
|
||||
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
|
||||
dev: true
|
||||
|
||||
/cookie-es@1.0.0:
|
||||
resolution: {integrity: sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==}
|
||||
dev: false
|
||||
|
||||
/cookie-signature@1.0.6:
|
||||
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
|
||||
dev: false
|
||||
@ -3162,6 +3196,10 @@ packages:
|
||||
resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==}
|
||||
dev: false
|
||||
|
||||
/defu@6.1.2:
|
||||
resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==}
|
||||
dev: false
|
||||
|
||||
/degenerator@5.0.1:
|
||||
resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
|
||||
engines: {node: '>= 14'}
|
||||
@ -3176,11 +3214,20 @@ packages:
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/depd@1.1.2:
|
||||
resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/depd@2.0.0:
|
||||
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: false
|
||||
|
||||
/destr@2.0.1:
|
||||
resolution: {integrity: sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==}
|
||||
dev: false
|
||||
|
||||
/destroy@1.2.0:
|
||||
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
|
||||
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
|
||||
@ -3843,6 +3890,19 @@ packages:
|
||||
resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==}
|
||||
dev: false
|
||||
|
||||
/h3@1.8.2:
|
||||
resolution: {integrity: sha512-1Ca0orJJlCaiFY68BvzQtP2lKLk46kcLAxVM8JgYbtm2cUg6IY7pjpYgWMwUvDO9QI30N5JAukOKoT8KD3Q0PQ==}
|
||||
dependencies:
|
||||
cookie-es: 1.0.0
|
||||
defu: 6.1.2
|
||||
destr: 2.0.1
|
||||
iron-webcrypto: 0.10.1
|
||||
radix3: 1.1.0
|
||||
ufo: 1.3.1
|
||||
uncrypto: 0.1.3
|
||||
unenv: 1.7.4
|
||||
dev: false
|
||||
|
||||
/hammerjs@2.0.8:
|
||||
resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
@ -3954,6 +4014,11 @@ packages:
|
||||
resolve-from: 4.0.0
|
||||
dev: false
|
||||
|
||||
/inflation@2.1.0:
|
||||
resolution: {integrity: sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
dev: false
|
||||
|
||||
/inflight@1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
dependencies:
|
||||
@ -4004,6 +4069,10 @@ packages:
|
||||
engines: {node: '>= 0.10'}
|
||||
dev: false
|
||||
|
||||
/iron-webcrypto@0.10.1:
|
||||
resolution: {integrity: sha512-QGOS8MRMnj/UiOa+aMIgfyHcvkhqNUsUxb1XzskENvbo+rEfp6TOwqd1KPuDzXC4OnGHcMSVxDGRoilqB8ViqA==}
|
||||
dev: false
|
||||
|
||||
/is-any-array@2.0.1:
|
||||
resolution: {integrity: sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==}
|
||||
dev: false
|
||||
@ -4316,6 +4385,10 @@ packages:
|
||||
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
|
||||
dev: false
|
||||
|
||||
/lodash.clonedeep@4.5.0:
|
||||
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
|
||||
dev: false
|
||||
|
||||
/lodash.includes@4.3.0:
|
||||
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
|
||||
dev: false
|
||||
@ -4487,6 +4560,12 @@ packages:
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/mime@3.0.0:
|
||||
resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
dependencies:
|
||||
@ -4643,6 +4722,10 @@ packages:
|
||||
engines: {node: '>= 0.4.0'}
|
||||
dev: false
|
||||
|
||||
/node-fetch-native@1.4.0:
|
||||
resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==}
|
||||
dev: false
|
||||
|
||||
/node-fetch@2.7.0:
|
||||
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
@ -4655,6 +4738,22 @@ packages:
|
||||
whatwg-url: 5.0.0
|
||||
dev: false
|
||||
|
||||
/node-mocks-http@1.13.0:
|
||||
resolution: {integrity: sha512-lArD6sJMPJ53WF50GX0nJ89B1nkV1TdMvNwq8WXXFrUXF80ujSyye1T30mgiHh4h2It0/svpF3C4kZ2OAONVlg==}
|
||||
engines: {node: '>=14'}
|
||||
dependencies:
|
||||
accepts: 1.3.8
|
||||
content-disposition: 0.5.4
|
||||
depd: 1.1.2
|
||||
fresh: 0.5.2
|
||||
merge-descriptors: 1.0.1
|
||||
methods: 1.1.2
|
||||
mime: 1.6.0
|
||||
parseurl: 1.3.3
|
||||
range-parser: 1.2.1
|
||||
type-is: 1.6.18
|
||||
dev: false
|
||||
|
||||
/node-releases@2.0.13:
|
||||
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
|
||||
dev: true
|
||||
@ -4758,6 +4857,10 @@ packages:
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
|
||||
/openapi-types@12.1.3:
|
||||
resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==}
|
||||
dev: false
|
||||
|
||||
/pac-proxy-agent@7.0.1:
|
||||
resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==}
|
||||
engines: {node: '>= 14'}
|
||||
@ -4852,6 +4955,10 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/pathe@1.1.1:
|
||||
resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
|
||||
dev: false
|
||||
|
||||
/pause@0.0.1:
|
||||
resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==}
|
||||
dev: false
|
||||
@ -5137,6 +5244,10 @@ packages:
|
||||
resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==}
|
||||
dev: false
|
||||
|
||||
/radix3@1.1.0:
|
||||
resolution: {integrity: sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A==}
|
||||
dev: false
|
||||
|
||||
/range-parser@1.2.1:
|
||||
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@ -6433,6 +6544,20 @@ packages:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
/swagger-ui-dist@5.9.0:
|
||||
resolution: {integrity: sha512-NUHSYoe5XRTk/Are8jPJ6phzBh3l9l33nEyXosM17QInoV95/jng8+PuSGtbD407QoPf93MH3Bkh773OgesJpA==}
|
||||
dev: false
|
||||
|
||||
/swagger-ui-express@5.0.0(express@4.18.2):
|
||||
resolution: {integrity: sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==}
|
||||
engines: {node: '>= v0.10.32'}
|
||||
peerDependencies:
|
||||
express: '>=4.0.0 || >=5.0.0-beta'
|
||||
dependencies:
|
||||
express: 4.18.2
|
||||
swagger-ui-dist: 5.9.0
|
||||
dev: false
|
||||
|
||||
/tailwindcss@3.3.3(ts-node@10.9.1):
|
||||
resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@ -6600,6 +6725,22 @@ packages:
|
||||
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||
dev: false
|
||||
|
||||
/trpc-openapi@1.2.0(@trpc/server@10.38.4)(zod@3.22.2):
|
||||
resolution: {integrity: sha512-pfYoCd/3KYXWXvUPZBKJw455OOwngKN/6SIcj7Yit19OMLJ+8yVZkEvGEeg5wUSwfsiTdRsKuvqkRPXVSwV7ew==}
|
||||
peerDependencies:
|
||||
'@trpc/server': ^10.0.0
|
||||
zod: ^3.14.4
|
||||
dependencies:
|
||||
'@trpc/server': 10.38.4
|
||||
co-body: 6.1.0
|
||||
h3: 1.8.2
|
||||
lodash.clonedeep: 4.5.0
|
||||
node-mocks-http: 1.13.0
|
||||
openapi-types: 12.1.3
|
||||
zod: 3.22.2
|
||||
zod-to-json-schema: 3.21.4(zod@3.22.2)
|
||||
dev: false
|
||||
|
||||
/ts-easing@0.2.0:
|
||||
resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==}
|
||||
dev: false
|
||||
@ -6710,6 +6851,10 @@ packages:
|
||||
resolution: {integrity: sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==}
|
||||
dev: false
|
||||
|
||||
/ufo@1.3.1:
|
||||
resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==}
|
||||
dev: false
|
||||
|
||||
/uglify-js@2.8.29:
|
||||
resolution: {integrity: sha512-qLq/4y2pjcU3vhlhseXGGJ7VbFO4pBANu0kwl8VCa9KEI0V8VfZIx2Fy3w01iSTA/pGwKZSmu/+I4etLNDdt5w==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
@ -6743,10 +6888,24 @@ packages:
|
||||
through: 2.3.8
|
||||
dev: false
|
||||
|
||||
/uncrypto@0.1.3:
|
||||
resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
|
||||
dev: false
|
||||
|
||||
/undefsafe@2.0.5:
|
||||
resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
|
||||
dev: true
|
||||
|
||||
/unenv@1.7.4:
|
||||
resolution: {integrity: sha512-fjYsXYi30It0YCQYqLOcT6fHfMXsBr2hw9XC7ycf8rTG7Xxpe3ZssiqUnD0khrjiZEmkBXWLwm42yCSCH46fMw==}
|
||||
dependencies:
|
||||
consola: 3.2.3
|
||||
defu: 6.1.2
|
||||
mime: 3.0.0
|
||||
node-fetch-native: 1.4.0
|
||||
pathe: 1.1.1
|
||||
dev: false
|
||||
|
||||
/universalify@0.1.2:
|
||||
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
@ -7049,6 +7208,14 @@ packages:
|
||||
type-fest: 2.19.0
|
||||
dev: false
|
||||
|
||||
/zod-to-json-schema@3.21.4(zod@3.22.2):
|
||||
resolution: {integrity: sha512-fjUZh4nQ1s6HMccgIeE0VP4QG/YRGPmyjO9sAh890aQKPEk3nqbfUXhMFaC+Dr5KvYBm8BCyvfpZf2jY9aGSsw==}
|
||||
peerDependencies:
|
||||
zod: ^3.21.4
|
||||
dependencies:
|
||||
zod: 3.22.2
|
||||
dev: false
|
||||
|
||||
/zod@3.22.2:
|
||||
resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==}
|
||||
dev: false
|
||||
|
@ -4,17 +4,23 @@ import express from 'express';
|
||||
import 'express-async-errors';
|
||||
import ViteExpress from 'vite-express';
|
||||
import compression from 'compression';
|
||||
import swaggerUI from 'swagger-ui-express';
|
||||
import passport from 'passport';
|
||||
import morgan from 'morgan';
|
||||
import { websiteRouter } from './router/website';
|
||||
import { workspaceRouter } from './router/workspace';
|
||||
import { telemetryRouter } from './router/telemetry';
|
||||
import { trpcExpressMiddleware } from './trpc';
|
||||
import {
|
||||
trpcExpressMiddleware,
|
||||
trpcOpenapiDocument,
|
||||
trpcOpenapiHttpHandler,
|
||||
} from './trpc';
|
||||
import { initUdpServer } from './udp/server';
|
||||
import { createServer } from 'http';
|
||||
import { initSocketio } from './ws';
|
||||
import { monitorManager } from './model/monitor';
|
||||
import { settings } from './utils/settings';
|
||||
import { env } from './utils/env';
|
||||
|
||||
const port = settings.port;
|
||||
|
||||
@ -39,6 +45,10 @@ app.use('/api/website', websiteRouter);
|
||||
app.use('/api/workspace', workspaceRouter);
|
||||
app.use('/telemetry', telemetryRouter);
|
||||
|
||||
if (env.allowOpenapi) {
|
||||
app.use('/open/_ui', swaggerUI.serve, swaggerUI.setup(trpcOpenapiDocument));
|
||||
app.use('/open', trpcOpenapiHttpHandler);
|
||||
}
|
||||
app.use('/trpc', trpcExpressMiddleware);
|
||||
|
||||
app.use((err: any, req: any, res: any, next: any) => {
|
||||
@ -49,6 +59,9 @@ app.use((err: any, req: any, res: any, next: any) => {
|
||||
httpServer.listen(port, () => {
|
||||
ViteExpress.bind(app, httpServer, () => {
|
||||
console.log(`Server is listening on port ${port}...`);
|
||||
if (env.allowOpenapi) {
|
||||
console.log(`Openapi UI: http://127.0.0.1:${port}/open/_ui`);
|
||||
}
|
||||
console.log(`Website: http://127.0.0.1:${port}`);
|
||||
});
|
||||
});
|
||||
|
23
src/server/model/_schema/index.ts
Normal file
23
src/server/model/_schema/index.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const workspaceSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
dashboardOrder: z.array(z.string()),
|
||||
});
|
||||
|
||||
export const userInfoSchema = z.object({
|
||||
username: z.string(),
|
||||
id: z.string(),
|
||||
role: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
deletedAt: z.date().nullable(),
|
||||
currentWorkspace: workspaceSchema.nullable(),
|
||||
workspaces: z.array(
|
||||
z.object({
|
||||
role: z.string(),
|
||||
workspace: workspaceSchema,
|
||||
})
|
||||
),
|
||||
});
|
@ -1,6 +1,10 @@
|
||||
import * as trpcExpress from '@trpc/server/adapters/express';
|
||||
import { createContext, router } from './trpc';
|
||||
import { createContext } from './trpc';
|
||||
import { appRouter } from './routers';
|
||||
import {
|
||||
createOpenApiHttpHandler,
|
||||
generateOpenApiDocument,
|
||||
} from 'trpc-openapi';
|
||||
|
||||
export const trpcExpressMiddleware = trpcExpress.createExpressMiddleware({
|
||||
router: appRouter,
|
||||
@ -9,3 +13,15 @@ export const trpcExpressMiddleware = trpcExpress.createExpressMiddleware({
|
||||
console.error('Error:', path, error);
|
||||
},
|
||||
});
|
||||
|
||||
export const trpcOpenapiHttpHandler = createOpenApiHttpHandler({
|
||||
router: appRouter,
|
||||
createContext,
|
||||
});
|
||||
|
||||
export const trpcOpenapiDocument = generateOpenApiDocument(appRouter, {
|
||||
title: 'Tianji OpenAPI',
|
||||
description: 'Insight into everything',
|
||||
version: '1.0.0',
|
||||
baseUrl: '/open',
|
||||
});
|
||||
|
@ -10,15 +10,27 @@ import {
|
||||
} from '../../model/user';
|
||||
import { jwtSign } from '../../middleware/auth';
|
||||
import { TRPCError } from '@trpc/server';
|
||||
import { env } from '../../utils/env';
|
||||
import { userInfoSchema } from '../../model/_schema/index';
|
||||
import { OPENAPI_TAG } from '../../utils/const';
|
||||
|
||||
export const userRouter = router({
|
||||
login: publicProcedure
|
||||
.meta({
|
||||
openapi: { method: 'POST', path: '/login', tags: [OPENAPI_TAG.USER] },
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
username: z.string(),
|
||||
password: z.string(),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
z.object({
|
||||
info: userInfoSchema,
|
||||
token: z.string(),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
const { username, password } = input;
|
||||
const user = await authUser(username, password);
|
||||
@ -28,11 +40,24 @@ export const userRouter = router({
|
||||
return { info: user, token };
|
||||
}),
|
||||
loginWithToken: publicProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/loginWithToken',
|
||||
tags: [OPENAPI_TAG.USER],
|
||||
},
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
token: z.string(),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
z.object({
|
||||
info: userInfoSchema,
|
||||
token: z.string(),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
const { token } = input;
|
||||
|
||||
@ -51,13 +76,34 @@ export const userRouter = router({
|
||||
}
|
||||
}),
|
||||
register: publicProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
enabled: env.allowRegister,
|
||||
method: 'POST',
|
||||
path: '/register',
|
||||
tags: [OPENAPI_TAG.USER],
|
||||
},
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
username: z.string(),
|
||||
password: z.string(),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
z.object({
|
||||
info: userInfoSchema,
|
||||
token: z.string(),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
if (!env.allowRegister) {
|
||||
throw new TRPCError({
|
||||
code: 'FORBIDDEN',
|
||||
message: 'Not allow register',
|
||||
});
|
||||
}
|
||||
|
||||
const { username, password } = input;
|
||||
|
||||
const userCount = await getUserCount();
|
||||
|
@ -5,6 +5,7 @@ import { jwtVerify } from '../middleware/auth';
|
||||
import { getWorkspaceUser } from '../model/workspace';
|
||||
import { ROLES, SYSTEM_ROLES } from '../utils/const';
|
||||
import type { IncomingMessage } from 'http';
|
||||
import { OpenApiMeta } from 'trpc-openapi';
|
||||
|
||||
export function createContext({ req }: { req: IncomingMessage }) {
|
||||
const authorization = req.headers['authorization'] ?? '';
|
||||
@ -14,7 +15,7 @@ export function createContext({ req }: { req: IncomingMessage }) {
|
||||
}
|
||||
|
||||
type Context = inferAsyncReturnType<typeof createContext>;
|
||||
const t = initTRPC.context<Context>().create();
|
||||
const t = initTRPC.context<Context>().meta<OpenApiMeta>().create();
|
||||
|
||||
export const middleware = t.middleware;
|
||||
export const router = t.router;
|
||||
|
@ -113,3 +113,7 @@ export const FILTER_COLUMNS = {
|
||||
};
|
||||
|
||||
export const DEFAULT_RESET_DATE = '2000-01-01';
|
||||
|
||||
export enum OPENAPI_TAG {
|
||||
USER = 'User',
|
||||
}
|
||||
|
9
src/server/utils/env.ts
Normal file
9
src/server/utils/env.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export const env = {
|
||||
allowRegister: checkEnvTrusty(process.env.ALLOW_REGISTER),
|
||||
allowOpenapi: checkEnvTrusty(process.env.ALLOW_OPENAPI),
|
||||
websiteId: process.env.WEBSITE_ID,
|
||||
};
|
||||
|
||||
export function checkEnvTrusty(env: string | undefined): boolean {
|
||||
return env === '1' || env === 'true';
|
||||
}
|
Loading…
Reference in New Issue
Block a user