streamby-core 0.25.8 → 0.26.1

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.
@@ -8,103 +8,39 @@ const mongodb_1 = require("mongodb");
8
8
  const connectionManager_1 = require("../adapters/database/connectionManager");
9
9
  const nosql_1 = require("../adapters/database/nosql");
10
10
  const sql_1 = require("../adapters/database/sql");
11
- const encryption_1 = require("../utils/encryption");
12
- async function createExport(config, projectId, description, fields, exportName, jsonData, dbType, exportType, isPrivate, allowedOrigin, apiUrl, credentialId, prefix) {
11
+ async function createExport(config, projectId, description, exportName, dbType, exportType, isPrivate, allowedOrigin, nodeSchema, useConnections, useCredentials) {
13
12
  const targetDb = config.databases?.find(db => db.type === dbType && db.main) ||
14
13
  config.databases?.find(db => db.type === dbType);
15
14
  if (!targetDb) {
16
15
  throw new Error(`Database connection not found for type ${dbType}`);
17
16
  }
18
17
  const connection = (0, connectionManager_1.getConnection)(targetDb.id);
19
- let result;
20
- if (exportType === 'externalApi') {
21
- if (!apiUrl) {
22
- throw new Error('API URL is required for externalApi export type.');
23
- }
24
- const ProjectModel = (0, manager_1.getModel)('projects', 'nosql');
25
- const project = await ProjectModel.findOne({ _id: projectId });
26
- if (!project) {
27
- throw new Error('Project not found.');
28
- }
29
- if (credentialId) {
30
- if (!(0, encryption_1.isEncryptionKeySet)()) {
31
- throw new Error('Encryption key is not set. Cannot use encrypted credentials.');
32
- }
33
- const credential = project.credentials?.find(cred => cred.id === credentialId);
34
- if (!credential) {
35
- throw new Error(`Credential with ID ${credentialId} not found.`);
36
- }
37
- }
38
- if (dbType === 'nosql') {
39
- result = await (0, nosql_1.createNoSQLRawExportCollection)(connection.client, projectId, exportName, 'GET', null);
40
- }
41
- else if (dbType === 'sql') {
42
- result = await (0, sql_1.createSQLRawExportTable)(connection.client, projectId, exportName, null);
43
- }
44
- else {
45
- throw new Error('Unsupported database type for externalApi export');
46
- }
47
- }
48
- else if (dbType === 'nosql') {
49
- result = await (0, nosql_1.createNoSQLRawExportCollection)(connection.client, projectId, exportName, 'GET', jsonData);
18
+ let exportId;
19
+ if (dbType === 'nosql') {
20
+ const result = await (0, nosql_1.createNoSQLRawExportCollection)(connection.client, projectId, exportName, 'GET', nodeSchema);
21
+ exportId = result.exportId;
50
22
  }
51
23
  else if (dbType === 'sql') {
52
- result = await (0, sql_1.createSQLRawExportTable)(connection.client, projectId, exportName, jsonData);
24
+ const result = await (0, sql_1.createSQLRawExportTable)(connection.client, projectId, exportName, nodeSchema);
25
+ exportId = result.exportId;
53
26
  }
54
27
  else {
55
28
  throw new Error('Unsupported database type');
56
29
  }
57
- // Update the project with the new export reference
58
- // Assuming project metadata is always in NoSQL (MongoDB)
59
30
  const NoSQLProject = (0, manager_1.getModel)('projects', 'nosql');
60
- await NoSQLProject.update({ _id: projectId }, { $push: { exports: { id: dbType === 'nosql' ? new mongodb_1.ObjectId(result.exportId) : result.exportId, name: exportName, collectionName: result.collectionName, type: exportType, method: 'GET', private: isPrivate, allowedOrigin: allowedOrigin, apiUrl: apiUrl, credentialId: credentialId, prefix: prefix, description: description, fields: fields } } });
61
- return { ...result, message: `${exportType} export created successfully` };
31
+ await NoSQLProject.update({ _id: projectId }, { $push: { exports: { id: new mongodb_1.ObjectId(exportId), name: exportName, type: exportType, method: 'GET', private: isPrivate, allowedOrigin, nodeSchema, useConnections, useCredentials, description } } });
32
+ return { exportId, message: `${exportType} export created successfully` };
62
33
  }
63
- async function updateExport(config, projectId, exportId, description, fields, exportName, collectionName, jsonData, dbType, exportType, isPrivate, allowedOrigin, apiUrl, credentialId, prefix) {
34
+ async function updateExport(config, projectId, exportId, description, exportName, dbType, exportType, isPrivate, allowedOrigin, nodeSchema, useConnections, useCredentials) {
64
35
  const targetDb = config.databases?.find(db => db.type === dbType && db.main) ||
65
36
  config.databases?.find(db => db.type === dbType);
66
37
  if (!targetDb) {
67
38
  throw new Error(`Database connection not found for type ${dbType}`);
68
39
  }
69
40
  const connection = (0, connectionManager_1.getConnection)(targetDb.id);
70
- let result;
71
- if (exportType === 'externalApi') {
72
- if (!apiUrl) {
73
- throw new Error('API URL is required for externalApi export type.');
74
- }
75
- const ProjectModel = (0, manager_1.getModel)('projects', 'nosql');
76
- const project = await ProjectModel.findOne({ _id: projectId });
77
- if (!project) {
78
- throw new Error('Project not found.');
79
- }
80
- if (dbType === 'nosql') {
81
- const db = connection.client.db();
82
- const updateData = {
83
- json: jsonData,
84
- description: description,
85
- fields: fields,
86
- updatedAt: new Date(),
87
- apiUrl: apiUrl,
88
- credentialId: credentialId,
89
- prefix: prefix,
90
- };
91
- await db.collection(collectionName).updateOne({ _id: new mongodb_1.ObjectId(exportId) }, { $set: updateData });
92
- }
93
- else {
94
- throw new Error('Unsupported database type for externalApi export update');
95
- }
96
- }
97
- else if (dbType === 'nosql') {
41
+ if (dbType === 'nosql') {
98
42
  const db = connection.client.db();
99
- const updateData = {
100
- json: jsonData,
101
- description: description,
102
- fields: fields,
103
- apiUrl: apiUrl,
104
- credentialId: credentialId,
105
- prefix: prefix,
106
- };
107
- await db.collection(collectionName).updateOne({ _id: new mongodb_1.ObjectId(exportId) }, { $set: updateData });
43
+ await db.collection(projectId).updateOne({ _id: new mongodb_1.ObjectId(exportId) }, { $set: { nodeSchema, description, updatedAt: new Date() } });
108
44
  }
109
45
  else {
110
46
  throw new Error('Unsupported database type for update');
@@ -113,11 +49,10 @@ async function updateExport(config, projectId, exportId, description, fields, ex
113
49
  await NoSQLProject.update({
114
50
  _id: new mongodb_1.ObjectId(projectId),
115
51
  'exports.id': { $in: [new mongodb_1.ObjectId(exportId), exportId] }
116
- }, { $set: { 'exports.$.name': exportName, 'exports.$.collectionName': collectionName, 'exports.$.private': isPrivate, 'exports.$.allowedOrigin': allowedOrigin, 'exports.$.apiUrl': apiUrl, 'exports.$.credentialId': credentialId, 'exports.$.prefix': prefix, 'exports.$.description': description, 'exports.$.fields': fields } });
117
- result = { collectionName, exportId };
118
- return { ...result, message: `${exportType} export updated successfully` };
52
+ }, { $set: { 'exports.$.name': exportName, 'exports.$.private': isPrivate, 'exports.$.allowedOrigin': allowedOrigin, 'exports.$.nodeSchema': nodeSchema, 'exports.$.useConnections': useConnections, 'exports.$.useCredentials': useCredentials, 'exports.$.description': description } });
53
+ return { exportId, message: `${exportType} export updated successfully` };
119
54
  }
120
- async function deleteExport(config, projectId, exportId, dbType, collectionName) {
55
+ async function deleteExport(config, projectId, exportId, dbType, exportName) {
121
56
  const targetDb = config.databases?.find(db => db.type === dbType && db.main) ||
122
57
  config.databases?.find(db => db.type === dbType);
123
58
  if (!targetDb) {
@@ -126,7 +61,7 @@ async function deleteExport(config, projectId, exportId, dbType, collectionName)
126
61
  const connection = (0, connectionManager_1.getConnection)(targetDb.id);
127
62
  if (dbType === 'nosql') {
128
63
  const db = connection.client.db();
129
- await db.collection(collectionName).deleteOne({ _id: new mongodb_1.ObjectId(exportId) });
64
+ await db.collection(projectId).deleteOne({ _id: new mongodb_1.ObjectId(exportId) });
130
65
  }
131
66
  else {
132
67
  throw new Error('Unsupported database type for delete');
@@ -0,0 +1,2 @@
1
+ import { NodeSchema, StreamByConfig } from '../types';
2
+ export declare function executePipeline(nodeSchema: NodeSchema, project: any, config: StreamByConfig): Promise<any>;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executePipeline = executePipeline;
4
+ const connectionManager_1 = require("../adapters/database/connectionManager");
5
+ const encryption_1 = require("../utils/encryption");
6
+ function getSources(nodes, edges, targetId, targetHandle) {
7
+ return edges
8
+ .filter(e => e.target === targetId && e.targetHandle === targetHandle)
9
+ .map(e => nodes.find(n => n.id === e.source))
10
+ .filter((n) => n !== undefined);
11
+ }
12
+ function getTarget(nodes, edges, sourceId, sourceHandle) {
13
+ const edge = edges.find(e => e.source === sourceId && e.sourceHandle === sourceHandle);
14
+ return edge ? (nodes.find(n => n.id === edge.target) ?? null) : null;
15
+ }
16
+ async function executePipeline(nodeSchema, project, config) {
17
+ const nodes = nodeSchema.nodes;
18
+ const edges = nodeSchema.edges;
19
+ // 1. Data layer — nodes connected to streamby in-bottom
20
+ const dataSources = getSources(nodes, edges, 'streamby', 'in-bottom');
21
+ const dataResults = [];
22
+ for (const node of dataSources) {
23
+ if (node.type === 'jsonInputNode') {
24
+ try {
25
+ dataResults.push(JSON.parse(node.data?.jsonString || 'null'));
26
+ }
27
+ catch {
28
+ dataResults.push(null);
29
+ }
30
+ }
31
+ else if (node.type === 'dataSourceNode') {
32
+ const collectionName = node.data?.subtitle || node.data?.label;
33
+ if (!collectionName)
34
+ continue;
35
+ const targetDb = config.databases?.find(db => db.type === project.dbType && db.main)
36
+ ?? config.databases?.find(db => db.type === project.dbType);
37
+ if (!targetDb)
38
+ throw new Error(`No database connection for type ${project.dbType}`);
39
+ const connection = (0, connectionManager_1.getConnection)(targetDb.id);
40
+ const db = connection.client.db();
41
+ dataResults.push(await db.collection(collectionName).find({}).toArray());
42
+ }
43
+ else if (node.type === 'apiConnectionNode') {
44
+ const apiConnection = project.apiConnections?.find((c) => c.id === node.data?.connectionId);
45
+ if (!apiConnection)
46
+ continue;
47
+ const headers = { 'Content-Type': 'application/json' };
48
+ if (apiConnection.credentialId && (0, encryption_1.isEncryptionKeySet)()) {
49
+ const credential = project.credentials?.find((c) => c.id === apiConnection.credentialId);
50
+ if (credential) {
51
+ const decrypted = (0, encryption_1.decrypt)(credential.encryptedValue);
52
+ const prefix = apiConnection.prefix ? `${apiConnection.prefix} ` : '';
53
+ headers['Authorization'] = `${prefix}${decrypted}`;
54
+ }
55
+ }
56
+ const response = await fetch(apiConnection.baseUrl, { method: apiConnection.method || 'GET', headers });
57
+ if (!response.ok)
58
+ throw new Error(`API connection fetch failed: ${response.statusText}`);
59
+ dataResults.push(await response.json());
60
+ }
61
+ }
62
+ let payload = dataResults.length === 1 ? dataResults[0] : dataResults;
63
+ // 2. Process layer — chain from streamby out-top → processNode in-process → out-process → ...
64
+ let processNode = getTarget(nodes, edges, 'streamby', 'out-top');
65
+ while (processNode) {
66
+ // transform/auth/custom logic per processNode.data.label — pass-through until defined
67
+ processNode = getTarget(nodes, edges, processNode.id, 'out-process');
68
+ }
69
+ // 3. Filter layer — chain from streamby out-right → filterNode in-filter → out-filter → ...
70
+ let filterNode = getTarget(nodes, edges, 'streamby', 'out-right');
71
+ while (filterNode) {
72
+ // filter logic per filterNode.data.label — pass-through until defined
73
+ filterNode = getTarget(nodes, edges, filterNode.id, 'out-filter');
74
+ }
75
+ return payload;
76
+ }
@@ -106,19 +106,25 @@ export interface Auth {
106
106
  role: 'viewer' | 'editor' | 'admin';
107
107
  }
108
108
  export type AuthProvider = (req: Request) => Promise<Auth>;
109
+ export interface NodeSchema {
110
+ nodes: any[];
111
+ edges: any[];
112
+ }
109
113
  export interface Export {
110
114
  _id?: string;
111
115
  id: string;
112
- collectionName: string;
113
116
  projectId: string;
114
117
  createdAt: Date;
115
118
  updatedAt: Date;
116
- type: 'json' | 'externalApi';
119
+ type?: 'json' | 'externalApi';
117
120
  fields?: FieldDefinition[];
118
121
  jsonData?: any;
119
- private?: boolean;
120
- allowedOrigin?: string[];
121
122
  apiUrl?: string;
122
123
  credentialId?: string;
123
124
  prefix?: string;
125
+ private?: boolean;
126
+ allowedOrigin?: string[];
127
+ nodeSchema?: NodeSchema;
128
+ useConnections?: boolean;
129
+ useCredentials?: boolean;
124
130
  }
@@ -0,0 +1,3 @@
1
+ export declare function encrypt(text: string, secretKey: string): string;
2
+ export declare function decrypt(text: string, secretKey: string): string;
3
+ export declare function hash(text: string): string;
@@ -0,0 +1,32 @@
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.encrypt = encrypt;
7
+ exports.decrypt = decrypt;
8
+ exports.hash = hash;
9
+ const crypto_1 = __importDefault(require("crypto"));
10
+ const ALGORITHM = 'aes-256-cbc';
11
+ const IV_LENGTH = 16;
12
+ function encrypt(text, secretKey) {
13
+ const iv = crypto_1.default.randomBytes(IV_LENGTH);
14
+ const key = crypto_1.default.createHash('sha256').update(String(secretKey)).digest('base64').substr(0, 32);
15
+ const cipher = crypto_1.default.createCipheriv(ALGORITHM, Buffer.from(key), iv);
16
+ let encrypted = cipher.update(text);
17
+ encrypted = Buffer.concat([encrypted, cipher.final()]);
18
+ return iv.toString('hex') + ':' + encrypted.toString('hex');
19
+ }
20
+ function decrypt(text, secretKey) {
21
+ const textParts = text.split(':');
22
+ const iv = Buffer.from(textParts.shift(), 'hex');
23
+ const encryptedText = Buffer.from(textParts.join(':'), 'hex');
24
+ const key = crypto_1.default.createHash('sha256').update(String(secretKey)).digest('base64').substr(0, 32);
25
+ const decipher = crypto_1.default.createDecipheriv(ALGORITHM, Buffer.from(key), iv);
26
+ let decrypted = decipher.update(encryptedText);
27
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
28
+ return decrypted.toString();
29
+ }
30
+ function hash(text) {
31
+ return crypto_1.default.createHash('sha256').update(text).digest('hex');
32
+ }
package/package.json CHANGED
@@ -1,61 +1,61 @@
1
- {
2
- "name": "streamby-core",
3
- "version": "0.25.8",
4
- "description": "StreamBy middleware framework for media storage management",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "files": [
8
- "dist"
9
- ],
10
- "scripts": {
11
- "build": "tsc",
12
- "test": "vitest",
13
- "dev": "ts-node-dev --respawn --clear dev.ts",
14
- "prepublishOnly": "npm run build"
15
- },
16
- "repository": {
17
- "type": "git",
18
- "url": "https://github.com/GwerhDev/StreamBy-Package.git"
19
- },
20
- "keywords": [
21
- "streamby",
22
- "middleware",
23
- "upload",
24
- "storage",
25
- "s3",
26
- "express",
27
- "typescript"
28
- ],
29
- "author": "TerminalCore Labs",
30
- "license": "MIT",
31
- "dependencies": {
32
- "@aws-sdk/client-s3": "^3.528.0",
33
- "@aws-sdk/s3-request-presigner": "^3.787.0",
34
- "@prisma/client": "^6.12.0",
35
- "bcrypt": "^5.1.1",
36
- "dotenv": "^16.5.0",
37
- "express": "^4.0.0",
38
- "mongodb": "^6.17.0",
39
- "mongoose": "^8.13.2",
40
- "pg": "^8.16.3",
41
- "prisma": "^6.12.0",
42
- "node-fetch": "^3.0.0"
43
- },
44
- "devDependencies": {
45
- "@types/bcrypt": "^5.0.2",
46
- "@types/cors": "^2.8.18",
47
- "@types/express": "^4.17.17",
48
- "@types/mongodb": "^4.0.7",
49
- "@types/node": "^22.15.21",
50
- "@types/pg": "^8.15.4",
51
- "@types/supertest": "^6.0.3",
52
- "cors": "^2.8.5",
53
- "supertest": "^7.1.4",
54
- "ts-node-dev": "^2.0.0",
55
- "typescript": "^5.8.3",
56
- "vitest": "^3.1.1"
57
- },
58
- "peerDependencies": {
59
- "express": "^4.0.0"
60
- }
61
- }
1
+ {
2
+ "name": "streamby-core",
3
+ "version": "0.26.1",
4
+ "description": "StreamBy middleware framework for media storage management",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "test": "vitest",
13
+ "dev": "ts-node-dev --respawn --clear dev.ts",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/GwerhDev/StreamBy-Package.git"
19
+ },
20
+ "keywords": [
21
+ "streamby",
22
+ "middleware",
23
+ "upload",
24
+ "storage",
25
+ "s3",
26
+ "express",
27
+ "typescript"
28
+ ],
29
+ "author": "TerminalCore Labs",
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "@aws-sdk/client-s3": "^3.528.0",
33
+ "@aws-sdk/s3-request-presigner": "^3.787.0",
34
+ "@prisma/client": "^6.12.0",
35
+ "bcrypt": "^5.1.1",
36
+ "dotenv": "^16.5.0",
37
+ "express": "^4.0.0",
38
+ "mongodb": "^6.17.0",
39
+ "mongoose": "^8.13.2",
40
+ "pg": "^8.16.3",
41
+ "prisma": "^6.12.0",
42
+ "node-fetch": "^3.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/bcrypt": "^5.0.2",
46
+ "@types/cors": "^2.8.18",
47
+ "@types/express": "^4.17.17",
48
+ "@types/mongodb": "^4.0.7",
49
+ "@types/node": "^22.15.21",
50
+ "@types/pg": "^8.15.4",
51
+ "@types/supertest": "^6.0.3",
52
+ "cors": "^2.8.5",
53
+ "supertest": "^7.1.4",
54
+ "ts-node-dev": "^2.0.0",
55
+ "typescript": "^5.8.3",
56
+ "vitest": "^3.1.1"
57
+ },
58
+ "peerDependencies": {
59
+ "express": "^4.0.0"
60
+ }
61
+ }