streamby-core 0.13.0 → 0.15.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.
@@ -1,16 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createMongoProjectProvider = createMongoProjectProvider;
4
- function createMongoProjectProvider(ProjectModel, adapter) {
4
+ function createMongoProjectProvider(ProjectModel, ExportModel, adapter) {
5
5
  return {
6
- async getById(projectId) {
7
- const project = await ProjectModel.findById(projectId);
6
+ async getById(projectId, populateMembers = false) {
7
+ let query = ProjectModel.findById(projectId).populate('exports', ['_id', 'collectionName']);
8
+ if (populateMembers) {
9
+ query = query.populate('members.userId');
10
+ }
11
+ const project = await query;
8
12
  if (!project)
9
13
  throw new Error('Project not found');
10
14
  return formatProject(project);
11
15
  },
12
16
  async create(data) {
13
17
  const newProject = await ProjectModel.create({
18
+ dbType: data.dbType,
14
19
  members: [
15
20
  {
16
21
  userId: data.members?.[0].userId,
@@ -21,29 +26,23 @@ function createMongoProjectProvider(ProjectModel, adapter) {
21
26
  name: data.name,
22
27
  description: data.description || '',
23
28
  image: data.image || '',
24
- rootFolders: data.rootFolders || [],
29
+ rootFolders: data.folders || [],
25
30
  allowUpload: data.allowUpload ?? true,
26
31
  allowSharing: data.allowSharing ?? false,
27
32
  });
28
33
  return formatProject(newProject);
29
34
  },
30
35
  async update(projectId, updates) {
31
- const updated = await ProjectModel.findByIdAndUpdate(projectId, updates, { new: true });
36
+ const updated = await ProjectModel.findByIdAndUpdate(projectId, updates, { new: true }).populate('exports', ['_id', 'collectionName']);
32
37
  if (!updated)
33
38
  throw new Error('Project not found');
34
39
  return formatProject(updated);
35
40
  },
36
41
  async list(userId) {
37
42
  const all = await ProjectModel.find(userId
38
- ? { 'members': { $elemMatch: { userId, archived: { $ne: true } } } }
43
+ ? { 'members': { $elemMatch: { userId } } }
39
44
  : {});
40
- return all.map(formatProject);
41
- },
42
- async listArchived(userId) {
43
- const all = await ProjectModel.find(userId
44
- ? { 'members': { $elemMatch: { userId, archived: true } } }
45
- : {});
46
- return all.map(formatProject);
45
+ return all.map(doc => formatProjectList(doc, userId));
47
46
  },
48
47
  async delete(projectId) {
49
48
  try {
@@ -57,29 +56,52 @@ function createMongoProjectProvider(ProjectModel, adapter) {
57
56
  },
58
57
  async archive(projectId, userId) {
59
58
  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) };
59
+ return { success: true, projects: await this.list(userId) };
61
60
  },
62
61
  async unarchive(projectId, userId) {
63
62
  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) };
65
- }
66
- };
67
- }
68
- function formatProject(doc) {
69
- return {
70
- id: doc._id.toString(),
71
- name: doc.name,
72
- image: doc.image,
73
- members: doc.members.map((m) => ({
74
- userId: m.userId,
75
- role: m.role,
76
- archived: m.archived ?? false
77
- })),
78
- description: doc.description,
79
- rootFolders: doc.rootFolders || [],
80
- settings: {
81
- allowUpload: doc.allowUpload,
82
- allowSharing: doc.allowSharing,
63
+ return { success: true, projects: await this.list(userId) };
64
+ },
65
+ async getExport(projectId, exportId) {
66
+ const exportDoc = await ExportModel.findOne({ _id: exportId, project: projectId });
67
+ if (!exportDoc)
68
+ throw new Error('Export not found');
69
+ return exportDoc;
70
+ },
71
+ async addExportToProject(projectId, exportId) {
72
+ await ProjectModel.findByIdAndUpdate(projectId, { $push: { exports: exportId } });
83
73
  }
84
74
  };
75
+ function formatProject(doc) {
76
+ return {
77
+ id: doc._id.toString(),
78
+ dbType: doc.dbType,
79
+ name: doc.name,
80
+ image: doc.image,
81
+ members: doc.members.map((m) => ({
82
+ userId: m.userId?._id || m.userId,
83
+ username: m.userId?.username,
84
+ email: m.userId?.email,
85
+ role: m.role,
86
+ archived: m.archived ?? false
87
+ })),
88
+ description: doc.description,
89
+ folders: doc.rootFolders || [],
90
+ settings: {
91
+ allowUpload: doc.allowUpload,
92
+ allowSharing: doc.allowSharing,
93
+ },
94
+ exports: doc.exports || []
95
+ };
96
+ }
97
+ function formatProjectList(doc, userId) {
98
+ const archived = doc.members?.find((m) => m.userId?.toString() === userId)?.archived ?? false;
99
+ return {
100
+ id: doc._id.toString(),
101
+ dbType: doc.dbType,
102
+ name: doc.name,
103
+ image: doc.image,
104
+ archived
105
+ };
106
+ }
85
107
  }
@@ -0,0 +1,61 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+ export declare function createPrismaExportCollectionProvider(prisma: PrismaClient): {
3
+ getById(id: string): Promise<({
4
+ entries: {
5
+ id: string;
6
+ exportCollectionId: string;
7
+ key: string;
8
+ value: string;
9
+ }[];
10
+ } & {
11
+ id: string;
12
+ name: string;
13
+ createdAt: Date;
14
+ updatedAt: Date;
15
+ projectId: string;
16
+ }) | null>;
17
+ create(data: {
18
+ projectId: string;
19
+ name: string;
20
+ entries: Array<{
21
+ key: string;
22
+ value: string;
23
+ }>;
24
+ }): Promise<{
25
+ entries: {
26
+ id: string;
27
+ exportCollectionId: string;
28
+ key: string;
29
+ value: string;
30
+ }[];
31
+ } & {
32
+ id: string;
33
+ name: string;
34
+ createdAt: Date;
35
+ updatedAt: Date;
36
+ projectId: string;
37
+ }>;
38
+ update(id: string, data: {
39
+ name?: string;
40
+ entries?: Array<{
41
+ key: string;
42
+ value: string;
43
+ }>;
44
+ }): Promise<{
45
+ entries: {
46
+ id: string;
47
+ exportCollectionId: string;
48
+ key: string;
49
+ value: string;
50
+ }[];
51
+ } & {
52
+ id: string;
53
+ name: string;
54
+ createdAt: Date;
55
+ updatedAt: Date;
56
+ projectId: string;
57
+ }>;
58
+ delete(id: string): Promise<{
59
+ success: boolean;
60
+ }>;
61
+ };
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPrismaExportCollectionProvider = createPrismaExportCollectionProvider;
4
+ function createPrismaExportCollectionProvider(prisma) {
5
+ return {
6
+ async getById(id) {
7
+ return prisma.exportCollection.findUnique({
8
+ where: { id },
9
+ include: { entries: true },
10
+ });
11
+ },
12
+ async create(data) {
13
+ const { entries, ...rest } = data;
14
+ return prisma.exportCollection.create({
15
+ data: {
16
+ ...rest,
17
+ entries: {
18
+ createMany: { data: entries },
19
+ },
20
+ },
21
+ include: { entries: true },
22
+ });
23
+ },
24
+ async update(id, data) {
25
+ const { entries, ...rest } = data;
26
+ const updateData = { ...rest };
27
+ if (entries) {
28
+ // Eliminar entradas existentes y crear nuevas
29
+ await prisma.exportEntry.deleteMany({ where: { exportCollectionId: id } });
30
+ updateData.entries = {
31
+ createMany: { data: entries },
32
+ };
33
+ }
34
+ return prisma.exportCollection.update({
35
+ where: { id },
36
+ data: updateData,
37
+ include: { entries: true },
38
+ });
39
+ },
40
+ async delete(id) {
41
+ await prisma.exportCollection.delete({ where: { id } });
42
+ return { success: true };
43
+ },
44
+ };
45
+ }
@@ -0,0 +1,3 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+ import { ExportProvider } from '../types';
3
+ export declare function createPrismaExportProvider(prisma: PrismaClient): ExportProvider;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPrismaExportProvider = createPrismaExportProvider;
4
+ function createPrismaExportProvider(prisma) {
5
+ return {
6
+ async getById(exportId) {
7
+ return await prisma.export.findUnique({ where: { id: exportId } });
8
+ },
9
+ async create(data) {
10
+ return await prisma.export.create({ data });
11
+ },
12
+ };
13
+ }
@@ -0,0 +1,3 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+ import { ProjectProvider, StorageAdapter } from '../types';
3
+ export declare function createPrismaProjectProvider(prisma: PrismaClient, adapter: StorageAdapter): ProjectProvider;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPrismaProjectProvider = createPrismaProjectProvider;
4
+ function createPrismaProjectProvider(prisma, adapter) {
5
+ return {
6
+ async getById(projectId, populateMembers = false) {
7
+ const project = await prisma.project.findUnique({
8
+ where: { id: projectId },
9
+ include: {
10
+ exports: { select: { id: true, collectionName: true } },
11
+ members: populateMembers ? true : false,
12
+ },
13
+ });
14
+ if (!project)
15
+ throw new Error('Project not found');
16
+ return formatProject(project);
17
+ },
18
+ async create(data) {
19
+ const newProject = await prisma.project.create({
20
+ data: {
21
+ dbType: data.dbType,
22
+ name: data.name,
23
+ description: data.description || '',
24
+ image: data.image || '',
25
+ allowUpload: data.allowUpload ?? true,
26
+ allowSharing: data.allowSharing ?? false,
27
+ members: {
28
+ create: data.members?.[0] ? {
29
+ userId: data.members[0].userId,
30
+ role: data.members[0].role,
31
+ archived: false,
32
+ } : undefined,
33
+ },
34
+ },
35
+ include: {
36
+ exports: { select: { id: true, collectionName: true } },
37
+ members: true,
38
+ },
39
+ });
40
+ return formatProject(newProject);
41
+ },
42
+ async update(projectId, updates) {
43
+ const updated = await prisma.project.update({
44
+ where: { id: projectId },
45
+ data: {
46
+ name: updates.name,
47
+ description: updates.description,
48
+ image: updates.image,
49
+ allowUpload: updates.settings?.allowUpload,
50
+ allowSharing: updates.settings?.allowSharing,
51
+ },
52
+ include: {
53
+ exports: { select: { id: true, collectionName: true } },
54
+ members: true,
55
+ },
56
+ });
57
+ if (!updated)
58
+ throw new Error('Project not found');
59
+ return formatProject(updated);
60
+ },
61
+ async list(userId) {
62
+ const all = await prisma.project.findMany({
63
+ where: userId ? { members: { some: { userId } } } : {},
64
+ include: {
65
+ members: true,
66
+ },
67
+ });
68
+ return all.map(doc => formatProjectList(doc, userId));
69
+ },
70
+ async delete(projectId) {
71
+ try {
72
+ await prisma.project.delete({ where: { id: projectId } });
73
+ await adapter.deleteProjectDirectory(projectId);
74
+ return { success: true };
75
+ }
76
+ catch (error) {
77
+ throw new Error('Project not found');
78
+ }
79
+ },
80
+ async archive(projectId, userId) {
81
+ await prisma.member.updateMany({
82
+ where: { projectId, userId },
83
+ data: { archived: true },
84
+ });
85
+ return { success: true, projects: await this.list(userId) };
86
+ },
87
+ async unarchive(projectId, userId) {
88
+ await prisma.member.updateMany({
89
+ where: { projectId, userId },
90
+ data: { archived: false },
91
+ });
92
+ return { success: true, projects: await this.list(userId) };
93
+ },
94
+ async getExport(projectId, exportId) {
95
+ const exportDoc = await prisma.export.findFirst({
96
+ where: { id: exportId, projectId: projectId },
97
+ });
98
+ if (!exportDoc)
99
+ throw new Error('Export not found');
100
+ return exportDoc;
101
+ },
102
+ async addExportToProject(projectId, exportId) {
103
+ // En Prisma, la relación ya está definida en el modelo Export.
104
+ // No es necesario actualizar el Project directamente.
105
+ // Si se necesita vincular un Export existente a un Project, se haría al crear o actualizar el Export.
106
+ // Por ejemplo, al crear un Export:
107
+ // prisma.export.create({ data: { ..., projectId: projectId } });
108
+ // O al actualizar un Export:
109
+ // prisma.export.update({ where: { id: exportId }, data: { projectId: projectId } });
110
+ // Dado que el método original de Mongoose solo añade el ID, asumimos que el Export ya existe y tiene el projectId correcto.
111
+ // Si la lógica requiere añadir un Export existente a un Project, y el Export no tiene el projectId, se debería actualizar el Export.
112
+ // Por ahora, no se requiere ninguna acción aquí si la relación ya está establecida en el modelo Export.
113
+ },
114
+ };
115
+ function formatProject(doc) {
116
+ return {
117
+ id: doc.id,
118
+ dbType: doc.dbType,
119
+ name: doc.name,
120
+ image: doc.image,
121
+ members: doc.members?.map((m) => ({
122
+ userId: m.userId,
123
+ username: m.username, // Asumimos que el username y email se obtendrán de un servicio externo si es necesario
124
+ email: m.email,
125
+ role: m.role,
126
+ archived: m.archived ?? false
127
+ })) || [],
128
+ description: doc.description,
129
+ folders: doc.folders || [], // Prisma usa 'folders' en lugar de 'rootFolders'
130
+ settings: {
131
+ allowUpload: doc.allowUpload,
132
+ allowSharing: doc.allowSharing,
133
+ },
134
+ exports: doc.exports || []
135
+ };
136
+ }
137
+ function formatProjectList(doc, userId) {
138
+ const archived = doc.members?.find((m) => m.userId === userId)?.archived ?? false;
139
+ return {
140
+ id: doc.id,
141
+ dbType: doc.dbType,
142
+ name: doc.name,
143
+ image: doc.image,
144
+ archived
145
+ };
146
+ }
147
+ }
@@ -25,6 +25,7 @@ export interface StorageAdapter {
25
25
  }
26
26
  export interface ProjectInfo {
27
27
  id: string;
28
+ dbType: DatabaseType;
28
29
  name: string;
29
30
  image?: string;
30
31
  members?: {
@@ -33,21 +34,32 @@ export interface ProjectInfo {
33
34
  archived?: boolean;
34
35
  }[];
35
36
  description?: string;
36
- rootFolders?: FolderNode[];
37
+ folders?: FolderNode[];
38
+ exports?: {
39
+ id: string;
40
+ collectionName: string;
41
+ }[];
37
42
  settings?: {
38
43
  allowUpload?: boolean;
39
44
  allowSharing?: boolean;
40
45
  };
41
46
  }
47
+ export interface ProjectListInfo {
48
+ id: string;
49
+ dbType: DatabaseType;
50
+ name: string;
51
+ image?: string;
52
+ archived: boolean;
53
+ }
42
54
  export interface FolderNode {
43
55
  id: string;
44
56
  name: string;
45
57
  children?: FolderNode[];
46
58
  }
47
- export type DatabaseType = 'mongo';
59
+ export type DatabaseType = 'sql' | 'nosql';
48
60
  export interface DatabaseCredential {
49
61
  dbType: DatabaseType;
50
- connectionString: string;
62
+ connectionString?: string;
51
63
  }
52
64
  export interface StreamByConfig {
53
65
  storageProviders: {
@@ -56,7 +68,9 @@ export interface StreamByConfig {
56
68
  }[];
57
69
  authProvider: AuthProvider;
58
70
  databases?: DatabaseCredential[];
71
+ exportProvider?: ExportProvider;
59
72
  projectProvider?: ProjectProvider;
73
+ exportCollectionProvider?: ExportCollectionProvider;
60
74
  adapter?: StorageAdapter;
61
75
  }
62
76
  export interface AuthContext {
@@ -66,25 +80,40 @@ export interface AuthContext {
66
80
  role: 'viewer' | 'editor' | 'admin';
67
81
  }
68
82
  export type AuthProvider = (req: Request) => Promise<AuthContext>;
83
+ export interface Export {
84
+ id: string;
85
+ collectionName: string;
86
+ projectId: string;
87
+ createdAt: Date;
88
+ updatedAt: Date;
89
+ }
90
+ export interface ExportProvider {
91
+ getById(exportId: string): Promise<Export | null>;
92
+ create(data: {
93
+ name: string;
94
+ description?: string;
95
+ collectionName: string;
96
+ projectId: string;
97
+ }): Promise<Export>;
98
+ }
69
99
  export interface ProjectProvider {
100
+ getExport(projectId: string, exportId: string): Promise<any | null>;
70
101
  archive(projectId: string, userId: string): Promise<{
71
102
  success: boolean;
72
- projects: ProjectInfo[];
73
- archivedProjects: ProjectInfo[];
103
+ projects: ProjectListInfo[];
74
104
  }>;
75
105
  unarchive(projectId: string, userId: string): Promise<{
76
106
  success: boolean;
77
- projects: ProjectInfo[];
78
- archivedProjects: ProjectInfo[];
107
+ projects: ProjectListInfo[];
79
108
  }>;
80
- list(userId?: string): Promise<ProjectInfo[]>;
81
- listArchived(userId?: string): Promise<ProjectInfo[]>;
82
- getById(projectId: string): Promise<ProjectInfo>;
109
+ list(userId?: string): Promise<ProjectListInfo[]>;
110
+ getById(projectId: string, populateMembers?: boolean): Promise<ProjectInfo>;
83
111
  delete(projectId: string): Promise<{
84
112
  success: boolean;
85
113
  }>;
86
- update(projectId: string, updates: Partial<Omit<ProjectInfo, 'id' | 'rootFolders'>>): Promise<ProjectInfo>;
114
+ update(projectId: string, updates: Partial<Omit<ProjectInfo, 'id' | 'folders'>>): Promise<ProjectInfo>;
87
115
  create(data: {
116
+ dbType: DatabaseType;
88
117
  name: string;
89
118
  image?: string;
90
119
  members?: {
@@ -94,6 +123,34 @@ export interface ProjectProvider {
94
123
  description?: string;
95
124
  allowUpload?: boolean;
96
125
  allowSharing?: boolean;
97
- rootFolders?: FolderNode[];
126
+ folders?: FolderNode[];
98
127
  }): Promise<ProjectInfo>;
128
+ addExportToProject(projectId: string, exportId: string): Promise<void>;
129
+ }
130
+ export interface ExportEntry {
131
+ id: string;
132
+ key: string;
133
+ value: string;
134
+ exportCollectionId: string;
135
+ }
136
+ export interface ExportCollectionProvider {
137
+ getById(id: string): Promise<any | null>;
138
+ create(data: {
139
+ projectId: string;
140
+ name: string;
141
+ entries: Array<{
142
+ key: string;
143
+ value: string;
144
+ }>;
145
+ }): Promise<any>;
146
+ update(id: string, data: {
147
+ name?: string;
148
+ entries?: Array<{
149
+ key: string;
150
+ value: string;
151
+ }>;
152
+ }): Promise<any>;
153
+ delete(id: string): Promise<{
154
+ success: boolean;
155
+ }>;
99
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "streamby-core",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "StreamBy middleware framework for media storage management",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -31,10 +31,12 @@
31
31
  "dependencies": {
32
32
  "@aws-sdk/client-s3": "^3.528.0",
33
33
  "@aws-sdk/s3-request-presigner": "^3.787.0",
34
+ "@prisma/client": "^6.12.0",
34
35
  "bcrypt": "^5.1.1",
35
36
  "dotenv": "^16.5.0",
36
37
  "express": "^4.0.0",
37
- "mongoose": "^8.13.2"
38
+ "mongoose": "^8.13.2",
39
+ "prisma": "^6.12.0"
38
40
  },
39
41
  "devDependencies": {
40
42
  "@types/bcrypt": "^5.0.2",
@@ -1,4 +0,0 @@
1
- import { StorageAdapter, StreamByConfig } from "../types";
2
- export declare function createDevServer(config: StreamByConfig & {
3
- adapter?: StorageAdapter;
4
- }): import("express-serve-static-core").Express;
@@ -1,14 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createDevServer = createDevServer;
7
- const express_1 = __importDefault(require("express"));
8
- const createRouter_1 = require("../middleware/createRouter");
9
- function createDevServer(config) {
10
- const app = (0, express_1.default)();
11
- app.use(express_1.default.json());
12
- app.use((0, createRouter_1.createStreamByRouter)(config));
13
- return app;
14
- }