@m6d/cortex-server 1.1.1 → 1.2.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 +38 -38
- package/dist/src/ai/interceptors/{resolve-captured-files.d.ts → request-interceptor.d.ts} +3 -2
- package/dist/src/config.d.ts +6 -3
- package/dist/src/factory.d.ts +13 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/ws/index.d.ts +1 -1
- package/package.json +54 -54
- package/src/adapters/database.ts +21 -28
- package/src/adapters/minio.ts +69 -69
- package/src/adapters/mssql.ts +167 -195
- package/src/adapters/storage.ts +4 -4
- package/src/ai/fetch.ts +31 -31
- package/src/ai/helpers.ts +18 -22
- package/src/ai/index.ts +106 -114
- package/src/ai/interceptors/request-interceptor.ts +61 -0
- package/src/ai/prompt.ts +80 -83
- package/src/ai/tools/call-endpoint.tool.ts +75 -82
- package/src/ai/tools/capture-files.tool.ts +15 -17
- package/src/ai/tools/execute-code.tool.ts +73 -80
- package/src/ai/tools/query-graph.tool.ts +17 -17
- package/src/auth/middleware.ts +51 -51
- package/src/cli/extract-endpoints.ts +436 -474
- package/src/config.ts +128 -135
- package/src/db/migrate.ts +13 -13
- package/src/db/migrations/20260309012148_cloudy_maria_hill/snapshot.json +303 -303
- package/src/db/schema.ts +46 -58
- package/src/factory.ts +136 -139
- package/src/graph/generate-cypher.ts +97 -97
- package/src/graph/helpers.ts +37 -37
- package/src/graph/index.ts +20 -20
- package/src/graph/neo4j.ts +82 -89
- package/src/graph/resolver.ts +201 -211
- package/src/graph/seed.ts +101 -114
- package/src/graph/types.ts +88 -88
- package/src/graph/validate.ts +55 -57
- package/src/index.ts +12 -5
- package/src/routes/chat.ts +23 -23
- package/src/routes/files.ts +75 -80
- package/src/routes/threads.ts +52 -54
- package/src/routes/ws.ts +22 -22
- package/src/types.ts +30 -30
- package/src/ws/connections.ts +11 -11
- package/src/ws/events.ts +2 -2
- package/src/ws/index.ts +1 -5
- package/src/ws/notify.ts +4 -4
- package/src/ai/interceptors/resolve-captured-files.ts +0 -64
package/README.md
CHANGED
|
@@ -8,50 +8,50 @@ Multi-agent AI chat server built on Hono + Bun. Supports MSSQL persistence, MinI
|
|
|
8
8
|
import { createCortex } from "@m6d/cortex-server";
|
|
9
9
|
|
|
10
10
|
const cortex = createCortex({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
11
|
+
database: {
|
|
12
|
+
type: "mssql",
|
|
13
|
+
connectionString: process.env.DB_CONNECTION_STRING!,
|
|
14
|
+
},
|
|
15
|
+
storage: {
|
|
16
|
+
endPoint: "localhost",
|
|
17
|
+
port: 9000,
|
|
18
|
+
useSSL: false,
|
|
19
|
+
accessKey: "minioadmin",
|
|
20
|
+
secretKey: "minioadmin",
|
|
21
|
+
},
|
|
22
|
+
auth: {
|
|
23
|
+
jwksUri: "https://your-auth-provider/.well-known/jwks.json",
|
|
24
|
+
issuer: "https://your-auth-provider/",
|
|
25
|
+
},
|
|
26
|
+
model: {
|
|
27
|
+
baseURL: "https://api.openai.com/v1",
|
|
28
|
+
apiKey: process.env.MODEL_KEY!,
|
|
29
|
+
modelName: "gpt-4o",
|
|
30
|
+
},
|
|
31
|
+
embedding: {
|
|
32
|
+
baseURL: "https://api.openai.com/v1",
|
|
33
|
+
apiKey: process.env.EMBEDDING_KEY!,
|
|
34
|
+
modelName: "text-embedding-3-small",
|
|
35
|
+
dimension: 1536,
|
|
36
|
+
},
|
|
37
|
+
neo4j: {
|
|
38
|
+
url: "bolt://localhost:7687",
|
|
39
|
+
user: "neo4j",
|
|
40
|
+
password: "password",
|
|
41
|
+
},
|
|
42
|
+
agents: {
|
|
43
|
+
assistant: {
|
|
44
|
+
systemPrompt: "You are a helpful assistant.",
|
|
45
|
+
tools: {},
|
|
46
|
+
},
|
|
46
47
|
},
|
|
47
|
-
},
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
const server = await cortex.serve();
|
|
51
51
|
|
|
52
52
|
export default {
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
fetch: server.fetch,
|
|
54
|
+
websocket: server.websocket,
|
|
55
55
|
};
|
|
56
56
|
```
|
|
57
57
|
|
|
@@ -4,8 +4,9 @@ export type ResolvedFile = {
|
|
|
4
4
|
name: string;
|
|
5
5
|
bytes: string;
|
|
6
6
|
};
|
|
7
|
-
export
|
|
7
|
+
export type RequestInterceptorOptions = {
|
|
8
8
|
transformFile?: (file: ResolvedFile) => unknown;
|
|
9
|
-
}
|
|
9
|
+
};
|
|
10
|
+
export declare function createRequestInterceptor(db: DatabaseAdapter, storage: StorageAdapter, options?: RequestInterceptorOptions): (body: Record<string, unknown>, context: {
|
|
10
11
|
token: string;
|
|
11
12
|
}) => Promise<Record<string, unknown>>;
|
package/dist/src/config.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { UIMessage } from "ai";
|
|
1
|
+
import type { ToolSet, UIMessage } from "ai";
|
|
2
2
|
import type { DatabaseAdapter } from "./adapters/database";
|
|
3
3
|
import type { StorageAdapter } from "./adapters/storage";
|
|
4
4
|
import type { DomainDef } from "./graph/types.ts";
|
|
5
|
+
import type { RequestInterceptorOptions } from "./ai/interceptors/request-interceptor.ts";
|
|
5
6
|
export type KnowledgeConfig = {
|
|
6
7
|
swagger?: {
|
|
7
8
|
url: string;
|
|
@@ -22,7 +23,7 @@ export type StorageConfig = {
|
|
|
22
23
|
};
|
|
23
24
|
export type CortexAgentDefinition = {
|
|
24
25
|
systemPrompt: string | ((session: Record<string, unknown> | null) => string | Promise<string>);
|
|
25
|
-
tools?:
|
|
26
|
+
tools?: ToolSet;
|
|
26
27
|
backendFetch?: {
|
|
27
28
|
baseUrl: string;
|
|
28
29
|
apiKey: string;
|
|
@@ -30,6 +31,7 @@ export type CortexAgentDefinition = {
|
|
|
30
31
|
transformRequestBody?: (body: Record<string, unknown>, context: {
|
|
31
32
|
token: string;
|
|
32
33
|
}) => Promise<Record<string, unknown>>;
|
|
34
|
+
interceptor?: RequestInterceptorOptions;
|
|
33
35
|
};
|
|
34
36
|
loadSessionData?: (token: string) => Promise<Record<string, unknown>>;
|
|
35
37
|
onToolCall?: (toolCall: {
|
|
@@ -89,7 +91,7 @@ export type ResolvedCortexAgentConfig = {
|
|
|
89
91
|
apiKey: string;
|
|
90
92
|
};
|
|
91
93
|
systemPrompt: string | ((session: Record<string, unknown> | null) => string | Promise<string>);
|
|
92
|
-
tools?:
|
|
94
|
+
tools?: ToolSet;
|
|
93
95
|
backendFetch?: {
|
|
94
96
|
baseUrl: string;
|
|
95
97
|
apiKey: string;
|
|
@@ -97,6 +99,7 @@ export type ResolvedCortexAgentConfig = {
|
|
|
97
99
|
transformRequestBody?: (body: Record<string, unknown>, context: {
|
|
98
100
|
token: string;
|
|
99
101
|
}) => Promise<Record<string, unknown>>;
|
|
102
|
+
interceptor?: RequestInterceptorOptions;
|
|
100
103
|
};
|
|
101
104
|
loadSessionData?: (token: string) => Promise<Record<string, unknown>>;
|
|
102
105
|
onToolCall?: (toolCall: {
|
package/dist/src/factory.d.ts
CHANGED
|
@@ -15,4 +15,16 @@ export type CortexInstance = {
|
|
|
15
15
|
write?: boolean;
|
|
16
16
|
}): Promise<void>;
|
|
17
17
|
};
|
|
18
|
-
export declare function createCortex(config: CortexConfig):
|
|
18
|
+
export declare function createCortex(config: CortexConfig): {
|
|
19
|
+
serve(): Promise<{
|
|
20
|
+
app: Hono<AppEnv, import("hono/types").BlankSchema, "/">;
|
|
21
|
+
port: number;
|
|
22
|
+
fetch: (request: Request, Env?: {} | undefined, executionCtx?: import("hono").ExecutionContext) => Response | Promise<Response>;
|
|
23
|
+
websocket: import("hono/bun").BunWebSocketHandler<import("hono/bun").BunWebSocketData>;
|
|
24
|
+
}>;
|
|
25
|
+
seedGraph(): Promise<void>;
|
|
26
|
+
extractEndpoints(options: {
|
|
27
|
+
domainsDir: string;
|
|
28
|
+
write?: boolean;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export type { CortexConfig, CortexAgentDefinition, KnowledgeConfig, DatabaseConf
|
|
|
2
2
|
export type { Thread, AppEnv } from "./types";
|
|
3
3
|
export type { CortexInstance } from "./factory";
|
|
4
4
|
export { createCortex } from "./factory";
|
|
5
|
+
export type { ResolvedFile, RequestInterceptorOptions, } from "./ai/interceptors/request-interceptor";
|
|
6
|
+
export { createRequestInterceptor } from "./ai/interceptors/request-interceptor";
|
|
5
7
|
export { captureFilesTool } from "./ai/tools/capture-files.tool";
|
|
6
8
|
export { createQueryGraphTool } from "./ai/tools/query-graph.tool";
|
|
7
9
|
export { createCallEndpointTool } from "./ai/tools/call-endpoint.tool";
|
package/dist/src/ws/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { addConnection, removeConnection, getConnections
|
|
1
|
+
export { addConnection, removeConnection, getConnections } from "./connections.ts";
|
|
2
2
|
export { notify } from "./notify.ts";
|
|
3
3
|
export type { WsEvent, ThreadTitleUpdatedEvent } from "./events.ts";
|
package/package.json
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
"name": "@m6d/cortex-server",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Reusable AI agent chat server library for Hono + Bun",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"bun": "./index.ts",
|
|
11
|
+
"default": "./index.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"main": "./index.ts",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src",
|
|
19
|
+
"index.ts",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc -p tsconfig.build.json",
|
|
24
|
+
"db:generate": "drizzle-kit generate",
|
|
25
|
+
"db:migrate": "drizzle-kit migrate"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@ai-sdk/provider": "^3.0.0",
|
|
29
|
+
"@hono/zod-validator": "^0.5.0",
|
|
30
|
+
"drizzle-orm": "^1.0.0-beta.15-859cf75",
|
|
31
|
+
"minio": "^8.0.7",
|
|
32
|
+
"mssql": "^12.2.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@ai-sdk/openai-compatible": "^2.0.0",
|
|
36
|
+
"@types/bun": "latest",
|
|
37
|
+
"@types/minio": "^7.1.1",
|
|
38
|
+
"@types/mssql": "^9.1.5",
|
|
39
|
+
"ai": "^6.0.104",
|
|
40
|
+
"drizzle-kit": "^1.0.0-beta.15-859cf75",
|
|
41
|
+
"hono": "^4.12.3",
|
|
42
|
+
"typescript": "^5"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@ai-sdk/openai-compatible": "^2.0.0",
|
|
46
|
+
"ai": "^6.0.0",
|
|
47
|
+
"hono": "^4.12.3",
|
|
48
|
+
"jose": "^6.1.3",
|
|
49
|
+
"zod": "^3.24.0"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"bun": ">=1.0.0"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public"
|
|
12
56
|
}
|
|
13
|
-
},
|
|
14
|
-
"main": "./index.ts",
|
|
15
|
-
"types": "./dist/index.d.ts",
|
|
16
|
-
"files": [
|
|
17
|
-
"dist",
|
|
18
|
-
"src",
|
|
19
|
-
"index.ts",
|
|
20
|
-
"README.md"
|
|
21
|
-
],
|
|
22
|
-
"scripts": {
|
|
23
|
-
"build": "tsc -p tsconfig.build.json",
|
|
24
|
-
"db:generate": "drizzle-kit generate",
|
|
25
|
-
"db:migrate": "drizzle-kit migrate"
|
|
26
|
-
},
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"@ai-sdk/provider": "^3.0.0",
|
|
29
|
-
"@hono/zod-validator": "^0.5.0",
|
|
30
|
-
"drizzle-orm": "^1.0.0-beta.15-859cf75",
|
|
31
|
-
"minio": "^8.0.7",
|
|
32
|
-
"mssql": "^12.2.0"
|
|
33
|
-
},
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"@ai-sdk/openai-compatible": "^2.0.0",
|
|
36
|
-
"@types/bun": "latest",
|
|
37
|
-
"@types/minio": "^7.1.1",
|
|
38
|
-
"@types/mssql": "^9.1.5",
|
|
39
|
-
"ai": "^6.0.104",
|
|
40
|
-
"drizzle-kit": "^1.0.0-beta.15-859cf75",
|
|
41
|
-
"hono": "^4.12.3",
|
|
42
|
-
"typescript": "^5"
|
|
43
|
-
},
|
|
44
|
-
"peerDependencies": {
|
|
45
|
-
"@ai-sdk/openai-compatible": "^2.0.0",
|
|
46
|
-
"ai": "^6.0.0",
|
|
47
|
-
"hono": "^4.12.3",
|
|
48
|
-
"jose": "^6.1.3",
|
|
49
|
-
"zod": "^3.24.0"
|
|
50
|
-
},
|
|
51
|
-
"engines": {
|
|
52
|
-
"bun": ">=1.0.0"
|
|
53
|
-
},
|
|
54
|
-
"publishConfig": {
|
|
55
|
-
"access": "public"
|
|
56
|
-
}
|
|
57
57
|
}
|
package/src/adapters/database.ts
CHANGED
|
@@ -2,32 +2,25 @@ import type { ToolUIPart, UIMessage } from "ai";
|
|
|
2
2
|
import type { Thread, StoredMessage, CapturedFileInput } from "../types";
|
|
3
3
|
|
|
4
4
|
export type DatabaseAdapter = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
userId: string,
|
|
27
|
-
messageId: string,
|
|
28
|
-
toolPart: ToolUIPart,
|
|
29
|
-
files: CapturedFileInput[],
|
|
30
|
-
): Promise<{ id: string; uploadId: string }[]>;
|
|
31
|
-
getById(id: string, userId: string): Promise<{ name: string } | null>;
|
|
32
|
-
};
|
|
5
|
+
threads: {
|
|
6
|
+
list(userId: string, agentId: string): Promise<Thread[]>;
|
|
7
|
+
getById(userId: string, threadId: string): Promise<Thread | null>;
|
|
8
|
+
create(userId: string, agentId: string): Promise<Thread>;
|
|
9
|
+
delete(userId: string, threadId: string): Promise<void>;
|
|
10
|
+
updateTitle(threadId: string, title: string): Promise<void>;
|
|
11
|
+
updateSession(threadId: string, session: Record<string, unknown>): Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
messages: {
|
|
14
|
+
list(userId: string, threadId: string, opts?: { limit?: number }): Promise<StoredMessage[]>;
|
|
15
|
+
upsert(threadId: string, messages: UIMessage[]): Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
capturedFiles: {
|
|
18
|
+
create(
|
|
19
|
+
userId: string,
|
|
20
|
+
messageId: string,
|
|
21
|
+
toolPart: ToolUIPart,
|
|
22
|
+
files: CapturedFileInput[],
|
|
23
|
+
): Promise<{ id: string; uploadId: string }[]>;
|
|
24
|
+
getById(id: string, userId: string): Promise<{ name: string } | null>;
|
|
25
|
+
};
|
|
33
26
|
};
|
package/src/adapters/minio.ts
CHANGED
|
@@ -3,87 +3,87 @@ import { Readable } from "node:stream";
|
|
|
3
3
|
import type { StorageAdapter } from "./storage";
|
|
4
4
|
|
|
5
5
|
export type MinioConfig = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
endPoint: string;
|
|
7
|
+
port: number;
|
|
8
|
+
useSSL: boolean;
|
|
9
|
+
accessKey: string;
|
|
10
|
+
secretKey: string;
|
|
11
|
+
bucketName?: string;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
export function createMinioAdapter(config: MinioConfig) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
if (!config.endPoint) {
|
|
16
|
+
throw new Error("MinIO adapter: endPoint is required");
|
|
17
|
+
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
const client = new Minio.Client({
|
|
20
|
+
endPoint: config.endPoint,
|
|
21
|
+
port: config.port,
|
|
22
|
+
useSSL: config.useSSL,
|
|
23
|
+
accessKey: config.accessKey,
|
|
24
|
+
secretKey: config.secretKey,
|
|
25
|
+
});
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const bucketName = config.bucketName ?? "ai-storage";
|
|
28
|
+
let bucketReady = false;
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
async function ensureBucket() {
|
|
31
|
+
if (bucketReady) return;
|
|
32
|
+
if (!(await client.bucketExists(bucketName))) {
|
|
33
|
+
await client.makeBucket(bucketName);
|
|
34
|
+
}
|
|
35
|
+
bucketReady = true;
|
|
34
36
|
}
|
|
35
|
-
bucketReady = true;
|
|
36
|
-
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
const adapter: StorageAdapter = {
|
|
39
|
+
async put(path: string, data: string) {
|
|
40
|
+
try {
|
|
41
|
+
await ensureBucket();
|
|
42
|
+
await client.putObject(bucketName, path, Buffer.from(data, "base64"));
|
|
43
|
+
return true;
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
async get(path: string) {
|
|
50
|
+
try {
|
|
51
|
+
const stream = await client.getObject(bucketName, path);
|
|
52
|
+
return await new Promise<string>((resolve, reject) => {
|
|
53
|
+
const chunks: Uint8Array[] = [];
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
stream.on("error", () => {
|
|
56
|
+
reject();
|
|
57
|
+
});
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
stream.on("data", (chunk) => chunks.push(chunk));
|
|
60
|
+
stream.on("end", () => {
|
|
61
|
+
const buffer = Buffer.concat(chunks);
|
|
62
|
+
resolve(buffer.toString("base64"));
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
70
|
+
async delete(paths: string[]) {
|
|
71
|
+
try {
|
|
72
|
+
await client.removeObjects(
|
|
73
|
+
bucketName,
|
|
74
|
+
paths.map((x) => ({ name: x })),
|
|
75
|
+
);
|
|
76
|
+
return true;
|
|
77
|
+
} catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
async stream(path: string) {
|
|
83
|
+
const nodeStream = await client.getObject(bucketName, path);
|
|
84
|
+
return Readable.toWeb(nodeStream) as unknown as ReadableStream;
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
return adapter;
|
|
89
89
|
}
|