@enactprotocol/shared 1.2.13 → 2.0.1
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 +44 -0
- package/dist/config.d.ts +164 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +386 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +15 -5
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +24 -8
- package/dist/constants.js.map +1 -0
- package/dist/execution/command.d.ts +102 -0
- package/dist/execution/command.d.ts.map +1 -0
- package/dist/execution/command.js +262 -0
- package/dist/execution/command.js.map +1 -0
- package/dist/execution/index.d.ts +12 -0
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +17 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/execution/runtime.d.ts +82 -0
- package/dist/execution/runtime.d.ts.map +1 -0
- package/dist/execution/runtime.js +273 -0
- package/dist/execution/runtime.js.map +1 -0
- package/dist/execution/types.d.ts +306 -0
- package/dist/execution/types.d.ts.map +1 -0
- package/dist/execution/types.js +14 -0
- package/dist/execution/types.js.map +1 -0
- package/dist/execution/validation.d.ts +43 -0
- package/dist/execution/validation.d.ts.map +1 -0
- package/dist/execution/validation.js +430 -0
- package/dist/execution/validation.js.map +1 -0
- package/dist/index.d.ts +21 -21
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -25
- package/dist/index.js.map +1 -0
- package/dist/manifest/index.d.ts +7 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +10 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/loader.d.ts +76 -0
- package/dist/manifest/loader.d.ts.map +1 -0
- package/dist/manifest/loader.js +146 -0
- package/dist/manifest/loader.js.map +1 -0
- package/dist/manifest/parser.d.ts +64 -0
- package/dist/manifest/parser.d.ts.map +1 -0
- package/dist/manifest/parser.js +135 -0
- package/dist/manifest/parser.js.map +1 -0
- package/dist/manifest/validator.d.ts +95 -0
- package/dist/manifest/validator.d.ts.map +1 -0
- package/dist/manifest/validator.js +258 -0
- package/dist/manifest/validator.js.map +1 -0
- package/dist/paths.d.ts +57 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +93 -0
- package/dist/paths.js.map +1 -0
- package/dist/registry.d.ts +73 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +147 -0
- package/dist/registry.js.map +1 -0
- package/dist/resolver.d.ts +89 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +282 -0
- package/dist/resolver.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/manifest.d.ts +201 -0
- package/dist/types/manifest.d.ts.map +1 -0
- package/dist/types/manifest.js +13 -0
- package/dist/types/manifest.js.map +1 -0
- package/dist/types.d.ts +5 -132
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -3
- package/dist/types.js.map +1 -0
- package/dist/utils/fs.d.ts +105 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +233 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +102 -25
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +214 -57
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/version.d.ts +60 -2
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +255 -31
- package/dist/utils/version.js.map +1 -0
- package/package.json +16 -58
- package/src/config.ts +510 -0
- package/src/constants.ts +36 -0
- package/src/execution/command.ts +314 -0
- package/src/execution/index.ts +73 -0
- package/src/execution/runtime.ts +308 -0
- package/src/execution/types.ts +379 -0
- package/src/execution/validation.ts +508 -0
- package/src/index.ts +238 -30
- package/src/manifest/index.ts +36 -0
- package/src/manifest/loader.ts +187 -0
- package/src/manifest/parser.ts +173 -0
- package/src/manifest/validator.ts +309 -0
- package/src/paths.ts +108 -0
- package/src/registry.ts +219 -0
- package/src/resolver.ts +345 -0
- package/src/types/index.ts +30 -0
- package/src/types/manifest.ts +255 -0
- package/src/types.ts +5 -188
- package/src/utils/fs.ts +281 -0
- package/src/utils/logger.ts +270 -59
- package/src/utils/version.ts +304 -36
- package/tests/config.test.ts +515 -0
- package/tests/execution/command.test.ts +317 -0
- package/tests/execution/validation.test.ts +384 -0
- package/tests/fixtures/invalid-tool.yaml +4 -0
- package/tests/fixtures/valid-tool.md +62 -0
- package/tests/fixtures/valid-tool.yaml +40 -0
- package/tests/index.test.ts +8 -0
- package/tests/manifest/loader.test.ts +291 -0
- package/tests/manifest/parser.test.ts +345 -0
- package/tests/manifest/validator.test.ts +394 -0
- package/tests/manifest-types.test.ts +358 -0
- package/tests/paths.test.ts +153 -0
- package/tests/registry.test.ts +231 -0
- package/tests/resolver.test.ts +272 -0
- package/tests/utils/fs.test.ts +388 -0
- package/tests/utils/logger.test.ts +480 -0
- package/tests/utils/version.test.ts +390 -0
- package/tsconfig.json +12 -0
- package/dist/LocalToolResolver.d.ts +0 -84
- package/dist/LocalToolResolver.js +0 -353
- package/dist/api/enact-api.d.ts +0 -130
- package/dist/api/enact-api.js +0 -428
- package/dist/api/index.d.ts +0 -2
- package/dist/api/index.js +0 -2
- package/dist/api/types.d.ts +0 -103
- package/dist/api/types.js +0 -1
- package/dist/core/DaggerExecutionProvider.d.ts +0 -169
- package/dist/core/DaggerExecutionProvider.js +0 -1029
- package/dist/core/DirectExecutionProvider.d.ts +0 -23
- package/dist/core/DirectExecutionProvider.js +0 -406
- package/dist/core/EnactCore.d.ts +0 -162
- package/dist/core/EnactCore.js +0 -597
- package/dist/core/NativeExecutionProvider.d.ts +0 -9
- package/dist/core/NativeExecutionProvider.js +0 -16
- package/dist/core/index.d.ts +0 -3
- package/dist/core/index.js +0 -3
- package/dist/exec/index.d.ts +0 -3
- package/dist/exec/index.js +0 -3
- package/dist/exec/logger.d.ts +0 -11
- package/dist/exec/logger.js +0 -57
- package/dist/exec/validate.d.ts +0 -5
- package/dist/exec/validate.js +0 -167
- package/dist/lib/enact-direct.d.ts +0 -150
- package/dist/lib/enact-direct.js +0 -159
- package/dist/lib/index.d.ts +0 -1
- package/dist/lib/index.js +0 -1
- package/dist/security/index.d.ts +0 -3
- package/dist/security/index.js +0 -3
- package/dist/security/security.d.ts +0 -23
- package/dist/security/security.js +0 -137
- package/dist/security/sign.d.ts +0 -103
- package/dist/security/sign.js +0 -666
- package/dist/security/verification-enforcer.d.ts +0 -53
- package/dist/security/verification-enforcer.js +0 -204
- package/dist/services/McpCoreService.d.ts +0 -98
- package/dist/services/McpCoreService.js +0 -124
- package/dist/services/index.d.ts +0 -1
- package/dist/services/index.js +0 -1
- package/dist/utils/config.d.ts +0 -111
- package/dist/utils/config.js +0 -342
- package/dist/utils/env-loader.d.ts +0 -54
- package/dist/utils/env-loader.js +0 -270
- package/dist/utils/help.d.ts +0 -36
- package/dist/utils/help.js +0 -248
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.js +0 -7
- package/dist/utils/silent-monitor.d.ts +0 -67
- package/dist/utils/silent-monitor.js +0 -242
- package/dist/utils/timeout.d.ts +0 -5
- package/dist/utils/timeout.js +0 -23
- package/dist/web/env-manager-server.d.ts +0 -29
- package/dist/web/env-manager-server.js +0 -367
- package/dist/web/index.d.ts +0 -1
- package/dist/web/index.js +0 -1
- package/src/LocalToolResolver.ts +0 -424
- package/src/api/enact-api.ts +0 -604
- package/src/api/index.ts +0 -2
- package/src/api/types.ts +0 -114
- package/src/core/DaggerExecutionProvider.ts +0 -1357
- package/src/core/DirectExecutionProvider.ts +0 -484
- package/src/core/EnactCore.ts +0 -847
- package/src/core/index.ts +0 -3
- package/src/exec/index.ts +0 -3
- package/src/exec/logger.ts +0 -63
- package/src/exec/validate.ts +0 -238
- package/src/lib/enact-direct.ts +0 -254
- package/src/lib/index.ts +0 -1
- package/src/services/McpCoreService.ts +0 -201
- package/src/services/index.ts +0 -1
- package/src/utils/config.ts +0 -438
- package/src/utils/env-loader.ts +0 -370
- package/src/utils/help.ts +0 -257
- package/src/utils/index.ts +0 -7
- package/src/utils/silent-monitor.ts +0 -328
- package/src/utils/timeout.ts +0 -26
- package/src/web/env-manager-server.ts +0 -465
- package/src/web/index.ts +0 -1
- package/src/web/static/app.js +0 -663
- package/src/web/static/index.html +0 -117
- package/src/web/static/style.css +0 -291
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import {
|
|
5
|
+
copyDir,
|
|
6
|
+
copyFile,
|
|
7
|
+
ensureDir,
|
|
8
|
+
ensureParentDir,
|
|
9
|
+
findFiles,
|
|
10
|
+
findFilesRecursive,
|
|
11
|
+
getFileSize,
|
|
12
|
+
getStats,
|
|
13
|
+
isDirectory,
|
|
14
|
+
isFile,
|
|
15
|
+
listDir,
|
|
16
|
+
listDirEntries,
|
|
17
|
+
pathExists,
|
|
18
|
+
readJsonFile,
|
|
19
|
+
readTextFile,
|
|
20
|
+
remove,
|
|
21
|
+
touchFile,
|
|
22
|
+
tryReadJsonFile,
|
|
23
|
+
tryReadTextFile,
|
|
24
|
+
writeJsonFile,
|
|
25
|
+
writeTextFile,
|
|
26
|
+
} from "../../src/utils/fs";
|
|
27
|
+
|
|
28
|
+
const TEST_DIR = join(import.meta.dir, "temp-fs-test");
|
|
29
|
+
|
|
30
|
+
describe("File system helpers", () => {
|
|
31
|
+
beforeAll(() => {
|
|
32
|
+
// Create test directory structure
|
|
33
|
+
mkdirSync(join(TEST_DIR, "existing"), { recursive: true });
|
|
34
|
+
mkdirSync(join(TEST_DIR, "nested", "deep"), { recursive: true });
|
|
35
|
+
writeFileSync(join(TEST_DIR, "test.txt"), "hello world", "utf-8");
|
|
36
|
+
writeFileSync(join(TEST_DIR, "test.json"), '{"key": "value"}', "utf-8");
|
|
37
|
+
writeFileSync(join(TEST_DIR, "existing", "file.txt"), "content", "utf-8");
|
|
38
|
+
writeFileSync(join(TEST_DIR, "nested", "file1.txt"), "file1", "utf-8");
|
|
39
|
+
writeFileSync(join(TEST_DIR, "nested", "deep", "file2.txt"), "file2", "utf-8");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
afterAll(() => {
|
|
43
|
+
// Clean up
|
|
44
|
+
if (existsSync(TEST_DIR)) {
|
|
45
|
+
rmSync(TEST_DIR, { recursive: true, force: true });
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe("ensureDir", () => {
|
|
50
|
+
test("creates new directory", () => {
|
|
51
|
+
const newDir = join(TEST_DIR, "new-dir");
|
|
52
|
+
ensureDir(newDir);
|
|
53
|
+
expect(existsSync(newDir)).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("does nothing if directory exists", () => {
|
|
57
|
+
const existingDir = join(TEST_DIR, "existing");
|
|
58
|
+
ensureDir(existingDir);
|
|
59
|
+
expect(existsSync(existingDir)).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("creates nested directories", () => {
|
|
63
|
+
const nestedDir = join(TEST_DIR, "a", "b", "c");
|
|
64
|
+
ensureDir(nestedDir);
|
|
65
|
+
expect(existsSync(nestedDir)).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe("ensureParentDir", () => {
|
|
70
|
+
test("creates parent directory for file path", () => {
|
|
71
|
+
const filePath = join(TEST_DIR, "parent-test", "file.txt");
|
|
72
|
+
ensureParentDir(filePath);
|
|
73
|
+
expect(existsSync(join(TEST_DIR, "parent-test"))).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("pathExists", () => {
|
|
78
|
+
test("returns true for existing file", () => {
|
|
79
|
+
expect(pathExists(join(TEST_DIR, "test.txt"))).toBe(true);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("returns true for existing directory", () => {
|
|
83
|
+
expect(pathExists(join(TEST_DIR, "existing"))).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("returns false for non-existent path", () => {
|
|
87
|
+
expect(pathExists(join(TEST_DIR, "non-existent"))).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe("isDirectory", () => {
|
|
92
|
+
test("returns true for directory", () => {
|
|
93
|
+
expect(isDirectory(join(TEST_DIR, "existing"))).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("returns false for file", () => {
|
|
97
|
+
expect(isDirectory(join(TEST_DIR, "test.txt"))).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("returns false for non-existent", () => {
|
|
101
|
+
expect(isDirectory(join(TEST_DIR, "non-existent"))).toBe(false);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe("isFile", () => {
|
|
106
|
+
test("returns true for file", () => {
|
|
107
|
+
expect(isFile(join(TEST_DIR, "test.txt"))).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("returns false for directory", () => {
|
|
111
|
+
expect(isFile(join(TEST_DIR, "existing"))).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("returns false for non-existent", () => {
|
|
115
|
+
expect(isFile(join(TEST_DIR, "non-existent"))).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("readJsonFile", () => {
|
|
120
|
+
test("reads and parses JSON file", () => {
|
|
121
|
+
const data = readJsonFile(join(TEST_DIR, "test.json"));
|
|
122
|
+
expect(data).toEqual({ key: "value" });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("throws for non-existent file", () => {
|
|
126
|
+
expect(() => readJsonFile(join(TEST_DIR, "non-existent.json"))).toThrow();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("throws for invalid JSON", () => {
|
|
130
|
+
const invalidJson = join(TEST_DIR, "invalid.json");
|
|
131
|
+
writeFileSync(invalidJson, "not valid json", "utf-8");
|
|
132
|
+
expect(() => readJsonFile(invalidJson)).toThrow();
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe("tryReadJsonFile", () => {
|
|
137
|
+
test("returns parsed JSON for valid file", () => {
|
|
138
|
+
const data = tryReadJsonFile(join(TEST_DIR, "test.json"));
|
|
139
|
+
expect(data).toEqual({ key: "value" });
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("returns null for non-existent file", () => {
|
|
143
|
+
expect(tryReadJsonFile(join(TEST_DIR, "non-existent.json"))).toBeNull();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("returns null for invalid JSON", () => {
|
|
147
|
+
const invalidJson = join(TEST_DIR, "invalid2.json");
|
|
148
|
+
writeFileSync(invalidJson, "not valid json", "utf-8");
|
|
149
|
+
expect(tryReadJsonFile(invalidJson)).toBeNull();
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe("writeJsonFile", () => {
|
|
154
|
+
test("writes formatted JSON", () => {
|
|
155
|
+
const filePath = join(TEST_DIR, "write-test.json");
|
|
156
|
+
writeJsonFile(filePath, { test: true });
|
|
157
|
+
const content = readTextFile(filePath);
|
|
158
|
+
expect(content).toBe('{\n "test": true\n}\n');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("creates parent directories", () => {
|
|
162
|
+
const filePath = join(TEST_DIR, "write-parent", "nested", "file.json");
|
|
163
|
+
writeJsonFile(filePath, { nested: true });
|
|
164
|
+
expect(existsSync(filePath)).toBe(true);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("respects custom indent", () => {
|
|
168
|
+
const filePath = join(TEST_DIR, "indent-test.json");
|
|
169
|
+
writeJsonFile(filePath, { a: 1 }, { indent: 4 });
|
|
170
|
+
const content = readTextFile(filePath);
|
|
171
|
+
expect(content).toBe('{\n "a": 1\n}\n');
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe("readTextFile", () => {
|
|
176
|
+
test("reads text file content", () => {
|
|
177
|
+
const content = readTextFile(join(TEST_DIR, "test.txt"));
|
|
178
|
+
expect(content).toBe("hello world");
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test("throws for non-existent file", () => {
|
|
182
|
+
expect(() => readTextFile(join(TEST_DIR, "non-existent.txt"))).toThrow();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
describe("tryReadTextFile", () => {
|
|
187
|
+
test("returns content for existing file", () => {
|
|
188
|
+
const content = tryReadTextFile(join(TEST_DIR, "test.txt"));
|
|
189
|
+
expect(content).toBe("hello world");
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("returns null for non-existent file", () => {
|
|
193
|
+
expect(tryReadTextFile(join(TEST_DIR, "non-existent.txt"))).toBeNull();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
describe("writeTextFile", () => {
|
|
198
|
+
test("writes text content", () => {
|
|
199
|
+
const filePath = join(TEST_DIR, "write-text.txt");
|
|
200
|
+
writeTextFile(filePath, "test content");
|
|
201
|
+
expect(readTextFile(filePath)).toBe("test content");
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("creates parent directories", () => {
|
|
205
|
+
const filePath = join(TEST_DIR, "write-text-parent", "file.txt");
|
|
206
|
+
writeTextFile(filePath, "nested content");
|
|
207
|
+
expect(existsSync(filePath)).toBe(true);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe("copyFile", () => {
|
|
212
|
+
test("copies file to new location", () => {
|
|
213
|
+
const src = join(TEST_DIR, "test.txt");
|
|
214
|
+
const dest = join(TEST_DIR, "copy-test", "copied.txt");
|
|
215
|
+
copyFile(src, dest);
|
|
216
|
+
expect(existsSync(dest)).toBe(true);
|
|
217
|
+
expect(readTextFile(dest)).toBe("hello world");
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe("copyDir", () => {
|
|
222
|
+
test("copies directory recursively", () => {
|
|
223
|
+
const src = join(TEST_DIR, "nested");
|
|
224
|
+
const dest = join(TEST_DIR, "nested-copy");
|
|
225
|
+
copyDir(src, dest);
|
|
226
|
+
expect(existsSync(join(dest, "file1.txt"))).toBe(true);
|
|
227
|
+
expect(existsSync(join(dest, "deep", "file2.txt"))).toBe(true);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
describe("remove", () => {
|
|
232
|
+
test("removes file", () => {
|
|
233
|
+
const filePath = join(TEST_DIR, "to-remove.txt");
|
|
234
|
+
writeFileSync(filePath, "delete me", "utf-8");
|
|
235
|
+
expect(existsSync(filePath)).toBe(true);
|
|
236
|
+
remove(filePath);
|
|
237
|
+
expect(existsSync(filePath)).toBe(false);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("removes directory recursively", () => {
|
|
241
|
+
const dirPath = join(TEST_DIR, "dir-to-remove");
|
|
242
|
+
mkdirSync(join(dirPath, "nested"), { recursive: true });
|
|
243
|
+
writeFileSync(join(dirPath, "nested", "file.txt"), "content", "utf-8");
|
|
244
|
+
remove(dirPath);
|
|
245
|
+
expect(existsSync(dirPath)).toBe(false);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test("does nothing for non-existent path", () => {
|
|
249
|
+
// Should not throw
|
|
250
|
+
remove(join(TEST_DIR, "non-existent"));
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
describe("listDir", () => {
|
|
255
|
+
test("lists directory contents", () => {
|
|
256
|
+
const contents = listDir(join(TEST_DIR, "existing"));
|
|
257
|
+
expect(contents).toContain("file.txt");
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
test("returns empty array for non-existent directory", () => {
|
|
261
|
+
expect(listDir(join(TEST_DIR, "non-existent"))).toEqual([]);
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
describe("listDirEntries", () => {
|
|
266
|
+
test("lists entries with types", () => {
|
|
267
|
+
const entries = listDirEntries(TEST_DIR);
|
|
268
|
+
const existing = entries.find((e) => e.name === "existing");
|
|
269
|
+
const testTxt = entries.find((e) => e.name === "test.txt");
|
|
270
|
+
|
|
271
|
+
expect(existing?.type).toBe("directory");
|
|
272
|
+
expect(testTxt?.type).toBe("file");
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("includes full paths", () => {
|
|
276
|
+
const entries = listDirEntries(TEST_DIR);
|
|
277
|
+
const testTxt = entries.find((e) => e.name === "test.txt");
|
|
278
|
+
expect(testTxt?.path).toBe(join(TEST_DIR, "test.txt"));
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("returns empty array for non-existent directory", () => {
|
|
282
|
+
expect(listDirEntries(join(TEST_DIR, "non-existent"))).toEqual([]);
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
describe("findFiles", () => {
|
|
287
|
+
test("finds files matching regex pattern", () => {
|
|
288
|
+
const files = findFiles(TEST_DIR, /\.txt$/);
|
|
289
|
+
expect(files.some((f) => f.endsWith("test.txt"))).toBe(true);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test("finds files matching string pattern", () => {
|
|
293
|
+
const files = findFiles(TEST_DIR, "\\.json$");
|
|
294
|
+
expect(files.some((f) => f.endsWith("test.json"))).toBe(true);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test("returns empty array for no matches", () => {
|
|
298
|
+
const files = findFiles(TEST_DIR, /\.xyz$/);
|
|
299
|
+
expect(files).toEqual([]);
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
describe("findFilesRecursive", () => {
|
|
304
|
+
test("finds files recursively", () => {
|
|
305
|
+
const files = findFilesRecursive(join(TEST_DIR, "nested"));
|
|
306
|
+
expect(files.length).toBeGreaterThanOrEqual(2);
|
|
307
|
+
expect(files.some((f) => f.includes("file1.txt"))).toBe(true);
|
|
308
|
+
expect(files.some((f) => f.includes("file2.txt"))).toBe(true);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test("filters by pattern", () => {
|
|
312
|
+
const files = findFilesRecursive(join(TEST_DIR, "nested"), /file1/);
|
|
313
|
+
expect(files.length).toBe(1);
|
|
314
|
+
expect(files[0]).toContain("file1.txt");
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
test("returns empty for non-existent dir", () => {
|
|
318
|
+
expect(findFilesRecursive(join(TEST_DIR, "non-existent"))).toEqual([]);
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
describe("getStats", () => {
|
|
323
|
+
test("returns stats for file", () => {
|
|
324
|
+
const stats = getStats(join(TEST_DIR, "test.txt"));
|
|
325
|
+
expect(stats).not.toBeNull();
|
|
326
|
+
expect(stats?.isFile).toBe(true);
|
|
327
|
+
expect(stats?.isDirectory).toBe(false);
|
|
328
|
+
expect(stats?.size).toBeGreaterThan(0);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
test("returns stats for directory", () => {
|
|
332
|
+
const stats = getStats(join(TEST_DIR, "existing"));
|
|
333
|
+
expect(stats?.isDirectory).toBe(true);
|
|
334
|
+
expect(stats?.isFile).toBe(false);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
test("returns null for non-existent", () => {
|
|
338
|
+
expect(getStats(join(TEST_DIR, "non-existent"))).toBeNull();
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
describe("getFileSize", () => {
|
|
343
|
+
test("returns file size", () => {
|
|
344
|
+
const size = getFileSize(join(TEST_DIR, "test.txt"));
|
|
345
|
+
expect(size).toBe(11); // "hello world" = 11 bytes
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
test("returns null for directory", () => {
|
|
349
|
+
expect(getFileSize(join(TEST_DIR, "existing"))).toBeNull();
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test("returns null for non-existent", () => {
|
|
353
|
+
expect(getFileSize(join(TEST_DIR, "non-existent"))).toBeNull();
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
describe("touchFile", () => {
|
|
358
|
+
test("creates new file if not exists", () => {
|
|
359
|
+
const filePath = join(TEST_DIR, "touched-new.txt");
|
|
360
|
+
touchFile(filePath);
|
|
361
|
+
expect(existsSync(filePath)).toBe(true);
|
|
362
|
+
expect(readTextFile(filePath)).toBe("");
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test("updates existing file mtime", () => {
|
|
366
|
+
const filePath = join(TEST_DIR, "touched-existing.txt");
|
|
367
|
+
writeFileSync(filePath, "content", "utf-8");
|
|
368
|
+
|
|
369
|
+
// Wait a bit to ensure mtime changes
|
|
370
|
+
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
371
|
+
|
|
372
|
+
return delay(10).then(() => {
|
|
373
|
+
touchFile(filePath);
|
|
374
|
+
const statsAfter = getStats(filePath);
|
|
375
|
+
// Content should be preserved
|
|
376
|
+
expect(readTextFile(filePath)).toBe("content");
|
|
377
|
+
// mtime should be updated (or at least stats should exist)
|
|
378
|
+
expect(statsAfter).not.toBeNull();
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
test("creates parent directories", () => {
|
|
383
|
+
const filePath = join(TEST_DIR, "touch-parent", "nested", "file.txt");
|
|
384
|
+
touchFile(filePath);
|
|
385
|
+
expect(existsSync(filePath)).toBe(true);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
});
|