streamby-core 0.1.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.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # @streamby/core
2
+
3
+ Middleware framework for building storage-agnostic media APIs.
4
+ Part of the [StreamBy](https://streamby.nhexa.cl) ecosystem by TerminalCore Labs.
5
+
6
+ ---
7
+
8
+ ## ๐Ÿš€ What is it?
9
+
10
+ `@streamby/core` is a plug-and-play middleware for Express (or compatible frameworks) that enables file uploads, listings and project-based access over services like:
11
+
12
+ - โœ… AWS S3
13
+ - โœ… Google Cloud Storage (soon)
14
+ - โœ… Cloudflare R2 (soon)
15
+ - โœ… Local/Personal servers (soon)
16
+
17
+ It's designed to be installed inside your existing API as a library โ€” **no need to run a separate backend**.
18
+
19
+ ---
20
+
21
+ ## ๐Ÿ“ฆ Installation
22
+
23
+ ```bash
24
+ npm install @streamby/core
25
+ ```
26
+
27
+ ---
28
+
29
+ ## ๐Ÿงฑ Basic usage
30
+
31
+ ```ts
32
+ import express from 'express';
33
+ import { createStreamByRouter } from '@streamby/core';
34
+
35
+ const app = express();
36
+
37
+ app.use('/streamby', createStreamByRouter({
38
+ storageProvider: {
39
+ type: 's3',
40
+ config: {
41
+ bucket: 'your-bucket-name',
42
+ region: 'your-region',
43
+ accessKeyId: 'YOUR_AWS_KEY',
44
+ secretAccessKey: 'YOUR_AWS_SECRET'
45
+ }
46
+ },
47
+ authProvider: async (req) => {
48
+ // validate token, session, etc.
49
+ return {
50
+ userId: 'demo',
51
+ projectId: 'demo-project',
52
+ role: 'admin',
53
+ };
54
+ }
55
+ }));
56
+
57
+ app.listen(3000);
58
+ ```
59
+
60
+ ---
61
+
62
+ ## ๐Ÿงช Testing
63
+
64
+ ```bash
65
+ npm run test
66
+ ```
67
+
68
+ Unit tests use [Vitest](https://vitest.dev) and [Supertest](https://www.npmjs.com/package/supertest).
69
+
70
+ ---
71
+
72
+ ## ๐Ÿ“ Features
73
+
74
+ - ๐Ÿงน Modular adapters per storage provider
75
+ - ๐Ÿ” Auth/permission integration per request
76
+ - ๐Ÿ“‚ File listing, uploading and deletion
77
+ - ๐Ÿงฐ Built-in testability with mock adapters
78
+ - โšก Easy to extend and compose
79
+
80
+ ---
81
+
82
+ ## ๐Ÿšฃ Roadmap
83
+
84
+ - [ ] Support for Google Cloud Storage
85
+ - [ ] CLI tool for uploading files
86
+ - [ ] Role-based access control middleware
87
+ - [ ] Plugin system for extended routes
88
+
89
+ ---
90
+
91
+ ## ๐Ÿง‘โ€๐Ÿ’ป Maintained by
92
+
93
+ **TerminalCore Labs** โ€“ part of [Nhexa Entertainment](https://nhexa.cl)
94
+ Developed as open-source infrastructure for creative and media-oriented apps.
95
+
96
+ Visit us [here](https://terminalcore.cl)
97
+
98
+ ---
99
+
100
+ ## ๐Ÿ“Ÿ License
101
+
102
+ [MIT](./LICENSE)
103
+
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,2 @@
1
+ import { StorageAdapter, S3Config } from '../types';
2
+ export declare function createS3Adapter(config: S3Config): StorageAdapter;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createS3Adapter = createS3Adapter;
4
+ const client_s3_1 = require("@aws-sdk/client-s3");
5
+ function createS3Adapter(config) {
6
+ const s3 = new client_s3_1.S3Client({
7
+ region: config.region,
8
+ credentials: {
9
+ accessKeyId: config.accessKeyId,
10
+ secretAccessKey: config.secretAccessKey,
11
+ },
12
+ });
13
+ return {
14
+ async uploadFile(req, projectId) {
15
+ const file = req.body.file;
16
+ const command = new client_s3_1.PutObjectCommand({
17
+ Bucket: config.bucket,
18
+ Key: `${projectId}/${file.name}`,
19
+ Body: file.buffer,
20
+ });
21
+ await s3.send(command);
22
+ return { success: true, key: command.input.Key };
23
+ },
24
+ async listFiles(projectId) {
25
+ const command = new client_s3_1.ListObjectsV2Command({
26
+ Bucket: config.bucket,
27
+ Prefix: `${projectId}/`
28
+ });
29
+ const result = await s3.send(command);
30
+ return result.Contents || [];
31
+ },
32
+ };
33
+ }
File without changes
package/dist/config.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ export { createStreamByRouter } from './middleware/createRouter';
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createStreamByRouter = void 0;
4
+ var createRouter_1 = require("./middleware/createRouter");
5
+ Object.defineProperty(exports, "createStreamByRouter", { enumerable: true, get: function () { return createRouter_1.createStreamByRouter; } });
@@ -0,0 +1,5 @@
1
+ import { Router } from 'express';
2
+ import { StreamByConfig, StorageAdapter } from '../types';
3
+ export declare function createStreamByRouter(config: StreamByConfig & {
4
+ adapter?: StorageAdapter;
5
+ }): Router;
@@ -0,0 +1,41 @@
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.createStreamByRouter = createStreamByRouter;
7
+ const express_1 = __importDefault(require("express"));
8
+ const s3_1 = require("../adapters/s3");
9
+ const file_1 = require("../services/file");
10
+ function createStreamByRouter(config) {
11
+ const router = express_1.default.Router();
12
+ const adapter = config.adapter || (() => {
13
+ switch (config.storageProvider.type) {
14
+ case 's3':
15
+ return (0, s3_1.createS3Adapter)(config.storageProvider.config);
16
+ default:
17
+ throw new Error('Unsupported storage type');
18
+ }
19
+ })();
20
+ router.get('/files', async (req, res) => {
21
+ try {
22
+ const auth = await config.authProvider(req);
23
+ const files = await (0, file_1.listFilesService)(adapter, req, auth.projectId);
24
+ res.json(files);
25
+ }
26
+ catch (err) {
27
+ res.status(500).json({ error: 'Failed to list files', details: err });
28
+ }
29
+ });
30
+ router.post('/upload', async (req, res) => {
31
+ try {
32
+ const auth = await config.authProvider(req);
33
+ const result = await (0, file_1.uploadFileService)(adapter, req, auth.projectId);
34
+ res.json(result);
35
+ }
36
+ catch (err) {
37
+ res.status(500).json({ error: 'Failed to upload file', details: err });
38
+ }
39
+ });
40
+ return router;
41
+ }
@@ -0,0 +1,4 @@
1
+ import { Request } from 'express';
2
+ import { StreamByConfig, AuthContext } from '../types';
3
+ export declare function resolveAuth(config: StreamByConfig, req: Request): Promise<AuthContext>;
4
+ export declare function checkRole(auth: AuthContext, required: 'viewer' | 'editor' | 'admin'): void;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveAuth = resolveAuth;
4
+ exports.checkRole = checkRole;
5
+ async function resolveAuth(config, req) {
6
+ const auth = await config.authProvider(req);
7
+ if (!auth || !auth.userId || !auth.projectId || !auth.role) {
8
+ throw new Error('Invalid or missing authentication context');
9
+ }
10
+ return auth;
11
+ }
12
+ function checkRole(auth, required) {
13
+ const roles = ['viewer', 'editor', 'admin'];
14
+ const userIdx = roles.indexOf(auth.role);
15
+ const requiredIdx = roles.indexOf(required);
16
+ if (userIdx < requiredIdx) {
17
+ throw new Error(`Insufficient role: requires ${required}, found ${auth.role}`);
18
+ }
19
+ }
@@ -0,0 +1,4 @@
1
+ import { StorageAdapter } from '../types';
2
+ import { Request } from 'express';
3
+ export declare function listFilesService(adapter: StorageAdapter, req: Request, projectId: string): Promise<any[]>;
4
+ export declare function uploadFileService(adapter: StorageAdapter, req: Request, projectId: string): Promise<any>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listFilesService = listFilesService;
4
+ exports.uploadFileService = uploadFileService;
5
+ async function listFilesService(adapter, req, projectId) {
6
+ return adapter.listFiles(projectId);
7
+ }
8
+ async function uploadFileService(adapter, req, projectId) {
9
+ return adapter.uploadFile(req, projectId);
10
+ }
@@ -0,0 +1,29 @@
1
+ import { Request } from 'express';
2
+ export interface S3Config {
3
+ bucket: string;
4
+ region: string;
5
+ accessKeyId: string;
6
+ secretAccessKey: string;
7
+ }
8
+ export type StorageProviderType = 's3';
9
+ export interface StorageAdapter {
10
+ uploadFile(req: Request, projectId: string): Promise<any>;
11
+ listFiles(projectId: string): Promise<any[]>;
12
+ }
13
+ export interface StreamByConfig {
14
+ storageProvider: {
15
+ type: StorageProviderType;
16
+ config: S3Config;
17
+ };
18
+ authProvider: (req: Request) => Promise<{
19
+ userId: string;
20
+ projectId: string;
21
+ role: 'viewer' | 'editor' | 'admin';
22
+ }>;
23
+ }
24
+ export interface AuthContext {
25
+ userId: string;
26
+ projectId: string;
27
+ role: 'viewer' | 'editor' | 'admin';
28
+ }
29
+ export type AuthProvider = (req: Request) => Promise<AuthContext>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "streamby-core",
3
+ "version": "0.1.0",
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": "tsc --watch",
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
+ "express": "^4.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/express": "^4.17.17",
37
+ "@types/supertest": "^6.0.3",
38
+ "supertest": "^7.1.0",
39
+ "typescript": "^5.8.3",
40
+ "vitest": "^3.1.1"
41
+ },
42
+ "peerDependencies": {
43
+ "express": "^4.0.0"
44
+ }
45
+ }