streamby-core 0.29.8 → 0.29.11

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.
@@ -0,0 +1,17 @@
1
+ import { IntegrationKind, UserIntegration } from '../types';
2
+ export declare function listUserIntegrations(userId: string): Promise<UserIntegration[]>;
3
+ export declare function createUserIntegration(userId: string, input: {
4
+ kind: IntegrationKind;
5
+ provider: string;
6
+ name: string;
7
+ description?: string;
8
+ credentialValue: unknown;
9
+ }): Promise<UserIntegration>;
10
+ export declare function updateUserIntegration(userId: string, integrationId: string, updates: {
11
+ name?: string;
12
+ description?: string;
13
+ credentialValue?: unknown;
14
+ }): Promise<UserIntegration | null>;
15
+ export declare function deleteUserIntegration(userId: string, integrationId: string): Promise<boolean>;
16
+ export declare function getDecryptedIntegrationCredential(userId: string, integrationId: string): Promise<unknown | null>;
17
+ export declare function getDecryptedIntegrationCredentialById(integrationId: string): Promise<unknown | null>;
@@ -0,0 +1,86 @@
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.listUserIntegrations = listUserIntegrations;
7
+ exports.createUserIntegration = createUserIntegration;
8
+ exports.updateUserIntegration = updateUserIntegration;
9
+ exports.deleteUserIntegration = deleteUserIntegration;
10
+ exports.getDecryptedIntegrationCredential = getDecryptedIntegrationCredential;
11
+ exports.getDecryptedIntegrationCredentialById = getDecryptedIntegrationCredentialById;
12
+ const crypto_1 = __importDefault(require("crypto"));
13
+ const manager_1 = require("../models/manager");
14
+ const encryption_1 = require("../utils/encryption");
15
+ function encryptCredential(kind, value) {
16
+ return kind === 'storage' ? (0, encryption_1.encrypt)(JSON.stringify(value)) : (0, encryption_1.encrypt)(String(value));
17
+ }
18
+ async function listUserIntegrations(userId) {
19
+ const UserIntegrationModel = (0, manager_1.getModel)('user_integrations');
20
+ return UserIntegrationModel.find({ userId });
21
+ }
22
+ async function createUserIntegration(userId, input) {
23
+ if (!(0, encryption_1.isEncryptionKeySet)()) {
24
+ throw new Error('Encryption key is not set. Cannot create integration.');
25
+ }
26
+ const UserIntegrationModel = (0, manager_1.getModel)('user_integrations');
27
+ const now = new Date();
28
+ const integration = {
29
+ id: crypto_1.default.randomUUID(),
30
+ userId,
31
+ kind: input.kind,
32
+ provider: input.provider,
33
+ name: input.name,
34
+ description: input.description,
35
+ encryptedCredential: encryptCredential(input.kind, input.credentialValue),
36
+ createdAt: now,
37
+ updatedAt: now,
38
+ };
39
+ return UserIntegrationModel.create(integration);
40
+ }
41
+ async function updateUserIntegration(userId, integrationId, updates) {
42
+ const UserIntegrationModel = (0, manager_1.getModel)('user_integrations');
43
+ const existing = await UserIntegrationModel.findOne({ id: integrationId, userId });
44
+ if (!existing)
45
+ return null;
46
+ const $set = { updatedAt: new Date() };
47
+ if (updates.name !== undefined)
48
+ $set.name = updates.name;
49
+ if (updates.description !== undefined)
50
+ $set.description = updates.description;
51
+ if (updates.credentialValue !== undefined) {
52
+ if (!(0, encryption_1.isEncryptionKeySet)()) {
53
+ throw new Error('Encryption key is not set. Cannot update integration.');
54
+ }
55
+ $set.encryptedCredential = encryptCredential(existing.kind, updates.credentialValue);
56
+ }
57
+ return UserIntegrationModel.update({ id: integrationId, userId }, $set);
58
+ }
59
+ async function deleteUserIntegration(userId, integrationId) {
60
+ const UserIntegrationModel = (0, manager_1.getModel)('user_integrations');
61
+ const deletedCount = await UserIntegrationModel.delete({ id: integrationId, userId });
62
+ return deletedCount > 0;
63
+ }
64
+ async function getDecryptedIntegrationCredential(userId, integrationId) {
65
+ const UserIntegrationModel = (0, manager_1.getModel)('user_integrations');
66
+ const integration = await UserIntegrationModel.findOne({ id: integrationId, userId });
67
+ return decryptIntegration(integration);
68
+ }
69
+ // Used when resolving a project connection's `integrationId` at connection-use time — the
70
+ // project already validated ownership when the connection was created (see project.ts /
71
+ // dbConnection.ts POST), so there's no userId to filter by here, only the integrationId
72
+ // stored on the connection itself.
73
+ async function getDecryptedIntegrationCredentialById(integrationId) {
74
+ const UserIntegrationModel = (0, manager_1.getModel)('user_integrations');
75
+ const integration = await UserIntegrationModel.findOne({ id: integrationId });
76
+ return decryptIntegration(integration);
77
+ }
78
+ async function decryptIntegration(integration) {
79
+ if (!integration)
80
+ return null;
81
+ if (!(0, encryption_1.isEncryptionKeySet)()) {
82
+ throw new Error('Encryption key is not set. Cannot decrypt integration credential.');
83
+ }
84
+ const decrypted = (0, encryption_1.decrypt)(integration.encryptedCredential);
85
+ return integration.kind === 'storage' ? JSON.parse(decrypted) : decrypted;
86
+ }
@@ -17,8 +17,12 @@ export interface StorageConnection {
17
17
  createdAt: Date;
18
18
  description?: string;
19
19
  isBuiltin?: boolean;
20
+ integrationId?: string;
21
+ source?: 'builtin' | 'integration' | 'manual';
22
+ available?: boolean;
20
23
  }
