ai-vault 2.0.1 → 3.0.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/dist/api/middleware/error-handler.d.ts +12 -0
- package/dist/api/middleware/error-handler.d.ts.map +1 -0
- package/dist/api/middleware/error-handler.js +29 -0
- package/dist/api/middleware/error-handler.js.map +1 -0
- package/dist/api/middleware/logger.d.ts +6 -0
- package/dist/api/middleware/logger.d.ts.map +1 -0
- package/dist/api/middleware/logger.js +17 -0
- package/dist/api/middleware/logger.js.map +1 -0
- package/dist/api/middleware/rate-limiter.d.ts +6 -0
- package/dist/api/middleware/rate-limiter.d.ts.map +1 -0
- package/dist/api/middleware/rate-limiter.js +41 -0
- package/dist/api/middleware/rate-limiter.js.map +1 -0
- package/dist/api/routes/archive.d.ts +6 -0
- package/dist/api/routes/archive.d.ts.map +1 -0
- package/dist/api/routes/archive.js +140 -0
- package/dist/api/routes/archive.js.map +1 -0
- package/dist/api/routes/conversations.d.ts +6 -0
- package/dist/api/routes/conversations.d.ts.map +1 -0
- package/dist/api/routes/conversations.js +193 -0
- package/dist/api/routes/conversations.js.map +1 -0
- package/dist/api/routes/media.d.ts +6 -0
- package/dist/api/routes/media.d.ts.map +1 -0
- package/dist/api/routes/media.js +152 -0
- package/dist/api/routes/media.js.map +1 -0
- package/dist/api/routes/providers.d.ts +6 -0
- package/dist/api/routes/providers.d.ts.map +1 -0
- package/dist/api/routes/providers.js +111 -0
- package/dist/api/routes/providers.js.map +1 -0
- package/dist/api/routes/schedules.d.ts +6 -0
- package/dist/api/routes/schedules.d.ts.map +1 -0
- package/dist/api/routes/schedules.js +119 -0
- package/dist/api/routes/schedules.js.map +1 -0
- package/dist/api/routes/search.d.ts +6 -0
- package/dist/api/routes/search.d.ts.map +1 -0
- package/dist/api/routes/search.js +107 -0
- package/dist/api/routes/search.js.map +1 -0
- package/dist/api/routes/settings.d.ts +6 -0
- package/dist/api/routes/settings.d.ts.map +1 -0
- package/dist/api/routes/settings.js +82 -0
- package/dist/api/routes/settings.js.map +1 -0
- package/dist/api/server.d.ts +28 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +161 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/services/search-service.d.ts +71 -0
- package/dist/api/services/search-service.d.ts.map +1 -0
- package/dist/api/services/search-service.js +259 -0
- package/dist/api/services/search-service.js.map +1 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/archive.d.ts +1 -0
- package/dist/commands/archive.d.ts.map +1 -1
- package/dist/commands/archive.js +158 -126
- package/dist/commands/archive.js.map +1 -1
- package/dist/commands/ui.d.ts +6 -0
- package/dist/commands/ui.d.ts.map +1 -0
- package/dist/commands/ui.js +48 -0
- package/dist/commands/ui.js.map +1 -0
- package/dist/providers/auth/base-strategy-provider.d.ts +67 -0
- package/dist/providers/auth/base-strategy-provider.d.ts.map +1 -0
- package/dist/providers/auth/base-strategy-provider.js +158 -0
- package/dist/providers/auth/base-strategy-provider.js.map +1 -0
- package/dist/providers/auth/index.d.ts +8 -0
- package/dist/providers/auth/index.d.ts.map +1 -0
- package/dist/providers/auth/index.js +8 -0
- package/dist/providers/auth/index.js.map +1 -0
- package/dist/providers/auth/strategies.d.ts +138 -0
- package/dist/providers/auth/strategies.d.ts.map +1 -0
- package/dist/providers/auth/strategies.js +283 -0
- package/dist/providers/auth/strategies.js.map +1 -0
- package/dist/providers/chatgpt/api-provider.d.ts +51 -0
- package/dist/providers/chatgpt/api-provider.d.ts.map +1 -0
- package/dist/providers/chatgpt/api-provider.js +435 -0
- package/dist/providers/chatgpt/api-provider.js.map +1 -0
- package/dist/providers/claude/api-provider.d.ts +49 -0
- package/dist/providers/claude/api-provider.d.ts.map +1 -0
- package/dist/providers/claude/api-provider.js +357 -0
- package/dist/providers/claude/api-provider.js.map +1 -0
- package/dist/providers/grok-web/api-provider.d.ts +57 -0
- package/dist/providers/grok-web/api-provider.d.ts.map +1 -0
- package/dist/providers/grok-web/api-provider.js +393 -0
- package/dist/providers/grok-web/api-provider.js.map +1 -0
- package/dist/providers/grok-x/api-provider.d.ts +41 -0
- package/dist/providers/grok-x/api-provider.d.ts.map +1 -0
- package/dist/providers/grok-x/api-provider.js +173 -0
- package/dist/providers/grok-x/api-provider.js.map +1 -0
- package/dist/utils/scheduler.d.ts.map +1 -1
- package/dist/utils/scheduler.js +20 -3
- package/dist/utils/scheduler.js.map +1 -1
- package/dist/utils/scheduler.spec.d.ts +5 -0
- package/dist/utils/scheduler.spec.d.ts.map +1 -0
- package/dist/utils/scheduler.spec.js +163 -0
- package/dist/utils/scheduler.spec.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global error handler middleware
|
|
3
|
+
*/
|
|
4
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
5
|
+
export interface ApiError extends Error {
|
|
6
|
+
statusCode?: number;
|
|
7
|
+
details?: unknown;
|
|
8
|
+
}
|
|
9
|
+
export declare function errorHandler(err: ApiError, _req: Request, res: Response, _next: NextFunction): void;
|
|
10
|
+
export declare function createError(message: string, statusCode?: number, details?: unknown): ApiError;
|
|
11
|
+
export declare function isApiError(error: unknown): error is ApiError;
|
|
12
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/api/middleware/error-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG/D,MAAM,WAAW,QAAS,SAAQ,KAAK;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,YAAY,CAC1B,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,IAAI,CAgBN;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,UAAU,GAAE,MAAY,EACxB,OAAO,CAAC,EAAE,OAAO,GAChB,QAAQ,CAKV;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global error handler middleware
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
export function errorHandler(err, _req, res, _next) {
|
|
6
|
+
const statusCode = err.statusCode || 500;
|
|
7
|
+
const message = err.message || 'Internal server error';
|
|
8
|
+
// Log error
|
|
9
|
+
console.error(chalk.red(`[API Error] ${statusCode}: ${message}`));
|
|
10
|
+
if (err.stack) {
|
|
11
|
+
console.error(chalk.gray(err.stack));
|
|
12
|
+
}
|
|
13
|
+
// Send error response
|
|
14
|
+
res.status(statusCode).json({
|
|
15
|
+
error: message,
|
|
16
|
+
details: err.details,
|
|
17
|
+
...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export function createError(message, statusCode = 500, details) {
|
|
21
|
+
const error = new Error(message);
|
|
22
|
+
error.statusCode = statusCode;
|
|
23
|
+
error.details = details;
|
|
24
|
+
return error;
|
|
25
|
+
}
|
|
26
|
+
export function isApiError(error) {
|
|
27
|
+
return typeof error === 'object' && error !== null && 'statusCode' in error;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../src/api/middleware/error-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,UAAU,YAAY,CAC1B,GAAa,EACb,IAAa,EACb,GAAa,EACb,KAAmB;IAEnB,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,uBAAuB,CAAC;IAEvD,YAAY;IACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,UAAU,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,sBAAsB;IACtB,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC1B,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;KACpE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,aAAqB,GAAG,EACxB,OAAiB;IAEjB,MAAM,KAAK,GAAa,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3C,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,YAAY,IAAI,KAAK,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/api/middleware/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG/D,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAkBnF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request logging middleware
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
export function requestLogger(req, res, next) {
|
|
6
|
+
const start = Date.now();
|
|
7
|
+
// Log request
|
|
8
|
+
console.log(chalk.gray(`[${new Date().toISOString()}] ${req.method} ${req.path}`));
|
|
9
|
+
// Log response when finished
|
|
10
|
+
res.on('finish', () => {
|
|
11
|
+
const duration = Date.now() - start;
|
|
12
|
+
const statusColor = res.statusCode >= 400 ? chalk.red : chalk.green;
|
|
13
|
+
console.log(chalk.gray(`[${new Date().toISOString()}] ${req.method} ${req.path} ${statusColor(res.statusCode)} - ${duration}ms`));
|
|
14
|
+
});
|
|
15
|
+
next();
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/api/middleware/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,cAAc;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEnF,6BAA6B;IAC7B,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACpC,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;QACpE,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,QAAQ,IAAI,CACzG,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/api/middleware/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAY/D,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAuCjF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple rate limiting middleware
|
|
3
|
+
*/
|
|
4
|
+
const rateLimitStore = new Map();
|
|
5
|
+
const RATE_LIMIT_WINDOW = 60 * 1000; // 1 minute
|
|
6
|
+
const RATE_LIMIT_MAX_REQUESTS = 100; // 100 requests per minute
|
|
7
|
+
export function rateLimiter(req, res, next) {
|
|
8
|
+
const clientId = req.ip || 'unknown';
|
|
9
|
+
const now = Date.now();
|
|
10
|
+
// Clean up expired entries
|
|
11
|
+
for (const [key, entry] of rateLimitStore.entries()) {
|
|
12
|
+
if (now > entry.resetTime) {
|
|
13
|
+
rateLimitStore.delete(key);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// Get or create entry for this client
|
|
17
|
+
let entry = rateLimitStore.get(clientId);
|
|
18
|
+
if (!entry || now > entry.resetTime) {
|
|
19
|
+
entry = {
|
|
20
|
+
count: 0,
|
|
21
|
+
resetTime: now + RATE_LIMIT_WINDOW,
|
|
22
|
+
};
|
|
23
|
+
rateLimitStore.set(clientId, entry);
|
|
24
|
+
}
|
|
25
|
+
// Increment request count
|
|
26
|
+
entry.count++;
|
|
27
|
+
// Check if rate limit exceeded
|
|
28
|
+
if (entry.count > RATE_LIMIT_MAX_REQUESTS) {
|
|
29
|
+
res.status(429).json({
|
|
30
|
+
error: 'Too many requests',
|
|
31
|
+
retryAfter: Math.ceil((entry.resetTime - now) / 1000),
|
|
32
|
+
});
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Set rate limit headers
|
|
36
|
+
res.setHeader('X-RateLimit-Limit', RATE_LIMIT_MAX_REQUESTS);
|
|
37
|
+
res.setHeader('X-RateLimit-Remaining', RATE_LIMIT_MAX_REQUESTS - entry.count);
|
|
38
|
+
res.setHeader('X-RateLimit-Reset', entry.resetTime);
|
|
39
|
+
next();
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../../src/api/middleware/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,MAAM,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEzD,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;AAChD,MAAM,uBAAuB,GAAG,GAAG,CAAC,CAAC,0BAA0B;AAE/D,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IACzE,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,2BAA2B;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC;QACpD,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAC1B,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,IAAI,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QACpC,KAAK,GAAG;YACN,KAAK,EAAE,CAAC;YACR,SAAS,EAAE,GAAG,GAAG,iBAAiB;SACnC,CAAC;QACF,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,0BAA0B;IAC1B,KAAK,CAAC,KAAK,EAAE,CAAC;IAEd,+BAA+B;IAC/B,IAAI,KAAK,CAAC,KAAK,GAAG,uBAAuB,EAAE,CAAC;QAC1C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,mBAAmB;YAC1B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC;SACtD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,yBAAyB;IACzB,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;IAC5D,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,uBAAuB,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9E,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAEpD,IAAI,EAAE,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/api/routes/archive.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAgK9D,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archive operations API endpoints
|
|
3
|
+
*/
|
|
4
|
+
import { Router } from 'express';
|
|
5
|
+
import { loadConfig } from '../../utils/config.js';
|
|
6
|
+
import { getProvider } from '../../providers/index.js';
|
|
7
|
+
import { Archiver } from '../../core/archiver.js';
|
|
8
|
+
import { Storage, getDefaultStorageConfig } from '../../core/storage.js';
|
|
9
|
+
import { MediaManager } from '../../core/media.js';
|
|
10
|
+
import { createError, isApiError } from '../middleware/error-handler.js';
|
|
11
|
+
const router = Router();
|
|
12
|
+
// Track running archive operations
|
|
13
|
+
const runningOperations = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* GET /api/archive/status
|
|
16
|
+
* Get current archive status for all providers
|
|
17
|
+
*/
|
|
18
|
+
router.get('/status', async (_req, res) => {
|
|
19
|
+
try {
|
|
20
|
+
const operations = Array.from(runningOperations.entries()).map(([id, op]) => ({
|
|
21
|
+
id,
|
|
22
|
+
...op,
|
|
23
|
+
}));
|
|
24
|
+
res.json({ operations });
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw createError('Failed to get archive status', 500, error);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* POST /api/archive/start
|
|
32
|
+
* Start an archive operation
|
|
33
|
+
*/
|
|
34
|
+
router.post('/start', async (req, res) => {
|
|
35
|
+
try {
|
|
36
|
+
const { provider: providerName, options = {} } = req.body;
|
|
37
|
+
if (!providerName) {
|
|
38
|
+
throw createError('Provider name is required', 400);
|
|
39
|
+
}
|
|
40
|
+
const config = await loadConfig();
|
|
41
|
+
const providerConfig = config.providers?.[providerName];
|
|
42
|
+
if (!providerConfig) {
|
|
43
|
+
throw createError(`Provider ${providerName} not configured`, 404);
|
|
44
|
+
}
|
|
45
|
+
const provider = getProvider(providerName);
|
|
46
|
+
if (!provider) {
|
|
47
|
+
throw createError(`Provider ${providerName} not found`, 404);
|
|
48
|
+
}
|
|
49
|
+
// Create operation ID
|
|
50
|
+
const operationId = `${providerName}-${Date.now()}`;
|
|
51
|
+
// Initialize operation tracking
|
|
52
|
+
runningOperations.set(operationId, {
|
|
53
|
+
provider: providerName,
|
|
54
|
+
startTime: new Date(),
|
|
55
|
+
status: 'running',
|
|
56
|
+
});
|
|
57
|
+
// Start archive in background
|
|
58
|
+
(async () => {
|
|
59
|
+
try {
|
|
60
|
+
await provider.authenticate(providerConfig);
|
|
61
|
+
const storageConfig = getDefaultStorageConfig();
|
|
62
|
+
if (config.settings?.archiveDir) {
|
|
63
|
+
storageConfig.baseDir = config.settings.archiveDir;
|
|
64
|
+
}
|
|
65
|
+
const storage = new Storage(storageConfig);
|
|
66
|
+
const mediaManager = new MediaManager(storageConfig.baseDir);
|
|
67
|
+
const archiver = new Archiver(storage, mediaManager);
|
|
68
|
+
await archiver.init();
|
|
69
|
+
const result = await archiver.archive(provider, {
|
|
70
|
+
...options,
|
|
71
|
+
silent: true, // Suppress console output for API
|
|
72
|
+
});
|
|
73
|
+
const operation = runningOperations.get(operationId);
|
|
74
|
+
if (operation) {
|
|
75
|
+
operation.status = 'completed';
|
|
76
|
+
operation.result = result;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
const operation = runningOperations.get(operationId);
|
|
81
|
+
if (operation) {
|
|
82
|
+
operation.status = 'failed';
|
|
83
|
+
operation.error = error instanceof Error ? error.message : 'Unknown error';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
})();
|
|
87
|
+
res.json({
|
|
88
|
+
success: true,
|
|
89
|
+
operationId,
|
|
90
|
+
message: 'Archive operation started',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (isApiError(error)) {
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
throw createError('Failed to start archive', 500, error);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
/**
|
|
101
|
+
* GET /api/archive/operation/:id
|
|
102
|
+
* Get status of a specific archive operation
|
|
103
|
+
*/
|
|
104
|
+
router.get('/operation/:id', async (req, res) => {
|
|
105
|
+
try {
|
|
106
|
+
const { id } = req.params;
|
|
107
|
+
const operation = runningOperations.get(id);
|
|
108
|
+
if (!operation) {
|
|
109
|
+
throw createError('Operation not found', 404);
|
|
110
|
+
}
|
|
111
|
+
res.json({ id, ...operation });
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
if (isApiError(error)) {
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
throw createError('Failed to get operation status', 500, error);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
/**
|
|
121
|
+
* GET /api/archive/history
|
|
122
|
+
* Get archive operation history
|
|
123
|
+
*/
|
|
124
|
+
router.get('/history', async (_req, res) => {
|
|
125
|
+
try {
|
|
126
|
+
const history = Array.from(runningOperations.entries())
|
|
127
|
+
.filter(([_, op]) => op.status !== 'running')
|
|
128
|
+
.map(([id, op]) => ({ id, ...op }))
|
|
129
|
+
.sort((a, b) => b.startTime.getTime() - a.startTime.getTime())
|
|
130
|
+
.slice(0, 50); // Last 50 operations
|
|
131
|
+
res.json({ history });
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
throw createError('Failed to get archive history', 500, error);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
export function createArchiveRouter() {
|
|
138
|
+
return router;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/api/routes/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../../src/api/routes/conversations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAiO9D,wBAAgB,yBAAyB,IAAI,MAAM,CAElD"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation browsing and detail API endpoints
|
|
3
|
+
*/
|
|
4
|
+
import { Router } from 'express';
|
|
5
|
+
import { getDefaultStorageConfig } from '../../core/storage.js';
|
|
6
|
+
import { loadConfig } from '../../utils/config.js';
|
|
7
|
+
import { createError, isApiError } from '../middleware/error-handler.js';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import fs from 'fs/promises';
|
|
10
|
+
import { existsSync } from 'fs';
|
|
11
|
+
const router = Router();
|
|
12
|
+
/**
|
|
13
|
+
* GET /api/conversations
|
|
14
|
+
* List all archived conversations with pagination and filtering
|
|
15
|
+
*/
|
|
16
|
+
router.get('/', async (req, res) => {
|
|
17
|
+
try {
|
|
18
|
+
const config = await loadConfig();
|
|
19
|
+
const storageConfig = getDefaultStorageConfig();
|
|
20
|
+
if (config.settings?.archiveDir) {
|
|
21
|
+
storageConfig.baseDir = config.settings.archiveDir;
|
|
22
|
+
}
|
|
23
|
+
const { provider, limit = 50, offset = 0, sortBy = 'updatedAt', sortOrder = 'desc', since, until, } = req.query;
|
|
24
|
+
// Get all conversations
|
|
25
|
+
const allConversations = [];
|
|
26
|
+
// Determine which providers to query
|
|
27
|
+
const providers = provider ? [provider] : Object.keys(config.providers || {});
|
|
28
|
+
for (const providerName of providers) {
|
|
29
|
+
const providerPath = path.join(storageConfig.baseDir, providerName);
|
|
30
|
+
if (!existsSync(providerPath)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
// Load index
|
|
34
|
+
const indexPath = path.join(providerPath, 'index.json');
|
|
35
|
+
if (!existsSync(indexPath)) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const indexData = await fs.readFile(indexPath, 'utf-8');
|
|
39
|
+
const index = JSON.parse(indexData);
|
|
40
|
+
// Add conversations from index
|
|
41
|
+
for (const [conversationId, entry] of Object.entries(index)) {
|
|
42
|
+
const conv = {
|
|
43
|
+
id: conversationId,
|
|
44
|
+
provider: providerName,
|
|
45
|
+
...entry,
|
|
46
|
+
};
|
|
47
|
+
// Apply date filters
|
|
48
|
+
if (since && new Date(conv.updatedAt) < new Date(since)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (until && new Date(conv.updatedAt) > new Date(until)) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
allConversations.push(conv);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Sort conversations
|
|
58
|
+
allConversations.sort((a, b) => {
|
|
59
|
+
const aVal = a[sortBy];
|
|
60
|
+
const bVal = b[sortBy];
|
|
61
|
+
const order = sortOrder === 'asc' ? 1 : -1;
|
|
62
|
+
if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
63
|
+
return aVal.localeCompare(bVal) * order;
|
|
64
|
+
}
|
|
65
|
+
return ((aVal > bVal ? 1 : -1) * order);
|
|
66
|
+
});
|
|
67
|
+
// Apply pagination
|
|
68
|
+
const total = allConversations.length;
|
|
69
|
+
const limitNum = parseInt(limit);
|
|
70
|
+
const offsetNum = parseInt(offset);
|
|
71
|
+
const conversations = allConversations.slice(offsetNum, offsetNum + limitNum);
|
|
72
|
+
res.json({
|
|
73
|
+
conversations,
|
|
74
|
+
pagination: {
|
|
75
|
+
total,
|
|
76
|
+
limit: limitNum,
|
|
77
|
+
offset: offsetNum,
|
|
78
|
+
hasMore: offsetNum + limitNum < total,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw createError('Failed to list conversations', 500, error);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
/**
|
|
87
|
+
* GET /api/conversations/:provider/:id
|
|
88
|
+
* Get detailed conversation by ID
|
|
89
|
+
*/
|
|
90
|
+
router.get('/:provider/:id', async (req, res) => {
|
|
91
|
+
try {
|
|
92
|
+
const { provider, id } = req.params;
|
|
93
|
+
const config = await loadConfig();
|
|
94
|
+
const storageConfig = getDefaultStorageConfig();
|
|
95
|
+
if (config.settings?.archiveDir) {
|
|
96
|
+
storageConfig.baseDir = config.settings.archiveDir;
|
|
97
|
+
}
|
|
98
|
+
// Find conversation file
|
|
99
|
+
const providerPath = path.join(storageConfig.baseDir, provider);
|
|
100
|
+
if (!existsSync(providerPath)) {
|
|
101
|
+
throw createError(`Provider ${provider} not found`, 404);
|
|
102
|
+
}
|
|
103
|
+
// Load index to find conversation location
|
|
104
|
+
const indexPath = path.join(providerPath, 'index.json');
|
|
105
|
+
if (!existsSync(indexPath)) {
|
|
106
|
+
throw createError('No conversations found', 404);
|
|
107
|
+
}
|
|
108
|
+
const indexData = await fs.readFile(indexPath, 'utf-8');
|
|
109
|
+
const index = JSON.parse(indexData);
|
|
110
|
+
const entry = index[id];
|
|
111
|
+
if (!entry) {
|
|
112
|
+
throw createError(`Conversation ${id} not found`, 404);
|
|
113
|
+
}
|
|
114
|
+
// Load conversation data
|
|
115
|
+
const conversationPath = path.join(providerPath, entry.filePath);
|
|
116
|
+
if (!existsSync(conversationPath)) {
|
|
117
|
+
throw createError(`Conversation file not found`, 404);
|
|
118
|
+
}
|
|
119
|
+
const conversationData = await fs.readFile(conversationPath, 'utf-8');
|
|
120
|
+
const conversation = JSON.parse(conversationData);
|
|
121
|
+
// Load markdown if available
|
|
122
|
+
const markdownPath = conversationPath.replace('.json', '.md');
|
|
123
|
+
let markdown;
|
|
124
|
+
if (existsSync(markdownPath)) {
|
|
125
|
+
markdown = await fs.readFile(markdownPath, 'utf-8');
|
|
126
|
+
}
|
|
127
|
+
res.json({
|
|
128
|
+
conversation,
|
|
129
|
+
markdown,
|
|
130
|
+
metadata: entry,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (isApiError(error)) {
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
throw createError('Failed to get conversation', 500, error);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
/**
|
|
141
|
+
* GET /api/conversations/stats
|
|
142
|
+
* Get conversation statistics
|
|
143
|
+
*/
|
|
144
|
+
router.get('/stats', async (_req, res) => {
|
|
145
|
+
try {
|
|
146
|
+
const config = await loadConfig();
|
|
147
|
+
const storageConfig = getDefaultStorageConfig();
|
|
148
|
+
if (config.settings?.archiveDir) {
|
|
149
|
+
storageConfig.baseDir = config.settings.archiveDir;
|
|
150
|
+
}
|
|
151
|
+
const stats = {
|
|
152
|
+
totalConversations: 0,
|
|
153
|
+
byProvider: {},
|
|
154
|
+
totalMessages: 0,
|
|
155
|
+
totalMedia: 0,
|
|
156
|
+
storageUsed: 0,
|
|
157
|
+
};
|
|
158
|
+
const providers = Object.keys(config.providers || {});
|
|
159
|
+
for (const provider of providers) {
|
|
160
|
+
const providerPath = path.join(storageConfig.baseDir, provider);
|
|
161
|
+
if (!existsSync(providerPath)) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const indexPath = path.join(providerPath, 'index.json');
|
|
165
|
+
if (!existsSync(indexPath)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const indexData = await fs.readFile(indexPath, 'utf-8');
|
|
169
|
+
const index = JSON.parse(indexData);
|
|
170
|
+
const providerConvCount = Object.keys(index).length;
|
|
171
|
+
stats.totalConversations += providerConvCount;
|
|
172
|
+
stats.byProvider[provider] = {
|
|
173
|
+
conversations: providerConvCount,
|
|
174
|
+
messages: 0,
|
|
175
|
+
};
|
|
176
|
+
// Count messages
|
|
177
|
+
for (const entry of Object.values(index)) {
|
|
178
|
+
if (entry.messageCount) {
|
|
179
|
+
stats.totalMessages += entry.messageCount;
|
|
180
|
+
stats.byProvider[provider].messages += entry.messageCount;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
res.json(stats);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
throw createError('Failed to get conversation stats', 500, error);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
export function createConversationsRouter() {
|
|
191
|
+
return router;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=conversations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversations.js","sourceRoot":"","sources":["../../../src/api/routes/conversations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../src/api/routes/media.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAkL9D,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
|