streamby-core 0.9.19 → 0.9.21
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/adapters/s3.js +11 -1
- package/dist/middleware/createRouter.d.ts +2 -5
- package/dist/middleware/createRouter.js +17 -141
- package/dist/services/file.d.ts +1 -0
- package/dist/services/file.js +7 -0
- package/dist/services/presign.d.ts +1 -1
- package/dist/services/presign.js +2 -2
- package/dist/services/project.d.ts +8 -1
- package/dist/services/project.js +33 -0
- package/dist/types/index.d.ts +3 -1
- package/package.json +1 -1
package/dist/adapters/s3.js
CHANGED
|
@@ -23,7 +23,17 @@ function createS3Adapter(config) {
|
|
|
23
23
|
const publicUrl = `https://${config.bucket}.s3.${config.region}.amazonaws.com/${encodeURIComponent(key)}`;
|
|
24
24
|
return { url, publicUrl };
|
|
25
25
|
},
|
|
26
|
-
async
|
|
26
|
+
async deleteProjectImage(projectId) {
|
|
27
|
+
const key = `${projectId}/project-image`;
|
|
28
|
+
const command = new client_s3_1.DeleteObjectsCommand({
|
|
29
|
+
Bucket: config.bucket,
|
|
30
|
+
Delete: {
|
|
31
|
+
Objects: [{ Key: key }],
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
await s3.send(command);
|
|
35
|
+
},
|
|
36
|
+
async getPresignedUrl(contentType, projectId) {
|
|
27
37
|
const key = `${projectId}/${contentType}/file-${Date.now()}`;
|
|
28
38
|
const command = new client_s3_1.PutObjectCommand({
|
|
29
39
|
Bucket: config.bucket,
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export declare function createStreamByRouter(config: StreamByConfig & {
|
|
4
|
-
adapter?: StorageAdapter;
|
|
5
|
-
}): Router;
|
|
1
|
+
import type { StreamByConfig } from '../types';
|
|
2
|
+
export declare function createStreamByRouter(config: StreamByConfig): import("express-serve-static-core").Router;
|
|
@@ -5,147 +5,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.createStreamByRouter = createStreamByRouter;
|
|
7
7
|
const express_1 = __importDefault(require("express"));
|
|
8
|
-
const s3_1 = require("../adapters/s3");
|
|
9
|
-
const file_1 = require("../services/file");
|
|
10
8
|
const project_1 = require("../services/project");
|
|
11
|
-
const presign_1 = require("../services/presign");
|
|
12
9
|
function createStreamByRouter(config) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
router.get('/upload-project-image-url/:id', async (req, res) => {
|
|
32
|
-
try {
|
|
33
|
-
const auth = await config.authProvider(req);
|
|
34
|
-
if (auth.role !== 'admin' && auth.role !== 'editor') {
|
|
35
|
-
return res.status(403).json({ error: 'Permission denied' });
|
|
36
|
-
}
|
|
37
|
-
const projectId = req.params.id;
|
|
38
|
-
if (!projectId) {
|
|
39
|
-
return res.status(400).json({ error: 'Missing filename, contentType, or projectId' });
|
|
40
|
-
}
|
|
41
|
-
const url = await (0, presign_1.getPresignedProjectImageUrl)(adapter, projectId);
|
|
42
|
-
res.json(url);
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
res.status(500).json({ error: 'Failed to generate presigned URL', details: err.message });
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
router.post('/upload-url', async (req, res) => {
|
|
49
|
-
try {
|
|
50
|
-
const auth = await config.authProvider(req);
|
|
51
|
-
if (auth.role !== 'admin' && auth.role !== 'editor') {
|
|
52
|
-
return res.status(403).json({ error: 'Permission denied' });
|
|
53
|
-
}
|
|
54
|
-
const { filename, contentType, projectId } = req.body;
|
|
55
|
-
if (!filename || !contentType || !projectId) {
|
|
56
|
-
return res.status(400).json({ error: 'Missing filename, contentType, or projectId' });
|
|
57
|
-
}
|
|
58
|
-
const url = await (0, presign_1.getPresignedUrl)(adapter, filename, contentType, projectId);
|
|
59
|
-
res.json(url);
|
|
60
|
-
}
|
|
61
|
-
catch (err) {
|
|
62
|
-
res.status(500).json({ error: 'Failed to generate presigned URL', details: err.message });
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
router.get('/files', async (req, res) => {
|
|
66
|
-
try {
|
|
67
|
-
const auth = await config.authProvider(req);
|
|
68
|
-
const projectId = (req.query.projectId || req.headers['x-project-id']);
|
|
69
|
-
if (!projectId || !auth.projects.includes(projectId)) {
|
|
70
|
-
return res.status(403).json({ error: 'Unauthorized or missing projectId' });
|
|
71
|
-
}
|
|
72
|
-
const files = await (0, file_1.listFilesService)(adapter, req, projectId);
|
|
73
|
-
res.json(files);
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
res.status(500).json({ error: 'Failed to list files', details: err });
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
router.patch('/projects/:id', async (req, res) => {
|
|
80
|
-
try {
|
|
81
|
-
const auth = await config.authProvider(req);
|
|
82
|
-
if (auth.role !== 'admin' && auth.role !== 'editor') {
|
|
83
|
-
return res.status(403).json({ error: 'Permission denied' });
|
|
84
|
-
}
|
|
85
|
-
const projectId = req.params.id;
|
|
86
|
-
const updates = req.body;
|
|
87
|
-
if (!updates || typeof updates !== 'object') {
|
|
88
|
-
return res.status(400).json({ error: 'Missing updates payload' });
|
|
89
|
-
}
|
|
90
|
-
const updated = await config.projectProvider.update(projectId, updates);
|
|
91
|
-
res.status(200).json({ success: true, project: updated });
|
|
92
|
-
}
|
|
93
|
-
catch (err) {
|
|
94
|
-
res.status(500).json({ error: 'Failed to update project', details: err.message });
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
router.get('/projects/:id', async (req, res) => {
|
|
98
|
-
try {
|
|
99
|
-
const auth = await config.authProvider(req);
|
|
100
|
-
const projectId = req.params.id;
|
|
101
|
-
const project = await config.projectProvider.getById(projectId);
|
|
102
|
-
const isMember = project.members?.some((m) => m.userId?.toString() === auth.userId?.toString());
|
|
103
|
-
if (!isMember) {
|
|
104
|
-
return res.status(403).json({ error: 'Unauthorized project access' });
|
|
105
|
-
}
|
|
106
|
-
res.json({ project });
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
res.status(404).json({ error: 'Project not found', details: err.message });
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
router.post('/projects/create', async (req, res) => {
|
|
113
|
-
try {
|
|
114
|
-
const auth = await config.authProvider(req);
|
|
115
|
-
if (auth.role !== 'admin' && auth.role !== 'editor') {
|
|
116
|
-
return res.status(403).json({ error: 'Permission denied' });
|
|
117
|
-
}
|
|
118
|
-
const created = await (0, project_1.createProjectService)(req, config.authProvider, config.projectProvider);
|
|
119
|
-
res.status(201).json(created);
|
|
120
|
-
}
|
|
121
|
-
catch (err) {
|
|
122
|
-
res.status(500).json({ error: 'Failed to create project', details: err.message });
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
router.delete('/projects/:id', async (req, res) => {
|
|
126
|
-
try {
|
|
127
|
-
const auth = await config.authProvider(req);
|
|
128
|
-
const projectId = req.params.id;
|
|
129
|
-
if (auth.role !== 'admin' && auth.role !== 'editor') {
|
|
130
|
-
return res.status(403).json({ error: 'Permission denied' });
|
|
131
|
-
}
|
|
132
|
-
await config.projectProvider.delete(projectId);
|
|
133
|
-
await adapter.deleteProjectDirectory(projectId);
|
|
134
|
-
res.status(200).json({ success: true });
|
|
135
|
-
}
|
|
136
|
-
catch (err) {
|
|
137
|
-
res.status(500).json({ error: 'Failed to delete project', details: err.message });
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
router.get('/projects', async (req, res) => {
|
|
141
|
-
try {
|
|
142
|
-
const auth = await config.authProvider(req);
|
|
143
|
-
const projects = await config.projectProvider.list(auth.userId);
|
|
144
|
-
res.json({ projects });
|
|
145
|
-
}
|
|
146
|
-
catch (err) {
|
|
147
|
-
res.status(500).json({ error: 'Failed to list projects', details: err });
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
return router;
|
|
10
|
+
const app = express_1.default.Router();
|
|
11
|
+
app.post('/project', (req, res) => {
|
|
12
|
+
(0, project_1.createProjectService)(req, config.authProvider, config.projectProvider)
|
|
13
|
+
.then((result) => res.json(result))
|
|
14
|
+
.catch((err) => res.status(400).json({ error: err.message }));
|
|
15
|
+
});
|
|
16
|
+
app.put('/project/:projectId', (req, res) => {
|
|
17
|
+
(0, project_1.updateProjectService)(req, config.authProvider, config.projectProvider)
|
|
18
|
+
.then((result) => res.json(result))
|
|
19
|
+
.catch((err) => res.status(400).json({ error: err.message }));
|
|
20
|
+
});
|
|
21
|
+
app.delete('/project/:projectId/image', (req, res) => {
|
|
22
|
+
(0, project_1.deleteProjectImageService)(req, config.authProvider, config.projectProvider, config.storageAdapter)
|
|
23
|
+
.then((result) => res.json(result))
|
|
24
|
+
.catch((err) => res.status(400).json({ error: err.message }));
|
|
25
|
+
});
|
|
26
|
+
return app;
|
|
151
27
|
}
|
package/dist/services/file.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { StorageAdapter } from '../types';
|
|
2
2
|
import { Request } from 'express';
|
|
3
3
|
export declare function listFilesService(adapter: StorageAdapter, req: Request, projectId: string): Promise<any[]>;
|
|
4
|
+
export declare function deleteProjectImage(adapter: StorageAdapter, projectId: string): Promise<any>;
|
package/dist/services/file.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.listFilesService = listFilesService;
|
|
4
|
+
exports.deleteProjectImage = deleteProjectImage;
|
|
4
5
|
async function listFilesService(adapter, req, projectId) {
|
|
5
6
|
return adapter.listFiles(projectId);
|
|
6
7
|
}
|
|
8
|
+
async function deleteProjectImage(adapter, projectId) {
|
|
9
|
+
if (!('deleteProjectImage' in adapter)) {
|
|
10
|
+
throw new Error('StorageAdapter does not support deleting project images');
|
|
11
|
+
}
|
|
12
|
+
return adapter.deleteProjectImage(projectId);
|
|
13
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { StorageAdapter } from '../types';
|
|
2
|
-
export declare function getPresignedUrl(adapter: StorageAdapter,
|
|
2
|
+
export declare function getPresignedUrl(adapter: StorageAdapter, contentType: string, projectId: string): Promise<any>;
|
|
3
3
|
export declare function getPresignedProjectImageUrl(adapter: StorageAdapter, projectId: string): Promise<any>;
|
package/dist/services/presign.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getPresignedUrl = getPresignedUrl;
|
|
4
4
|
exports.getPresignedProjectImageUrl = getPresignedProjectImageUrl;
|
|
5
|
-
async function getPresignedUrl(adapter,
|
|
5
|
+
async function getPresignedUrl(adapter, contentType, projectId) {
|
|
6
6
|
if (!('getPresignedUrl' in adapter)) {
|
|
7
7
|
throw new Error('StorageAdapter does not support presigned URLs');
|
|
8
8
|
}
|
|
9
|
-
return adapter.getPresignedUrl(
|
|
9
|
+
return adapter.getPresignedUrl(contentType, projectId);
|
|
10
10
|
}
|
|
11
11
|
async function getPresignedProjectImageUrl(adapter, projectId) {
|
|
12
12
|
if (!('getPresignedProjectImageUrl' in adapter)) {
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Request } from 'express';
|
|
2
|
-
import { AuthProvider, ProjectProvider } from '../types';
|
|
2
|
+
import { AuthProvider, ProjectProvider, StorageAdapter } from '../types';
|
|
3
3
|
export declare function createProjectService(req: Request, authProvider: AuthProvider, projectProvider: ProjectProvider): Promise<{
|
|
4
4
|
success: boolean;
|
|
5
5
|
project: import("../types").ProjectInfo;
|
|
6
6
|
}>;
|
|
7
|
+
export declare function updateProjectService(req: Request, authProvider: AuthProvider, projectProvider: ProjectProvider): Promise<{
|
|
8
|
+
success: boolean;
|
|
9
|
+
project: import("../types").ProjectInfo;
|
|
10
|
+
}>;
|
|
11
|
+
export declare function deleteProjectImageService(req: Request, authProvider: AuthProvider, projectProvider: ProjectProvider, storageAdapter: StorageAdapter): Promise<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
}>;
|
package/dist/services/project.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createProjectService = createProjectService;
|
|
4
|
+
exports.updateProjectService = updateProjectService;
|
|
5
|
+
exports.deleteProjectImageService = deleteProjectImageService;
|
|
6
|
+
const file_1 = require("./file");
|
|
4
7
|
async function createProjectService(req, authProvider, projectProvider) {
|
|
5
8
|
const { name, description } = req.body;
|
|
6
9
|
const auth = await authProvider(req);
|
|
@@ -17,3 +20,33 @@ async function createProjectService(req, authProvider, projectProvider) {
|
|
|
17
20
|
project: newProject,
|
|
18
21
|
};
|
|
19
22
|
}
|
|
23
|
+
async function updateProjectService(req, authProvider, projectProvider) {
|
|
24
|
+
const { projectId } = req.params;
|
|
25
|
+
const updates = req.body;
|
|
26
|
+
const auth = await authProvider(req);
|
|
27
|
+
const project = await projectProvider.getById(projectId);
|
|
28
|
+
if (!project) {
|
|
29
|
+
throw new Error('Project not found');
|
|
30
|
+
}
|
|
31
|
+
if (!project.members?.find((e) => e.userId === auth.userId)) {
|
|
32
|
+
throw new Error('Unauthorized');
|
|
33
|
+
}
|
|
34
|
+
const updatedProject = await projectProvider.update(projectId, updates);
|
|
35
|
+
return {
|
|
36
|
+
success: true,
|
|
37
|
+
project: updatedProject,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async function deleteProjectImageService(req, authProvider, projectProvider, storageAdapter) {
|
|
41
|
+
const { projectId } = req.params;
|
|
42
|
+
const auth = await authProvider(req);
|
|
43
|
+
const project = await projectProvider.getById(projectId);
|
|
44
|
+
if (!project) {
|
|
45
|
+
throw new Error('Project not found');
|
|
46
|
+
}
|
|
47
|
+
if (!project.members?.find((e) => e.userId === auth.userId)) {
|
|
48
|
+
throw new Error('Unauthorized');
|
|
49
|
+
}
|
|
50
|
+
await (0, file_1.deleteProjectImage)(storageAdapter, projectId);
|
|
51
|
+
return { success: true };
|
|
52
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -9,8 +9,9 @@ export interface S3Config {
|
|
|
9
9
|
export type StorageProviderType = 's3';
|
|
10
10
|
export interface StorageAdapter {
|
|
11
11
|
listFiles(projectId: string): Promise<any[]>;
|
|
12
|
+
deleteProjectImage: (projectId: string) => Promise<any>;
|
|
12
13
|
deleteProjectDirectory: (projectId: string) => Promise<any>;
|
|
13
|
-
getPresignedUrl?: (
|
|
14
|
+
getPresignedUrl?: (contentType: string, projectId: string) => Promise<any>;
|
|
14
15
|
getPresignedProjectImageUrl?: (projectId: string) => Promise<any>;
|
|
15
16
|
}
|
|
16
17
|
export interface ProjectInfo {
|
|
@@ -39,6 +40,7 @@ export interface StreamByConfig {
|
|
|
39
40
|
config: S3Config;
|
|
40
41
|
};
|
|
41
42
|
authProvider: AuthProvider;
|
|
43
|
+
storageAdapter: StorageAdapter;
|
|
42
44
|
projectProvider: ProjectProvider;
|
|
43
45
|
dbConnection?: Connection;
|
|
44
46
|
}
|