21
24
  export type StorageProvider = {
25
+ id: string;
22
26
  type: StorageProviderType;
23
27
  config: S3Config;
24
28
  };
@@ -74,6 +78,7 @@ export interface ProjectInfo {
74
78
  dbConnections?: DbConnection[];
75
79
  storageConnections?: StorageConnection[];
76
80
  pipelines?: PipelineRef[];
81
+ builtinBackfilledAt?: Date;
77
82
  }
78
83
  export interface Credential {
79
84
  id: string;
@@ -107,10 +112,7 @@ export interface DatabaseCredential {
107
112
  main?: boolean;
108
113
  }
109
114
  export interface StreamByConfig {
110
- storageProviders: {
111
- type: StorageProviderType;
112
- config: S3Config;
113
- }[];
115
+ storageProviders: StorageProvider[];
114
116
  authProvider: AuthProvider;
115
117
  databases?: DatabaseCredential[];
116
118
  adapter?: StorageAdapter;
@@ -118,6 +120,7 @@ export interface StreamByConfig {
118
120
  websocket?: {
119
121
  server: WebSocketServer;
120
122
  };
123
+ canUseBuiltin?: (auth: Auth, builtinId: string, kind: 'database' | 'storage') => boolean | Promise<boolean>;
121
124
  }
122
125
  export interface Notification {
123
126
  _id?: string;
@@ -154,6 +157,21 @@ export interface DbConnection {
154
157
  projectId: string;
155
158
  createdAt: Date;
156
159
  description?: string;
160
+ isBuiltin?: boolean;
161
+ integrationId?: string;
162
+ source?: 'builtin' | 'integration' | 'manual';
163
+ }
164
+ export type IntegrationKind = 'database' | 'storage';
165
+ export interface UserIntegration {
166
+ id: string;
167
+ userId: string;
168
+ kind: IntegrationKind;
169
+ provider: ExternalDbType | StorageProviderType;
170
+ name: string;
171
+ description?: string;
172
+ encryptedCredential: string;
173
+ createdAt: Date;
174
+ updatedAt: Date;
157
175
  }
158
176
  export interface ColumnDefinition {
159
177
  name: string;
@@ -0,0 +1,6 @@
1
+ import { Auth, StreamByConfig } from '../types';
2
+ export declare function assertBuiltinAccess(auth: Auth, builtinId: string, config: StreamByConfig, kind: 'database' | 'storage'): Promise<boolean>;
3
+ export declare function isBuiltinStorageId(id: string, config: StreamByConfig): boolean;
4
+ export declare function isBuiltinDb(id: string, config: StreamByConfig): boolean;
5
+ export declare const BUILTIN_STORAGE_DISPLAY: Record<string, string>;
6
+ export declare const BUILTIN_DB_DISPLAY: Record<string, string>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BUILTIN_DB_DISPLAY = exports.BUILTIN_STORAGE_DISPLAY = void 0;
4
+ exports.assertBuiltinAccess = assertBuiltinAccess;
5
+ exports.isBuiltinStorageId = isBuiltinStorageId;
6
+ exports.isBuiltinDb = isBuiltinDb;
7
+ // Gates access to a built-in database/storage provider. Delegates to config.canUseBuiltin
8
+ // when the mounting app implements it (e.g. Nhexa-API checking user_subscriptions);
9
+ // defaults to allow when absent, preserving pre-BYOC behavior for deploys without gating.
10
+ async function assertBuiltinAccess(auth, builtinId, config, kind) {
11
+ if (!config.canUseBuiltin)
12
+ return true;
13
+ return config.canUseBuiltin(auth, builtinId, kind);
14
+ }
15
+ function isBuiltinStorageId(id, config) {
16
+ return (config.storageProviders ?? []).some(p => p.id === id);
17
+ }
18
+ function isBuiltinDb(id, config) {
19
+ return (config.databases ?? []).some(db => db.id === id);
20
+ }
21
+ // Display names for builtin connections — never the raw config id/type. The frontend pairs
22
+ // this with the StreamBy icon to visually mark a connection as built-in vs BYOC.
23
+ exports.BUILTIN_STORAGE_DISPLAY = {
24
+ s3: 'AWS S3',
25
+ gcs: 'Google Cloud Storage',
26
+ r2: 'Cloudflare R2',
27
+ azure: 'Azure Blob Storage',
28
+ };
29
+ exports.BUILTIN_DB_DISPLAY = {
30
+ sql: 'PostgreSQL',
31
+ nosql: 'MongoDB',
32
+ };
@@ -1 +1,2 @@
1
1
  export declare function sanitizeProject(project: any): any;
2
+ export declare function sanitizeUserIntegration(integration: any): any;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sanitizeProject = sanitizeProject;
4
+ exports.sanitizeUserIntegration = sanitizeUserIntegration;
4
5
  function sanitizeProject(project) {
5
6
  if (!project)
6
7
  return project;
@@ -9,3 +10,9 @@ function sanitizeProject(project) {
9
10
  credentials: project.credentials?.map(({ id, key }) => ({ id, key })) ?? [],
10
11
  };
11
12
  }
13
+ function sanitizeUserIntegration(integration) {
14
+ if (!integration)
15
+ return integration;
16
+ const { encryptedCredential, ...rest } = integration;
17
+ return rest;
18
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "streamby-core",
3
- "version": "0.29.8",
3
+ "version": "0.29.11",
4
4
  "description": "StreamBy middleware framework for media storage management",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",