@canmingir/link-express 1.6.11 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.ts +29 -0
- package/index.ts +2 -0
- package/package.json +52 -12
- package/{prepare.js → prepare.ts} +1 -1
- package/src/{authorization.js → authorization.ts} +31 -9
- package/src/config.ts +112 -0
- package/src/dynamodb.ts +24 -0
- package/src/{error.js → error.ts} +30 -11
- package/src/express.ts +66 -0
- package/src/lib/{settings.js → settings.ts} +16 -4
- package/src/lib/test.ts +68 -0
- package/src/{logger.js → logger.ts} +11 -9
- package/src/metrics/{dbMetrics.js → dbMetrics.ts} +37 -14
- package/src/models/Organization.model.ts +27 -0
- package/src/models/Permission.model.ts +48 -0
- package/src/models/Project.model.ts +50 -0
- package/src/models/Settings.model.ts +31 -0
- package/src/models/{index.js → index.ts} +8 -8
- package/src/platform.ts +55 -0
- package/src/postgres.ts +309 -0
- package/src/routes/index.ts +8 -0
- package/src/routes/metrics.ts +13 -0
- package/src/routes/oauth.ts +267 -0
- package/src/routes/{organizations.js → organizations.ts} +10 -8
- package/src/routes/{permissions.js → permissions.ts} +8 -6
- package/src/routes/{projects.js → projects.ts} +22 -16
- package/src/routes/settings.ts +31 -0
- package/src/schemas/{Organization.js → Organization.ts} +2 -2
- package/src/schemas/{Permission.js → Permission.ts} +2 -2
- package/src/schemas/{Project.js → Project.ts} +2 -2
- package/src/schemas/index.ts +5 -0
- package/src/sequelize.ts +13 -0
- package/src/{test.js → test.ts} +11 -13
- package/src/types/Organization.ts +9 -0
- package/src/types/Permission.ts +13 -0
- package/src/types/Project.ts +14 -0
- package/src/types/index.ts +5 -0
- package/tsconfig.json +32 -0
- package/.eslintrc.js +0 -20
- package/index.js +0 -1
- package/src/config.js +0 -21
- package/src/dynamodb.js +0 -18
- package/src/express.js +0 -58
- package/src/lib/test.js +0 -69
- package/src/models/Organization.js +0 -17
- package/src/models/Permission.js +0 -33
- package/src/models/Project.js +0 -37
- package/src/models/Settings.js +0 -21
- package/src/openapi.js +0 -40
- package/src/platform.js +0 -56
- package/src/postgres.js +0 -308
- package/src/routes/index.js +0 -15
- package/src/routes/metrics.js +0 -12
- package/src/routes/oauth.js +0 -213
- package/src/routes/settings.js +0 -25
- package/src/schemas/index.js +0 -5
package/.eslintrc.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
env: {
|
|
3
|
+
es6: true,
|
|
4
|
+
node: true,
|
|
5
|
+
mocha: true,
|
|
6
|
+
},
|
|
7
|
+
parser: "@typescript-eslint/parser",
|
|
8
|
+
parserOptions: {
|
|
9
|
+
ecmaVersion: 2022,
|
|
10
|
+
sourceType: "module",
|
|
11
|
+
project: "./tsconfig.json",
|
|
12
|
+
},
|
|
13
|
+
plugins: ["@typescript-eslint"],
|
|
14
|
+
extends: [
|
|
15
|
+
"eslint:recommended",
|
|
16
|
+
"plugin:@typescript-eslint/recommended",
|
|
17
|
+
"plugin:prettier/recommended",
|
|
18
|
+
],
|
|
19
|
+
ignorePatterns: ["/node_modules", "/dist"],
|
|
20
|
+
rules: {
|
|
21
|
+
eqeqeq: ["error", "always"],
|
|
22
|
+
"no-console": "off",
|
|
23
|
+
"no-eval": "error",
|
|
24
|
+
"no-var": "error",
|
|
25
|
+
"prefer-arrow-callback": "error",
|
|
26
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
27
|
+
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
|
28
|
+
},
|
|
29
|
+
};
|
package/index.ts
ADDED
package/package.json
CHANGED
|
@@ -1,22 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canmingir/link-express",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "index.
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"types": "index.ts",
|
|
7
|
+
"typesVersions": {
|
|
8
|
+
"*": {
|
|
9
|
+
"models": [
|
|
10
|
+
"src/models/index.ts"
|
|
11
|
+
],
|
|
12
|
+
"test": [
|
|
13
|
+
"src/test.ts"
|
|
14
|
+
],
|
|
15
|
+
"authorization": [
|
|
16
|
+
"src/authorization.ts"
|
|
17
|
+
],
|
|
18
|
+
"error": [
|
|
19
|
+
"src/error.ts"
|
|
20
|
+
],
|
|
21
|
+
"types": [
|
|
22
|
+
"src/types/index.ts"
|
|
23
|
+
],
|
|
24
|
+
"sequelize": [
|
|
25
|
+
"src/sequelize.ts"
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
},
|
|
6
29
|
"author": "NucTeam",
|
|
7
30
|
"exports": {
|
|
8
|
-
".": "./index.
|
|
9
|
-
"./models": "./src/models/index.
|
|
10
|
-
"./test": "./src/test.
|
|
11
|
-
"./authorization": "./src/authorization.
|
|
12
|
-
"./error": "./src/error.
|
|
31
|
+
".": "./index.ts",
|
|
32
|
+
"./models": "./src/models/index.ts",
|
|
33
|
+
"./test": "./src/test.ts",
|
|
34
|
+
"./authorization": "./src/authorization.ts",
|
|
35
|
+
"./error": "./src/error.ts",
|
|
36
|
+
"./types": "./src/types/index.ts",
|
|
37
|
+
"./sequelize": "./src/sequelize.ts"
|
|
13
38
|
},
|
|
14
39
|
"scripts": {
|
|
15
|
-
"prepare": "
|
|
40
|
+
"prepare": "tsx prepare.ts",
|
|
41
|
+
"build": "tsc",
|
|
16
42
|
"dev": "node server --dev",
|
|
17
43
|
"start": "node server",
|
|
18
44
|
"test": "echo 'No tests'",
|
|
19
|
-
"lint": "eslint . --ext .
|
|
45
|
+
"lint": "eslint . --ext .ts"
|
|
20
46
|
},
|
|
21
47
|
"dependencies": {
|
|
22
48
|
"@aws-sdk/client-dynamodb": "^3.614.0",
|
|
@@ -37,12 +63,24 @@
|
|
|
37
63
|
"pino": "^10.1.0",
|
|
38
64
|
"pino-elasticsearch": "^8.1.0",
|
|
39
65
|
"prom-client": "^15.1.3",
|
|
40
|
-
"sequelize": "^6.37.
|
|
66
|
+
"sequelize": "^6.37.7",
|
|
67
|
+
"sequelize-typescript": "^2.1.6",
|
|
41
68
|
"swagger-jsdoc": "^6.2.8",
|
|
42
|
-
"swagger-ui-express": "^5.0.1",
|
|
43
69
|
"uuid": "^10.0.0"
|
|
44
70
|
},
|
|
45
71
|
"devDependencies": {
|
|
72
|
+
"@types/cors": "^2.8.19",
|
|
73
|
+
"@types/express": "^5.0.5",
|
|
74
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
75
|
+
"@types/lodash": "^4.17.21",
|
|
76
|
+
"@types/morgan": "^1.9.10",
|
|
77
|
+
"@types/node": "^24.10.1",
|
|
78
|
+
"@types/pg": "^8.15.6",
|
|
79
|
+
"@types/swagger-jsdoc": "^6.0.4",
|
|
80
|
+
"@types/swagger-ui-express": "^4.1.8",
|
|
81
|
+
"@types/uuid": "^10.0.0",
|
|
82
|
+
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
|
83
|
+
"@typescript-eslint/parser": "^8.48.0",
|
|
46
84
|
"axios-mock-adapter": "^1.21.1",
|
|
47
85
|
"eslint": "^8.57.1",
|
|
48
86
|
"eslint-config-prettier": "^8.5.0",
|
|
@@ -50,6 +88,8 @@
|
|
|
50
88
|
"mocha": "10.8.2",
|
|
51
89
|
"prettier": "^2.6.2",
|
|
52
90
|
"sqlite3": "^5.1.6",
|
|
53
|
-
"supertest": "^7.0.0"
|
|
91
|
+
"supertest": "^7.0.0",
|
|
92
|
+
"tsx": "^4.20.6",
|
|
93
|
+
"typescript": "^5.9.3"
|
|
54
94
|
}
|
|
55
95
|
}
|
|
@@ -1,6 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
import { Request, Response, NextFunction } from "express";
|
|
3
|
+
import { AuthorizationError } from "./error";
|
|
4
|
+
|
|
5
|
+
interface Session {
|
|
6
|
+
projectId: string;
|
|
7
|
+
userId: string;
|
|
8
|
+
roles: string[];
|
|
9
|
+
appId: string;
|
|
10
|
+
organizationId: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare module "express-serve-static-core" {
|
|
14
|
+
interface Request {
|
|
15
|
+
session: Session;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function verify(req: Request, _res: Response, next: NextFunction): void {
|
|
4
20
|
if (process.env.PROFILE === "TEST") {
|
|
5
21
|
switch (process.env.PROJECT_ID) {
|
|
6
22
|
case "0c756054-2d28-4f87-9b12-8023a79136a5":
|
|
@@ -69,8 +85,15 @@ function verify(req, res, next) {
|
|
|
69
85
|
try {
|
|
70
86
|
const { sub, aud, rls, aid, oid } = jwt.verify(
|
|
71
87
|
token,
|
|
72
|
-
process.env.JWT_SECRET
|
|
73
|
-
)
|
|
88
|
+
process.env.JWT_SECRET as string
|
|
89
|
+
) as {
|
|
90
|
+
sub: string;
|
|
91
|
+
aud: string;
|
|
92
|
+
rls: string[];
|
|
93
|
+
aid: string;
|
|
94
|
+
oid: string;
|
|
95
|
+
};
|
|
96
|
+
|
|
74
97
|
req.session = {
|
|
75
98
|
projectId: aud,
|
|
76
99
|
userId: sub,
|
|
@@ -85,9 +108,8 @@ function verify(req, res, next) {
|
|
|
85
108
|
next();
|
|
86
109
|
}
|
|
87
110
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return (req, res, next) => {
|
|
111
|
+
function authorize(_role: string) {
|
|
112
|
+
return (req: Request, _res: Response, next: NextFunction): void => {
|
|
91
113
|
const { roles } = req.session;
|
|
92
114
|
|
|
93
115
|
// TODO Add expression check for role
|
|
@@ -99,4 +121,4 @@ function authorize(role) {
|
|
|
99
121
|
};
|
|
100
122
|
}
|
|
101
123
|
|
|
102
|
-
|
|
124
|
+
export { verify, authorize };
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import _ from "lodash";
|
|
2
|
+
|
|
3
|
+
interface LoggerConfig {
|
|
4
|
+
elasticsearch: {
|
|
5
|
+
index: string;
|
|
6
|
+
consistency?: string;
|
|
7
|
+
node: string;
|
|
8
|
+
esVersion?: number;
|
|
9
|
+
flushBytes?: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ProjectConfig {
|
|
14
|
+
name: string;
|
|
15
|
+
version: string;
|
|
16
|
+
oauth?: {
|
|
17
|
+
jwt: {
|
|
18
|
+
identifier: string;
|
|
19
|
+
};
|
|
20
|
+
providers: Record<
|
|
21
|
+
string,
|
|
22
|
+
{
|
|
23
|
+
tokenUrl: string;
|
|
24
|
+
userUrl: string;
|
|
25
|
+
clientId: string;
|
|
26
|
+
redirectUri?: string;
|
|
27
|
+
userIdentifier: string;
|
|
28
|
+
userFields: {
|
|
29
|
+
name: string;
|
|
30
|
+
displayName: string;
|
|
31
|
+
avatarUrl: string;
|
|
32
|
+
email: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
>;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface LinkConfig {
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface OpenapiConfig {
|
|
44
|
+
[key: string]: unknown;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface PostgresConfig {
|
|
48
|
+
uri: string;
|
|
49
|
+
debug?: boolean;
|
|
50
|
+
sync?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface DynamodbConfig {
|
|
54
|
+
region: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface PushGatewayConfig {
|
|
58
|
+
url?: string;
|
|
59
|
+
jobName?: string;
|
|
60
|
+
instance?: string;
|
|
61
|
+
interval?: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface MetricsConfig {
|
|
65
|
+
enabled: boolean;
|
|
66
|
+
url?: string;
|
|
67
|
+
pushGateway: PushGatewayConfig;
|
|
68
|
+
interval?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface Config {
|
|
72
|
+
link: LinkConfig;
|
|
73
|
+
project: ProjectConfig | null;
|
|
74
|
+
openapi: OpenapiConfig;
|
|
75
|
+
postgres: PostgresConfig | null;
|
|
76
|
+
dynamodb: DynamodbConfig | null;
|
|
77
|
+
pushGateway: PushGatewayConfig;
|
|
78
|
+
title?: string;
|
|
79
|
+
version?: string;
|
|
80
|
+
logger?: LoggerConfig;
|
|
81
|
+
metrics?: MetricsConfig;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let _config: Config = {
|
|
85
|
+
link: {},
|
|
86
|
+
project: null,
|
|
87
|
+
openapi: {},
|
|
88
|
+
postgres: null,
|
|
89
|
+
dynamodb: null,
|
|
90
|
+
pushGateway: {},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
function init(config: Partial<Config> = {}): Config {
|
|
94
|
+
_config = _.merge(
|
|
95
|
+
{
|
|
96
|
+
link: {},
|
|
97
|
+
project: null,
|
|
98
|
+
openapi: {},
|
|
99
|
+
postgres: null,
|
|
100
|
+
dynamodb: null,
|
|
101
|
+
pushGateway: {},
|
|
102
|
+
},
|
|
103
|
+
config
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return _config;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const getConfig = (): Config => _config;
|
|
110
|
+
|
|
111
|
+
export { getConfig, init, Config };
|
|
112
|
+
export default getConfig;
|
package/src/dynamodb.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|
2
|
+
import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
|
|
3
|
+
import { getConfig } from "./config";
|
|
4
|
+
import dotenv from "dotenv";
|
|
5
|
+
|
|
6
|
+
dotenv.config();
|
|
7
|
+
|
|
8
|
+
const { dynamodb } = getConfig();
|
|
9
|
+
|
|
10
|
+
if (!dynamodb) {
|
|
11
|
+
throw new Error("DynamoDB configuration is required");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const client = new DynamoDBClient({
|
|
15
|
+
region: dynamodb.region,
|
|
16
|
+
credentials: {
|
|
17
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID as string,
|
|
18
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const docClient = DynamoDBDocumentClient.from(client);
|
|
23
|
+
|
|
24
|
+
export { docClient };
|
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
import { ValidationError } from "joi";
|
|
2
|
+
import { Request, Response, NextFunction } from "express";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
interface AxiosError extends Error {
|
|
5
|
+
isAxiosError: boolean;
|
|
6
|
+
response?: {
|
|
7
|
+
status: number;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ErrorWithError {
|
|
12
|
+
error: unknown;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const handle = (
|
|
16
|
+
err:
|
|
17
|
+
| string
|
|
18
|
+
| ValidationError
|
|
19
|
+
| AuthorizationError
|
|
20
|
+
| AuthenticationError
|
|
21
|
+
| NotFoundError
|
|
22
|
+
| AxiosError
|
|
23
|
+
| ErrorWithError
|
|
24
|
+
| Error,
|
|
25
|
+
_req: Request,
|
|
26
|
+
res: Response,
|
|
27
|
+
_next: NextFunction
|
|
28
|
+
): Response => {
|
|
5
29
|
if (typeof err === "string") {
|
|
6
30
|
return res.status(400).json({ error: err });
|
|
7
31
|
}
|
|
@@ -22,11 +46,11 @@ const handle = (err, req, res, next) => {
|
|
|
22
46
|
return res.status(404).end();
|
|
23
47
|
}
|
|
24
48
|
|
|
25
|
-
if (err.isAxiosError) {
|
|
49
|
+
if ("isAxiosError" in err && err.isAxiosError) {
|
|
26
50
|
return res.status(err.response?.status || 503).end();
|
|
27
51
|
}
|
|
28
52
|
|
|
29
|
-
if (err.error) {
|
|
53
|
+
if ("error" in err && err.error) {
|
|
30
54
|
return res.status(400).json(err);
|
|
31
55
|
} else {
|
|
32
56
|
console.error(err);
|
|
@@ -38,9 +62,4 @@ class AuthorizationError extends Error {}
|
|
|
38
62
|
class AuthenticationError extends Error {}
|
|
39
63
|
class NotFoundError extends Error {}
|
|
40
64
|
|
|
41
|
-
|
|
42
|
-
handle,
|
|
43
|
-
AuthorizationError,
|
|
44
|
-
NotFoundError,
|
|
45
|
-
AuthenticationError,
|
|
46
|
-
};
|
|
65
|
+
export { handle, AuthorizationError, NotFoundError, AuthenticationError };
|
package/src/express.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import express, { Request, Response, NextFunction } from "express";
|
|
2
|
+
import "express-async-errors";
|
|
3
|
+
import cors from "cors";
|
|
4
|
+
import morgan from "morgan";
|
|
5
|
+
import helmet from "helmet";
|
|
6
|
+
import * as error from "./error";
|
|
7
|
+
import * as authorization from "./authorization";
|
|
8
|
+
import settings from "./routes/settings";
|
|
9
|
+
import metrics from "./routes/metrics";
|
|
10
|
+
import { getConfig } from "./config";
|
|
11
|
+
|
|
12
|
+
const app = express();
|
|
13
|
+
|
|
14
|
+
const appConfig = getConfig();
|
|
15
|
+
|
|
16
|
+
app.use(helmet());
|
|
17
|
+
app.use(cors());
|
|
18
|
+
app.use(morgan("tiny"));
|
|
19
|
+
|
|
20
|
+
app.use(
|
|
21
|
+
express.json(),
|
|
22
|
+
(err: Error, _req: Request, res: Response, next: NextFunction) =>
|
|
23
|
+
err ? res.status(422).end() : next()
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (appConfig.project) {
|
|
27
|
+
import("./routes/oauth.ts").then((oauthModule) => {
|
|
28
|
+
const oauth = oauthModule.default || oauthModule;
|
|
29
|
+
app.use(
|
|
30
|
+
"/oauth",
|
|
31
|
+
express.urlencoded(),
|
|
32
|
+
(err: Error, _req: Request, res: Response, next: NextFunction) =>
|
|
33
|
+
err ? res.status(422).end() : next(),
|
|
34
|
+
oauth
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
app.use("/metrics", metrics);
|
|
40
|
+
|
|
41
|
+
setImmediate(async () => {
|
|
42
|
+
process.env.PROFILE === "TEST" && app.use(authorization.verify);
|
|
43
|
+
|
|
44
|
+
if (appConfig.project) {
|
|
45
|
+
const [permissionsModule, organizationsModule, projectsModule] =
|
|
46
|
+
await Promise.all([
|
|
47
|
+
import("./routes/permissions.ts"),
|
|
48
|
+
import("./routes/organizations.ts"),
|
|
49
|
+
import("./routes/projects.ts"),
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
const permissions = permissionsModule.default || permissionsModule;
|
|
53
|
+
const organizations = organizationsModule.default || organizationsModule;
|
|
54
|
+
const projects = projectsModule.default || projectsModule;
|
|
55
|
+
|
|
56
|
+
app.use("/projects", projects);
|
|
57
|
+
app.use("/organizations", organizations);
|
|
58
|
+
app.use("/permissions", permissions);
|
|
59
|
+
app.use("/projects/:projectId/settings", settings);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
app.use((_req: Request, res: Response) => res.status(404).end());
|
|
63
|
+
app.use(error.handle);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
export default app;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import Settings from "../models/Settings.model";
|
|
2
2
|
|
|
3
|
-
async function get({
|
|
3
|
+
async function get({
|
|
4
|
+
projectId,
|
|
5
|
+
}: {
|
|
6
|
+
projectId: string;
|
|
7
|
+
}): Promise<Record<string, unknown>> {
|
|
4
8
|
const settingsInstance = await Settings.findOne({
|
|
5
9
|
where: { projectId },
|
|
6
10
|
});
|
|
@@ -12,7 +16,15 @@ async function get({ projectId }) {
|
|
|
12
16
|
}
|
|
13
17
|
}
|
|
14
18
|
|
|
15
|
-
async function upsert(
|
|
19
|
+
async function upsert(
|
|
20
|
+
{
|
|
21
|
+
projectId,
|
|
22
|
+
}: {
|
|
23
|
+
projectId: string;
|
|
24
|
+
},
|
|
25
|
+
settings: Record<string, unknown>,
|
|
26
|
+
_params?: Record<string, unknown>
|
|
27
|
+
): Promise<void> {
|
|
16
28
|
const settingsInstance = await Settings.findOne({
|
|
17
29
|
where: { projectId },
|
|
18
30
|
});
|
|
@@ -33,4 +45,4 @@ async function upsert({ projectId }, settings) {
|
|
|
33
45
|
}
|
|
34
46
|
}
|
|
35
47
|
|
|
36
|
-
|
|
48
|
+
export { get, upsert };
|
package/src/lib/test.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
import platform from "../platform";
|
|
3
|
+
import { Sequelize } from "sequelize";
|
|
4
|
+
|
|
5
|
+
dotenv.config({ path: ".env.test" });
|
|
6
|
+
|
|
7
|
+
platform.init({
|
|
8
|
+
project: {
|
|
9
|
+
name: "test",
|
|
10
|
+
version: "1.0.0",
|
|
11
|
+
oauth: {
|
|
12
|
+
jwt: {
|
|
13
|
+
identifier: "email",
|
|
14
|
+
},
|
|
15
|
+
providers: {
|
|
16
|
+
github: {
|
|
17
|
+
tokenUrl: "https://github.com/login/oauth/access_token",
|
|
18
|
+
userUrl: "https://api.github.com/user",
|
|
19
|
+
clientId: "0c2844d3d19dc9293fc5",
|
|
20
|
+
redirectUri: "http://localhost:5173/callback",
|
|
21
|
+
userIdentifier: "id",
|
|
22
|
+
userFields: {
|
|
23
|
+
name: "name",
|
|
24
|
+
displayName: "login",
|
|
25
|
+
avatarUrl: "avatar_url",
|
|
26
|
+
email: "email",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
postgres: {
|
|
33
|
+
uri: "sqlite::memory:",
|
|
34
|
+
debug: true,
|
|
35
|
+
sync: false,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
import { init } from "../models";
|
|
40
|
+
|
|
41
|
+
async function reset(): Promise<void> {
|
|
42
|
+
const { sequelize }: { sequelize: Sequelize } = await import("../postgres");
|
|
43
|
+
|
|
44
|
+
if (await init()) {
|
|
45
|
+
await sequelize.sync({ force: true });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
await sequelize.models.Organization.destroy({ truncate: true });
|
|
49
|
+
await sequelize.models.Project.destroy({ truncate: true });
|
|
50
|
+
await sequelize.models.Permission.destroy({ truncate: true });
|
|
51
|
+
await sequelize.models.Settings.destroy({ truncate: true });
|
|
52
|
+
|
|
53
|
+
async function seed(): Promise<void> {
|
|
54
|
+
const { seed: organizations } = await import("../seeds/Organization.json");
|
|
55
|
+
const { seed: permissions } = await import("../seeds/Permission.json");
|
|
56
|
+
const { seed: projects } = await import("../seeds/Project.json");
|
|
57
|
+
const { seed: settings } = await import("../seeds/Settings.json");
|
|
58
|
+
|
|
59
|
+
await sequelize.models.Organization.bulkCreate(organizations);
|
|
60
|
+
await sequelize.models.Project.bulkCreate(projects);
|
|
61
|
+
await sequelize.models.Permission.bulkCreate(permissions);
|
|
62
|
+
await sequelize.models.Settings.bulkCreate(settings);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
await seed();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { reset };
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { ecsFormat } from "@elastic/ecs-pino-format";
|
|
2
|
+
import pino from "pino";
|
|
3
|
+
import pinoElastic from "pino-elasticsearch";
|
|
4
|
+
import { getConfig } from "./config";
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
+
const { logger: loggerConfig, project } = getConfig();
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
if (!loggerConfig || !project) {
|
|
9
|
+
throw new Error("Logger and project configuration are required");
|
|
10
|
+
}
|
|
8
11
|
|
|
9
|
-
const streams = [{ stream: process.stdout }];
|
|
12
|
+
const streams: pino.StreamEntry[] = [{ stream: process.stdout }];
|
|
10
13
|
|
|
11
14
|
const streamToElastic = pinoElastic({
|
|
12
15
|
index: loggerConfig.elasticsearch.index,
|
|
13
|
-
consistency: loggerConfig.elasticsearch.consistency || "one",
|
|
14
16
|
node: loggerConfig.elasticsearch.node,
|
|
15
17
|
esVersion: loggerConfig.elasticsearch.esVersion || 8,
|
|
16
18
|
flushBytes: loggerConfig.elasticsearch.flushBytes || 1000,
|
|
17
|
-
});
|
|
19
|
+
} as Parameters<typeof pinoElastic>[0]);
|
|
18
20
|
|
|
19
21
|
streams.push({ stream: streamToElastic });
|
|
20
22
|
|
|
@@ -31,4 +33,4 @@ const logger = pino(
|
|
|
31
33
|
pino.multistream(streams)
|
|
32
34
|
);
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
export default logger;
|