streamby-core 0.12.2 → 0.13.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.
@@ -398,12 +398,15 @@ export declare function initProjectModel(connection: mongoose.Connection): mongo
398
398
  members: mongoose.Types.DocumentArray<{
399
399
  userId: mongoose.Types.ObjectId;
400
400
  role: "viewer" | "editor" | "admin";
401
+ archived: boolean;
401
402
  }, mongoose.Types.Subdocument<mongoose.Types.ObjectId, any, {
402
403
  userId: mongoose.Types.ObjectId;
403
404
  role: "viewer" | "editor" | "admin";
405
+ archived: boolean;
404
406
  }> & {
405
407
  userId: mongoose.Types.ObjectId;
406
408
  role: "viewer" | "editor" | "admin";
409
+ archived: boolean;
407
410
  }>;
408
411
  allowUpload: boolean;
409
412
  allowSharing: boolean;
@@ -808,12 +811,15 @@ export declare function initProjectModel(connection: mongoose.Connection): mongo
808
811
  members: mongoose.Types.DocumentArray<{
809
812
  userId: mongoose.Types.ObjectId;
810
813
  role: "viewer" | "editor" | "admin";
814
+ archived: boolean;
811
815
  }, mongoose.Types.Subdocument<mongoose.Types.ObjectId, any, {
812
816
  userId: mongoose.Types.ObjectId;
813
817
  role: "viewer" | "editor" | "admin";
818
+ archived: boolean;
814
819
  }> & {
815
820
  userId: mongoose.Types.ObjectId;
816
821
  role: "viewer" | "editor" | "admin";
822
+ archived: boolean;
817
823
  }>;
818
824
  allowUpload: boolean;
819
825
  allowSharing: boolean;
@@ -1218,12 +1224,15 @@ export declare function initProjectModel(connection: mongoose.Connection): mongo
1218
1224
  members: mongoose.Types.DocumentArray<{
1219
1225
  userId: mongoose.Types.ObjectId;
1220
1226
  role: "viewer" | "editor" | "admin";
1227
+ archived: boolean;
1221
1228
  }, mongoose.Types.Subdocument<mongoose.Types.ObjectId, any, {
1222
1229
  userId: mongoose.Types.ObjectId;
1223
1230
  role: "viewer" | "editor" | "admin";
1231
+ archived: boolean;
1224
1232
  }> & {
1225
1233
  userId: mongoose.Types.ObjectId;
1226
1234
  role: "viewer" | "editor" | "admin";
1235
+ archived: boolean;
1227
1236
  }>;
1228
1237
  allowUpload: boolean;
1229
1238
  allowSharing: boolean;
@@ -1634,12 +1643,15 @@ export declare function initProjectModel(connection: mongoose.Connection): mongo
1634
1643
  members: mongoose.Types.DocumentArray<{
1635
1644
  userId: mongoose.Types.ObjectId;
1636
1645
  role: "viewer" | "editor" | "admin";
1646
+ archived: boolean;
1637
1647
  }, mongoose.Types.Subdocument<mongoose.Types.ObjectId, any, {
1638
1648
  userId: mongoose.Types.ObjectId;
1639
1649
  role: "viewer" | "editor" | "admin";
1650
+ archived: boolean;
1640
1651
  }> & {
1641
1652
  userId: mongoose.Types.ObjectId;
1642
1653
  role: "viewer" | "editor" | "admin";
1654
+ archived: boolean;
1643
1655
  }>;
1644
1656
  allowUpload: boolean;
1645
1657
  allowSharing: boolean;
@@ -2044,12 +2056,15 @@ export declare function initProjectModel(connection: mongoose.Connection): mongo
2044
2056
  members: mongoose.Types.DocumentArray<{
2045
2057
  userId: mongoose.Types.ObjectId;
2046
2058
  role: "viewer" | "editor" | "admin";
2059
+ archived: boolean;
2047
2060
  }, mongoose.Types.Subdocument<mongoose.Types.ObjectId, any, {
2048
2061
  userId: mongoose.Types.ObjectId;
2049
2062
  role: "viewer" | "editor" | "admin";
2063
+ archived: boolean;
2050
2064
  }> & {
2051
2065
  userId: mongoose.Types.ObjectId;
2052
2066
  role: "viewer" | "editor" | "admin";
2067
+ archived: boolean;
2053
2068
  }>;
2054
2069
  allowUpload: boolean;
2055
2070
  allowSharing: boolean;
@@ -2454,12 +2469,15 @@ export declare function initProjectModel(connection: mongoose.Connection): mongo
2454
2469
  members: mongoose.Types.DocumentArray<{
2455
2470
  userId: mongoose.Types.ObjectId;
2456
2471
  role: "viewer" | "editor" | "admin";
2472
+ archived: boolean;
2457
2473
  }, mongoose.Types.Subdocument<mongoose.Types.ObjectId, any, {
2458
2474
  userId: mongoose.Types.ObjectId;
2459
2475
  role: "viewer" | "editor" | "admin";
2476
+ archived: boolean;
2460
2477
  }> & {
2461
2478
  userId: mongoose.Types.ObjectId;
2462
2479
  role: "viewer" | "editor" | "admin";
2480
+ archived: boolean;
2463
2481
  }>;
