forked from github/plane
Compare commits
2 Commits
fix/spread
...
feat/segwa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
affbe62f21 | ||
|
|
5233c60da8 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -80,3 +80,6 @@ tmp/
|
||||
## packages
|
||||
dist
|
||||
.temp/
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
17
packages/tsconfig/express.json
Normal file
17
packages/tsconfig/express.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "./dist",
|
||||
"baseUrl": "./src",
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
2
segway/.env.example
Normal file
2
segway/.env.example
Normal file
@@ -0,0 +1,2 @@
|
||||
APP_ENV=local
|
||||
SERVER_PORT=9000
|
||||
21
segway/Dockerfile
Normal file
21
segway/Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
||||
# Use the official Node.js 18-alpine image as the base image
|
||||
FROM node:18-alpine
|
||||
|
||||
# Set the working directory inside the container
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Copy package.json and package-lock.json to the working directory
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy the rest of the application code to the working directory
|
||||
COPY . .
|
||||
|
||||
# Build the TypeScript code
|
||||
RUN npm run build
|
||||
|
||||
# Expose the port that your application will run on
|
||||
EXPOSE 9000
|
||||
|
||||
3
segway/README.md
Normal file
3
segway/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Plane Segway
|
||||
|
||||
A node process that take care of external integration with plane.
|
||||
33
segway/package.json
Normal file
33
segway/package.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "segway",
|
||||
"version": "0.0.1",
|
||||
"description": "An integration service syncs plane data with external sources.",
|
||||
"author": "plane team",
|
||||
"license": "ISC",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "npx tsc",
|
||||
"start": "node dist/start.js",
|
||||
"dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/start.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@overnightjs/core": "^1.7.6",
|
||||
"@sentry/node": "^7.73.0",
|
||||
"@sentry/tracing": "^7.73.0",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"postgres": "^3.4.1",
|
||||
"winston": "^3.10.0",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cors": "^2.8.14",
|
||||
"@types/express": "^4.17.18",
|
||||
"@types/node": "^20.8.3",
|
||||
"@types/pg": "^8.10.7",
|
||||
"concurrently": "^8.2.1",
|
||||
"nodemon": "^3.0.1",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
10
segway/src/controllers/github.controller.ts
Normal file
10
segway/src/controllers/github.controller.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Controller, Get } from "@overnightjs/core";
|
||||
|
||||
|
||||
@Controller("/api/github")
|
||||
export class GithubController {
|
||||
/**
|
||||
* This controller houses all routes for the Github Importer/Integration
|
||||
*/
|
||||
}
|
||||
3
segway/src/controllers/index.ts
Normal file
3
segway/src/controllers/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./jira.controller";
|
||||
export * from "./slack.controller"
|
||||
export * from "./github.controller"
|
||||
10
segway/src/controllers/jira.controller.ts
Normal file
10
segway/src/controllers/jira.controller.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Controller, Get } from "@overnightjs/core";
|
||||
|
||||
|
||||
@Controller("/api/jira")
|
||||
export class JiraController {
|
||||
/**
|
||||
* This controller houses all routes for the Jira Importer
|
||||
*/
|
||||
}
|
||||
10
segway/src/controllers/slack.controller.ts
Normal file
10
segway/src/controllers/slack.controller.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Controller, Get } from "@overnightjs/core";
|
||||
|
||||
|
||||
@Controller("/api/slack")
|
||||
export class SlackController {
|
||||
/**
|
||||
* This controller houses all routes for the Slack Integration
|
||||
*/
|
||||
}
|
||||
0
segway/src/middlewares/index.ts
Normal file
0
segway/src/middlewares/index.ts
Normal file
8
segway/src/middlewares/logger.middleware.ts
Normal file
8
segway/src/middlewares/logger.middleware.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { RequestHandler } from "express";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
const loggerMiddleware: RequestHandler = (req, res, next) => {
|
||||
logger.info(`${req.method}: ${req.path}`);
|
||||
next();
|
||||
};
|
||||
export default loggerMiddleware;
|
||||
112
segway/src/server.ts
Normal file
112
segway/src/server.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import dotenv from "dotenv";
|
||||
import path from "path";
|
||||
import express from "express";
|
||||
import { Server } from "@overnightjs/core";
|
||||
import cors from "cors";
|
||||
import * as Sentry from "@sentry/node";
|
||||
import * as Tracing from "@sentry/tracing";
|
||||
// controllers
|
||||
import * as controllers from "./controllers";
|
||||
// middlewares
|
||||
import loggerMiddleware from "./middlewares/logger.middleware";
|
||||
// utils
|
||||
import { logger } from "./utils/logger";
|
||||
|
||||
|
||||
class ApiServer extends Server {
|
||||
private readonly SERVER_STARTED = "Api server started on port: ";
|
||||
SERVER_PORT: number;
|
||||
|
||||
constructor() {
|
||||
super(true);
|
||||
// disabling overnight logs
|
||||
this.showLogs = false;
|
||||
// enabling env variable from .env file
|
||||
dotenv.config();
|
||||
// assigning port
|
||||
this.SERVER_PORT = process.env.SERVER_PORT
|
||||
? parseInt(process.env.SERVER_PORT, 10)
|
||||
: 8080;
|
||||
// logger
|
||||
this.app.use(loggerMiddleware);
|
||||
// exposing public folder for static files.
|
||||
this.app.use(express.static("public"));
|
||||
// body parser
|
||||
this.app.use(express.json());
|
||||
this.app.use(express.urlencoded({ extended: true }));
|
||||
// views engine
|
||||
this.app.set("views", path.join(__dirname, "views"));
|
||||
this.app.set("view engine", "hbs");
|
||||
// cors
|
||||
this.app.use(cors());
|
||||
// sentry setup
|
||||
if (
|
||||
process.env.APP_ENV === "staging" ||
|
||||
process.env.APP_ENV === "production"
|
||||
) {
|
||||
// setting up error logging and tracing.
|
||||
this.setupSentryInit();
|
||||
}
|
||||
// setting up controllers
|
||||
this.setupControllers();
|
||||
// setting up sentry error handling
|
||||
this.sentryErrorHandling();
|
||||
}
|
||||
|
||||
public getAppInstance() {
|
||||
return this.app;
|
||||
}
|
||||
|
||||
private setupControllers(): void {
|
||||
const controllerInstances = [];
|
||||
for (const name in controllers) {
|
||||
if (Object.prototype.hasOwnProperty.call(controllers, name)) {
|
||||
const Controller = (controllers as any)[name];
|
||||
controllerInstances.push(new Controller());
|
||||
}
|
||||
}
|
||||
super.addControllers(controllerInstances);
|
||||
}
|
||||
|
||||
private setupSentryInit() {
|
||||
Sentry.init({
|
||||
dsn: "",
|
||||
integrations: [
|
||||
// enable HTTP calls tracing
|
||||
new Sentry.Integrations.Http({ tracing: true }),
|
||||
// enable Express.js middleware tracing
|
||||
new Tracing.Integrations.Express({ app: this.app }),
|
||||
],
|
||||
// Set tracesSampleRate to 1.0 to capture 100%
|
||||
// of transactions for performance monitoring.
|
||||
// We recommend adjusting this value in production
|
||||
tracesSampleRate: 1.0,
|
||||
});
|
||||
|
||||
// RequestHandler creates a separate execution context using domains, so that every
|
||||
// transaction/span/breadcrumb is attached to its own Hub instance
|
||||
this.app.use(Sentry.Handlers.requestHandler());
|
||||
// TracingHandler creates a trace for every incoming request
|
||||
this.app.use(Sentry.Handlers.tracingHandler());
|
||||
}
|
||||
|
||||
private sentryErrorHandling() {
|
||||
// The error handler must be before any other error middleware and after all controllers
|
||||
this.app.use(Sentry.Handlers.errorHandler());
|
||||
|
||||
this.app.use(function onError(req, res: any) {
|
||||
// The error id is attached to `res.sentry` to be returned
|
||||
// and optionally displayed to the user for support.
|
||||
res.statusCode = 500;
|
||||
res.end(res.sentry + "\n");
|
||||
});
|
||||
}
|
||||
|
||||
public start(port: number): void {
|
||||
this.app.listen(port, () => {
|
||||
logger.info(this.SERVER_STARTED + port);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default ApiServer;
|
||||
5
segway/src/start.ts
Normal file
5
segway/src/start.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import ApiServer from "./server";
|
||||
|
||||
const apiServer = new ApiServer();
|
||||
// starting server
|
||||
apiServer.start(apiServer.SERVER_PORT);
|
||||
8
segway/src/utils/logger.ts
Normal file
8
segway/src/utils/logger.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import winston from "winston";
|
||||
|
||||
export const logger = winston.createLogger({
|
||||
transports: [
|
||||
new winston.transports.Console(),
|
||||
new winston.transports.File({ filename: "combined.log" }),
|
||||
],
|
||||
});
|
||||
9
segway/tsconfig.json
Normal file
9
segway/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "tsconfig/express.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["node_modules"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src/",
|
||||
"outDir": "./dist",
|
||||
}
|
||||
}
|
||||
1328
segway/yarn.lock
Normal file
1328
segway/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user