@dexto/tools-filesystem 1.6.21 → 1.6.22
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/filesystem-service.cjs +62 -1
- package/dist/filesystem-service.d.ts +5 -1
- package/dist/filesystem-service.d.ts.map +1 -1
- package/dist/filesystem-service.js +62 -1
- package/dist/filesystem-service.test.cjs +123 -7
- package/dist/filesystem-service.test.js +123 -7
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +33 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/mime-utils.cjs +170 -0
- package/dist/mime-utils.d.ts +6 -0
- package/dist/mime-utils.d.ts.map +1 -0
- package/dist/mime-utils.js +133 -0
- package/dist/read-file-tool.cjs +1 -1
- package/dist/read-file-tool.js +1 -1
- package/dist/read-media-file-tool.cjs +87 -0
- package/dist/read-media-file-tool.d.ts +18 -0
- package/dist/read-media-file-tool.d.ts.map +1 -0
- package/dist/read-media-file-tool.js +63 -0
- package/dist/read-media-file-tool.test.cjs +150 -0
- package/dist/read-media-file-tool.test.d.ts +2 -0
- package/dist/read-media-file-tool.test.d.ts.map +1 -0
- package/dist/read-media-file-tool.test.js +127 -0
- package/dist/tool-factory-config.cjs +1 -0
- package/dist/tool-factory-config.d.ts +4 -4
- package/dist/tool-factory-config.d.ts.map +1 -1
- package/dist/tool-factory-config.js +1 -0
- package/dist/tool-factory.cjs +3 -1
- package/dist/tool-factory.d.ts.map +1 -1
- package/dist/tool-factory.js +3 -1
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -38,6 +38,7 @@ var import_safe_regex = __toESM(require("safe-regex"), 1);
|
|
|
38
38
|
var import_core = require("@dexto/core");
|
|
39
39
|
var import_path_validator = require("./path-validator.js");
|
|
40
40
|
var import_errors = require("./errors.js");
|
|
41
|
+
var import_mime_utils = require("./mime-utils.js");
|
|
41
42
|
const DEFAULT_ENCODING = "utf-8";
|
|
42
43
|
const DEFAULT_MAX_RESULTS = 1e3;
|
|
43
44
|
const DEFAULT_MAX_SEARCH_RESULTS = 100;
|
|
@@ -195,7 +196,17 @@ class FileSystemService {
|
|
|
195
196
|
}
|
|
196
197
|
try {
|
|
197
198
|
const encoding = options.encoding || DEFAULT_ENCODING;
|
|
198
|
-
const
|
|
199
|
+
const rawContent = await fs.readFile(normalizedPath);
|
|
200
|
+
const mimeType = (0, import_mime_utils.detectMimeType)(normalizedPath, rawContent);
|
|
201
|
+
const binaryLike = (0, import_mime_utils.isLikelyBinary)(rawContent);
|
|
202
|
+
const canReadAsText = !binaryLike && ((0, import_mime_utils.isTextMimeType)(mimeType) || mimeType === "image/svg+xml");
|
|
203
|
+
if (!canReadAsText) {
|
|
204
|
+
throw import_errors.FileSystemError.readFailed(
|
|
205
|
+
normalizedPath,
|
|
206
|
+
`File is binary (${mimeType}). Use read_media_file instead.`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
const content = rawContent.toString(encoding);
|
|
199
210
|
const lines = content.split("\n");
|
|
200
211
|
const limit = options.limit;
|
|
201
212
|
const offset1 = options.offset;
|
|
@@ -214,6 +225,7 @@ class FileSystemService {
|
|
|
214
225
|
content: returnedContent,
|
|
215
226
|
lines: selectedLines.length,
|
|
216
227
|
encoding,
|
|
228
|
+
mimeType,
|
|
217
229
|
truncated,
|
|
218
230
|
size: Buffer.byteLength(returnedContent, encoding)
|
|
219
231
|
};
|
|
@@ -235,6 +247,55 @@ class FileSystemService {
|
|
|
235
247
|
const normalizedPath = await this.validateReadPath(filePath, "execute");
|
|
236
248
|
return await this.readNormalizedFile(normalizedPath, options);
|
|
237
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Read a media or binary file and return base64-encoded data with MIME metadata.
|
|
252
|
+
*/
|
|
253
|
+
async readMediaFile(filePath) {
|
|
254
|
+
await this.ensureInitialized();
|
|
255
|
+
const normalizedPath = await this.validateReadPath(filePath, "execute");
|
|
256
|
+
try {
|
|
257
|
+
const stats = await fs.stat(normalizedPath);
|
|
258
|
+
if (!stats.isFile()) {
|
|
259
|
+
throw import_errors.FileSystemError.invalidPath(normalizedPath, "Path is not a file");
|
|
260
|
+
}
|
|
261
|
+
if (stats.size > this.config.maxFileSize) {
|
|
262
|
+
throw import_errors.FileSystemError.fileTooLarge(
|
|
263
|
+
normalizedPath,
|
|
264
|
+
stats.size,
|
|
265
|
+
this.config.maxFileSize
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
const rawContent = await fs.readFile(normalizedPath);
|
|
269
|
+
const mimeType = (0, import_mime_utils.detectMimeType)(normalizedPath, rawContent);
|
|
270
|
+
if ((0, import_mime_utils.isTextMimeType)(mimeType) && !(0, import_mime_utils.isLikelyBinary)(rawContent)) {
|
|
271
|
+
throw import_errors.FileSystemError.readFailed(
|
|
272
|
+
normalizedPath,
|
|
273
|
+
`File is text (${mimeType}). Use read_file instead.`
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
data: rawContent.toString("base64"),
|
|
278
|
+
mimeType,
|
|
279
|
+
filename: path.basename(normalizedPath),
|
|
280
|
+
kind: (0, import_mime_utils.getMediaFileKind)(mimeType),
|
|
281
|
+
size: stats.size
|
|
282
|
+
};
|
|
283
|
+
} catch (error) {
|
|
284
|
+
if (error instanceof import_core.DextoRuntimeError && error.scope === "filesystem") {
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
287
|
+
if (error.code === "ENOENT") {
|
|
288
|
+
throw import_errors.FileSystemError.fileNotFound(normalizedPath);
|
|
289
|
+
}
|
|
290
|
+
if (error.code === "EACCES") {
|
|
291
|
+
throw import_errors.FileSystemError.permissionDenied(normalizedPath, "read");
|
|
292
|
+
}
|
|
293
|
+
throw import_errors.FileSystemError.readFailed(
|
|
294
|
+
normalizedPath,
|
|
295
|
+
error instanceof Error ? error.message : String(error)
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
238
299
|
/**
|
|
239
300
|
* Preview-only file read that bypasses config-allowed roots.
|
|
240
301
|
*
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Secure file system operations for Dexto internal tools
|
|
5
5
|
*/
|
|
6
6
|
import { Logger } from '@dexto/core';
|
|
7
|
-
import { FileSystemConfig, FileContent, ReadFileOptions, GlobOptions, GlobResult, GrepOptions, SearchResult, WriteFileOptions, WriteResult, EditFileOptions, EditResult, EditOperation, ListDirectoryOptions, ListDirectoryResult, CreateDirectoryOptions, CreateDirectoryResult, DeletePathOptions, DeletePathResult, RenamePathResult } from './types.js';
|
|
7
|
+
import { FileSystemConfig, FileContent, MediaFileContent, ReadFileOptions, GlobOptions, GlobResult, GrepOptions, SearchResult, WriteFileOptions, WriteResult, EditFileOptions, EditResult, EditOperation, ListDirectoryOptions, ListDirectoryResult, CreateDirectoryOptions, CreateDirectoryResult, DeletePathOptions, DeletePathResult, RenamePathResult } from './types.js';
|
|
8
8
|
/**
|
|
9
9
|
* FileSystemService - Handles all file system operations with security checks
|
|
10
10
|
*
|
|
@@ -80,6 +80,10 @@ export declare class FileSystemService {
|
|
|
80
80
|
* Read a file with validation and size limits
|
|
81
81
|
*/
|
|
82
82
|
readFile(filePath: string, options?: ReadFileOptions): Promise<FileContent>;
|
|
83
|
+
/**
|
|
84
|
+
* Read a media or binary file and return base64-encoded data with MIME metadata.
|
|
85
|
+
*/
|
|
86
|
+
readMediaFile(filePath: string): Promise<MediaFileContent>;
|
|
83
87
|
/**
|
|
84
88
|
* Preview-only file read that bypasses config-allowed roots.
|
|
85
89
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem-service.d.ts","sourceRoot":"","sources":["../src/filesystem-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAmC,MAAM,EAAqB,MAAM,aAAa,CAAC;AACzF,OAAO,EACH,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EAEZ,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,UAAU,EACV,aAAa,EAGb,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAEnB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"filesystem-service.d.ts","sourceRoot":"","sources":["../src/filesystem-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import safeRegex from "safe-regex";
|
|
|
5
5
|
import { DextoRuntimeError, getDextoPath, DextoLogComponent } from "@dexto/core";
|
|
6
6
|
import { PathValidator } from "./path-validator.js";
|
|
7
7
|
import { FileSystemError } from "./errors.js";
|
|
8
|
+
import { detectMimeType, getMediaFileKind, isLikelyBinary, isTextMimeType } from "./mime-utils.js";
|
|
8
9
|
const DEFAULT_ENCODING = "utf-8";
|
|
9
10
|
const DEFAULT_MAX_RESULTS = 1e3;
|
|
10
11
|
const DEFAULT_MAX_SEARCH_RESULTS = 100;
|
|
@@ -162,7 +163,17 @@ class FileSystemService {
|
|
|
162
163
|
}
|
|
163
164
|
try {
|
|
164
165
|
const encoding = options.encoding || DEFAULT_ENCODING;
|
|
165
|
-
const
|
|
166
|
+
const rawContent = await fs.readFile(normalizedPath);
|
|
167
|
+
const mimeType = detectMimeType(normalizedPath, rawContent);
|
|
168
|
+
const binaryLike = isLikelyBinary(rawContent);
|
|
169
|
+
const canReadAsText = !binaryLike && (isTextMimeType(mimeType) || mimeType === "image/svg+xml");
|
|
170
|
+
if (!canReadAsText) {
|
|
171
|
+
throw FileSystemError.readFailed(
|
|
172
|
+
normalizedPath,
|
|
173
|
+
`File is binary (${mimeType}). Use read_media_file instead.`
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
const content = rawContent.toString(encoding);
|
|
166
177
|
const lines = content.split("\n");
|
|
167
178
|
const limit = options.limit;
|
|
168
179
|
const offset1 = options.offset;
|
|
@@ -181,6 +192,7 @@ class FileSystemService {
|
|
|
181
192
|
content: returnedContent,
|
|
182
193
|
lines: selectedLines.length,
|
|
183
194
|
encoding,
|
|
195
|
+
mimeType,
|
|
184
196
|
truncated,
|
|
185
197
|
size: Buffer.byteLength(returnedContent, encoding)
|
|
186
198
|
};
|
|
@@ -202,6 +214,55 @@ class FileSystemService {
|
|
|
202
214
|
const normalizedPath = await this.validateReadPath(filePath, "execute");
|
|
203
215
|
return await this.readNormalizedFile(normalizedPath, options);
|
|
204
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Read a media or binary file and return base64-encoded data with MIME metadata.
|
|
219
|
+
*/
|
|
220
|
+
async readMediaFile(filePath) {
|
|
221
|
+
await this.ensureInitialized();
|
|
222
|
+
const normalizedPath = await this.validateReadPath(filePath, "execute");
|
|
223
|
+
try {
|
|
224
|
+
const stats = await fs.stat(normalizedPath);
|
|
225
|
+
if (!stats.isFile()) {
|
|
226
|
+
throw FileSystemError.invalidPath(normalizedPath, "Path is not a file");
|
|
227
|
+
}
|
|
228
|
+
if (stats.size > this.config.maxFileSize) {
|
|
229
|
+
throw FileSystemError.fileTooLarge(
|
|
230
|
+
normalizedPath,
|
|
231
|
+
stats.size,
|
|
232
|
+
this.config.maxFileSize
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
const rawContent = await fs.readFile(normalizedPath);
|
|
236
|
+
const mimeType = detectMimeType(normalizedPath, rawContent);
|
|
237
|
+
if (isTextMimeType(mimeType) && !isLikelyBinary(rawContent)) {
|
|
238
|
+
throw FileSystemError.readFailed(
|
|
239
|
+
normalizedPath,
|
|
240
|
+
`File is text (${mimeType}). Use read_file instead.`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
data: rawContent.toString("base64"),
|
|
245
|
+
mimeType,
|
|
246
|
+
filename: path.basename(normalizedPath),
|
|
247
|
+
kind: getMediaFileKind(mimeType),
|
|
248
|
+
size: stats.size
|
|
249
|
+
};
|
|
250
|
+
} catch (error) {
|
|
251
|
+
if (error instanceof DextoRuntimeError && error.scope === "filesystem") {
|
|
252
|
+
throw error;
|
|
253
|
+
}
|
|
254
|
+
if (error.code === "ENOENT") {
|
|
255
|
+
throw FileSystemError.fileNotFound(normalizedPath);
|
|
256
|
+
}
|
|
257
|
+
if (error.code === "EACCES") {
|
|
258
|
+
throw FileSystemError.permissionDenied(normalizedPath, "read");
|
|
259
|
+
}
|
|
260
|
+
throw FileSystemError.readFailed(
|
|
261
|
+
normalizedPath,
|
|
262
|
+
error instanceof Error ? error.message : String(error)
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
205
266
|
/**
|
|
206
267
|
* Preview-only file read that bypasses config-allowed roots.
|
|
207
268
|
*
|
|
@@ -26,13 +26,23 @@ var path = __toESM(require("node:path"), 1);
|
|
|
26
26
|
var fs = __toESM(require("node:fs/promises"), 1);
|
|
27
27
|
var os = __toESM(require("node:os"), 1);
|
|
28
28
|
var import_filesystem_service = require("./filesystem-service.js");
|
|
29
|
-
const createMockLogger = () =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
const createMockLogger = () => {
|
|
30
|
+
const logger = {
|
|
31
|
+
debug: import_vitest.vi.fn(),
|
|
32
|
+
silly: import_vitest.vi.fn(),
|
|
33
|
+
info: import_vitest.vi.fn(),
|
|
34
|
+
warn: import_vitest.vi.fn(),
|
|
35
|
+
error: import_vitest.vi.fn(),
|
|
36
|
+
trackException: import_vitest.vi.fn(),
|
|
37
|
+
createChild: import_vitest.vi.fn(() => logger),
|
|
38
|
+
createFileOnlyChild: import_vitest.vi.fn(() => logger),
|
|
39
|
+
setLevel: import_vitest.vi.fn(),
|
|
40
|
+
getLevel: import_vitest.vi.fn(() => "debug"),
|
|
41
|
+
getLogFilePath: import_vitest.vi.fn(() => null),
|
|
42
|
+
destroy: import_vitest.vi.fn(async () => void 0)
|
|
43
|
+
};
|
|
44
|
+
return logger;
|
|
45
|
+
};
|
|
36
46
|
(0, import_vitest.describe)("FileSystemService", () => {
|
|
37
47
|
let mockLogger;
|
|
38
48
|
let tempDir;
|
|
@@ -50,6 +60,112 @@ const createMockLogger = () => ({
|
|
|
50
60
|
} catch {
|
|
51
61
|
}
|
|
52
62
|
});
|
|
63
|
+
(0, import_vitest.describe)("Read Modes", () => {
|
|
64
|
+
(0, import_vitest.it)("returns MIME metadata for text reads", async () => {
|
|
65
|
+
const fileSystemService = new import_filesystem_service.FileSystemService(
|
|
66
|
+
{
|
|
67
|
+
allowedPaths: [tempDir],
|
|
68
|
+
blockedPaths: [],
|
|
69
|
+
blockedExtensions: [],
|
|
70
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
71
|
+
workingDirectory: tempDir,
|
|
72
|
+
enableBackups: false,
|
|
73
|
+
backupRetentionDays: 7
|
|
74
|
+
},
|
|
75
|
+
mockLogger
|
|
76
|
+
);
|
|
77
|
+
await fileSystemService.initialize();
|
|
78
|
+
const testFile = path.join(tempDir, "notes.md");
|
|
79
|
+
await fs.writeFile(testFile, "# hello\nworld");
|
|
80
|
+
const result = await fileSystemService.readFile(testFile);
|
|
81
|
+
(0, import_vitest.expect)(result.content).toBe("# hello\nworld");
|
|
82
|
+
(0, import_vitest.expect)(result.mimeType).toBe("text/markdown");
|
|
83
|
+
});
|
|
84
|
+
(0, import_vitest.it)("rejects binary files from readFile and points callers to readMediaFile", async () => {
|
|
85
|
+
const fileSystemService = new import_filesystem_service.FileSystemService(
|
|
86
|
+
{
|
|
87
|
+
allowedPaths: [tempDir],
|
|
88
|
+
blockedPaths: [],
|
|
89
|
+
blockedExtensions: [],
|
|
90
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
91
|
+
workingDirectory: tempDir,
|
|
92
|
+
enableBackups: false,
|
|
93
|
+
backupRetentionDays: 7
|
|
94
|
+
},
|
|
95
|
+
mockLogger
|
|
96
|
+
);
|
|
97
|
+
await fileSystemService.initialize();
|
|
98
|
+
const testFile = path.join(tempDir, "image.png");
|
|
99
|
+
await fs.writeFile(testFile, Buffer.from([137, 80, 78, 71, 0, 1]));
|
|
100
|
+
await (0, import_vitest.expect)(fileSystemService.readFile(testFile)).rejects.toThrow(
|
|
101
|
+
/Use read_media_file instead/
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
(0, import_vitest.it)("rejects binary-like content even when the extension looks textual", async () => {
|
|
105
|
+
const fileSystemService = new import_filesystem_service.FileSystemService(
|
|
106
|
+
{
|
|
107
|
+
allowedPaths: [tempDir],
|
|
108
|
+
blockedPaths: [],
|
|
109
|
+
blockedExtensions: [],
|
|
110
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
111
|
+
workingDirectory: tempDir,
|
|
112
|
+
enableBackups: false,
|
|
113
|
+
backupRetentionDays: 7
|
|
114
|
+
},
|
|
115
|
+
mockLogger
|
|
116
|
+
);
|
|
117
|
+
await fileSystemService.initialize();
|
|
118
|
+
const testFile = path.join(tempDir, "data.json");
|
|
119
|
+
await fs.writeFile(testFile, Buffer.from([123, 0, 34, 120, 34, 125]));
|
|
120
|
+
await (0, import_vitest.expect)(fileSystemService.readFile(testFile)).rejects.toThrow(
|
|
121
|
+
/Use read_media_file instead/
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
(0, import_vitest.it)("reads media files as base64 with MIME-aware kind metadata", async () => {
|
|
125
|
+
const fileSystemService = new import_filesystem_service.FileSystemService(
|
|
126
|
+
{
|
|
127
|
+
allowedPaths: [tempDir],
|
|
128
|
+
blockedPaths: [],
|
|
129
|
+
blockedExtensions: [],
|
|
130
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
131
|
+
workingDirectory: tempDir,
|
|
132
|
+
enableBackups: false,
|
|
133
|
+
backupRetentionDays: 7
|
|
134
|
+
},
|
|
135
|
+
mockLogger
|
|
136
|
+
);
|
|
137
|
+
await fileSystemService.initialize();
|
|
138
|
+
const testFile = path.join(tempDir, "clip.mp4");
|
|
139
|
+
const buffer = Buffer.from([0, 0, 0, 24, 102, 116, 121, 112]);
|
|
140
|
+
await fs.writeFile(testFile, buffer);
|
|
141
|
+
const result = await fileSystemService.readMediaFile(testFile);
|
|
142
|
+
(0, import_vitest.expect)(result.data).toBe(buffer.toString("base64"));
|
|
143
|
+
(0, import_vitest.expect)(result.mimeType).toBe("video/mp4");
|
|
144
|
+
(0, import_vitest.expect)(result.kind).toBe("video");
|
|
145
|
+
(0, import_vitest.expect)(result.filename).toBe("clip.mp4");
|
|
146
|
+
(0, import_vitest.expect)(result.size).toBe(buffer.length);
|
|
147
|
+
});
|
|
148
|
+
(0, import_vitest.it)("rejects text files from readMediaFile and points callers to readFile", async () => {
|
|
149
|
+
const fileSystemService = new import_filesystem_service.FileSystemService(
|
|
150
|
+
{
|
|
151
|
+
allowedPaths: [tempDir],
|
|
152
|
+
blockedPaths: [],
|
|
153
|
+
blockedExtensions: [],
|
|
154
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
155
|
+
workingDirectory: tempDir,
|
|
156
|
+
enableBackups: false,
|
|
157
|
+
backupRetentionDays: 7
|
|
158
|
+
},
|
|
159
|
+
mockLogger
|
|
160
|
+
);
|
|
161
|
+
await fileSystemService.initialize();
|
|
162
|
+
const testFile = path.join(tempDir, "plain.txt");
|
|
163
|
+
await fs.writeFile(testFile, "hello world");
|
|
164
|
+
await (0, import_vitest.expect)(fileSystemService.readMediaFile(testFile)).rejects.toThrow(
|
|
165
|
+
/Use read_file instead/
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
53
169
|
(0, import_vitest.describe)("Backup Behavior", () => {
|
|
54
170
|
(0, import_vitest.describe)("writeFile", () => {
|
|
55
171
|
(0, import_vitest.it)("should NOT create backup when enableBackups is false (default)", async () => {
|
|
@@ -3,13 +3,23 @@ import * as path from "node:path";
|
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as os from "node:os";
|
|
5
5
|
import { FileSystemService } from "./filesystem-service.js";
|
|
6
|
-
const createMockLogger = () =>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
const createMockLogger = () => {
|
|
7
|
+
const logger = {
|
|
8
|
+
debug: vi.fn(),
|
|
9
|
+
silly: vi.fn(),
|
|
10
|
+
info: vi.fn(),
|
|
11
|
+
warn: vi.fn(),
|
|
12
|
+
error: vi.fn(),
|
|
13
|
+
trackException: vi.fn(),
|
|
14
|
+
createChild: vi.fn(() => logger),
|
|
15
|
+
createFileOnlyChild: vi.fn(() => logger),
|
|
16
|
+
setLevel: vi.fn(),
|
|
17
|
+
getLevel: vi.fn(() => "debug"),
|
|
18
|
+
getLogFilePath: vi.fn(() => null),
|
|
19
|
+
destroy: vi.fn(async () => void 0)
|
|
20
|
+
};
|
|
21
|
+
return logger;
|
|
22
|
+
};
|
|
13
23
|
describe("FileSystemService", () => {
|
|
14
24
|
let mockLogger;
|
|
15
25
|
let tempDir;
|
|
@@ -27,6 +37,112 @@ describe("FileSystemService", () => {
|
|
|
27
37
|
} catch {
|
|
28
38
|
}
|
|
29
39
|
});
|
|
40
|
+
describe("Read Modes", () => {
|
|
41
|
+
it("returns MIME metadata for text reads", async () => {
|
|
42
|
+
const fileSystemService = new FileSystemService(
|
|
43
|
+
{
|
|
44
|
+
allowedPaths: [tempDir],
|
|
45
|
+
blockedPaths: [],
|
|
46
|
+
blockedExtensions: [],
|
|
47
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
48
|
+
workingDirectory: tempDir,
|
|
49
|
+
enableBackups: false,
|
|
50
|
+
backupRetentionDays: 7
|
|
51
|
+
},
|
|
52
|
+
mockLogger
|
|
53
|
+
);
|
|
54
|
+
await fileSystemService.initialize();
|
|
55
|
+
const testFile = path.join(tempDir, "notes.md");
|
|
56
|
+
await fs.writeFile(testFile, "# hello\nworld");
|
|
57
|
+
const result = await fileSystemService.readFile(testFile);
|
|
58
|
+
expect(result.content).toBe("# hello\nworld");
|
|
59
|
+
expect(result.mimeType).toBe("text/markdown");
|
|
60
|
+
});
|
|
61
|
+
it("rejects binary files from readFile and points callers to readMediaFile", async () => {
|
|
62
|
+
const fileSystemService = new FileSystemService(
|
|
63
|
+
{
|
|
64
|
+
allowedPaths: [tempDir],
|
|
65
|
+
blockedPaths: [],
|
|
66
|
+
blockedExtensions: [],
|
|
67
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
68
|
+
workingDirectory: tempDir,
|
|
69
|
+
enableBackups: false,
|
|
70
|
+
backupRetentionDays: 7
|
|
71
|
+
},
|
|
72
|
+
mockLogger
|
|
73
|
+
);
|
|
74
|
+
await fileSystemService.initialize();
|
|
75
|
+
const testFile = path.join(tempDir, "image.png");
|
|
76
|
+
await fs.writeFile(testFile, Buffer.from([137, 80, 78, 71, 0, 1]));
|
|
77
|
+
await expect(fileSystemService.readFile(testFile)).rejects.toThrow(
|
|
78
|
+
/Use read_media_file instead/
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
it("rejects binary-like content even when the extension looks textual", async () => {
|
|
82
|
+
const fileSystemService = new FileSystemService(
|
|
83
|
+
{
|
|
84
|
+
allowedPaths: [tempDir],
|
|
85
|
+
blockedPaths: [],
|
|
86
|
+
blockedExtensions: [],
|
|
87
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
88
|
+
workingDirectory: tempDir,
|
|
89
|
+
enableBackups: false,
|
|
90
|
+
backupRetentionDays: 7
|
|
91
|
+
},
|
|
92
|
+
mockLogger
|
|
93
|
+
);
|
|
94
|
+
await fileSystemService.initialize();
|
|
95
|
+
const testFile = path.join(tempDir, "data.json");
|
|
96
|
+
await fs.writeFile(testFile, Buffer.from([123, 0, 34, 120, 34, 125]));
|
|
97
|
+
await expect(fileSystemService.readFile(testFile)).rejects.toThrow(
|
|
98
|
+
/Use read_media_file instead/
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
it("reads media files as base64 with MIME-aware kind metadata", async () => {
|
|
102
|
+
const fileSystemService = new FileSystemService(
|
|
103
|
+
{
|
|
104
|
+
allowedPaths: [tempDir],
|
|
105
|
+
blockedPaths: [],
|
|
106
|
+
blockedExtensions: [],
|
|
107
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
108
|
+
workingDirectory: tempDir,
|
|
109
|
+
enableBackups: false,
|
|
110
|
+
backupRetentionDays: 7
|
|
111
|
+
},
|
|
112
|
+
mockLogger
|
|
113
|
+
);
|
|
114
|
+
await fileSystemService.initialize();
|
|
115
|
+
const testFile = path.join(tempDir, "clip.mp4");
|
|
116
|
+
const buffer = Buffer.from([0, 0, 0, 24, 102, 116, 121, 112]);
|
|
117
|
+
await fs.writeFile(testFile, buffer);
|
|
118
|
+
const result = await fileSystemService.readMediaFile(testFile);
|
|
119
|
+
expect(result.data).toBe(buffer.toString("base64"));
|
|
120
|
+
expect(result.mimeType).toBe("video/mp4");
|
|
121
|
+
expect(result.kind).toBe("video");
|
|
122
|
+
expect(result.filename).toBe("clip.mp4");
|
|
123
|
+
expect(result.size).toBe(buffer.length);
|
|
124
|
+
});
|
|
125
|
+
it("rejects text files from readMediaFile and points callers to readFile", async () => {
|
|
126
|
+
const fileSystemService = new FileSystemService(
|
|
127
|
+
{
|
|
128
|
+
allowedPaths: [tempDir],
|
|
129
|
+
blockedPaths: [],
|
|
130
|
+
blockedExtensions: [],
|
|
131
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
132
|
+
workingDirectory: tempDir,
|
|
133
|
+
enableBackups: false,
|
|
134
|
+
backupRetentionDays: 7
|
|
135
|
+
},
|
|
136
|
+
mockLogger
|
|
137
|
+
);
|
|
138
|
+
await fileSystemService.initialize();
|
|
139
|
+
const testFile = path.join(tempDir, "plain.txt");
|
|
140
|
+
await fs.writeFile(testFile, "hello world");
|
|
141
|
+
await expect(fileSystemService.readMediaFile(testFile)).rejects.toThrow(
|
|
142
|
+
/Use read_file instead/
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
30
146
|
describe("Backup Behavior", () => {
|
|
31
147
|
describe("writeFile", () => {
|
|
32
148
|
it("should NOT create backup when enableBackups is false (default)", async () => {
|
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
createGlobFilesTool: () => import_glob_files_tool.createGlobFilesTool,
|
|
28
28
|
createGrepContentTool: () => import_grep_content_tool.createGrepContentTool,
|
|
29
29
|
createReadFileTool: () => import_read_file_tool.createReadFileTool,
|
|
30
|
+
createReadMediaFileTool: () => import_read_media_file_tool.createReadMediaFileTool,
|
|
30
31
|
createWriteFileTool: () => import_write_file_tool.createWriteFileTool,
|
|
31
32
|
fileSystemToolsFactory: () => import_tool_factory.fileSystemToolsFactory
|
|
32
33
|
});
|
|
@@ -38,6 +39,7 @@ var import_path_validator = require("./path-validator.js");
|
|
|
38
39
|
var import_errors = require("./errors.js");
|
|
39
40
|
var import_error_codes = require("./error-codes.js");
|
|
40
41
|
var import_read_file_tool = require("./read-file-tool.js");
|
|
42
|
+
var import_read_media_file_tool = require("./read-media-file-tool.js");
|
|
41
43
|
var import_write_file_tool = require("./write-file-tool.js");
|
|
42
44
|
var import_edit_file_tool = require("./edit-file-tool.js");
|
|
43
45
|
var import_glob_files_tool = require("./glob-files-tool.js");
|
|
@@ -53,6 +55,7 @@ var import_grep_content_tool = require("./grep-content-tool.js");
|
|
|
53
55
|
createGlobFilesTool,
|
|
54
56
|
createGrepContentTool,
|
|
55
57
|
createReadFileTool,
|
|
58
|
+
createReadMediaFileTool,
|
|
56
59
|
createWriteFileTool,
|
|
57
60
|
fileSystemToolsFactory
|
|
58
61
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -32,7 +32,7 @@ declare const FileSystemToolsConfigSchema: z.ZodObject<{
|
|
|
32
32
|
enableBackups: z.ZodDefault<z.ZodBoolean>;
|
|
33
33
|
backupPath: z.ZodOptional<z.ZodString>;
|
|
34
34
|
backupRetentionDays: z.ZodDefault<z.ZodNumber>;
|
|
35
|
-
enabledTools: z.ZodOptional<z.ZodArray<z.ZodEnum<["read_file", "write_file", "edit_file", "glob_files", "grep_content"]>, "many">>;
|
|
35
|
+
enabledTools: z.ZodOptional<z.ZodArray<z.ZodEnum<["read_file", "read_media_file", "write_file", "edit_file", "glob_files", "grep_content"]>, "many">>;
|
|
36
36
|
}, "strict", z.ZodTypeAny, {
|
|
37
37
|
allowedPaths: string[];
|
|
38
38
|
blockedExtensions: string[];
|
|
@@ -43,7 +43,7 @@ declare const FileSystemToolsConfigSchema: z.ZodObject<{
|
|
|
43
43
|
type: "filesystem-tools";
|
|
44
44
|
backupPath?: string | undefined;
|
|
45
45
|
workingDirectory?: string | undefined;
|
|
46
|
-
enabledTools?: ("read_file" | "write_file" | "edit_file" | "glob_files" | "grep_content")[] | undefined;
|
|
46
|
+
enabledTools?: ("read_file" | "read_media_file" | "write_file" | "edit_file" | "glob_files" | "grep_content")[] | undefined;
|
|
47
47
|
}, {
|
|
48
48
|
type: "filesystem-tools";
|
|
49
49
|
allowedPaths?: string[] | undefined;
|
|
@@ -54,7 +54,7 @@ declare const FileSystemToolsConfigSchema: z.ZodObject<{
|
|
|
54
54
|
enableBackups?: boolean | undefined;
|
|
55
55
|
backupRetentionDays?: number | undefined;
|
|
56
56
|
workingDirectory?: string | undefined;
|
|
57
|
-
enabledTools?: ("read_file" | "write_file" | "edit_file" | "glob_files" | "grep_content")[] | undefined;
|
|
57
|
+
enabledTools?: ("read_file" | "read_media_file" | "write_file" | "edit_file" | "glob_files" | "grep_content")[] | undefined;
|
|
58
58
|
}>;
|
|
59
59
|
type FileSystemToolsConfig = z.output<typeof FileSystemToolsConfigSchema>;
|
|
60
60
|
|
|
@@ -78,6 +78,16 @@ interface FileContent {
|
|
|
78
78
|
truncated: boolean;
|
|
79
79
|
size: number;
|
|
80
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Media or binary file content with metadata.
|
|
83
|
+
*/
|
|
84
|
+
interface MediaFileContent {
|
|
85
|
+
data: string;
|
|
86
|
+
mimeType: string;
|
|
87
|
+
filename: string;
|
|
88
|
+
kind: 'image' | 'audio' | 'video' | 'file';
|
|
89
|
+
size: number;
|
|
90
|
+
}
|
|
81
91
|
/**
|
|
82
92
|
* Options for reading files
|
|
83
93
|
*/
|
|
@@ -383,6 +393,10 @@ declare class FileSystemService {
|
|
|
383
393
|
* Read a file with validation and size limits
|
|
384
394
|
*/
|
|
385
395
|
readFile(filePath: string, options?: ReadFileOptions): Promise<FileContent>;
|
|
396
|
+
/**
|
|
397
|
+
* Read a media or binary file and return base64-encoded data with MIME metadata.
|
|
398
|
+
*/
|
|
399
|
+
readMediaFile(filePath: string): Promise<MediaFileContent>;
|
|
386
400
|
/**
|
|
387
401
|
* Preview-only file read that bypasses config-allowed roots.
|
|
388
402
|
*
|
|
@@ -738,6 +752,21 @@ declare const ReadFileInputSchema: z.ZodObject<{
|
|
|
738
752
|
*/
|
|
739
753
|
declare function createReadFileTool(getFileSystemService: FileSystemServiceGetter): Tool<typeof ReadFileInputSchema>;
|
|
740
754
|
|
|
755
|
+
/**
|
|
756
|
+
* Read Media File Tool
|
|
757
|
+
*
|
|
758
|
+
* Internal tool for reading media or binary files as base64 with MIME metadata.
|
|
759
|
+
*/
|
|
760
|
+
|
|
761
|
+
declare const ReadMediaFileInputSchema: z.ZodObject<{
|
|
762
|
+
file_path: z.ZodString;
|
|
763
|
+
}, "strict", z.ZodTypeAny, {
|
|
764
|
+
file_path: string;
|
|
765
|
+
}, {
|
|
766
|
+
file_path: string;
|
|
767
|
+
}>;
|
|
768
|
+
declare function createReadMediaFileTool(getFileSystemService: FileSystemServiceGetter): Tool<typeof ReadMediaFileInputSchema>;
|
|
769
|
+
|
|
741
770
|
/**
|
|
742
771
|
* Write File Tool
|
|
743
772
|
*
|
|
@@ -849,4 +878,4 @@ declare const GrepContentInputSchema: z.ZodObject<{
|
|
|
849
878
|
*/
|
|
850
879
|
declare function createGrepContentTool(getFileSystemService: FileSystemServiceGetter): Tool<typeof GrepContentInputSchema>;
|
|
851
880
|
|
|
852
|
-
export { type BufferEncoding, type CreateDirectoryOptions, type CreateDirectoryResult, type DeletePathOptions, type DeletePathResult, type DirectoryEntry, type EditFileOptions, type EditOperation, type EditResult, type FileContent, type FileMetadata, type FileSystemConfig, FileSystemError, FileSystemErrorCode, FileSystemService, type FileSystemServiceGetter, type FileSystemToolsConfig, FileSystemToolsConfigSchema, type GlobOptions, type GlobResult, type GrepOptions, type ListDirectoryOptions, type ListDirectoryResult, type PathValidation, PathValidator, type ReadFileOptions, type RenamePathResult, type SearchMatch, type SearchResult, type WriteFileOptions, type WriteResult, createEditFileTool, createGlobFilesTool, createGrepContentTool, createReadFileTool, createWriteFileTool, fileSystemToolsFactory };
|
|
881
|
+
export { type BufferEncoding, type CreateDirectoryOptions, type CreateDirectoryResult, type DeletePathOptions, type DeletePathResult, type DirectoryEntry, type EditFileOptions, type EditOperation, type EditResult, type FileContent, type FileMetadata, type FileSystemConfig, FileSystemError, FileSystemErrorCode, FileSystemService, type FileSystemServiceGetter, type FileSystemToolsConfig, FileSystemToolsConfigSchema, type GlobOptions, type GlobResult, type GrepOptions, type ListDirectoryOptions, type ListDirectoryResult, type MediaFileContent, type PathValidation, PathValidator, type ReadFileOptions, type RenamePathResult, type SearchMatch, type SearchResult, type WriteFileOptions, type WriteResult, createEditFileTool, createGlobFilesTool, createGrepContentTool, createReadFileTool, createReadMediaFileTool, createWriteFileTool, fileSystemToolsFactory };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @dexto/tools-filesystem
|
|
3
3
|
*
|
|
4
4
|
* FileSystem tools factory for Dexto agents.
|
|
5
|
-
* Provides file operation tools: read, write, edit, glob, grep.
|
|
5
|
+
* Provides file operation tools: read text, read media, write, edit, glob, grep.
|
|
6
6
|
*/
|
|
7
7
|
export { fileSystemToolsFactory } from './tool-factory.js';
|
|
8
8
|
export type { FileSystemServiceGetter } from './file-tool-types.js';
|
|
@@ -11,8 +11,9 @@ export { FileSystemService } from './filesystem-service.js';
|
|
|
11
11
|
export { PathValidator } from './path-validator.js';
|
|
12
12
|
export { FileSystemError } from './errors.js';
|
|
13
13
|
export { FileSystemErrorCode } from './error-codes.js';
|
|
14
|
-
export type { FileSystemConfig, FileContent, ReadFileOptions, GlobOptions, GlobResult, GrepOptions, SearchResult, SearchMatch, WriteFileOptions, WriteResult, EditFileOptions, EditResult, EditOperation, FileMetadata, DirectoryEntry, ListDirectoryOptions, ListDirectoryResult, CreateDirectoryOptions, CreateDirectoryResult, DeletePathOptions, DeletePathResult, RenamePathResult, PathValidation, BufferEncoding, } from './types.js';
|
|
14
|
+
export type { FileSystemConfig, FileContent, MediaFileContent, ReadFileOptions, GlobOptions, GlobResult, GrepOptions, SearchResult, SearchMatch, WriteFileOptions, WriteResult, EditFileOptions, EditResult, EditOperation, FileMetadata, DirectoryEntry, ListDirectoryOptions, ListDirectoryResult, CreateDirectoryOptions, CreateDirectoryResult, DeletePathOptions, DeletePathResult, RenamePathResult, PathValidation, BufferEncoding, } from './types.js';
|
|
15
15
|
export { createReadFileTool } from './read-file-tool.js';
|
|
16
|
+
export { createReadMediaFileTool } from './read-media-file-tool.js';
|
|
16
17
|
export { createWriteFileTool } from './write-file-tool.js';
|
|
17
18
|
export { createEditFileTool } from './edit-file-tool.js';
|
|
18
19
|
export { createGlobFilesTool } from './glob-files-tool.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,2BAA2B,EAAE,KAAK,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,YAAY,EACR,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,UAAU,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,2BAA2B,EAAE,KAAK,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,YAAY,EACR,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,UAAU,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { PathValidator } from "./path-validator.js";
|
|
|
5
5
|
import { FileSystemError } from "./errors.js";
|
|
6
6
|
import { FileSystemErrorCode } from "./error-codes.js";
|
|
7
7
|
import { createReadFileTool } from "./read-file-tool.js";
|
|
8
|
+
import { createReadMediaFileTool } from "./read-media-file-tool.js";
|
|
8
9
|
import { createWriteFileTool } from "./write-file-tool.js";
|
|
9
10
|
import { createEditFileTool } from "./edit-file-tool.js";
|
|
10
11
|
import { createGlobFilesTool } from "./glob-files-tool.js";
|
|
@@ -19,6 +20,7 @@ export {
|
|
|
19
20
|
createGlobFilesTool,
|
|
20
21
|
createGrepContentTool,
|
|
21
22
|
createReadFileTool,
|
|
23
|
+
createReadMediaFileTool,
|
|
22
24
|
createWriteFileTool,
|
|
23
25
|
fileSystemToolsFactory
|
|
24
26
|
};
|