mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-29 11:43:49 +00:00
UBERF-9605: Test MTA hook integration (#8189)
Some checks are pending
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / uitest-workspaces (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions
Some checks are pending
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / uitest-workspaces (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions
* UBERF-9605: Test MTA hook service Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-9605: pod-hook config Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-9605: Minor fixes Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-9605: Add TODO Signed-off-by: Artem Savchenko <armisav@gmail.com> --------- Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
parent
03584ae057
commit
f94d8bfbaf
@ -246,7 +246,7 @@
|
||||
"summary": "Build docker with platform",
|
||||
"description": "use to build all docker containers required for platform",
|
||||
"safeForSimultaneousRushProcesses": true,
|
||||
"shellCommand": "rush docker:build -p 20 --to @hcengineering/pod-server --to @hcengineering/pod-front --to @hcengineering/prod --to @hcengineering/pod-account --to @hcengineering/pod-workspace --to @hcengineering/pod-collaborator --to @hcengineering/tool --to @hcengineering/pod-print --to @hcengineering/pod-sign --to @hcengineering/pod-analytics-collector --to @hcengineering/rekoni-service --to @hcengineering/pod-ai-bot --to @hcengineering/import-tool --to @hcengineering/pod-stats --to @hcengineering/pod-fulltext --to @hcengineering/pod-love --to @hcengineering/green --to @hcengineering/pod-mail --to @hcengineering/pod-datalake"
|
||||
"shellCommand": "rush docker:build -p 20 --to @hcengineering/pod-server --to @hcengineering/pod-front --to @hcengineering/prod --to @hcengineering/pod-account --to @hcengineering/pod-workspace --to @hcengineering/pod-collaborator --to @hcengineering/tool --to @hcengineering/pod-print --to @hcengineering/pod-sign --to @hcengineering/pod-analytics-collector --to @hcengineering/rekoni-service --to @hcengineering/pod-ai-bot --to @hcengineering/import-tool --to @hcengineering/pod-stats --to @hcengineering/pod-fulltext --to @hcengineering/pod-love --to @hcengineering/green --to @hcengineering/pod-mail --to @hcengineering/pod-datalake --to @hcengineering/pod-hook"
|
||||
},
|
||||
{
|
||||
"commandKind": "global",
|
||||
|
@ -703,6 +703,9 @@ importers:
|
||||
'@rush-temp/pod-gmail':
|
||||
specifier: file:./projects/pod-gmail.tgz
|
||||
version: file:projects/pod-gmail.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(encoding@0.1.13)(gcp-metadata@5.3.0(encoding@0.1.13))(snappy@7.2.2)(socks@2.8.3)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))
|
||||
'@rush-temp/pod-hook':
|
||||
specifier: file:./projects/pod-hook.tgz
|
||||
version: file:projects/pod-hook.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))
|
||||
'@rush-temp/pod-love':
|
||||
specifier: file:./projects/pod-love.tgz
|
||||
version: file:projects/pod-love.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
@ -4738,7 +4741,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/my-space@file:projects/my-space.tgz':
|
||||
resolution: {integrity: sha512-lZXMkLZnlmpSkjEj4lV2pxIaObjgAQ3OT4ktzUOzlpP1v3U78XKLJzRQ29SqVBYH+DcEHqL97znDPEGxzYHZKA==, tarball: file:projects/my-space.tgz}
|
||||
resolution: {integrity: sha512-HyPJ+wTQXLVKvzmJM7NzfJsEAYgBy6lszwGwdN2MLGIFPTT79621OOxX2Z7pEb120/G9r+BJuriVzbmJEZqRZA==, tarball: file:projects/my-space.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/notification-assets@file:projects/notification-assets.tgz':
|
||||
@ -4825,6 +4828,10 @@ packages:
|
||||
resolution: {integrity: sha512-aYecRf97Yj23bi2BdWXg4DrH4oy3AB2UfrpbwNo6nvLhHJLsrcRgOe9zCTakZ7Yb+nDzsxYuOwZiDIr9aWtsyw==, tarball: file:projects/pod-gmail.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/pod-hook@file:projects/pod-hook.tgz':
|
||||
resolution: {integrity: sha512-RgcAHfNOUxdFKPBrtcgIsNpQLo4ro8kuPIbNvG8omy/njf/HHWU5YJMFlznSlv+gCrvZmGsP9YV4k+X0uL/bdw==, tarball: file:projects/pod-hook.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/pod-love@file:projects/pod-love.tgz':
|
||||
resolution: {integrity: sha512-m+9dPMR45FJpQB+M5ka4PiJcTpV8COlQA5F36is2LkMLwnsDjcB94Sx+TFdIyjhVFpfB8l+t886mSPveHql4ag==, tarball: file:projects/pod-love.tgz}
|
||||
version: 0.0.0
|
||||
@ -21518,6 +21525,41 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
'@rush-temp/pod-hook@file:projects/pod-hook.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))':
|
||||
dependencies:
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/cors': 2.8.17
|
||||
'@types/express': 4.17.21
|
||||
'@types/jest': 29.5.12
|
||||
'@types/node': 20.11.19
|
||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3)
|
||||
cors: 2.8.5
|
||||
cross-env: 7.0.3
|
||||
dotenv: 16.0.3
|
||||
esbuild: 0.24.2
|
||||
eslint: 8.56.0
|
||||
eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3)
|
||||
eslint-plugin-import: 2.29.1(eslint@8.56.0)
|
||||
eslint-plugin-n: 15.7.0(eslint@8.56.0)
|
||||
eslint-plugin-node: 11.1.0(eslint@8.56.0)
|
||||
eslint-plugin-promise: 6.1.1(eslint@8.56.0)
|
||||
express: 4.21.2
|
||||
jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))
|
||||
prettier: 3.2.5
|
||||
ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3)
|
||||
ts-node: 10.9.2(@types/node@20.11.19)(typescript@5.7.3)
|
||||
typescript: 5.7.3
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- '@jest/types'
|
||||
- '@swc/core'
|
||||
- '@swc/wasm'
|
||||
- babel-jest
|
||||
- babel-plugin-macros
|
||||
- node-notifier
|
||||
- supports-color
|
||||
|
||||
'@rush-temp/pod-love@file:projects/pod-love.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(bufferutil@4.0.8)(utf-8-validate@6.0.4)':
|
||||
dependencies:
|
||||
'@tsconfig/node16': 1.0.4
|
||||
|
@ -2362,6 +2362,11 @@
|
||||
"packageName": "@hcengineering/pod-mail",
|
||||
"projectFolder": "services/mail/pod-mail",
|
||||
"shouldPublish": false
|
||||
},
|
||||
{
|
||||
"packageName": "@hcengineering/pod-hook",
|
||||
"projectFolder": "services/hook/pod-hook",
|
||||
"shouldPublish": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
7
services/hook/pod-hook/.eslintrc.js
Normal file
7
services/hook/pod-hook/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
1
services/hook/pod-hook/.gitignore
vendored
Normal file
1
services/hook/pod-hook/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.env
|
4
services/hook/pod-hook/.npmignore
Normal file
4
services/hook/pod-hook/.npmignore
Normal file
@ -0,0 +1,4 @@
|
||||
*
|
||||
!/lib/**
|
||||
!CHANGELOG.md
|
||||
/lib/**/__tests__/
|
7
services/hook/pod-hook/Dockerfile
Normal file
7
services/hook/pod-hook/Dockerfile
Normal file
@ -0,0 +1,7 @@
|
||||
FROM hardcoreeng/base:v20250310
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY bundle/bundle.js ./
|
||||
|
||||
EXPOSE 8098
|
||||
CMD [ "node", "bundle.js" ]
|
19
services/hook/pod-hook/build.sh
Executable file
19
services/hook/pod-hook/build.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright © 2025 Hardcore Engineering Inc.
|
||||
#
|
||||
# Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License. You may
|
||||
# obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
rushx bundle
|
||||
rushx docker:build
|
||||
rushx docker:push
|
4
services/hook/pod-hook/config/rig.json
Normal file
4
services/hook/pod-hook/config/rig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
7
services/hook/pod-hook/jest.config.js
Normal file
7
services/hook/pod-hook/jest.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
|
||||
roots: ["./src"],
|
||||
coverageReporters: ["text-summary", "html"]
|
||||
}
|
60
services/hook/pod-hook/package.json
Normal file
60
services/hook/pod-hook/package.json
Normal file
@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "@hcengineering/pod-hook",
|
||||
"version": "0.6.0",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"lib/**/*",
|
||||
"types/**/*",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"author": "Hardcore Engineering Inc.",
|
||||
"scripts": {
|
||||
"build": "compile",
|
||||
"build:watch": "compile",
|
||||
"test": "jest --passWithNoTests --silent",
|
||||
"_phase:bundle": "rushx bundle",
|
||||
"_phase:docker-build": "rushx docker:build",
|
||||
"_phase:docker-staging": "rushx docker:staging",
|
||||
"bundle": "node ../../../common/scripts/esbuild.js",
|
||||
"docker:build": "../../../common/scripts/docker_build.sh hardcoreeng/hook",
|
||||
"docker:staging": "../../../common/scripts/docker_tag.sh hardcoreeng/hook staging",
|
||||
"docker:abuild": "docker build -t hardcoreeng/hook . --platform=linux/arm64 && ../../../common/scripts/docker_tag_push.sh hardcoreeng/hook",
|
||||
"docker:push": "../../../common/scripts/docker_tag.sh hardcoreeng/hook",
|
||||
"run-local": "ts-node src/index.ts",
|
||||
"format": "format src",
|
||||
"_phase:build": "compile transpile src",
|
||||
"_phase:test": "jest --passWithNoTests --silent",
|
||||
"_phase:format": "format src",
|
||||
"_phase:validate": "compile validate"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "~7.0.3",
|
||||
"@hcengineering/platform-rig": "^0.6.0",
|
||||
"@types/node": "~20.11.16",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint": "^8.54.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"prettier": "^3.1.0",
|
||||
"ts-node": "^10.8.0",
|
||||
"typescript": "^5.3.3",
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@tsconfig/node16": "^1.0.4",
|
||||
"@types/cors": "^2.8.12",
|
||||
"@types/express": "^4.17.13",
|
||||
"eslint-plugin-node": "^11.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.21.2",
|
||||
"dotenv": "~16.0.0"
|
||||
}
|
||||
}
|
41
services/hook/pod-hook/src/config.ts
Normal file
41
services/hook/pod-hook/src/config.ts
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
import { config as dotenvConfig } from 'dotenv'
|
||||
|
||||
dotenvConfig()
|
||||
|
||||
export interface Config {
|
||||
port: number
|
||||
}
|
||||
|
||||
const envMap = {
|
||||
Port: 'PORT'
|
||||
}
|
||||
|
||||
const parseNumber = (str: string | undefined): number | undefined => (str !== undefined ? Number(str) : undefined)
|
||||
|
||||
const config: Config = (() => {
|
||||
const port = parseNumber(process.env[envMap.Port])
|
||||
if (port === undefined) {
|
||||
throw Error('Missing env variable: Port')
|
||||
}
|
||||
const params: Config = {
|
||||
port
|
||||
}
|
||||
|
||||
return params
|
||||
})()
|
||||
|
||||
export default config
|
23
services/hook/pod-hook/src/error.ts
Normal file
23
services/hook/pod-hook/src/error.ts
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
export class ApiError extends Error {
|
||||
constructor (
|
||||
readonly code: string,
|
||||
readonly message: string
|
||||
) {
|
||||
super(message)
|
||||
}
|
||||
}
|
22
services/hook/pod-hook/src/index.ts
Normal file
22
services/hook/pod-hook/src/index.ts
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { main } from './main'
|
||||
|
||||
void main().catch((err) => {
|
||||
if (err != null) {
|
||||
console.error(err)
|
||||
}
|
||||
})
|
78
services/hook/pod-hook/src/main.ts
Normal file
78
services/hook/pod-hook/src/main.ts
Normal file
@ -0,0 +1,78 @@
|
||||
//
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { createServer, listen } from './server'
|
||||
import { Endpoint } from './types'
|
||||
import config from './config'
|
||||
|
||||
export const main = async (): Promise<void> => {
|
||||
const endpoints: Endpoint[] = [
|
||||
{
|
||||
endpoint: '/mta',
|
||||
type: 'post',
|
||||
handler: async (req, res) => {
|
||||
console.log('mta-hook retrieved')
|
||||
const message = getMessageInfo(req.body)
|
||||
console.log('Email from:', message?.from)
|
||||
// TODO: Send request to add message or put event to the queue
|
||||
|
||||
res.json({
|
||||
action: 'accept'
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const server = listen(createServer(endpoints), config.port)
|
||||
|
||||
const shutdown = (): void => {
|
||||
server.close(() => {
|
||||
process.exit()
|
||||
})
|
||||
}
|
||||
|
||||
process.on('SIGINT', shutdown)
|
||||
process.on('SIGTERM', shutdown)
|
||||
process.on('uncaughtException', (e) => {
|
||||
console.error(e)
|
||||
})
|
||||
process.on('unhandledRejection', (e) => {
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
|
||||
const getMessageInfo = (
|
||||
body: any
|
||||
): { from: string, to: string[], subject: string, contents: any, size: number } | undefined => {
|
||||
try {
|
||||
const from = body.envelope.from.address
|
||||
const to = body.envelope.to.map((recipient: any) => recipient.address)
|
||||
const subjectHeader = body.message.headers.find((header: any) => header[0] === 'Subject')
|
||||
const subject = subjectHeader !== undefined ? subjectHeader[1] : 'No Subject'
|
||||
const contents = body.message.contents
|
||||
const size = body.message.size
|
||||
|
||||
return {
|
||||
from,
|
||||
to,
|
||||
subject,
|
||||
contents,
|
||||
size
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to parse message:', e)
|
||||
return undefined
|
||||
}
|
||||
}
|
69
services/hook/pod-hook/src/server.ts
Normal file
69
services/hook/pod-hook/src/server.ts
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import cors from 'cors'
|
||||
import express, { Express, NextFunction, Request, Response } from 'express'
|
||||
import { Server } from 'http'
|
||||
|
||||
import { Endpoint, RequestHandler } from './types'
|
||||
import { ApiError } from './error'
|
||||
|
||||
const catchError = (fn: RequestHandler) => (req: Request, res: Response, next: NextFunction) => {
|
||||
void (async () => {
|
||||
try {
|
||||
await fn(req, res, next)
|
||||
} catch (err: unknown) {
|
||||
next(err)
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
||||
export function createServer (endpoints: Endpoint[]): Express {
|
||||
const app = express()
|
||||
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
|
||||
endpoints.forEach((endpoint) => {
|
||||
if (endpoint.type === 'get') {
|
||||
app.get(endpoint.endpoint, catchError(endpoint.handler))
|
||||
} else if (endpoint.type === 'post') {
|
||||
app.post(endpoint.endpoint, catchError(endpoint.handler))
|
||||
}
|
||||
})
|
||||
|
||||
app.use((_req, res, _next) => {
|
||||
res.status(404).send({ message: 'Not found' })
|
||||
})
|
||||
|
||||
app.use((err: any, _req: any, res: any, _next: any) => {
|
||||
if (err instanceof ApiError) {
|
||||
res.status(400).send({ code: err.code, message: err.message })
|
||||
return
|
||||
}
|
||||
|
||||
res.status(500).send({ message: err.message })
|
||||
})
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
export function listen (e: Express, port: number, host?: string): Server {
|
||||
const cb = (): void => {
|
||||
console.log(`Hook service has been started at ${host ?? '*'}:${port}`)
|
||||
}
|
||||
|
||||
return host !== undefined ? e.listen(port, host, cb) : e.listen(port, cb)
|
||||
}
|
26
services/hook/pod-hook/src/types.ts
Normal file
26
services/hook/pod-hook/src/types.ts
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright © 2025 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
|
||||
export type RequestType = 'get' | 'post'
|
||||
|
||||
export type RequestHandler = (req: Request, res: Response, next?: NextFunction) => Promise<void>
|
||||
|
||||
export interface Endpoint {
|
||||
endpoint: string
|
||||
type: RequestType
|
||||
handler: RequestHandler
|
||||
}
|
10
services/hook/pod-hook/tsconfig.json
Normal file
10
services/hook/pod-hook/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"declarationDir": "./types",
|
||||
"tsBuildInfoFile": ".build/build.tsbuildinfo"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user