zyket 1.2.10 → 1.2.12
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/.github/workflows/publish.yml +37 -37
- package/README.md +279 -279
- package/bin/cli.js +201 -201
- package/index.js +32 -32
- package/package.json +54 -50
- package/src/Middleware.js +3 -3
- package/src/extensions/Extension.js +10 -10
- package/src/extensions/bullboard/index.js +38 -38
- package/src/extensions/interactive-storage/index.js +162 -162
- package/src/extensions/interactive-storage/middlewares/MulterMiddleware.js +31 -31
- package/src/extensions/interactive-storage/routes/browse.js +31 -31
- package/src/extensions/interactive-storage/routes/create-folder.js +37 -37
- package/src/extensions/interactive-storage/routes/delete-folder.js +57 -57
- package/src/extensions/interactive-storage/routes/delete.js +41 -41
- package/src/extensions/interactive-storage/routes/download.js +47 -47
- package/src/extensions/interactive-storage/routes/info.js +37 -37
- package/src/extensions/interactive-storage/routes/upload.js +46 -46
- package/src/kernel/HTTPServer.js +31 -31
- package/src/kernel/index.js +78 -78
- package/src/services/Service.js +10 -10
- package/src/services/auth/auth.js +7 -7
- package/src/services/auth/index.js +199 -199
- package/src/services/bullmq/Worker.js +7 -7
- package/src/services/bullmq/index.js +92 -92
- package/src/services/cache/index.js +96 -96
- package/src/services/database/index.js +127 -127
- package/src/services/events/Event.js +6 -6
- package/src/services/events/index.js +59 -59
- package/src/services/express/Express.js +248 -248
- package/src/services/express/Middleware.js +7 -7
- package/src/services/express/RedirectResponse.js +8 -8
- package/src/services/express/Route.js +6 -6
- package/src/services/express/index.js +4 -4
- package/src/services/index.js +29 -29
- package/src/services/logger/index.js +80 -80
- package/src/services/s3/index.js +82 -82
- package/src/services/scheduler/Schedule.js +6 -6
- package/src/services/scheduler/index.js +47 -47
- package/src/services/socketio/Guard.js +10 -10
- package/src/services/socketio/Handler.js +10 -10
- package/src/services/socketio/SocketIO.js +159 -132
- package/src/services/socketio/index.js +4 -4
- package/src/services/template-manager/index.js +73 -73
- package/src/templates/default/config/cors.js +5 -1
- package/src/templates/default/config/swagger.js +15 -15
- package/src/templates/default/frontend/main.jsx +15 -15
- package/src/templates/default/frontend/src/hooks/useAuth.jsx +51 -51
- package/src/templates/default/frontend/src/hooks/useLayout.jsx +18 -18
- package/src/templates/default/frontend/src/layouts/auth/index.jsx +45 -45
- package/src/templates/default/frontend/src/layouts/auth/routes.js +17 -17
- package/src/templates/default/frontend/src/layouts/landing/index.jsx +61 -61
- package/src/templates/default/frontend/src/layouts/landing/routes.js +10 -10
- package/src/templates/default/frontend/src/layouts/panel/index.jsx +115 -115
- package/src/templates/default/frontend/src/layouts/panel/routes.js +10 -10
- package/src/templates/default/frontend/src/middlewares/LoggedMiddleware.jsx +21 -21
- package/src/templates/default/frontend/src/middlewares/NotLoggedMiddleware.jsx +14 -14
- package/src/templates/default/frontend/src/store/index.jsx +5 -5
- package/src/templates/default/frontend/src/store/storeAuth.jsx +14 -14
- package/src/templates/default/frontend/src/views/auth/index.jsx +4 -4
- package/src/templates/default/frontend/src/views/auth/register/index.jsx +4 -4
- package/src/templates/default/frontend/src/views/landing/index.jsx +4 -4
- package/src/templates/default/frontend/src/views/panel/dashboard/index.jsx +4 -4
- package/src/templates/default/frontend/styles.css +1 -1
- package/src/templates/default/src/guards/default.js +6 -6
- package/src/templates/default/src/handlers/connection.js +6 -6
- package/src/templates/default/src/handlers/message.js +8 -8
- package/src/templates/default/src/middlewares/default.js +7 -7
- package/src/templates/default/src/routes/[test]/message.js +26 -26
- package/src/templates/default/src/routes/index.js +22 -22
- package/src/templates/default/src/services/auth/auth.js +7 -7
- package/src/templates/default/src/services/auth/index.js +32 -32
- package/src/utils/EnvManager.js +65 -65
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
const Extension = require('../Extension');
|
|
2
|
-
const { createBullBoard } = require('@bull-board/api')
|
|
3
|
-
const { BullMQAdapter } = require('@bull-board/api/bullMQAdapter')
|
|
4
|
-
const { ExpressAdapter } = require('@bull-board/express')
|
|
5
|
-
const basicAuth = require('express-basic-auth')
|
|
6
|
-
|
|
7
|
-
module.exports = class BullBoardExtension extends Extension {
|
|
8
|
-
path;
|
|
9
|
-
|
|
10
|
-
constructor({ path = '/bullboard', basePath = '' } = {}) {
|
|
11
|
-
super("BullBoardExtension");
|
|
12
|
-
this.path = path || '/bullboard';
|
|
13
|
-
this.basePath = basePath;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
load(container) {
|
|
17
|
-
if (!container.get('bullmq')) return container.get('logger').warn('BullBoardExtension: bullmq service not found, skipping BullBoard setup');
|
|
18
|
-
const bull = container.get('bullmq')
|
|
19
|
-
const serverAdapter = new ExpressAdapter()
|
|
20
|
-
serverAdapter.setBasePath(this.basePath + this.path)
|
|
21
|
-
|
|
22
|
-
createBullBoard({
|
|
23
|
-
queues: Object.values(bull.queues).map(queue => new BullMQAdapter(queue)),
|
|
24
|
-
serverAdapter
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const app = container.get('express').app()
|
|
28
|
-
const middlewares = []
|
|
29
|
-
|
|
30
|
-
if (process.env.BULLBOARD_ADMIN_PASSWORD) {
|
|
31
|
-
middlewares.push(basicAuth({
|
|
32
|
-
users: { admin: process.env.BULLBOARD_ADMIN_PASSWORD },
|
|
33
|
-
challenge: true,
|
|
34
|
-
}))
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
app.use(this.path, ...middlewares, serverAdapter.getRouter())
|
|
38
|
-
}
|
|
1
|
+
const Extension = require('../Extension');
|
|
2
|
+
const { createBullBoard } = require('@bull-board/api')
|
|
3
|
+
const { BullMQAdapter } = require('@bull-board/api/bullMQAdapter')
|
|
4
|
+
const { ExpressAdapter } = require('@bull-board/express')
|
|
5
|
+
const basicAuth = require('express-basic-auth')
|
|
6
|
+
|
|
7
|
+
module.exports = class BullBoardExtension extends Extension {
|
|
8
|
+
path;
|
|
9
|
+
|
|
10
|
+
constructor({ path = '/bullboard', basePath = '' } = {}) {
|
|
11
|
+
super("BullBoardExtension");
|
|
12
|
+
this.path = path || '/bullboard';
|
|
13
|
+
this.basePath = basePath;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
load(container) {
|
|
17
|
+
if (!container.get('bullmq')) return container.get('logger').warn('BullBoardExtension: bullmq service not found, skipping BullBoard setup');
|
|
18
|
+
const bull = container.get('bullmq')
|
|
19
|
+
const serverAdapter = new ExpressAdapter()
|
|
20
|
+
serverAdapter.setBasePath(this.basePath + this.path)
|
|
21
|
+
|
|
22
|
+
createBullBoard({
|
|
23
|
+
queues: Object.values(bull.queues).map(queue => new BullMQAdapter(queue)),
|
|
24
|
+
serverAdapter
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const app = container.get('express').app()
|
|
28
|
+
const middlewares = []
|
|
29
|
+
|
|
30
|
+
if (process.env.BULLBOARD_ADMIN_PASSWORD) {
|
|
31
|
+
middlewares.push(basicAuth({
|
|
32
|
+
users: { admin: process.env.BULLBOARD_ADMIN_PASSWORD },
|
|
33
|
+
challenge: true,
|
|
34
|
+
}))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
app.use(this.path, ...middlewares, serverAdapter.getRouter())
|
|
38
|
+
}
|
|
39
39
|
}
|
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
const Extension = require('../Extension');
|
|
2
|
-
|
|
3
|
-
// Import route classes
|
|
4
|
-
const UploadRoute = require('./routes/upload');
|
|
5
|
-
const BrowseRoute = require('./routes/browse');
|
|
6
|
-
const DownloadRoute = require('./routes/download');
|
|
7
|
-
const InfoRoute = require('./routes/info');
|
|
8
|
-
const DeleteRoute = require('./routes/delete');
|
|
9
|
-
const CreateFolderRoute = require('./routes/create-folder');
|
|
10
|
-
const DeleteFolderRoute = require('./routes/delete-folder');
|
|
11
|
-
const MulterMiddleware = require('./middlewares/MulterMiddleware');
|
|
12
|
-
|
|
13
|
-
module.exports = class InteractiveStorageExtension extends Extension {
|
|
14
|
-
static bucketName;
|
|
15
|
-
path;
|
|
16
|
-
maxFileSize;
|
|
17
|
-
middlewares;
|
|
18
|
-
|
|
19
|
-
constructor({ path = '/storage', bucketName = 'dropbox', maxFileSize = 100 * 1024 * 1024, middlewares = [] } = {}) {
|
|
20
|
-
super("InteractiveStorageExtension");
|
|
21
|
-
this.path = path || '/storage';
|
|
22
|
-
InteractiveStorageExtension.bucketName = bucketName;
|
|
23
|
-
this.maxFileSize = maxFileSize;
|
|
24
|
-
this.middlewares = middlewares || [];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
load(container) {
|
|
28
|
-
if (!container.get('s3')) return container.get('logger').warn('InteractiveStorageExtension: s3 service not found, skipping InteractiveStorage setup');
|
|
29
|
-
if (!container.get('express')) return container.get('logger').warn('InteractiveStorageExtension: express service not found, skipping InteractiveStorage setup');
|
|
30
|
-
|
|
31
|
-
const express = container.get('express');
|
|
32
|
-
const s3 = container.get('s3');
|
|
33
|
-
const logger = container.get('logger');
|
|
34
|
-
|
|
35
|
-
// Ensure bucket exists
|
|
36
|
-
this.#ensureBucket(s3, logger);
|
|
37
|
-
|
|
38
|
-
// Bind helper methods
|
|
39
|
-
const normalizePath = this.#normalizePath.bind(this);
|
|
40
|
-
const listFiles = this.#listFiles.bind(this);
|
|
41
|
-
const listFilesAndFolders = this.#listFilesAndFolders.bind(this);
|
|
42
|
-
const getFileStat = this.#getFileStat.bind(this);
|
|
43
|
-
|
|
44
|
-
// Create route instances
|
|
45
|
-
const routes = [
|
|
46
|
-
new UploadRoute(`${this.path}/upload`, s3, InteractiveStorageExtension.bucketName, normalizePath),
|
|
47
|
-
new BrowseRoute(`${this.path}/browse`, s3, InteractiveStorageExtension.bucketName, normalizePath, listFilesAndFolders),
|
|
48
|
-
new DownloadRoute(`${this.path}/download/:fileName`, s3, InteractiveStorageExtension.bucketName, getFileStat),
|
|
49
|
-
new InfoRoute(`${this.path}/info/:fileName`, s3, InteractiveStorageExtension.bucketName, getFileStat),
|
|
50
|
-
new DeleteRoute(`${this.path}/delete`, s3, InteractiveStorageExtension.bucketName),
|
|
51
|
-
new CreateFolderRoute(`${this.path}/create-folder`, s3, InteractiveStorageExtension.bucketName, normalizePath),
|
|
52
|
-
new DeleteFolderRoute(`${this.path}/delete-folder`, s3, InteractiveStorageExtension.bucketName, normalizePath, listFiles)
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
// Add multer middleware to upload route
|
|
56
|
-
routes[0].middlewares = {
|
|
57
|
-
post: [new MulterMiddleware(this.maxFileSize)]
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
// Register routes using the express service pattern
|
|
61
|
-
express.registerRoutes(routes);
|
|
62
|
-
|
|
63
|
-
logger.info(`InteractiveStorage extension loaded at ${this.path}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async #ensureBucket(s3, logger) {
|
|
67
|
-
try {
|
|
68
|
-
const buckets = await s3.listBuckets();
|
|
69
|
-
const bucketExists = buckets.some(bucket => bucket.name === InteractiveStorageExtension.bucketName);
|
|
70
|
-
|
|
71
|
-
if (!bucketExists) {
|
|
72
|
-
await s3.createBucket(InteractiveStorageExtension.bucketName);
|
|
73
|
-
logger.info(`Created S3 bucket: ${InteractiveStorageExtension.bucketName}`);
|
|
74
|
-
}
|
|
75
|
-
} catch (error) {
|
|
76
|
-
logger.error(`Error ensuring bucket exists: ${error.message}`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async #listFiles(s3, prefix = '') {
|
|
81
|
-
return new Promise((resolve, reject) => {
|
|
82
|
-
const files = [];
|
|
83
|
-
const stream = s3.client.listObjectsV2(InteractiveStorageExtension.bucketName, prefix, true);
|
|
84
|
-
|
|
85
|
-
stream.on('data', (obj) => {
|
|
86
|
-
files.push({
|
|
87
|
-
name: obj.name,
|
|
88
|
-
size: obj.size,
|
|
89
|
-
lastModified: obj.lastModified,
|
|
90
|
-
etag: obj.etag
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
stream.on('end', () => resolve(files));
|
|
95
|
-
stream.on('error', reject);
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async #listFilesAndFolders(s3, prefix = '') {
|
|
100
|
-
return new Promise((resolve, reject) => {
|
|
101
|
-
const items = [];
|
|
102
|
-
const folders = new Set();
|
|
103
|
-
|
|
104
|
-
const stream = s3.client.listObjectsV2(InteractiveStorageExtension.bucketName, prefix, false);
|
|
105
|
-
|
|
106
|
-
stream.on('data', (obj) => {
|
|
107
|
-
if (obj.prefix) {
|
|
108
|
-
// This is a folder
|
|
109
|
-
const folderName = obj.prefix.slice(prefix.length).replace(/\/$/, '');
|
|
110
|
-
if (folderName && !folderName.includes('/')) {
|
|
111
|
-
folders.add(folderName);
|
|
112
|
-
}
|
|
113
|
-
} else if (obj.name) {
|
|
114
|
-
// This is a file
|
|
115
|
-
const fileName = obj.name.slice(prefix.length);
|
|
116
|
-
|
|
117
|
-
// Skip folder markers and files in subfolders
|
|
118
|
-
if (fileName === '.folder' || fileName.includes('/')) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
items.push({
|
|
123
|
-
type: 'file',
|
|
124
|
-
name: fileName,
|
|
125
|
-
fullPath: obj.name,
|
|
126
|
-
size: obj.size,
|
|
127
|
-
lastModified: obj.lastModified,
|
|
128
|
-
etag: obj.etag
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
stream.on('end', () => {
|
|
134
|
-
// Add folders to items
|
|
135
|
-
folders.forEach(folder => {
|
|
136
|
-
items.unshift({
|
|
137
|
-
type: 'folder',
|
|
138
|
-
name: folder,
|
|
139
|
-
fullPath: prefix + folder
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
resolve(items);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
stream.on('error', reject);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
#normalizePath(path) {
|
|
151
|
-
// Remove leading/trailing slashes and normalize
|
|
152
|
-
return path.replace(/^\/+|\/+$/g, '').replace(/\/+/g, '/');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async #getFileStat(s3, fileName) {
|
|
156
|
-
return new Promise((resolve, reject) => {
|
|
157
|
-
s3.client.statObject(InteractiveStorageExtension.bucketName, fileName, (err, stat) => {
|
|
158
|
-
if (err) return reject(err);
|
|
159
|
-
resolve(stat);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
}
|
|
1
|
+
const Extension = require('../Extension');
|
|
2
|
+
|
|
3
|
+
// Import route classes
|
|
4
|
+
const UploadRoute = require('./routes/upload');
|
|
5
|
+
const BrowseRoute = require('./routes/browse');
|
|
6
|
+
const DownloadRoute = require('./routes/download');
|
|
7
|
+
const InfoRoute = require('./routes/info');
|
|
8
|
+
const DeleteRoute = require('./routes/delete');
|
|
9
|
+
const CreateFolderRoute = require('./routes/create-folder');
|
|
10
|
+
const DeleteFolderRoute = require('./routes/delete-folder');
|
|
11
|
+
const MulterMiddleware = require('./middlewares/MulterMiddleware');
|
|
12
|
+
|
|
13
|
+
module.exports = class InteractiveStorageExtension extends Extension {
|
|
14
|
+
static bucketName;
|
|
15
|
+
path;
|
|
16
|
+
maxFileSize;
|
|
17
|
+
middlewares;
|
|
18
|
+
|
|
19
|
+
constructor({ path = '/storage', bucketName = 'dropbox', maxFileSize = 100 * 1024 * 1024, middlewares = [] } = {}) {
|
|
20
|
+
super("InteractiveStorageExtension");
|
|
21
|
+
this.path = path || '/storage';
|
|
22
|
+
InteractiveStorageExtension.bucketName = bucketName;
|
|
23
|
+
this.maxFileSize = maxFileSize;
|
|
24
|
+
this.middlewares = middlewares || [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
load(container) {
|
|
28
|
+
if (!container.get('s3')) return container.get('logger').warn('InteractiveStorageExtension: s3 service not found, skipping InteractiveStorage setup');
|
|
29
|
+
if (!container.get('express')) return container.get('logger').warn('InteractiveStorageExtension: express service not found, skipping InteractiveStorage setup');
|
|
30
|
+
|
|
31
|
+
const express = container.get('express');
|
|
32
|
+
const s3 = container.get('s3');
|
|
33
|
+
const logger = container.get('logger');
|
|
34
|
+
|
|
35
|
+
// Ensure bucket exists
|
|
36
|
+
this.#ensureBucket(s3, logger);
|
|
37
|
+
|
|
38
|
+
// Bind helper methods
|
|
39
|
+
const normalizePath = this.#normalizePath.bind(this);
|
|
40
|
+
const listFiles = this.#listFiles.bind(this);
|
|
41
|
+
const listFilesAndFolders = this.#listFilesAndFolders.bind(this);
|
|
42
|
+
const getFileStat = this.#getFileStat.bind(this);
|
|
43
|
+
|
|
44
|
+
// Create route instances
|
|
45
|
+
const routes = [
|
|
46
|
+
new UploadRoute(`${this.path}/upload`, s3, InteractiveStorageExtension.bucketName, normalizePath),
|
|
47
|
+
new BrowseRoute(`${this.path}/browse`, s3, InteractiveStorageExtension.bucketName, normalizePath, listFilesAndFolders),
|
|
48
|
+
new DownloadRoute(`${this.path}/download/:fileName`, s3, InteractiveStorageExtension.bucketName, getFileStat),
|
|
49
|
+
new InfoRoute(`${this.path}/info/:fileName`, s3, InteractiveStorageExtension.bucketName, getFileStat),
|
|
50
|
+
new DeleteRoute(`${this.path}/delete`, s3, InteractiveStorageExtension.bucketName),
|
|
51
|
+
new CreateFolderRoute(`${this.path}/create-folder`, s3, InteractiveStorageExtension.bucketName, normalizePath),
|
|
52
|
+
new DeleteFolderRoute(`${this.path}/delete-folder`, s3, InteractiveStorageExtension.bucketName, normalizePath, listFiles)
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
// Add multer middleware to upload route
|
|
56
|
+
routes[0].middlewares = {
|
|
57
|
+
post: [new MulterMiddleware(this.maxFileSize)]
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Register routes using the express service pattern
|
|
61
|
+
express.registerRoutes(routes);
|
|
62
|
+
|
|
63
|
+
logger.info(`InteractiveStorage extension loaded at ${this.path}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async #ensureBucket(s3, logger) {
|
|
67
|
+
try {
|
|
68
|
+
const buckets = await s3.listBuckets();
|
|
69
|
+
const bucketExists = buckets.some(bucket => bucket.name === InteractiveStorageExtension.bucketName);
|
|
70
|
+
|
|
71
|
+
if (!bucketExists) {
|
|
72
|
+
await s3.createBucket(InteractiveStorageExtension.bucketName);
|
|
73
|
+
logger.info(`Created S3 bucket: ${InteractiveStorageExtension.bucketName}`);
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
logger.error(`Error ensuring bucket exists: ${error.message}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async #listFiles(s3, prefix = '') {
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
const files = [];
|
|
83
|
+
const stream = s3.client.listObjectsV2(InteractiveStorageExtension.bucketName, prefix, true);
|
|
84
|
+
|
|
85
|
+
stream.on('data', (obj) => {
|
|
86
|
+
files.push({
|
|
87
|
+
name: obj.name,
|
|
88
|
+
size: obj.size,
|
|
89
|
+
lastModified: obj.lastModified,
|
|
90
|
+
etag: obj.etag
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
stream.on('end', () => resolve(files));
|
|
95
|
+
stream.on('error', reject);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async #listFilesAndFolders(s3, prefix = '') {
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
const items = [];
|
|
102
|
+
const folders = new Set();
|
|
103
|
+
|
|
104
|
+
const stream = s3.client.listObjectsV2(InteractiveStorageExtension.bucketName, prefix, false);
|
|
105
|
+
|
|
106
|
+
stream.on('data', (obj) => {
|
|
107
|
+
if (obj.prefix) {
|
|
108
|
+
// This is a folder
|
|
109
|
+
const folderName = obj.prefix.slice(prefix.length).replace(/\/$/, '');
|
|
110
|
+
if (folderName && !folderName.includes('/')) {
|
|
111
|
+
folders.add(folderName);
|
|
112
|
+
}
|
|
113
|
+
} else if (obj.name) {
|
|
114
|
+
// This is a file
|
|
115
|
+
const fileName = obj.name.slice(prefix.length);
|
|
116
|
+
|
|
117
|
+
// Skip folder markers and files in subfolders
|
|
118
|
+
if (fileName === '.folder' || fileName.includes('/')) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
items.push({
|
|
123
|
+
type: 'file',
|
|
124
|
+
name: fileName,
|
|
125
|
+
fullPath: obj.name,
|
|
126
|
+
size: obj.size,
|
|
127
|
+
lastModified: obj.lastModified,
|
|
128
|
+
etag: obj.etag
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
stream.on('end', () => {
|
|
134
|
+
// Add folders to items
|
|
135
|
+
folders.forEach(folder => {
|
|
136
|
+
items.unshift({
|
|
137
|
+
type: 'folder',
|
|
138
|
+
name: folder,
|
|
139
|
+
fullPath: prefix + folder
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
resolve(items);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
stream.on('error', reject);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
#normalizePath(path) {
|
|
151
|
+
// Remove leading/trailing slashes and normalize
|
|
152
|
+
return path.replace(/^\/+|\/+$/g, '').replace(/\/+/g, '/');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async #getFileStat(s3, fileName) {
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
s3.client.statObject(InteractiveStorageExtension.bucketName, fileName, (err, stat) => {
|
|
158
|
+
if (err) return reject(err);
|
|
159
|
+
resolve(stat);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
163
|
}
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
const { Middleware } = require('../../../services/express');
|
|
2
|
-
const multer = require('multer');
|
|
3
|
-
|
|
4
|
-
module.exports = class MulterMiddleware extends Middleware {
|
|
5
|
-
upload;
|
|
6
|
-
|
|
7
|
-
constructor(maxFileSize = 100 * 1024 * 1024) {
|
|
8
|
-
super();
|
|
9
|
-
this.upload = multer({
|
|
10
|
-
storage: multer.memoryStorage(),
|
|
11
|
-
limits: {
|
|
12
|
-
fileSize: maxFileSize
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async handle({ container, request, response, next }) {
|
|
18
|
-
const uploadMiddleware = this.upload.array('files');
|
|
19
|
-
|
|
20
|
-
return new Promise((resolve, reject) => {
|
|
21
|
-
uploadMiddleware(request, response, (err) => {
|
|
22
|
-
if (err) {
|
|
23
|
-
container.get('logger').error(`Multer error: ${err.message}`);
|
|
24
|
-
return reject(err);
|
|
25
|
-
}
|
|
26
|
-
next();
|
|
27
|
-
resolve();
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
};
|
|
1
|
+
const { Middleware } = require('../../../services/express');
|
|
2
|
+
const multer = require('multer');
|
|
3
|
+
|
|
4
|
+
module.exports = class MulterMiddleware extends Middleware {
|
|
5
|
+
upload;
|
|
6
|
+
|
|
7
|
+
constructor(maxFileSize = 100 * 1024 * 1024) {
|
|
8
|
+
super();
|
|
9
|
+
this.upload = multer({
|
|
10
|
+
storage: multer.memoryStorage(),
|
|
11
|
+
limits: {
|
|
12
|
+
fileSize: maxFileSize
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async handle({ container, request, response, next }) {
|
|
18
|
+
const uploadMiddleware = this.upload.array('files');
|
|
19
|
+
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
uploadMiddleware(request, response, (err) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
container.get('logger').error(`Multer error: ${err.message}`);
|
|
24
|
+
return reject(err);
|
|
25
|
+
}
|
|
26
|
+
next();
|
|
27
|
+
resolve();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
const { Route } = require('../../../services/express');
|
|
2
|
-
|
|
3
|
-
module.exports = class BrowseRoute extends Route {
|
|
4
|
-
s3;
|
|
5
|
-
bucketName;
|
|
6
|
-
normalizePath;
|
|
7
|
-
listFilesAndFolders;
|
|
8
|
-
|
|
9
|
-
constructor(path, s3, bucketName, normalizePath, listFilesAndFolders) {
|
|
10
|
-
super(path);
|
|
11
|
-
this.s3 = s3;
|
|
12
|
-
this.bucketName = bucketName;
|
|
13
|
-
this.normalizePath = normalizePath;
|
|
14
|
-
this.listFilesAndFolders = listFilesAndFolders;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async get({ container, request }) {
|
|
18
|
-
const logger = container.get('logger');
|
|
19
|
-
const folder = request.query.folder || '';
|
|
20
|
-
const prefix = folder ? this.normalizePath(folder) + '/' : '';
|
|
21
|
-
|
|
22
|
-
const items = await this.listFilesAndFolders(this.s3, prefix);
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
success: true,
|
|
26
|
-
bucket: this.bucketName,
|
|
27
|
-
currentPath: folder,
|
|
28
|
-
items: items
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
};
|
|
1
|
+
const { Route } = require('../../../services/express');
|
|
2
|
+
|
|
3
|
+
module.exports = class BrowseRoute extends Route {
|
|
4
|
+
s3;
|
|
5
|
+
bucketName;
|
|
6
|
+
normalizePath;
|
|
7
|
+
listFilesAndFolders;
|
|
8
|
+
|
|
9
|
+
constructor(path, s3, bucketName, normalizePath, listFilesAndFolders) {
|
|
10
|
+
super(path);
|
|
11
|
+
this.s3 = s3;
|
|
12
|
+
this.bucketName = bucketName;
|
|
13
|
+
this.normalizePath = normalizePath;
|
|
14
|
+
this.listFilesAndFolders = listFilesAndFolders;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async get({ container, request }) {
|
|
18
|
+
const logger = container.get('logger');
|
|
19
|
+
const folder = request.query.folder || '';
|
|
20
|
+
const prefix = folder ? this.normalizePath(folder) + '/' : '';
|
|
21
|
+
|
|
22
|
+
const items = await this.listFilesAndFolders(this.s3, prefix);
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
success: true,
|
|
26
|
+
bucket: this.bucketName,
|
|
27
|
+
currentPath: folder,
|
|
28
|
+
items: items
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
const { Route } = require('../../../services/express');
|
|
2
|
-
|
|
3
|
-
module.exports = class CreateFolderRoute extends Route {
|
|
4
|
-
s3;
|
|
5
|
-
bucketName;
|
|
6
|
-
normalizePath;
|
|
7
|
-
|
|
8
|
-
constructor(path, s3, bucketName, normalizePath) {
|
|
9
|
-
super(path);
|
|
10
|
-
this.s3 = s3;
|
|
11
|
-
this.bucketName = bucketName;
|
|
12
|
-
this.normalizePath = normalizePath;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async post({ container, request }) {
|
|
16
|
-
const logger = container.get('logger');
|
|
17
|
-
const { folderPath } = request.body;
|
|
18
|
-
|
|
19
|
-
if (!folderPath) {
|
|
20
|
-
return { success: false, message: 'Folder path is required', status: 400 };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const normalizedPath = this.normalizePath(folderPath);
|
|
24
|
-
const folderMarker = `${normalizedPath}/.folder`;
|
|
25
|
-
|
|
26
|
-
// Create an empty marker file to represent the folder
|
|
27
|
-
await this.s3.saveFile(this.bucketName, folderMarker, Buffer.from(''), 'text/plain');
|
|
28
|
-
|
|
29
|
-
logger.info(`Created folder: ${normalizedPath}`);
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
success: true,
|
|
33
|
-
message: 'Folder created successfully',
|
|
34
|
-
folderPath: normalizedPath
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
};
|
|
1
|
+
const { Route } = require('../../../services/express');
|
|
2
|
+
|
|
3
|
+
module.exports = class CreateFolderRoute extends Route {
|
|
4
|
+
s3;
|
|
5
|
+
bucketName;
|
|
6
|
+
normalizePath;
|
|
7
|
+
|
|
8
|
+
constructor(path, s3, bucketName, normalizePath) {
|
|
9
|
+
super(path);
|
|
10
|
+
this.s3 = s3;
|
|
11
|
+
this.bucketName = bucketName;
|
|
12
|
+
this.normalizePath = normalizePath;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async post({ container, request }) {
|
|
16
|
+
const logger = container.get('logger');
|
|
17
|
+
const { folderPath } = request.body;
|
|
18
|
+
|
|
19
|
+
if (!folderPath) {
|
|
20
|
+
return { success: false, message: 'Folder path is required', status: 400 };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const normalizedPath = this.normalizePath(folderPath);
|
|
24
|
+
const folderMarker = `${normalizedPath}/.folder`;
|
|
25
|
+
|
|
26
|
+
// Create an empty marker file to represent the folder
|
|
27
|
+
await this.s3.saveFile(this.bucketName, folderMarker, Buffer.from(''), 'text/plain');
|
|
28
|
+
|
|
29
|
+
logger.info(`Created folder: ${normalizedPath}`);
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
success: true,
|
|
33
|
+
message: 'Folder created successfully',
|
|
34
|
+
folderPath: normalizedPath
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
};
|