2464
2482
  allowUpload: boolean;
2465
2483
  allowSharing: boolean;
@@ -11,6 +11,11 @@ function initProjectModel(connection) {
11
11
  name: String,
12
12
  children: [Object],
13
13
  }, { _id: false });
14
+ const memberSchema = new mongoose_1.default.Schema({
15
+ userId: { type: mongoose_1.default.Schema.Types.ObjectId, ref: 'User', required: true },
16
+ role: { type: String, enum: ['viewer', 'editor', 'admin'], default: 'viewer' },
17
+ archived: { type: Boolean, default: false }
18
+ }, { _id: false });
14
19
  const projectSchema = new mongoose_1.default.Schema({
15
20
  name: { type: String, required: true },
16
21
  description: { type: String },
@@ -18,10 +23,7 @@ function initProjectModel(connection) {
18
23
  rootFolders: [folderNodeSchema],
19
24
  allowUpload: { type: Boolean, default: true },
20
25
  allowSharing: { type: Boolean, default: false },
21
- members: [{
22
- userId: { type: mongoose_1.default.Schema.Types.ObjectId, ref: 'User', required: true },
23
- role: { type: String, enum: ['viewer', 'editor', 'admin'], default: 'viewer' }
24
- }]
26
+ members: [memberSchema]
25
27
  }, {
26
28
  timestamps: true
27
29
  });
@@ -80,6 +80,16 @@ function createStreamByRouter(config) {
80
80
  res.status(500).json({ error: 'Failed to list files', details: err });
81
81
  }
82
82
  });
83
+ router.get('/projects/archived', async (req, res) => {
84
+ try {
85
+ const auth = await config.authProvider(req);
86
+ const archivedProjects = await projectProvider.listArchived(auth.userId);
87
+ res.json({ projects: archivedProjects });
88
+ }
89
+ catch (err) {
90
+ res.status(500).json({ error: 'Failed to list archived projects', details: err });
91
+ }
92
+ });
83
93
  router.get('/projects/:id', async (req, res) => {
84
94
  try {
85
95
  const auth = await config.authProvider(req);
@@ -168,5 +178,39 @@ function createStreamByRouter(config) {
168
178
  res.status(500).json({ error: 'Failed to list projects', details: err });
169
179
  }
170
180
  });
181
+ router.patch('/projects/:id/archive', async (req, res) => {
182
+ try {
183
+ const auth = await config.authProvider(req);
184
+ const projectId = req.params.id;
185
+ const project = await projectProvider.getById(projectId);
186
+ if (!project || !isProjectMember(project, auth.userId)) {
187
+ return res.status(403).json({ error: 'Unauthorized project access' });
188
+ }
189
+ await projectProvider.archive(projectId, auth.userId);
190
+ const projects = await projectProvider.list(auth.userId);
191
+ const archivedProjects = await projectProvider.listArchived(auth.userId);
192
+ res.status(200).json({ success: true, projects, archivedProjects });
193
+ }
194
+ catch (err) {
195
+ res.status(500).json({ error: 'Failed to archive project', details: err.message });
196
+ }
197
+ });
198
+ router.patch('/projects/:id/unarchive', async (req, res) => {
199
+ try {
200
+ const auth = await config.authProvider(req);
201
+ const projectId = req.params.id;
202
+ const project = await projectProvider.getById(projectId);
203
+ if (!project || !isProjectMember(project, auth.userId)) {
204
+ return res.status(403).json({ error: 'Unauthorized project access' });
205
+ }
206
+ await projectProvider.unarchive(projectId, auth.userId);
207
+ const projects = await projectProvider.list(auth.userId);
208
+ const archivedProjects = await projectProvider.listArchived(auth.userId);
209
+ res.status(200).json({ success: true, projects, archivedProjects });
210
+ }
211
+ catch (err) {
212
+ res.status(500).json({ error: 'Failed to unarchive project', details: err.message });
213
+ }
214
+ });
171
215
  return router;
172
216
  }
@@ -15,6 +15,7 @@ function createMongoProjectProvider(ProjectModel, adapter) {
15
15
  {
16
16
  userId: data.members?.[0].userId,
17
17
  role: data.members?.[0].role,
18
+ archived: false
18
19
  }
19
20
  ],
20
21
  name: data.name,
@@ -33,8 +34,15 @@ function createMongoProjectProvider(ProjectModel, adapter) {
33
34
  return formatProject(updated);
34
35
  },
