@medyll/idae-api 0.1.0 → 0.3.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/README.md +240 -0
- package/dist/client/IdaeApiClient.d.ts +21 -0
- package/dist/client/IdaeApiClient.js +31 -0
- package/dist/client/IdaeApiClientCollection.d.ts +14 -0
- package/dist/client/IdaeApiClientCollection.js +53 -0
- package/dist/client/IdaeApiClientConfig.d.ts +23 -0
- package/dist/client/IdaeApiClientConfig.js +43 -0
- package/dist/client/IdaeApiClientRequest.d.ts +24 -0
- package/dist/client/IdaeApiClientRequest.js +47 -0
- package/dist/config/routeDefinitions.d.ts +10 -0
- package/dist/config/routeDefinitions.js +48 -0
- package/dist/idae-api.d.ts +15 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/server/IdaeApi.d.ts +38 -0
- package/dist/server/IdaeApi.js +213 -0
- package/dist/server/adapters/MongoDBAdapter.d.ts +20 -0
- package/dist/server/adapters/MongoDBAdapter.js +66 -0
- package/dist/server/adapters/MySQLAdapter.d.ts +23 -0
- package/dist/server/adapters/MySQLAdapter.js +78 -0
- package/dist/server/adapters/types.d.ts +12 -0
- package/dist/server/engine/DatabaseManager.d.ts +26 -0
- package/dist/server/engine/DatabaseManager.js +60 -0
- package/dist/server/engine/mongooseConnectionManager.d.ts +11 -0
- package/dist/server/engine/mongooseConnectionManager.js +25 -0
- package/dist/server/engine/routeManager.d.ts +13 -0
- package/dist/server/engine/routeManager.js +38 -0
- package/dist/server/engine/types.d.ts +10 -0
- package/dist/server/engine/types.js +1 -0
- package/dist/server/middleware/authMiddleware.d.ts +15 -0
- package/dist/server/middleware/authMiddleware.js +83 -0
- package/dist/server/middleware/databaseMiddleware.d.ts +2 -0
- package/dist/server/middleware/databaseMiddleware.js +15 -0
- package/dist/server/services/AuthService.d.ts +13 -0
- package/dist/server/services/AuthService.js +56 -0
- package/dist/server/services/DBaseService.d.ts +17 -0
- package/dist/server/services/DBaseService.js +62 -0
- package/package.json +31 -20
- package/dist/ApiServe.d.ts +0 -10
- package/dist/ApiServe.js +0 -113
- package/dist/engine/DBaseManager.d.ts +0 -15
- package/dist/engine/DBaseManager.js +0 -49
- package/dist/engine/DBaseService.d.ts +0 -16
- package/dist/engine/DBaseService.js +0 -48
- package/dist/engine/tools.d.ts +0 -2
- package/dist/engine/tools.js +0 -11
- package/dist/engine/types.d.ts +0 -9
- /package/dist/{engine → server/adapters}/types.js +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// packages\idae-api\src\lib\authMiddleware.ts
|
|
2
|
+
import jwt from 'jsonwebtoken';
|
|
3
|
+
class AuthMiddleWare {
|
|
4
|
+
constructor(jwtSecret, tokenExpiration) {
|
|
5
|
+
this.jwtSecret = jwtSecret;
|
|
6
|
+
this.tokenExpiration = tokenExpiration;
|
|
7
|
+
}
|
|
8
|
+
// Generate a JWT token
|
|
9
|
+
generateToken(payload) {
|
|
10
|
+
return jwt.sign(payload, this.jwtSecret, { expiresIn: this.tokenExpiration });
|
|
11
|
+
}
|
|
12
|
+
// Verify a JWT token
|
|
13
|
+
verifyToken(token) {
|
|
14
|
+
try {
|
|
15
|
+
return jwt.verify(token, this.jwtSecret);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw new Error('Invalid token');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Refresh a JWT token
|
|
22
|
+
refreshToken(token) {
|
|
23
|
+
const payload = this.verifyToken(token);
|
|
24
|
+
delete payload.iat;
|
|
25
|
+
delete payload.exp;
|
|
26
|
+
return this.generateToken(payload);
|
|
27
|
+
}
|
|
28
|
+
// Middleware to verify JWT token
|
|
29
|
+
createMiddleware() {
|
|
30
|
+
return (req, res, next) => {
|
|
31
|
+
const authHeader = req.headers.authorization;
|
|
32
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
33
|
+
return res.status(401).json({ error: 'Unauthorized' });
|
|
34
|
+
}
|
|
35
|
+
const token = authHeader.split(' ')[1];
|
|
36
|
+
try {
|
|
37
|
+
const user = this.verifyToken(token);
|
|
38
|
+
req.user = user; // Attach user info to the request object
|
|
39
|
+
next();
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return res.status(401).json({ error: 'Unauthorized' });
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Configure authentication routes
|
|
47
|
+
configureAuthRoutes(app) {
|
|
48
|
+
app.post('/login', this.handleLogin.bind(this));
|
|
49
|
+
app.post('/logout', this.handleLogout.bind(this));
|
|
50
|
+
app.post('/refresh-token', this.handleRefreshToken.bind(this));
|
|
51
|
+
}
|
|
52
|
+
// Handle login
|
|
53
|
+
handleLogin(req, res) {
|
|
54
|
+
const { username, password } = req.body;
|
|
55
|
+
// Validate user credentials (this is a placeholder, replace with actual validation logic)
|
|
56
|
+
if (username === 'admin' && password === 'password') {
|
|
57
|
+
const payload = { username };
|
|
58
|
+
const token = this.generateToken(payload);
|
|
59
|
+
res.json({ token });
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
res.status(401).json({ error: 'Invalid credentials' });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Handle logout
|
|
66
|
+
handleLogout(req, res) {
|
|
67
|
+
// Invalidate the token (this is a placeholder, implement actual token invalidation logic if needed)
|
|
68
|
+
res.json({ message: 'Logged out successfully' });
|
|
69
|
+
}
|
|
70
|
+
// Handle token refresh
|
|
71
|
+
handleRefreshToken(req, res) {
|
|
72
|
+
const { token } = req.body;
|
|
73
|
+
try {
|
|
74
|
+
const newToken = this.refreshToken(token);
|
|
75
|
+
res.json({ token: newToken });
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
res.status(401).json({ error: 'Invalid token' });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// always use named exports !
|
|
83
|
+
export { AuthMiddleWare };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// packages\idae-api\src\lib\middleware\databaseMiddleware.ts
|
|
2
|
+
import databaseManager from '../engine/DatabaseManager';
|
|
3
|
+
export const databaseMiddleware = async (req, res, next) => {
|
|
4
|
+
try {
|
|
5
|
+
const { collectionName, dbName, connection } = await databaseManager.connectToDatabase(req);
|
|
6
|
+
req.collectionName = collectionName;
|
|
7
|
+
req.dbConnection = connection;
|
|
8
|
+
req.dbName = dbName;
|
|
9
|
+
next();
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
console.error('Error in database connection middleware:', error);
|
|
13
|
+
next(error);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Express } from 'express';
|
|
2
|
+
export declare class AuthService {
|
|
3
|
+
private jwtSecret;
|
|
4
|
+
private tokenExpiration;
|
|
5
|
+
constructor(jwtSecret: string, tokenExpiration: string);
|
|
6
|
+
generateToken(payload: object): string;
|
|
7
|
+
verifyToken(token: string): any;
|
|
8
|
+
refreshToken(token: string): string;
|
|
9
|
+
configureAuthRoutes(app: Express): void;
|
|
10
|
+
private handleLogin;
|
|
11
|
+
private handleLogout;
|
|
12
|
+
private handleRefreshToken;
|
|
13
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// packages\idae-api\src\lib\services\AuthService.ts
|
|
2
|
+
import jwt from 'jsonwebtoken';
|
|
3
|
+
export class AuthService {
|
|
4
|
+
constructor(jwtSecret, tokenExpiration) {
|
|
5
|
+
this.jwtSecret = jwtSecret;
|
|
6
|
+
this.tokenExpiration = tokenExpiration;
|
|
7
|
+
}
|
|
8
|
+
generateToken(payload) {
|
|
9
|
+
return jwt.sign(payload, this.jwtSecret, { expiresIn: this.tokenExpiration });
|
|
10
|
+
}
|
|
11
|
+
verifyToken(token) {
|
|
12
|
+
try {
|
|
13
|
+
return jwt.verify(token, this.jwtSecret);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
throw new Error('Invalid token');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
refreshToken(token) {
|
|
20
|
+
const payload = this.verifyToken(token);
|
|
21
|
+
delete payload.iat;
|
|
22
|
+
delete payload.exp;
|
|
23
|
+
return this.generateToken(payload);
|
|
24
|
+
}
|
|
25
|
+
configureAuthRoutes(app) {
|
|
26
|
+
app.post('/login', this.handleLogin.bind(this));
|
|
27
|
+
app.post('/logout', this.handleLogout.bind(this));
|
|
28
|
+
app.post('/refresh-token', this.handleRefreshToken.bind(this));
|
|
29
|
+
}
|
|
30
|
+
handleLogin(req, res) {
|
|
31
|
+
const { username, password } = req.body;
|
|
32
|
+
// Validate user credentials (this is a placeholder, replace with actual validation logic)
|
|
33
|
+
if (username === 'admin' && password === 'password') {
|
|
34
|
+
const payload = { username };
|
|
35
|
+
const token = this.generateToken(payload);
|
|
36
|
+
res.json({ token });
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
res.status(401).json({ error: 'Invalid credentials' });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
handleLogout(req, res) {
|
|
43
|
+
// Invalidate the token (this is a placeholder, implement actual token invalidation logic if needed)
|
|
44
|
+
res.json({ message: 'Logged out successfully' });
|
|
45
|
+
}
|
|
46
|
+
handleRefreshToken(req, res) {
|
|
47
|
+
const { token } = req.body;
|
|
48
|
+
try {
|
|
49
|
+
const newToken = this.refreshToken(token);
|
|
50
|
+
res.json({ token: newToken });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
res.status(401).json({ error: 'Invalid token' });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import mongoose, { type Document } from 'mongoose';
|
|
2
|
+
import { type ApiServerRequestParams } from '../engine/types';
|
|
3
|
+
declare class DBaseService<T extends Document> {
|
|
4
|
+
private adapter;
|
|
5
|
+
constructor(collection: string, connection: mongoose.Connection, dbType?: 'mongodb' | 'mysql' | 'mariadb' | 'postgres');
|
|
6
|
+
create(document: Partial<T>): Promise<T>;
|
|
7
|
+
where(params: ApiServerRequestParams): Promise<T[]>;
|
|
8
|
+
findById(id: string): Promise<T | null>;
|
|
9
|
+
findOne(params: ApiServerRequestParams): Promise<T | null>;
|
|
10
|
+
update(id: string, updateData: Partial<T>): Promise<T | null>;
|
|
11
|
+
deleteById(id: string): Promise<T | null>;
|
|
12
|
+
deleteManyByQuery(params: ApiServerRequestParams): Promise<{
|
|
13
|
+
deletedCount?: number;
|
|
14
|
+
}>;
|
|
15
|
+
decodeUrlParams(urlParams: string): ApiServerRequestParams;
|
|
16
|
+
}
|
|
17
|
+
export { DBaseService };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// packages\idae-api\src\lib\engine\DBaseService.ts
|
|
2
|
+
import mongoose, {} from 'mongoose';
|
|
3
|
+
import {} from '../engine/types';
|
|
4
|
+
import { MongoDBAdapter } from '../adapters/MongoDBAdapter';
|
|
5
|
+
class DBaseService {
|
|
6
|
+
constructor(collection, connection, dbType = 'mongodb') {
|
|
7
|
+
switch (dbType) {
|
|
8
|
+
case 'mongodb':
|
|
9
|
+
this.adapter = new MongoDBAdapter(collection, connection);
|
|
10
|
+
break;
|
|
11
|
+
case 'mysql':
|
|
12
|
+
case 'mariadb':
|
|
13
|
+
// TODO: Implement MySQL adapter
|
|
14
|
+
throw new Error('MySQL adapter not implemented yet');
|
|
15
|
+
case 'postgres':
|
|
16
|
+
// TODO: Implement postgres adapter
|
|
17
|
+
throw new Error('Postgres adapter not implemented yet');
|
|
18
|
+
default:
|
|
19
|
+
console.log('dbType', dbType);
|
|
20
|
+
throw new Error(`Unsupported database type: ${dbType}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async create(document) {
|
|
24
|
+
return this.adapter.create(document);
|
|
25
|
+
}
|
|
26
|
+
async where(params) {
|
|
27
|
+
console.log('where', params);
|
|
28
|
+
return this.adapter.where(params);
|
|
29
|
+
}
|
|
30
|
+
async findById(id) {
|
|
31
|
+
return this.adapter.findById(id);
|
|
32
|
+
}
|
|
33
|
+
async findOne(params) {
|
|
34
|
+
return this.adapter.findOne(params);
|
|
35
|
+
}
|
|
36
|
+
async update(id, updateData) {
|
|
37
|
+
return this.adapter.update(id, updateData);
|
|
38
|
+
}
|
|
39
|
+
async deleteById(id) {
|
|
40
|
+
return this.adapter.deleteById(id);
|
|
41
|
+
}
|
|
42
|
+
async deleteManyByQuery(params) {
|
|
43
|
+
return this.adapter.deleteManyByQuery(params);
|
|
44
|
+
}
|
|
45
|
+
decodeUrlParams(urlParams) {
|
|
46
|
+
const params = {};
|
|
47
|
+
const urlParamsArray = urlParams.split('&');
|
|
48
|
+
urlParamsArray.forEach((param) => {
|
|
49
|
+
const [key, value] = param.split('=');
|
|
50
|
+
if (key && value) {
|
|
51
|
+
try {
|
|
52
|
+
params[key] = JSON.parse(decodeURIComponent(value));
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
params[key] = decodeURIComponent(value);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return params;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export { DBaseService };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medyll/idae-api",
|
|
3
3
|
"scope": "@medyll",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
7
7
|
"build": "vite build && npm run package",
|
|
@@ -27,36 +27,47 @@
|
|
|
27
27
|
"!dist/**/*.spec.*"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"@typegoose/auto-increment": "^4.5.0",
|
|
30
31
|
"express": "^4.19.2",
|
|
31
|
-
"
|
|
32
|
+
"jsonwebtoken": "^9.0.2",
|
|
33
|
+
"mongoose": "^8.5.2",
|
|
34
|
+
"mongoose-sequence": "^6.0.1",
|
|
35
|
+
"sequelize": "^6.37.3"
|
|
32
36
|
},
|
|
33
37
|
"peerDependencies": {
|
|
34
38
|
"svelte": "^5.0.0-next.1"
|
|
35
39
|
},
|
|
36
40
|
"devDependencies": {
|
|
37
41
|
"@medyll/idae-prettier-config": "^1.0.0",
|
|
38
|
-
"@sveltejs/adapter-auto": "^3.
|
|
39
|
-
"@sveltejs/kit": "^2.
|
|
40
|
-
"@sveltejs/package": "^2.
|
|
41
|
-
"@sveltejs/vite-plugin-svelte": "^3.
|
|
42
|
-
"@types/eslint": "^
|
|
42
|
+
"@sveltejs/adapter-auto": "^3.2.2",
|
|
43
|
+
"@sveltejs/kit": "^2.5.20",
|
|
44
|
+
"@sveltejs/package": "^2.3.2",
|
|
45
|
+
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
|
46
|
+
"@types/eslint": "^9.6.0",
|
|
43
47
|
"@types/express": "^4.17.21",
|
|
48
|
+
"@types/jest": "^29.5.12",
|
|
49
|
+
"@types/jsonwebtoken": "^9.0.6",
|
|
44
50
|
"@types/mongoose": "^5.11.97",
|
|
45
|
-
"
|
|
51
|
+
"@types/mongoose-sequence": "^3.0.11",
|
|
52
|
+
"@types/supertest": "^6.0.2",
|
|
53
|
+
"eslint": "^9.8.0",
|
|
46
54
|
"eslint-config-prettier": "^9.1.0",
|
|
47
|
-
"eslint-plugin-svelte": "^2.
|
|
48
|
-
"globals": "^15.
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
55
|
+
"eslint-plugin-svelte": "^2.43.0",
|
|
56
|
+
"globals": "^15.9.0",
|
|
57
|
+
"jest": "^29.7.0",
|
|
58
|
+
"mongodb-memory-server": "^10.0.0",
|
|
59
|
+
"mysql2": "^3.11.0",
|
|
60
|
+
"prettier": "^3.3.3",
|
|
61
|
+
"prettier-plugin-svelte": "^3.2.6",
|
|
62
|
+
"supertest": "^7.0.0",
|
|
52
63
|
"svelte": "^5.0.0-next.183",
|
|
53
|
-
"svelte-check": "^3.
|
|
54
|
-
"tslib": "^2.
|
|
55
|
-
"tsx": "^4.16.
|
|
56
|
-
"typescript": "^5.
|
|
57
|
-
"typescript-eslint": "^8.0.0
|
|
58
|
-
"vite": "^5.
|
|
59
|
-
"vitest": "^
|
|
64
|
+
"svelte-check": "^3.8.5",
|
|
65
|
+
"tslib": "^2.6.3",
|
|
66
|
+
"tsx": "^4.16.5",
|
|
67
|
+
"typescript": "^5.5.4",
|
|
68
|
+
"typescript-eslint": "^8.0.0",
|
|
69
|
+
"vite": "^5.3.5",
|
|
70
|
+
"vitest": "^2.0.5"
|
|
60
71
|
},
|
|
61
72
|
"svelte": "./dist/index.js",
|
|
62
73
|
"types": "./dist/index.d.ts",
|
package/dist/ApiServe.d.ts
DELETED
package/dist/ApiServe.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
// ServerConfig.ts
|
|
2
|
-
import express, {} from 'express';
|
|
3
|
-
import DBaseService from './engine/DBaseService.js';
|
|
4
|
-
import DatabaseManager from './engine/DBaseManager.js';
|
|
5
|
-
import mongoose, { Schema, Model, Document } from 'mongoose';
|
|
6
|
-
export class ApiServe {
|
|
7
|
-
constructor(port = 3000) {
|
|
8
|
-
this.app = express();
|
|
9
|
-
this.port = port;
|
|
10
|
-
this.configureMiddleware();
|
|
11
|
-
this.configureRoutes();
|
|
12
|
-
}
|
|
13
|
-
configureMiddleware() {
|
|
14
|
-
this.app.use(express.json());
|
|
15
|
-
}
|
|
16
|
-
getDynamicModel(collectionName) {
|
|
17
|
-
if (mongoose.models[collectionName]) {
|
|
18
|
-
return mongoose.models[collectionName];
|
|
19
|
-
}
|
|
20
|
-
const schema = new Schema({}, { strict: false });
|
|
21
|
-
return mongoose.model(collectionName, schema, collectionName);
|
|
22
|
-
}
|
|
23
|
-
getCollectionName(collectionName) {
|
|
24
|
-
let dbName, collection;
|
|
25
|
-
if (collectionName.includes('.')) {
|
|
26
|
-
[dbName, collection] = collectionName.split('.');
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
collection = collectionName;
|
|
30
|
-
}
|
|
31
|
-
return collection;
|
|
32
|
-
}
|
|
33
|
-
configureRoutes() {
|
|
34
|
-
this.app.use('/:collectionName', DatabaseManager.connectToDatabase);
|
|
35
|
-
this.app.get('/:collectionName', async (req, res) => {
|
|
36
|
-
try {
|
|
37
|
-
const { collectionName } = req.params;
|
|
38
|
-
const collection = this.getCollectionName(collectionName);
|
|
39
|
-
const databaseService = new DBaseService(collection);
|
|
40
|
-
const documents = await databaseService.findAll(req.query);
|
|
41
|
-
res.send(documents);
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
res.status(500).send(error);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
this.app.get('/:collectionName/:id', async (req, res) => {
|
|
48
|
-
try {
|
|
49
|
-
const { collectionName, id } = req.params;
|
|
50
|
-
const collection = this.getCollectionName(collectionName);
|
|
51
|
-
const databaseService = new DBaseService(collection);
|
|
52
|
-
const document = await databaseService.findById(id);
|
|
53
|
-
if (!document) {
|
|
54
|
-
return res.status(404).send({ error: 'Document not found' });
|
|
55
|
-
}
|
|
56
|
-
res.send(document);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
res.status(500).send(error);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
this.app.delete('/:collectionName/:id', async (req, res) => {
|
|
63
|
-
try {
|
|
64
|
-
const { collectionName, id } = req.params;
|
|
65
|
-
const collection = this.getCollectionName(collectionName);
|
|
66
|
-
const databaseService = new DBaseService(collection);
|
|
67
|
-
const result = await databaseService.deleteById(id);
|
|
68
|
-
res.send(result);
|
|
69
|
-
}
|
|
70
|
-
catch (error) {
|
|
71
|
-
res.status(500).send(error);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
this.app.delete('/:collectionName/', async (req, res) => {
|
|
75
|
-
try {
|
|
76
|
-
const { collectionName } = req.params;
|
|
77
|
-
const collection = this.getCollectionName(collectionName);
|
|
78
|
-
const databaseService = new DBaseService(collection);
|
|
79
|
-
const result = await databaseService.deleteManyByQuery(req.query);
|
|
80
|
-
res.send(result);
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
res.status(500).send(error);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
const directCommands = ['findAll', 'create', 'update', 'deleteById', 'deleteManyByQuery'];
|
|
87
|
-
this.app.all('/:collectionName/:command/:params?', async (req, res) => {
|
|
88
|
-
try {
|
|
89
|
-
const { collectionName, command, params } = req.params;
|
|
90
|
-
const collection = this.getCollectionName(collectionName);
|
|
91
|
-
if (!directCommands.includes(command)) {
|
|
92
|
-
return res.status(400).send({ error: 'Command not supported' });
|
|
93
|
-
}
|
|
94
|
-
const databaseService = new DBaseService(collection);
|
|
95
|
-
const decodedParams = params ? databaseService.decodeUrlParams(params) : {};
|
|
96
|
-
const result = await databaseService[command](decodedParams);
|
|
97
|
-
res.status(200).send(result);
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
res.status(400).send({ error: error.message });
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
start() {
|
|
105
|
-
this.app.listen(this.port, () => {
|
|
106
|
-
console.log(`Server is running on port: ${this.port}`);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
// Usage:
|
|
111
|
-
// import { ServerConfig } from './ServerConfig.js';
|
|
112
|
-
// const server = new ApiServer(3050);
|
|
113
|
-
// server.start();
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Request, Response, NextFunction } from 'express';
|
|
2
|
-
declare const defaultDbName: string;
|
|
3
|
-
declare class DBaseManager {
|
|
4
|
-
private static instance;
|
|
5
|
-
static port: number;
|
|
6
|
-
constructor();
|
|
7
|
-
static getInstance(): DBaseManager;
|
|
8
|
-
connectToDatabase(req: Request<{
|
|
9
|
-
dbName: string;
|
|
10
|
-
collectionName: string;
|
|
11
|
-
}>, res: Response, next: NextFunction): Promise<void>;
|
|
12
|
-
}
|
|
13
|
-
declare const _default: DBaseManager;
|
|
14
|
-
export default _default;
|
|
15
|
-
export { DBaseManager as DatabaseManager, defaultDbName };
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import mongoose from 'mongoose';
|
|
2
|
-
const defaultDbName = 'idae';
|
|
3
|
-
// this is my middleware to connect to the appropriate database
|
|
4
|
-
class DBaseManager {
|
|
5
|
-
constructor() { }
|
|
6
|
-
static getInstance() {
|
|
7
|
-
if (!DBaseManager.instance) {
|
|
8
|
-
DBaseManager.instance = new DBaseManager();
|
|
9
|
-
}
|
|
10
|
-
return DBaseManager.instance;
|
|
11
|
-
}
|
|
12
|
-
async connectToDatabase(req, res, next) {
|
|
13
|
-
const { collectionName } = req.params;
|
|
14
|
-
let dbName;
|
|
15
|
-
//
|
|
16
|
-
if (collectionName.includes('.')) {
|
|
17
|
-
dbName = collectionName.split('.')[0];
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
dbName = defaultDbName;
|
|
21
|
-
}
|
|
22
|
-
const dbUri = `mongodb://localhost:${DBaseManager.port}/${dbName}`;
|
|
23
|
-
try {
|
|
24
|
-
if (!mongoose.connection.readyState) {
|
|
25
|
-
await mongoose.connect(dbUri, {
|
|
26
|
-
autoIndex: true,
|
|
27
|
-
dbName
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
else if (mongoose.connection.name !== dbName) {
|
|
31
|
-
await mongoose.disconnect();
|
|
32
|
-
await mongoose.connect(dbUri, {
|
|
33
|
-
autoIndex: true,
|
|
34
|
-
dbName
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
console.log('connected to db', `${dbName}`);
|
|
38
|
-
next();
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
/** @ts-ignore */
|
|
42
|
-
res.status(500).send(`Failed to connect to database ${dbName}: ${error.message}`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
DBaseManager.port = 27017;
|
|
47
|
-
// i can call it as a normal class or as a singleton
|
|
48
|
-
export default DBaseManager.getInstance();
|
|
49
|
-
export { DBaseManager as DatabaseManager, defaultDbName };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Document } from 'mongoose';
|
|
2
|
-
import { type RequestParams } from './types';
|
|
3
|
-
declare class DBaseService {
|
|
4
|
-
private model;
|
|
5
|
-
constructor(collection: string);
|
|
6
|
-
create(document: any): Promise<Document>;
|
|
7
|
-
findAll(params: RequestParams): Promise<Document[]>;
|
|
8
|
-
findById(id: string): Promise<Document | null>;
|
|
9
|
-
findOne(params: RequestParams): Promise<Document | null>;
|
|
10
|
-
deleteById(id: string): Promise<Document | null>;
|
|
11
|
-
deleteManyByQuery(params: RequestParams): Promise<{
|
|
12
|
-
deletedCount?: number;
|
|
13
|
-
}>;
|
|
14
|
-
decodeUrlParams(urlParams: string): RequestParams;
|
|
15
|
-
}
|
|
16
|
-
export default DBaseService;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { Model, Document } from 'mongoose';
|
|
2
|
-
import { getModel } from './tools';
|
|
3
|
-
import {} from './types';
|
|
4
|
-
class DBaseService {
|
|
5
|
-
constructor(collection) {
|
|
6
|
-
this.model = getModel(collection);
|
|
7
|
-
}
|
|
8
|
-
async create(document) {
|
|
9
|
-
const newDocument = new this.model(document);
|
|
10
|
-
return newDocument.save();
|
|
11
|
-
}
|
|
12
|
-
async findAll(params) {
|
|
13
|
-
const sortOptions = {};
|
|
14
|
-
if (params.sortBy) {
|
|
15
|
-
const sortFields = params.sortBy.split(',');
|
|
16
|
-
sortFields.forEach((field) => {
|
|
17
|
-
const [key, order] = field.split(':');
|
|
18
|
-
sortOptions[key] = order === 'desc' ? -1 : 1;
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
return this.model.find().sort(sortOptions);
|
|
22
|
-
}
|
|
23
|
-
async findById(id) {
|
|
24
|
-
return this.model.findById(id);
|
|
25
|
-
}
|
|
26
|
-
async findOne(params) {
|
|
27
|
-
return this.model.findOne(params.query);
|
|
28
|
-
}
|
|
29
|
-
async deleteById(id) {
|
|
30
|
-
return this.model.findByIdAndDelete(id);
|
|
31
|
-
}
|
|
32
|
-
async deleteManyByQuery(params) {
|
|
33
|
-
return this.model.deleteMany(params.query);
|
|
34
|
-
}
|
|
35
|
-
decodeUrlParams(urlParams) {
|
|
36
|
-
const params = {};
|
|
37
|
-
const urlParamsArray = urlParams.split('&');
|
|
38
|
-
urlParamsArray.forEach((param) => {
|
|
39
|
-
const [key, value] = param.split('=');
|
|
40
|
-
if (key && value) {
|
|
41
|
-
/** @ts-ignore */
|
|
42
|
-
params[key] = JSON.parse(decodeURIComponent(value));
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
return params;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
export default DBaseService;
|
package/dist/engine/tools.d.ts
DELETED
package/dist/engine/tools.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import mongoose, { Schema, Document, Model } from 'mongoose';
|
|
2
|
-
import AutoIncrementFactory from 'mongoose-sequence';
|
|
3
|
-
const AutoIncrement = AutoIncrementFactory(mongoose);
|
|
4
|
-
export const getModel = (collectionName) => {
|
|
5
|
-
if (mongoose.models[collectionName]) {
|
|
6
|
-
return mongoose.models[collectionName];
|
|
7
|
-
}
|
|
8
|
-
const schema = new Schema({}, { strict: false });
|
|
9
|
-
schema.plugin(AutoIncrement, { inc_field: 'idFieldName' });
|
|
10
|
-
return mongoose.model(collectionName, schema, collectionName);
|
|
11
|
-
};
|
package/dist/engine/types.d.ts
DELETED
|
File without changes
|