@omss/framework 1.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/LICENSE +21 -0
- package/README.md +516 -0
- package/dist/controllers/content.controller.d.ts +37 -0
- package/dist/controllers/content.controller.d.ts.map +1 -0
- package/dist/controllers/content.controller.js +37 -0
- package/dist/controllers/content.controller.js.map +1 -0
- package/dist/controllers/health.controller.d.ts +11 -0
- package/dist/controllers/health.controller.d.ts.map +1 -0
- package/dist/controllers/health.controller.js +18 -0
- package/dist/controllers/health.controller.js.map +1 -0
- package/dist/controllers/proxy.controller.d.ts +17 -0
- package/dist/controllers/proxy.controller.d.ts.map +1 -0
- package/dist/controllers/proxy.controller.js +32 -0
- package/dist/controllers/proxy.controller.js.map +1 -0
- package/dist/core/cache.d.ts +29 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +95 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/errors.d.ts +27 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +42 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/server.d.ts +46 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +210 -0
- package/dist/core/server.js.map +1 -0
- package/dist/core/types.d.ts +123 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +4 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +57 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/logger.d.ts +3 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/logger.js +34 -0
- package/dist/middleware/logger.js.map +1 -0
- package/dist/middleware/validation.d.ts +33 -0
- package/dist/middleware/validation.d.ts.map +1 -0
- package/dist/middleware/validation.js +93 -0
- package/dist/middleware/validation.js.map +1 -0
- package/dist/providers/base-provider.d.ts +91 -0
- package/dist/providers/base-provider.d.ts.map +1 -0
- package/dist/providers/base-provider.js +170 -0
- package/dist/providers/base-provider.js.map +1 -0
- package/dist/providers/provider-registry.d.ts +56 -0
- package/dist/providers/provider-registry.d.ts.map +1 -0
- package/dist/providers/provider-registry.js +182 -0
- package/dist/providers/provider-registry.js.map +1 -0
- package/dist/services/health.service.d.ts +16 -0
- package/dist/services/health.service.d.ts.map +1 -0
- package/dist/services/health.service.js +44 -0
- package/dist/services/health.service.js.map +1 -0
- package/dist/services/proxy.service.d.ts +56 -0
- package/dist/services/proxy.service.d.ts.map +1 -0
- package/dist/services/proxy.service.js +224 -0
- package/dist/services/proxy.service.js.map +1 -0
- package/dist/services/source.service.d.ts +57 -0
- package/dist/services/source.service.d.ts.map +1 -0
- package/dist/services/source.service.js +226 -0
- package/dist/services/source.service.js.map +1 -0
- package/dist/services/tmdb.service.d.ts +67 -0
- package/dist/services/tmdb.service.d.ts.map +1 -0
- package/dist/services/tmdb.service.js +237 -0
- package/dist/services/tmdb.service.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { BaseProvider } from './base-provider';
|
|
2
|
+
export interface ProviderRegistryConfig {
|
|
3
|
+
proxyBaseUrl?: string;
|
|
4
|
+
host?: string;
|
|
5
|
+
port?: number;
|
|
6
|
+
protocol?: 'http' | 'https';
|
|
7
|
+
}
|
|
8
|
+
export declare class ProviderRegistry {
|
|
9
|
+
private providers;
|
|
10
|
+
constructor(config?: ProviderRegistryConfig);
|
|
11
|
+
/**
|
|
12
|
+
* Register a provider instance
|
|
13
|
+
*/
|
|
14
|
+
register(provider: BaseProvider): void;
|
|
15
|
+
/**
|
|
16
|
+
* Unregister a provider
|
|
17
|
+
*/
|
|
18
|
+
unregister(providerId: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Auto-discover and register providers from a directory
|
|
21
|
+
*/
|
|
22
|
+
discoverProviders(directory: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Get all providers
|
|
25
|
+
*/
|
|
26
|
+
getProviders(): BaseProvider[];
|
|
27
|
+
/**
|
|
28
|
+
* Get provider by ID
|
|
29
|
+
*/
|
|
30
|
+
getProvider(id: string): BaseProvider | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Get enabled providers only
|
|
33
|
+
*/
|
|
34
|
+
getEnabledProviders(): BaseProvider[];
|
|
35
|
+
/**
|
|
36
|
+
* Check if a provider exists
|
|
37
|
+
*/
|
|
38
|
+
hasProvider(id: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Get provider count
|
|
41
|
+
*/
|
|
42
|
+
get count(): number;
|
|
43
|
+
/**
|
|
44
|
+
* Health check all providers
|
|
45
|
+
*/
|
|
46
|
+
healthCheckAll(): Promise<Map<string, boolean>>;
|
|
47
|
+
/**
|
|
48
|
+
* List all registered provider IDs
|
|
49
|
+
*/
|
|
50
|
+
listProviders(): string[];
|
|
51
|
+
/**
|
|
52
|
+
* Clear all providers
|
|
53
|
+
*/
|
|
54
|
+
clear(): void;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=provider-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../../src/providers/provider-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/C,MAAM,WAAW,sBAAsB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,SAAS,CAAwC;gBAE7C,MAAM,CAAC,EAAE,sBAAsB;IAY3C;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAQtC;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIvC;;OAEG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsDzD;;OAEG;IACH,YAAY,IAAI,YAAY,EAAE;IAI9B;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIjD;;OAEG;IACH,mBAAmB,IAAI,YAAY,EAAE;IAIrC;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAerD;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;OAEG;IACH,KAAK,IAAI,IAAI;CAIhB"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ProviderRegistry = void 0;
|
|
37
|
+
const base_provider_1 = require("./base-provider");
|
|
38
|
+
const fs = __importStar(require("fs/promises"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const url_1 = require("url");
|
|
41
|
+
class ProviderRegistry {
|
|
42
|
+
providers = new Map();
|
|
43
|
+
constructor(config) {
|
|
44
|
+
// Set proxy configuration for all providers
|
|
45
|
+
if (config) {
|
|
46
|
+
base_provider_1.BaseProvider.setProxyConfig({
|
|
47
|
+
baseUrl: config.proxyBaseUrl,
|
|
48
|
+
host: config.host,
|
|
49
|
+
port: config.port,
|
|
50
|
+
protocol: config.protocol,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Register a provider instance
|
|
56
|
+
*/
|
|
57
|
+
register(provider) {
|
|
58
|
+
if (this.providers.has(provider.id)) {
|
|
59
|
+
throw new Error(`Provider with id '${provider.id}' is already registered`);
|
|
60
|
+
}
|
|
61
|
+
this.providers.set(provider.id, provider);
|
|
62
|
+
console.log(`[ProviderRegistry] Registered provider: ${provider.name} (${provider.id})`);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Unregister a provider
|
|
66
|
+
*/
|
|
67
|
+
unregister(providerId) {
|
|
68
|
+
return this.providers.delete(providerId);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Auto-discover and register providers from a directory
|
|
72
|
+
*/
|
|
73
|
+
async discoverProviders(directory) {
|
|
74
|
+
try {
|
|
75
|
+
const absoluteDir = path.resolve(directory);
|
|
76
|
+
const dirExists = await fs
|
|
77
|
+
.access(absoluteDir)
|
|
78
|
+
.then(() => true)
|
|
79
|
+
.catch(() => false);
|
|
80
|
+
if (!dirExists) {
|
|
81
|
+
console.warn(`[ProviderRegistry] Directory does not exist: ${absoluteDir}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const files = await fs.readdir(absoluteDir);
|
|
85
|
+
console.log(`[ProviderRegistry] Scanning ${files.length} file(s) in ${absoluteDir}`);
|
|
86
|
+
for (const file of files) {
|
|
87
|
+
if (!file.endsWith('.js') && !file.endsWith('.ts'))
|
|
88
|
+
continue;
|
|
89
|
+
if (file.includes('.test.') || file.includes('.spec.'))
|
|
90
|
+
continue;
|
|
91
|
+
if (file.endsWith('.d.ts'))
|
|
92
|
+
continue;
|
|
93
|
+
const filePath = path.resolve(absoluteDir, file);
|
|
94
|
+
try {
|
|
95
|
+
const fileUrl = (0, url_1.pathToFileURL)(filePath).href;
|
|
96
|
+
console.log(`[ProviderRegistry] Loading provider from: ${file}`);
|
|
97
|
+
const module = await Promise.resolve(`${fileUrl}`).then(s => __importStar(require(s)));
|
|
98
|
+
let foundProvider = false;
|
|
99
|
+
for (const exportName of Object.keys(module)) {
|
|
100
|
+
const ExportedClass = module[exportName];
|
|
101
|
+
if (typeof ExportedClass === 'function' && ExportedClass.prototype instanceof base_provider_1.BaseProvider) {
|
|
102
|
+
const instance = new ExportedClass();
|
|
103
|
+
this.register(instance);
|
|
104
|
+
foundProvider = true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!foundProvider) {
|
|
108
|
+
console.warn(`[ProviderRegistry] No provider classes found in ${file}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error(`[ProviderRegistry] Failed to load provider from ${file}:`, error);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
console.log(`[ProviderRegistry] Discovery complete. Total providers: ${this.providers.size}`);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error(`[ProviderRegistry] Failed to discover providers in ${directory}:`, error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get all providers
|
|
123
|
+
*/
|
|
124
|
+
getProviders() {
|
|
125
|
+
return Array.from(this.providers.values());
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get provider by ID
|
|
129
|
+
*/
|
|
130
|
+
getProvider(id) {
|
|
131
|
+
return this.providers.get(id);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get enabled providers only
|
|
135
|
+
*/
|
|
136
|
+
getEnabledProviders() {
|
|
137
|
+
return this.getProviders().filter((p) => p.enabled);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Check if a provider exists
|
|
141
|
+
*/
|
|
142
|
+
hasProvider(id) {
|
|
143
|
+
return this.providers.has(id);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get provider count
|
|
147
|
+
*/
|
|
148
|
+
get count() {
|
|
149
|
+
return this.providers.size;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Health check all providers
|
|
153
|
+
*/
|
|
154
|
+
async healthCheckAll() {
|
|
155
|
+
const results = new Map();
|
|
156
|
+
for (const provider of this.providers.values()) {
|
|
157
|
+
try {
|
|
158
|
+
const healthy = await provider.healthCheck();
|
|
159
|
+
results.set(provider.id, healthy);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
results.set(provider.id, false);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return results;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* List all registered provider IDs
|
|
169
|
+
*/
|
|
170
|
+
listProviders() {
|
|
171
|
+
return Array.from(this.providers.keys());
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Clear all providers
|
|
175
|
+
*/
|
|
176
|
+
clear() {
|
|
177
|
+
this.providers.clear();
|
|
178
|
+
console.log('[ProviderRegistry] Cleared all providers');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.ProviderRegistry = ProviderRegistry;
|
|
182
|
+
//# sourceMappingURL=provider-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-registry.js","sourceRoot":"","sources":["../../src/providers/provider-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { HealthResponse, OMSSConfig } from '../core/types';
|
|
2
|
+
import { ProviderRegistry } from '../providers/provider-registry';
|
|
3
|
+
export declare class HealthService {
|
|
4
|
+
private config;
|
|
5
|
+
private registry;
|
|
6
|
+
constructor(config: OMSSConfig, registry: ProviderRegistry);
|
|
7
|
+
/**
|
|
8
|
+
* Get health/info response
|
|
9
|
+
*/
|
|
10
|
+
getHealth(): HealthResponse;
|
|
11
|
+
/**
|
|
12
|
+
* Determine current status
|
|
13
|
+
*/
|
|
14
|
+
private getStatus;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=health.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.service.d.ts","sourceRoot":"","sources":["../../src/services/health.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,qBAAa,aAAa;IAElB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;gBADR,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,gBAAgB;IAGtC;;OAEG;IACH,SAAS,IAAI,cAAc;IAmB3B;;OAEG;IACH,OAAO,CAAC,SAAS;CASpB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HealthService = void 0;
|
|
4
|
+
class HealthService {
|
|
5
|
+
config;
|
|
6
|
+
registry;
|
|
7
|
+
constructor(config, registry) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.registry = registry;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get health/info response
|
|
13
|
+
*/
|
|
14
|
+
getHealth() {
|
|
15
|
+
this.registry.healthCheckAll();
|
|
16
|
+
return {
|
|
17
|
+
name: this.config.name,
|
|
18
|
+
version: this.config.version,
|
|
19
|
+
status: this.getStatus(),
|
|
20
|
+
endpoints: {
|
|
21
|
+
movie: '/v1/movies/{id}',
|
|
22
|
+
tv: '/v1/tv/{id}/seasons/{s}/episodes/{e}',
|
|
23
|
+
proxy: '/v1/proxy?data={encoded_data}',
|
|
24
|
+
},
|
|
25
|
+
spec: 'omss',
|
|
26
|
+
note: `Running with ${this.registry.getEnabledProviders().length} provider(s). Supported Providers: ${this.registry
|
|
27
|
+
.getEnabledProviders()
|
|
28
|
+
.map((p) => p.name)
|
|
29
|
+
.join(', ')}`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Determine current status
|
|
34
|
+
*/
|
|
35
|
+
getStatus() {
|
|
36
|
+
const providerCount = this.registry.count;
|
|
37
|
+
if (providerCount === 0) {
|
|
38
|
+
return 'degraded'; // No providers but server is running
|
|
39
|
+
}
|
|
40
|
+
return 'operational';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.HealthService = HealthService;
|
|
44
|
+
//# sourceMappingURL=health.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.service.js","sourceRoot":"","sources":["../../src/services/health.service.ts"],"names":[],"mappings":";;;AAGA,MAAa,aAAa;IAEV;IACA;IAFZ,YACY,MAAkB,EAClB,QAA0B;QAD1B,WAAM,GAAN,MAAM,CAAY;QAClB,aAAQ,GAAR,QAAQ,CAAkB;IACnC,CAAC;IAEJ;;OAEG;IACH,SAAS;QACL,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC/B,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE;YACxB,SAAS,EAAE;gBACP,KAAK,EAAE,iBAAiB;gBACxB,EAAE,EAAE,sCAAsC;gBAC1C,KAAK,EAAE,+BAA+B;aACzC;YACD,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,gBAAgB,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,MAAM,sCAAsC,IAAI,CAAC,QAAQ;iBAC9G,mBAAmB,EAAE;iBACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAClB,IAAI,CAAC,IAAI,CAAC,EAAE;SACpB,CAAC;IACN,CAAC;IAED;;OAEG;IACK,SAAS;QACb,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAE1C,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,UAAU,CAAC,CAAC,qCAAqC;QAC5D,CAAC;QAED,OAAO,aAAa,CAAC;IACzB,CAAC;CACJ;AAxCD,sCAwCC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export interface ProxyResponse {
|
|
2
|
+
data: Buffer | string;
|
|
3
|
+
contentType: string;
|
|
4
|
+
statusCode: number;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export declare class ProxyService {
|
|
8
|
+
/**
|
|
9
|
+
* Proxy a request to an upstream provider
|
|
10
|
+
*/
|
|
11
|
+
proxyRequest(encodedData: string): Promise<ProxyResponse>;
|
|
12
|
+
/**
|
|
13
|
+
* Decode proxy data parameter
|
|
14
|
+
*/
|
|
15
|
+
private decodeProxyData;
|
|
16
|
+
/**
|
|
17
|
+
* Check if the response is a manifest file that needs rewriting
|
|
18
|
+
*/
|
|
19
|
+
private isManifestFile;
|
|
20
|
+
/**
|
|
21
|
+
* Rewrite manifest file URLs to go through proxy
|
|
22
|
+
* Handles all URL formats: absolute (http/https), protocol-relative (//), root-relative (/), and relative
|
|
23
|
+
* Also rewrites URLs in tag attributes like URI="..."
|
|
24
|
+
*/
|
|
25
|
+
private rewriteManifest;
|
|
26
|
+
/**
|
|
27
|
+
* Check if a tag line has URI attributes that need rewriting
|
|
28
|
+
*/
|
|
29
|
+
private hasUriAttribute;
|
|
30
|
+
/**
|
|
31
|
+
* Rewrite URI attributes in HLS tags
|
|
32
|
+
* Examples:
|
|
33
|
+
* #EXT-X-KEY:METHOD=AES-128,URI="/storage/enc.key",IV=...
|
|
34
|
+
* #EXT-X-MAP:URI="init.mp4",BYTERANGE="..."
|
|
35
|
+
*/
|
|
36
|
+
private rewriteTagAttributes;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a line contains a URL
|
|
39
|
+
*/
|
|
40
|
+
private isUrlLine;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a URL against a base URL
|
|
43
|
+
* Handles: absolute, protocol-relative, root-relative, and relative URLs
|
|
44
|
+
*/
|
|
45
|
+
private resolveUrl;
|
|
46
|
+
/**
|
|
47
|
+
* Create a proxy URL for a given upstream URL
|
|
48
|
+
* ALWAYS includes headers from the original request
|
|
49
|
+
*/
|
|
50
|
+
private createProxyUrl;
|
|
51
|
+
/**
|
|
52
|
+
* Encode a URL for proxy usage (helper for providers)
|
|
53
|
+
*/
|
|
54
|
+
static encodeProxyUrl(url: string, headers?: Record<string, string>): string;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=proxy.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.service.d.ts","sourceRoot":"","sources":["../../src/services/proxy.service.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,qBAAa,YAAY;IACrB;;OAEG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAkD/D;;OAEG;IACH,OAAO,CAAC,eAAe;IAkBvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAoCvB;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;OAEG;IACH,OAAO,CAAC,SAAS;IAmCjB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAoClB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;CAI/E"}
|
|
@@ -0,0 +1,224 @@
|
|
|
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.ProxyService = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const errors_1 = require("../core/errors");
|
|
9
|
+
class ProxyService {
|
|
10
|
+
/**
|
|
11
|
+
* Proxy a request to an upstream provider
|
|
12
|
+
*/
|
|
13
|
+
async proxyRequest(encodedData) {
|
|
14
|
+
// Decode the data parameter
|
|
15
|
+
const proxyData = this.decodeProxyData(encodedData);
|
|
16
|
+
console.log(`[ProxyService] Proxying request to: ${proxyData.url}`);
|
|
17
|
+
try {
|
|
18
|
+
const response = await axios_1.default.get(proxyData.url, {
|
|
19
|
+
headers: {
|
|
20
|
+
...proxyData.headers,
|
|
21
|
+
'User-Agent': proxyData.headers?.['User-Agent'] || 'OMSS-Backend/1.0',
|
|
22
|
+
},
|
|
23
|
+
responseType: 'arraybuffer',
|
|
24
|
+
timeout: 30000, // 30 second timeout
|
|
25
|
+
maxRedirects: 5,
|
|
26
|
+
validateStatus: (status) => status < 500, // Accept 4xx errors
|
|
27
|
+
});
|
|
28
|
+
// Check if we need to rewrite manifest files
|
|
29
|
+
const contentType = response.headers['content-type'] || '';
|
|
30
|
+
let responseData = response.data;
|
|
31
|
+
if (this.isManifestFile(contentType, proxyData.url)) {
|
|
32
|
+
const manifestContent = response.data.toString('utf-8');
|
|
33
|
+
const rewrittenContent = this.rewriteManifest(manifestContent, proxyData.url, proxyData.headers);
|
|
34
|
+
responseData = Buffer.from(rewrittenContent, 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
data: responseData,
|
|
38
|
+
contentType: contentType,
|
|
39
|
+
statusCode: response.status,
|
|
40
|
+
headers: {
|
|
41
|
+
'Cache-Control': response.headers['cache-control'] || 'public, max-age=300',
|
|
42
|
+
'Access-Control-Allow-Origin': '*',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
48
|
+
if (error.response) {
|
|
49
|
+
throw new errors_1.OMSSError('INTERNAL_ERROR', `Upstream returned ${error.response.status}`, error.response.status, { url: proxyData.url });
|
|
50
|
+
}
|
|
51
|
+
throw new errors_1.OMSSError('INTERNAL_ERROR', `Failed to proxy request: ${error.message}`, 500, { url: proxyData.url });
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Decode proxy data parameter
|
|
58
|
+
*/
|
|
59
|
+
decodeProxyData(encodedData) {
|
|
60
|
+
try {
|
|
61
|
+
const decoded = decodeURIComponent(encodedData);
|
|
62
|
+
const data = JSON.parse(decoded);
|
|
63
|
+
if (!data.url) {
|
|
64
|
+
throw new Error('Missing url field in proxy data');
|
|
65
|
+
}
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new errors_1.OMSSError('INVALID_PARAMETER', 'Invalid data parameter format', 400, {
|
|
70
|
+
parameter: 'data',
|
|
71
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if the response is a manifest file that needs rewriting
|
|
77
|
+
*/
|
|
78
|
+
isManifestFile(contentType, url) {
|
|
79
|
+
return contentType.includes('application/vnd.apple.mpegurl') || contentType.includes('application/x-mpegurl') || contentType.includes('application/dash+xml') || (contentType.includes('text/plain') && url.includes('.m3u8')) || url.endsWith('.m3u8') || url.endsWith('.mpd');
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Rewrite manifest file URLs to go through proxy
|
|
83
|
+
* Handles all URL formats: absolute (http/https), protocol-relative (//), root-relative (/), and relative
|
|
84
|
+
* Also rewrites URLs in tag attributes like URI="..."
|
|
85
|
+
*/
|
|
86
|
+
rewriteManifest(content, baseUrl, headers) {
|
|
87
|
+
const lines = content.split('\n');
|
|
88
|
+
const rewrittenLines = [];
|
|
89
|
+
for (const line of lines) {
|
|
90
|
+
const trimmedLine = line.trim();
|
|
91
|
+
// Handle tag lines with URI attributes (e.g., #EXT-X-KEY)
|
|
92
|
+
if (line.startsWith('#') && this.hasUriAttribute(line)) {
|
|
93
|
+
rewrittenLines.push(this.rewriteTagAttributes(line, baseUrl, headers));
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
// Skip other comments and empty lines
|
|
97
|
+
if (line.startsWith('#') || trimmedLine === '') {
|
|
98
|
+
rewrittenLines.push(line);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Detect if this line contains a URL
|
|
102
|
+
if (this.isUrlLine(trimmedLine)) {
|
|
103
|
+
const resolvedUrl = this.resolveUrl(baseUrl, trimmedLine);
|
|
104
|
+
const proxiedUrl = this.createProxyUrl(resolvedUrl, headers);
|
|
105
|
+
// Preserve original indentation
|
|
106
|
+
const indent = line.match(/^\s*/)?.[0] || '';
|
|
107
|
+
rewrittenLines.push(indent + proxiedUrl);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// Not a URL line, keep as-is
|
|
111
|
+
rewrittenLines.push(line);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return rewrittenLines.join('\n');
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Check if a tag line has URI attributes that need rewriting
|
|
118
|
+
*/
|
|
119
|
+
hasUriAttribute(line) {
|
|
120
|
+
return /URI\s*=\s*["']([^"']+)["']/i.test(line);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Rewrite URI attributes in HLS tags
|
|
124
|
+
* Examples:
|
|
125
|
+
* #EXT-X-KEY:METHOD=AES-128,URI="/storage/enc.key",IV=...
|
|
126
|
+
* #EXT-X-MAP:URI="init.mp4",BYTERANGE="..."
|
|
127
|
+
*/
|
|
128
|
+
rewriteTagAttributes(line, baseUrl, headers) {
|
|
129
|
+
// Match URI="..." or URI='...'
|
|
130
|
+
return line.replace(/URI\s*=\s*["']([^"']+)["']/gi, (match, capturedUrl) => {
|
|
131
|
+
const resolvedUrl = this.resolveUrl(baseUrl, capturedUrl);
|
|
132
|
+
const proxiedUrl = this.createProxyUrl(resolvedUrl, headers);
|
|
133
|
+
// Preserve the quote style from the original
|
|
134
|
+
const quote = match.includes('"') ? '"' : "'";
|
|
135
|
+
return `URI=${quote}${proxiedUrl}${quote}`;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Check if a line contains a URL
|
|
140
|
+
*/
|
|
141
|
+
isUrlLine(line) {
|
|
142
|
+
// Absolute URLs
|
|
143
|
+
if (line.startsWith('http://') || line.startsWith('https://')) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
// Protocol-relative URLs
|
|
147
|
+
if (line.startsWith('//')) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
// Root-relative URLs
|
|
151
|
+
if (line.startsWith('/')) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
// Relative URLs (files with extensions or paths)
|
|
155
|
+
// Common patterns: segment.ts, playlist.m3u8, path/to/file.mp4
|
|
156
|
+
if (line.includes('.ts') ||
|
|
157
|
+
line.includes('.m3u8') ||
|
|
158
|
+
line.includes('.mp4') ||
|
|
159
|
+
line.includes('.m4s') ||
|
|
160
|
+
line.includes('.webm') ||
|
|
161
|
+
line.includes('.vtt') ||
|
|
162
|
+
line.includes('.key') ||
|
|
163
|
+
line.includes('/') ||
|
|
164
|
+
/^[a-zA-Z0-9_-]+\.[a-zA-Z0-9]+/.test(line) // filename.extension pattern
|
|
165
|
+
) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Resolve a URL against a base URL
|
|
172
|
+
* Handles: absolute, protocol-relative, root-relative, and relative URLs
|
|
173
|
+
*/
|
|
174
|
+
resolveUrl(baseUrl, targetUrl) {
|
|
175
|
+
try {
|
|
176
|
+
// Absolute URL (http:// or https://)
|
|
177
|
+
if (targetUrl.startsWith('http://') || targetUrl.startsWith('https://')) {
|
|
178
|
+
return targetUrl;
|
|
179
|
+
}
|
|
180
|
+
const baseUrlObj = new URL(baseUrl);
|
|
181
|
+
// Protocol-relative URL (//example.com/path)
|
|
182
|
+
if (targetUrl.startsWith('//')) {
|
|
183
|
+
return `${baseUrlObj.protocol}${targetUrl}`;
|
|
184
|
+
}
|
|
185
|
+
// Root-relative URL (/path/to/file)
|
|
186
|
+
if (targetUrl.startsWith('/')) {
|
|
187
|
+
return `${baseUrlObj.protocol}//${baseUrlObj.host}${targetUrl}`;
|
|
188
|
+
}
|
|
189
|
+
// Relative URL (path/to/file or file.ts)
|
|
190
|
+
// Resolve against the base URL's directory
|
|
191
|
+
const baseDir = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1);
|
|
192
|
+
return new URL(targetUrl, baseDir).toString();
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
console.warn(`[ProxyService] Failed to resolve URL: ${targetUrl} against ${baseUrl}`);
|
|
196
|
+
// Fallback: try to construct a valid URL
|
|
197
|
+
try {
|
|
198
|
+
const baseUrlObj = new URL(baseUrl);
|
|
199
|
+
const baseDir = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1);
|
|
200
|
+
return baseDir + targetUrl;
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return targetUrl; // Last resort: return as-is
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Create a proxy URL for a given upstream URL
|
|
209
|
+
* ALWAYS includes headers from the original request
|
|
210
|
+
*/
|
|
211
|
+
createProxyUrl(url, headers) {
|
|
212
|
+
const data = JSON.stringify({ url, headers });
|
|
213
|
+
return `/v1/proxy?data=${encodeURIComponent(data)}`;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Encode a URL for proxy usage (helper for providers)
|
|
217
|
+
*/
|
|
218
|
+
static encodeProxyUrl(url, headers) {
|
|
219
|
+
const data = JSON.stringify({ url, headers });
|
|
220
|
+
return `/v1/proxy?data=${encodeURIComponent(data)}`;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
exports.ProxyService = ProxyService;
|
|
224
|
+
//# sourceMappingURL=proxy.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.service.js","sourceRoot":"","sources":["../../src/services/proxy.service.ts"],"names":[],"mappings":"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"}
|