35
36
  async list(userId) {
36
- const query = userId ? { 'members.userId': userId } : {};
37
- const all = await ProjectModel.find(query);
37
+ const all = await ProjectModel.find(userId
38
+ ? { 'members': { $elemMatch: { userId, archived: { $ne: true } } } }
39
+ : {});
40
+ return all.map(formatProject);
41
+ },
42
+ async listArchived(userId) {
43
+ const all = await ProjectModel.find(userId
44
+ ? { 'members': { $elemMatch: { userId, archived: true } } }
45
+ : {});
38
46
  return all.map(formatProject);
39
47
  },
40
48
  async delete(projectId) {
@@ -46,6 +54,14 @@ function createMongoProjectProvider(ProjectModel, adapter) {
46
54
  catch (error) {
47
55
  throw new Error('Project not found');
48
56
  }
57
+ },
58
+ async archive(projectId, userId) {
59
+ await ProjectModel.updateOne({ _id: projectId, 'members.userId': userId }, { $set: { 'members.$.archived': true } });
60
+ return { success: true, projects: await this.list(userId), archivedProjects: await this.listArchived(userId) };
61
+ },
62
+ async unarchive(projectId, userId) {
63
+ await ProjectModel.updateOne({ _id: projectId, 'members.userId': userId }, { $set: { 'members.$.archived': false } });
64
+ return { success: true, projects: await this.list(userId), archivedProjects: await this.listArchived(userId) };
49
65
  }
50
66
  };
51
67
  }
@@ -57,6 +73,7 @@ function formatProject(doc) {
57
73
  members: doc.members.map((m) => ({
58
74
  userId: m.userId,
59
75
  role: m.role,
76
+ archived: m.archived ?? false
60
77
  })),
61
78
  description: doc.description,
62
79
  rootFolders: doc.rootFolders || [],
@@ -28,8 +28,9 @@ export interface ProjectInfo {
28
28
  name: string;
29
29
  image?: string;
30
30
  members?: {
31
- userId: string;
32
31
  role: 'viewer' | 'editor' | 'admin';
32
+ userId: string;
33
+ archived?: boolean;
33
34
  }[];
34
35
  description?: string;
35
36
  rootFolders?: FolderNode[];
@@ -66,7 +67,18 @@ export interface AuthContext {
66
67
  }
67
68
  export type AuthProvider = (req: Request) => Promise<AuthContext>;
68
69
  export interface ProjectProvider {
70
+ archive(projectId: string, userId: string): Promise<{
71
+ success: boolean;
72
+ projects: ProjectInfo[];
73
+ archivedProjects: ProjectInfo[];
74
+ }>;
75
+ unarchive(projectId: string, userId: string): Promise<{
76
+ success: boolean;
77
+ projects: ProjectInfo[];
78
+ archivedProjects: ProjectInfo[];
79
+ }>;
69
80
  list(userId?: string): Promise<ProjectInfo[]>;
81
+ listArchived(userId?: string): Promise<ProjectInfo[]>;
70
82
  getById(projectId: string): Promise<ProjectInfo>;
71
83
  delete(projectId: string): Promise<{
72
84
  success: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "streamby-core",
3
- "version": "0.12.2",
3
+ "version": "0.13.0",
4
4
  "description": "StreamBy middleware framework for media storage management",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,9 +0,0 @@
1
- import { Request } from 'express';
2
- import { AuthProvider, ProjectProvider } from '../types';
3
- export declare function createProjectService(req: Request, authProvider: AuthProvider, projectProvider: ProjectProvider): Promise<{
4
- success: boolean;
5
- project: import("../types").ProjectInfo;
6
- }>;
7
- export declare function deleteProjectImageService(req: Request, authProvider: AuthProvider, projectProvider: ProjectProvider): Promise<{
8
- success: boolean;
9
- }>;
@@ -1,35 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createProjectService = createProjectService;
4
- exports.deleteProjectImageService = deleteProjectImageService;
5
- async function createProjectService(req, authProvider, projectProvider) {
6
- const { name, description } = req.body;
7
- const auth = await authProvider(req);
8
- if (!name) {
9
- throw new Error('Project name is required');
10
- }
11
- const newProject = await projectProvider.create({
12
- name,
13
- description: description || '',
14
- members: [{ userId: auth.userId, role: "admin" }]
15
- });
16
- return {
17
- success: true,
18
- project: newProject,
19
- };
20
- }
21
- async function deleteProjectImageService(req, authProvider, projectProvider) {
22
- const { projectId } = req.params;
23
- const auth = await authProvider(req);
24
- const project = await projectProvider.getById(projectId);
25
- if (!project) {
26
- throw new Error('Project not found');
27
- }
28
- if (!project.members?.find((e) => e.userId === auth.userId)) {
29
- throw new Error('Unauthorized');
30
- }
31
- await projectProvider.update(projectId, { image: '' });
32
- return {
33
- success: true,
34
- };
35
- }