mirror of
https://github.com/zkitter/groups.git
synced 2026-01-10 07:48:12 -05:00
feat: Serve swagger doc ui on root endpoint (#34)
* feat: serve swagger ui on root endpoint (#33) * feat: serve swagger ui on root endpoint * remove home controller * feat(swagger): Customize root page title and favicon
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
"@types/jest": "^29.2.3",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/supertest": "^2.0.12",
|
||||
"@types/swagger-ui-express": "^4.1.3",
|
||||
"@types/yargs": "^17.0.19",
|
||||
"barrelsby": "^2.5.1",
|
||||
"concurrently": "^7.6.0",
|
||||
@@ -70,6 +71,8 @@
|
||||
"@octokit/graphql": "^5.0.5",
|
||||
"@octokit/plugin-paginate-graphql": "^2.0.1",
|
||||
"@prisma/client": "^4.9.0",
|
||||
"@types/cors": "^2.8.13",
|
||||
"cors": "^2.8.5",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"express": "^4.18.2",
|
||||
"express-async-errors": "^3.1.1",
|
||||
@@ -77,6 +80,7 @@
|
||||
"is-docker": "^3.0.0",
|
||||
"module-alias": "^2.2.2",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"swagger-ui-express": "^4.6.0",
|
||||
"tslib": "^2.5.0",
|
||||
"typedi": "^0.10.0"
|
||||
}
|
||||
|
||||
49
pnpm-lock.yaml
generated
49
pnpm-lock.yaml
generated
@@ -11,13 +11,16 @@ specifiers:
|
||||
'@prisma/client': ^4.9.0
|
||||
'@r1oga/eslint-config': ^1.1.6
|
||||
'@r1oga/prettier-config': ^1.1.8
|
||||
'@types/cors': ^2.8.13
|
||||
'@types/express': ^4.17.15
|
||||
'@types/jest': ^29.2.3
|
||||
'@types/node': ^18.11.18
|
||||
'@types/supertest': ^2.0.12
|
||||
'@types/swagger-ui-express': ^4.1.3
|
||||
'@types/yargs': ^17.0.19
|
||||
barrelsby: ^2.5.1
|
||||
concurrently: ^7.6.0
|
||||
cors: ^2.8.5
|
||||
cross-fetch: ^3.1.5
|
||||
dotenv-cli: ^7.0.0
|
||||
express: ^4.18.2
|
||||
@@ -41,6 +44,7 @@ specifiers:
|
||||
prisma: ^4.9.0
|
||||
reflect-metadata: ^0.1.13
|
||||
supertest: ^6.3.3
|
||||
swagger-ui-express: ^4.6.0
|
||||
ts-jest: ^29.0.3
|
||||
ts-node-dev: ^2.0.0
|
||||
tsconfig-paths: ^4.1.0
|
||||
@@ -54,6 +58,8 @@ dependencies:
|
||||
'@octokit/graphql': 5.0.5
|
||||
'@octokit/plugin-paginate-graphql': 2.0.1_@octokit+core@4.2.0
|
||||
'@prisma/client': 4.9.0_prisma@4.9.0
|
||||
'@types/cors': 2.8.13
|
||||
cors: 2.8.5
|
||||
cross-fetch: 3.1.5
|
||||
express: 4.18.2
|
||||
express-async-errors: 3.1.1_express@4.18.2
|
||||
@@ -61,6 +67,7 @@ dependencies:
|
||||
is-docker: 3.0.0
|
||||
module-alias: 2.2.2
|
||||
reflect-metadata: 0.1.13
|
||||
swagger-ui-express: 4.6.0_express@4.18.2
|
||||
tslib: 2.5.0
|
||||
typedi: 0.10.0
|
||||
|
||||
@@ -75,6 +82,7 @@ devDependencies:
|
||||
'@types/jest': 29.2.3
|
||||
'@types/node': 18.11.18
|
||||
'@types/supertest': 2.0.12
|
||||
'@types/swagger-ui-express': 4.1.3
|
||||
'@types/yargs': 17.0.19
|
||||
barrelsby: 2.5.1
|
||||
concurrently: 7.6.0
|
||||
@@ -1146,6 +1154,12 @@ packages:
|
||||
resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==}
|
||||
dev: true
|
||||
|
||||
/@types/cors/2.8.13:
|
||||
resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==}
|
||||
dependencies:
|
||||
'@types/node': 18.11.18
|
||||
dev: false
|
||||
|
||||
/@types/express-serve-static-core/4.17.32:
|
||||
resolution: {integrity: sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA==}
|
||||
dependencies:
|
||||
@@ -1212,7 +1226,6 @@ packages:
|
||||
|
||||
/@types/node/18.11.18:
|
||||
resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==}
|
||||
dev: true
|
||||
|
||||
/@types/parse-json/4.0.0:
|
||||
resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
|
||||
@@ -1266,6 +1279,13 @@ packages:
|
||||
'@types/superagent': 4.1.16
|
||||
dev: true
|
||||
|
||||
/@types/swagger-ui-express/4.1.3:
|
||||
resolution: {integrity: sha512-jqCjGU/tGEaqIplPy3WyQg+Nrp6y80DCFnDEAvVKWkJyv0VivSSDCChkppHRHAablvInZe6pijDFMnavtN0vqA==}
|
||||
dependencies:
|
||||
'@types/express': 4.17.15
|
||||
'@types/serve-static': 1.15.0
|
||||
dev: true
|
||||
|
||||
/@types/unist/2.0.6:
|
||||
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
||||
dev: true
|
||||
@@ -2107,6 +2127,14 @@ packages:
|
||||
resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
|
||||
dev: true
|
||||
|
||||
/cors/2.8.5:
|
||||
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
dependencies:
|
||||
object-assign: 4.1.1
|
||||
vary: 1.1.2
|
||||
dev: false
|
||||
|
||||
/cosmiconfig/6.0.0:
|
||||
resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -4897,6 +4925,11 @@ packages:
|
||||
resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==}
|
||||
dev: true
|
||||
|
||||
/object-assign/4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/object-inspect/1.12.2:
|
||||
resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==}
|
||||
|
||||
@@ -5783,6 +5816,20 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: true
|
||||
|
||||
/swagger-ui-dist/4.15.5:
|
||||
resolution: {integrity: sha512-V3eIa28lwB6gg7/wfNvAbjwJYmDXy1Jo1POjyTzlB6wPcHiGlRxq39TSjYGVjQrUSAzpv+a7nzp7mDxgNy57xA==}
|
||||
dev: false
|
||||
|
||||
/swagger-ui-express/4.6.0_express@4.18.2:
|
||||
resolution: {integrity: sha512-ZxpQFp1JR2RF8Ar++CyJzEDdvufa08ujNUJgMVTMWPi86CuQeVdBtvaeO/ysrz6dJAYXf9kbVNhWD7JWocwqsA==}
|
||||
engines: {node: '>= v0.10.32'}
|
||||
peerDependencies:
|
||||
express: '>=4.0.0'
|
||||
dependencies:
|
||||
express: 4.18.2
|
||||
swagger-ui-dist: 4.15.5
|
||||
dev: false
|
||||
|
||||
/symbol-tree/3.2.4:
|
||||
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
||||
dev: true
|
||||
|
||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
22
src/app.ts
22
src/app.ts
@@ -1,18 +1,26 @@
|
||||
import 'express-async-errors'
|
||||
import cors from 'cors'
|
||||
import express, { Express, Router } from 'express'
|
||||
import swaggerUi from 'swagger-ui-express'
|
||||
import { Container } from 'typedi'
|
||||
import {
|
||||
HomeController,
|
||||
UserController,
|
||||
WhitelistController,
|
||||
} from './controllers'
|
||||
import { UserController, WhitelistController } from './controllers'
|
||||
import openApiSpecs from './openapi.json'
|
||||
|
||||
const app: Express = express()
|
||||
const homeController = Container.get(HomeController)
|
||||
const whitelistController = Container.get(WhitelistController)
|
||||
const userController = Container.get(UserController)
|
||||
|
||||
app.get('/', homeController.home.bind(HomeController))
|
||||
app.use(cors())
|
||||
|
||||
app.use(express.static('public'))
|
||||
app.use('/', swaggerUi.serve)
|
||||
app.get(
|
||||
'/',
|
||||
swaggerUi.setup(openApiSpecs, {
|
||||
customfavIcon: '/favicon.ico',
|
||||
customSiteTitle: 'Zkitter Groups API',
|
||||
}),
|
||||
)
|
||||
|
||||
app.use(
|
||||
'/whitelist',
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { Service } from 'typedi'
|
||||
|
||||
const html = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Zkitter Groups API</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1>ZKITTER GROUPS API</h1>
|
||||
<h2>Routes</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th>Path</th>
|
||||
<th>Response</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GET</td>
|
||||
<td>/whitelist?format=long|short</td>
|
||||
<td>Get list of whitelisted organizations in <code>short</code> or <code>long</code> format</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GET</td>
|
||||
<td>/whitelist/refresh</td>
|
||||
<td>Update list of whitelisted orgs and their repos. Return updated whitelist</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GET</td>
|
||||
<td>/user/:username?format=short|long</td>
|
||||
<td>Get user <code>username</code> in <code>short</code> (only groups info) or <code>long</code> (with repos) format</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GET</td>
|
||||
<td>/user/:username/refresh</td>
|
||||
<td>Update list of repos the user <code>username</code> contributed to and return updated user</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<footer>
|
||||
<a
|
||||
rel="stylesheet"
|
||||
target="_blank"
|
||||
href="https://github.com/zkitter/groups"
|
||||
>https://github.com/zkitter/groups</a
|
||||
>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
@Service()
|
||||
export class HomeController {
|
||||
async home(_: Request, res: Response) {
|
||||
res.send(html)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,5 @@
|
||||
* @file Automatically generated by barrelsby.
|
||||
*/
|
||||
|
||||
export * from './Home'
|
||||
export * from './User/index'
|
||||
export * from './Whitelist/index'
|
||||
|
||||
215
src/openapi.json
Normal file
215
src/openapi.json
Normal file
@@ -0,0 +1,215 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Zkitter Groups - OpenAPI 3.0",
|
||||
"description": "This is a sample Pet Store Server based on the OpenAPI 3.0 specification. \n\n[GitHub](https://github.com/zkitter/groups)",
|
||||
"license": {
|
||||
"name": "MIT",
|
||||
"url": "https://github.com/zkitter/groups/blob/main/LICENSE"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://zkitter-groups.fly.dev/"
|
||||
},
|
||||
{
|
||||
"url": "https://zkitter-groups-staging.fly.dev/"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"name": "whitelist",
|
||||
"description": "Whitelisted Organizations"
|
||||
},
|
||||
{
|
||||
"name": "user",
|
||||
"description": "GitHub User"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/user/{username}": {
|
||||
"get": {
|
||||
"tags": ["user"],
|
||||
"summary": "Get user by GitHub login/username",
|
||||
"description": "",
|
||||
"operationId": "getUserByGhName",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "username",
|
||||
"in": "path",
|
||||
"description": "The GitHub login that needs to be fetched.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "format",
|
||||
"in": "query",
|
||||
"description": "response format",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": ["short", "long"],
|
||||
"example": "long",
|
||||
"default": "short"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/User"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/{username}/refresh": {
|
||||
"get": {
|
||||
"tags": ["user"],
|
||||
"summary": "Update list of repos the user contributed.",
|
||||
"description": "",
|
||||
"operationId": "refreshUserByGhName",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "username",
|
||||
"in": "path",
|
||||
"description": "The GitHub login that needs to be refreshed.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/User"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/whitelist": {
|
||||
"get": {
|
||||
"tags": ["whitelist"],
|
||||
"summary": "Get whitelisted organizations.",
|
||||
"description": "",
|
||||
"operationId": "getWhitelist",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "format",
|
||||
"in": "query",
|
||||
"description": "response format",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": ["short", "long"],
|
||||
"example": "long",
|
||||
"default": "short"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "sucessful operation",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Org"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/whitelist/refresh": {
|
||||
"get": {
|
||||
"tags": ["whitelist"],
|
||||
"summary": "Update list of whitelisted orgs and their repos.",
|
||||
"description": "",
|
||||
"operationId": "refreshWhitelist",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "successful operation",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/User"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"User": {
|
||||
"required": ["belongsToGhContributorsGroup"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"belongsToGhContributorsGroup": {
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
"ghName": {
|
||||
"type": "string",
|
||||
"example": "r1oga"
|
||||
},
|
||||
"repos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Org": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ghName": {
|
||||
"type": "string",
|
||||
"example": "stargate-protocol"
|
||||
},
|
||||
"snapshotId": {
|
||||
"type": "string",
|
||||
"example": "stgdao.eth"
|
||||
},
|
||||
"snapshotName": {
|
||||
"type": "string",
|
||||
"example": "Stargate DAO"
|
||||
},
|
||||
"followers": {
|
||||
"type": "number",
|
||||
"example": 10000
|
||||
},
|
||||
"repos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"example": ["treasure-docs", "treasure-subgraph"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user