powr-sdk-api 2.3.6 → 2.3.8
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/dist/config.js +1 -3
- package/dist/middleware/jwtToken.js +12 -10
- package/dist/routes/auth.js +74 -4
- package/dist/routes/files.js +12 -13
- package/dist/routes/index.js +21 -8
- package/dist/routes/profiles.js +60 -0
- package/dist/services/dbService.js +25 -23
- package/package.json +67 -67
package/dist/config.js
CHANGED
|
@@ -5,10 +5,11 @@ const {
|
|
|
5
5
|
ObjectId
|
|
6
6
|
} = require('mongodb');
|
|
7
7
|
const config = require('../config');
|
|
8
|
-
const generateJWTToken = user => {
|
|
8
|
+
const generateJWTToken = (user, profile = null) => {
|
|
9
9
|
return jwt.sign({
|
|
10
10
|
userId: user._id,
|
|
11
|
-
fullName: user.fullName
|
|
11
|
+
fullName: user.fullName,
|
|
12
|
+
access: profile === null || profile === void 0 ? void 0 : profile.access
|
|
12
13
|
}, config.jwtToken, {
|
|
13
14
|
expiresIn: '24h'
|
|
14
15
|
});
|
|
@@ -28,20 +29,21 @@ const verifyToken = async (req, res, next) => {
|
|
|
28
29
|
|
|
29
30
|
// Extract token (remove 'Bearer ' if present)
|
|
30
31
|
const token = authHeader.startsWith("Bearer ") ? authHeader.slice(7) : authHeader;
|
|
32
|
+
if (!token) {
|
|
33
|
+
return res.status(401).json({
|
|
34
|
+
success: false,
|
|
35
|
+
message: 'No token provided'
|
|
36
|
+
});
|
|
37
|
+
}
|
|
31
38
|
|
|
32
39
|
// Verify JWT token
|
|
33
40
|
const decoded = jwt.verify(token, config.jwtToken);
|
|
34
41
|
console.log("JWT Decoded user data:", JSON.stringify(decoded, null, 2));
|
|
35
|
-
|
|
36
|
-
// Attach user info to request object
|
|
37
42
|
req.user = {
|
|
38
|
-
powrId:
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
powrId: decoded.userId,
|
|
44
|
+
fullName: decoded.fullName,
|
|
45
|
+
access: decoded.access
|
|
41
46
|
};
|
|
42
|
-
console.log("Authenticated user:", {
|
|
43
|
-
powrId: req.user.powrId
|
|
44
|
-
});
|
|
45
47
|
next();
|
|
46
48
|
} catch (error) {
|
|
47
49
|
console.error("Error in auth middleware:", error);
|
package/dist/routes/auth.js
CHANGED
|
@@ -23,7 +23,8 @@ router.post("/register", async (req, res) => {
|
|
|
23
23
|
fullName,
|
|
24
24
|
username,
|
|
25
25
|
phoneOrEmail,
|
|
26
|
-
password
|
|
26
|
+
password,
|
|
27
|
+
projectId
|
|
27
28
|
} = req.body;
|
|
28
29
|
try {
|
|
29
30
|
if (!(username || phoneOrEmail)) {
|
|
@@ -44,6 +45,14 @@ router.post("/register", async (req, res) => {
|
|
|
44
45
|
message: "Full name is required"
|
|
45
46
|
});
|
|
46
47
|
}
|
|
48
|
+
|
|
49
|
+
// if (!projectId) {
|
|
50
|
+
// return res.status(400).json({
|
|
51
|
+
// success: false,
|
|
52
|
+
// message: "Project ID is required"
|
|
53
|
+
// });
|
|
54
|
+
// }
|
|
55
|
+
|
|
47
56
|
let q = username ? {
|
|
48
57
|
username: username
|
|
49
58
|
} : {
|
|
@@ -72,6 +81,15 @@ router.post("/register", async (req, res) => {
|
|
|
72
81
|
createdAt: new Date()
|
|
73
82
|
};
|
|
74
83
|
const result = await getDb().collection("users").insertOne(newUser);
|
|
84
|
+
if (projectId) {
|
|
85
|
+
const newProfile = {
|
|
86
|
+
userId: result.insertedId,
|
|
87
|
+
projectId: projectId,
|
|
88
|
+
createdAt: new Date(),
|
|
89
|
+
updatedAt: new Date()
|
|
90
|
+
};
|
|
91
|
+
await getDb().collection("profiles").insertOne(newProfile);
|
|
92
|
+
}
|
|
75
93
|
return res.status(201).json({
|
|
76
94
|
success: true,
|
|
77
95
|
message: "User registered successfully",
|
|
@@ -91,7 +109,8 @@ router.post("/login", async (req, res) => {
|
|
|
91
109
|
const {
|
|
92
110
|
username,
|
|
93
111
|
phoneOrEmail,
|
|
94
|
-
password
|
|
112
|
+
password,
|
|
113
|
+
projectId
|
|
95
114
|
} = req.body;
|
|
96
115
|
try {
|
|
97
116
|
if (!(username || phoneOrEmail)) {
|
|
@@ -131,15 +150,66 @@ router.post("/login", async (req, res) => {
|
|
|
131
150
|
message: "Invalid username or password."
|
|
132
151
|
});
|
|
133
152
|
}
|
|
134
|
-
|
|
153
|
+
|
|
154
|
+
// Fetch profile data if projectId is provided
|
|
155
|
+
let profile = null;
|
|
156
|
+
if (projectId) {
|
|
157
|
+
profile = await getDb().collection("profiles").findOne({
|
|
158
|
+
userId: user._id,
|
|
159
|
+
projectId: projectId
|
|
160
|
+
});
|
|
161
|
+
if (profile) {
|
|
162
|
+
// Update lastActiveAt
|
|
163
|
+
await getDb().collection("profiles").updateOne({
|
|
164
|
+
_id: profile._id
|
|
165
|
+
}, {
|
|
166
|
+
$set: {
|
|
167
|
+
lastActiveAt: new Date()
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
} else {
|
|
171
|
+
// Create profile if it doesn't exist - only essential fields
|
|
172
|
+
const newProfile = {
|
|
173
|
+
userId: user._id,
|
|
174
|
+
projectId: projectId,
|
|
175
|
+
createdAt: new Date(),
|
|
176
|
+
updatedAt: new Date()
|
|
177
|
+
};
|
|
178
|
+
const profileResult = await getDb().collection("profiles").insertOne(newProfile);
|
|
179
|
+
profile = {
|
|
180
|
+
_id: profileResult.insertedId,
|
|
181
|
+
...newProfile
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const token = generateJWTToken(user, profile);
|
|
135
186
|
const {
|
|
136
187
|
password: _,
|
|
188
|
+
_id,
|
|
137
189
|
...userWithoutPassword
|
|
138
190
|
} = user;
|
|
191
|
+
let mergedUser = {
|
|
192
|
+
...userWithoutPassword,
|
|
193
|
+
powrId: user._id
|
|
194
|
+
};
|
|
195
|
+
if (profile) {
|
|
196
|
+
const {
|
|
197
|
+
_id,
|
|
198
|
+
userId,
|
|
199
|
+
projectId,
|
|
200
|
+
createdAt,
|
|
201
|
+
updatedAt,
|
|
202
|
+
...profileData
|
|
203
|
+
} = profile;
|
|
204
|
+
mergedUser = {
|
|
205
|
+
...mergedUser,
|
|
206
|
+
...profileData
|
|
207
|
+
};
|
|
208
|
+
}
|
|
139
209
|
return res.status(200).json({
|
|
140
210
|
success: true,
|
|
141
211
|
message: "Login successful",
|
|
142
|
-
user:
|
|
212
|
+
user: mergedUser,
|
|
143
213
|
token: token
|
|
144
214
|
});
|
|
145
215
|
} catch (error) {
|
package/dist/routes/files.js
CHANGED
|
@@ -3,11 +3,7 @@
|
|
|
3
3
|
const express = require('express');
|
|
4
4
|
const multer = require('multer');
|
|
5
5
|
// const { uploadToGCS, bucket } = require('../uploadToGCS')
|
|
6
|
-
const {
|
|
7
|
-
bucket,
|
|
8
|
-
uploadToGCS,
|
|
9
|
-
bucketName
|
|
10
|
-
} = require('../uploadToGCS.js');
|
|
6
|
+
// const { bucket, uploadToGCS, bucketName } = require('../uploadToGCS.js')
|
|
11
7
|
// const uploadToGCS = require('../uploadToGCS.js')
|
|
12
8
|
|
|
13
9
|
const router = express.Router();
|
|
@@ -20,11 +16,13 @@ router.post('/', upload.single('file'), async (req, res) => {
|
|
|
20
16
|
message: 'No file uploaded'
|
|
21
17
|
});
|
|
22
18
|
}
|
|
23
|
-
|
|
19
|
+
|
|
20
|
+
// const url = await uploadToGCS(req.file);
|
|
21
|
+
|
|
24
22
|
return res.status(200).json({
|
|
25
23
|
status: 'success',
|
|
26
|
-
message: 'File uploaded successfully'
|
|
27
|
-
url
|
|
24
|
+
message: 'File uploaded successfully'
|
|
25
|
+
// url,
|
|
28
26
|
});
|
|
29
27
|
} catch (err) {
|
|
30
28
|
console.error('Error uploading file:', err);
|
|
@@ -37,12 +35,13 @@ router.post('/', upload.single('file'), async (req, res) => {
|
|
|
37
35
|
});
|
|
38
36
|
router.get('/', async (req, res) => {
|
|
39
37
|
try {
|
|
40
|
-
const [files] = await bucket.getFiles();
|
|
41
|
-
const bucketName = bucket.name;
|
|
42
|
-
const imageUrls = files.map(file => `https://storage.googleapis.com/${bucketName}/${file.name}`);
|
|
38
|
+
// const [files] = await bucket.getFiles();
|
|
39
|
+
// const bucketName = bucket.name;
|
|
40
|
+
// const imageUrls = files.map(file => `https://storage.googleapis.com/${bucketName}/${file.name}`);
|
|
41
|
+
|
|
43
42
|
return res.status(200).json({
|
|
44
|
-
message: 'Images fetched successfully'
|
|
45
|
-
images: imageUrls
|
|
43
|
+
message: 'Images fetched successfully'
|
|
44
|
+
// images: imageUrls,
|
|
46
45
|
});
|
|
47
46
|
} catch (err) {
|
|
48
47
|
console.error('Error listing files from GCS:', err);
|
package/dist/routes/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const express = require('express');
|
|
4
|
+
const config = require('../config');
|
|
4
5
|
|
|
5
6
|
// Import all route modules
|
|
6
7
|
const commentsRoutes = require('./comments');
|
|
@@ -17,17 +18,30 @@ const authRoutes = require('./auth');
|
|
|
17
18
|
const blogsRoutes = require('./blogs');
|
|
18
19
|
const slidesRoutes = require('./slides');
|
|
19
20
|
const notificationsRoutes = require('./notifications');
|
|
20
|
-
const
|
|
21
|
+
const profilesRoutes = require('./profiles');
|
|
22
|
+
const createPowrRoutes = (options = {}) => {
|
|
21
23
|
const router = express.Router();
|
|
22
24
|
|
|
25
|
+
// Check if this is a central service (like powr-base-cloud)
|
|
26
|
+
const isCentralService = options.isCentralService || false;
|
|
27
|
+
|
|
23
28
|
// Middleware to inject projectId into all requests
|
|
24
29
|
router.use((req, res, next) => {
|
|
25
30
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
if (isCentralService) {
|
|
32
|
+
// For central services, get projectId from request
|
|
33
|
+
const projectId = req.query.projectId || req.body.projectId;
|
|
34
|
+
if (!projectId) {
|
|
35
|
+
return res.status(400).json({
|
|
36
|
+
success: false,
|
|
37
|
+
message: 'projectId is required for central services'
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
req.projectId = projectId;
|
|
41
|
+
} else {
|
|
42
|
+
// For individual APIs, use config.projectId
|
|
43
|
+
req.projectId = config.projectId;
|
|
44
|
+
}
|
|
31
45
|
} catch (error) {
|
|
32
46
|
console.error('❌ Config error:', error.message);
|
|
33
47
|
return res.status(500).json({
|
|
@@ -38,8 +52,6 @@ const createPowrRoutes = () => {
|
|
|
38
52
|
}
|
|
39
53
|
next();
|
|
40
54
|
});
|
|
41
|
-
|
|
42
|
-
// Mount all route modules
|
|
43
55
|
router.use('/comments', commentsRoutes);
|
|
44
56
|
// router.use('/files', filesRoutes); // Commented out for now
|
|
45
57
|
router.use('/forms', formsRoutes);
|
|
@@ -54,6 +66,7 @@ const createPowrRoutes = () => {
|
|
|
54
66
|
router.use('/blogs', blogsRoutes);
|
|
55
67
|
router.use('/slides', slidesRoutes);
|
|
56
68
|
router.use('/notifications', notificationsRoutes);
|
|
69
|
+
router.use('/profiles', profilesRoutes);
|
|
57
70
|
return router;
|
|
58
71
|
};
|
|
59
72
|
module.exports = {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const express = require("express");
|
|
4
|
+
const router = express.Router();
|
|
5
|
+
const {
|
|
6
|
+
getDb
|
|
7
|
+
} = require("../services/dbService");
|
|
8
|
+
|
|
9
|
+
// Get all users for a project
|
|
10
|
+
router.get("/", async (req, res) => {
|
|
11
|
+
try {
|
|
12
|
+
const {
|
|
13
|
+
projectId
|
|
14
|
+
} = req.query;
|
|
15
|
+
const profiles = await getDb().collection("profiles").find({
|
|
16
|
+
projectId: projectId
|
|
17
|
+
}).toArray();
|
|
18
|
+
if (profiles.length === 0) {
|
|
19
|
+
return res.status(200).json({
|
|
20
|
+
success: true,
|
|
21
|
+
users: []
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Get core user data for all profiles
|
|
26
|
+
const userIds = profiles.map(profile => profile.userId);
|
|
27
|
+
const users = await getDb().collection("users").find({
|
|
28
|
+
_id: {
|
|
29
|
+
$in: userIds
|
|
30
|
+
}
|
|
31
|
+
}).toArray();
|
|
32
|
+
|
|
33
|
+
// Create a map for quick lookup
|
|
34
|
+
const usersMap = users.reduce((acc, user) => {
|
|
35
|
+
const {
|
|
36
|
+
password,
|
|
37
|
+
...userWithoutPassword
|
|
38
|
+
} = user;
|
|
39
|
+
acc[user._id.toString()] = userWithoutPassword;
|
|
40
|
+
return acc;
|
|
41
|
+
}, {});
|
|
42
|
+
|
|
43
|
+
// Merge user and profile data
|
|
44
|
+
const usersWithProfiles = profiles.map(profile => ({
|
|
45
|
+
...usersMap[profile.userId.toString()],
|
|
46
|
+
...profile
|
|
47
|
+
}));
|
|
48
|
+
return res.status(200).json({
|
|
49
|
+
success: true,
|
|
50
|
+
users: usersWithProfiles
|
|
51
|
+
});
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error("Error fetching project users:", error);
|
|
54
|
+
return res.status(500).json({
|
|
55
|
+
success: false,
|
|
56
|
+
message: "Failed to fetch project users"
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
module.exports = router;
|
|
@@ -3,38 +3,40 @@
|
|
|
3
3
|
const {
|
|
4
4
|
MongoClient
|
|
5
5
|
} = require('mongodb');
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// Connect only when first needed
|
|
6
|
+
const {
|
|
7
|
+
config
|
|
8
|
+
} = require('../config');
|
|
9
|
+
const mongoClient = new MongoClient(config.mongoUri, {
|
|
10
|
+
maxPoolSize: 10,
|
|
11
|
+
serverSelectionTimeoutMS: 5000,
|
|
12
|
+
socketTimeoutMS: 45000
|
|
13
|
+
});
|
|
14
|
+
let db;
|
|
15
|
+
async function connect() {
|
|
17
16
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
db = client.db();
|
|
22
|
-
console.log('✅ Connected to MongoDB via SDK (lazy connection)');
|
|
23
|
-
return db;
|
|
17
|
+
await mongoClient.connect();
|
|
18
|
+
db = mongoClient.db();
|
|
19
|
+
console.log("Connected to MongoDB via SDK");
|
|
24
20
|
} catch (error) {
|
|
25
|
-
console.error(
|
|
26
|
-
|
|
21
|
+
console.error("Failed to connect to MongoDB:", error);
|
|
22
|
+
process.exit(1);
|
|
27
23
|
}
|
|
28
|
-
}
|
|
24
|
+
}
|
|
25
|
+
function getDb() {
|
|
26
|
+
if (!db) {
|
|
27
|
+
throw new Error("Database not initialized. Call connectToMongo() first.");
|
|
28
|
+
}
|
|
29
|
+
return db;
|
|
30
|
+
}
|
|
29
31
|
const closeConnection = async () => {
|
|
30
|
-
if (
|
|
31
|
-
await
|
|
32
|
-
client = null;
|
|
32
|
+
if (mongoClient) {
|
|
33
|
+
await mongoClient.close();
|
|
33
34
|
db = null;
|
|
34
35
|
console.log('✅ MongoDB connection closed');
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
38
|
module.exports = {
|
|
39
|
+
connect,
|
|
38
40
|
getDb,
|
|
39
41
|
closeConnection
|
|
40
42
|
};
|
package/package.json
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "powr-sdk-api",
|
|
3
|
-
"version": "2.3.
|
|
4
|
-
"description": "Shared API core library for PowrStack projects",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist",
|
|
9
|
-
"README.md"
|
|
10
|
-
],
|
|
11
|
-
"scripts": {
|
|
12
|
-
"test": "jest --passWithNoTests",
|
|
13
|
-
"lint": "eslint .",
|
|
14
|
-
"build": "babel src -d dist",
|
|
15
|
-
"prepare": "npm run build",
|
|
16
|
-
"prepublishOnly": "npm run test"
|
|
17
|
-
},
|
|
18
|
-
"keywords": [
|
|
19
|
-
"api",
|
|
20
|
-
"express",
|
|
21
|
-
"middleware",
|
|
22
|
-
"error-handling",
|
|
23
|
-
"response-formatting",
|
|
24
|
-
"logging",
|
|
25
|
-
"swagger",
|
|
26
|
-
"documentation"
|
|
27
|
-
],
|
|
28
|
-
"author": "PowrStack",
|
|
29
|
-
"license": "ISC",
|
|
30
|
-
"repository": {
|
|
31
|
-
"type": "git",
|
|
32
|
-
"url": "git+https://github.com/powrstack/powr-sdk-api.git"
|
|
33
|
-
},
|
|
34
|
-
"bugs": {
|
|
35
|
-
"url": "https://github.com/powrstack/powr-sdk-api/issues"
|
|
36
|
-
},
|
|
37
|
-
"homepage": "https://github.com/powrstack/powr-sdk-api#readme",
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"@aws-sdk/client-s3": "^3.787.0",
|
|
40
|
-
"@google-cloud/storage": "^7.16.0",
|
|
41
|
-
"express": "^4.18.2",
|
|
42
|
-
"jsonwebtoken": "^9.0.2",
|
|
43
|
-
"swagger-jsdoc": "^6.2.8",
|
|
44
|
-
"swagger-ui-express": "^5.0.0",
|
|
45
|
-
"winston": "^3.17.0",
|
|
46
|
-
"mongodb": "^6.3.0",
|
|
47
|
-
"multer": "^1.4.5-lts.1",
|
|
48
|
-
"bcrypt": "^5.1.1"
|
|
49
|
-
},
|
|
50
|
-
"devDependencies": {
|
|
51
|
-
"@babel/cli": "^7.23.9",
|
|
52
|
-
"@babel/core": "^7.24.0",
|
|
53
|
-
"@babel/preset-env": "^7.24.0",
|
|
54
|
-
"@types/express": "^4.17.21",
|
|
55
|
-
"@types/swagger-jsdoc": "^6.0.4",
|
|
56
|
-
"@types/swagger-ui-express": "^4.1.6",
|
|
57
|
-
"eslint": "^8.57.0",
|
|
58
|
-
"jest": "^29.7.0",
|
|
59
|
-
"typescript": "^5.3.3"
|
|
60
|
-
},
|
|
61
|
-
"peerDependencies": {
|
|
62
|
-
"express": "^4.18.2"
|
|
63
|
-
},
|
|
64
|
-
"engines": {
|
|
65
|
-
"node": ">=14.0.0"
|
|
66
|
-
}
|
|
67
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "powr-sdk-api",
|
|
3
|
+
"version": "2.3.8",
|
|
4
|
+
"description": "Shared API core library for PowrStack projects",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "jest --passWithNoTests",
|
|
13
|
+
"lint": "eslint .",
|
|
14
|
+
"build": "babel src -d dist",
|
|
15
|
+
"prepare": "npm run build",
|
|
16
|
+
"prepublishOnly": "npm run test"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"api",
|
|
20
|
+
"express",
|
|
21
|
+
"middleware",
|
|
22
|
+
"error-handling",
|
|
23
|
+
"response-formatting",
|
|
24
|
+
"logging",
|
|
25
|
+
"swagger",
|
|
26
|
+
"documentation"
|
|
27
|
+
],
|
|
28
|
+
"author": "PowrStack",
|
|
29
|
+
"license": "ISC",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/powrstack/powr-sdk-api.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/powrstack/powr-sdk-api/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/powrstack/powr-sdk-api#readme",
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@aws-sdk/client-s3": "^3.787.0",
|
|
40
|
+
"@google-cloud/storage": "^7.16.0",
|
|
41
|
+
"express": "^4.18.2",
|
|
42
|
+
"jsonwebtoken": "^9.0.2",
|
|
43
|
+
"swagger-jsdoc": "^6.2.8",
|
|
44
|
+
"swagger-ui-express": "^5.0.0",
|
|
45
|
+
"winston": "^3.17.0",
|
|
46
|
+
"mongodb": "^6.3.0",
|
|
47
|
+
"multer": "^1.4.5-lts.1",
|
|
48
|
+
"bcrypt": "^5.1.1"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@babel/cli": "^7.23.9",
|
|
52
|
+
"@babel/core": "^7.24.0",
|
|
53
|
+
"@babel/preset-env": "^7.24.0",
|
|
54
|
+
"@types/express": "^4.17.21",
|
|
55
|
+
"@types/swagger-jsdoc": "^6.0.4",
|
|
56
|
+
"@types/swagger-ui-express": "^4.1.6",
|
|
57
|
+
"eslint": "^8.57.0",
|
|
58
|
+
"jest": "^29.7.0",
|
|
59
|
+
"typescript": "^5.3.3"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"express": "^4.18.2"
|
|
63
|
+
},
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=14.0.0"
|
|
66
|
+
}
|
|
67
|
+
}
|