@enactprotocol/shared 1.2.11 → 2.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/README.md +44 -0
- package/package.json +16 -58
- package/src/config.ts +476 -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 +237 -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/tsconfig.tsbuildinfo +1 -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/constants.d.ts +0 -7
- package/dist/constants.js +0 -10
- 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/index.d.ts +0 -21
- package/dist/index.js +0 -25
- 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/types.d.ts +0 -132
- package/dist/types.js +0 -3
- 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/logger.d.ts +0 -35
- package/dist/utils/logger.js +0 -75
- 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/utils/version.d.ts +0 -4
- package/dist/utils/version.js +0 -35
- 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,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
enact: "2.0.0"
|
|
3
|
+
name: acme/docs/analyzer
|
|
4
|
+
description: Analyzes documentation for completeness
|
|
5
|
+
version: "1.2.0"
|
|
6
|
+
from: python:3.11-slim
|
|
7
|
+
command: "python analyze.py ${file}"
|
|
8
|
+
timeout: 5m
|
|
9
|
+
license: Apache-2.0
|
|
10
|
+
tags:
|
|
11
|
+
- documentation
|
|
12
|
+
- analysis
|
|
13
|
+
inputSchema:
|
|
14
|
+
type: object
|
|
15
|
+
properties:
|
|
16
|
+
file:
|
|
17
|
+
type: string
|
|
18
|
+
description: Path to the documentation file
|
|
19
|
+
required:
|
|
20
|
+
- file
|
|
21
|
+
outputSchema:
|
|
22
|
+
type: object
|
|
23
|
+
properties:
|
|
24
|
+
score:
|
|
25
|
+
type: number
|
|
26
|
+
issues:
|
|
27
|
+
type: array
|
|
28
|
+
items:
|
|
29
|
+
type: string
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Documentation Analyzer
|
|
33
|
+
|
|
34
|
+
A powerful tool for analyzing documentation quality and completeness.
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
Provide a path to a documentation file and get a quality score along with
|
|
39
|
+
any issues found.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
enact run acme/docs/analyzer --file README.md
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Output
|
|
46
|
+
|
|
47
|
+
The tool returns a JSON object with:
|
|
48
|
+
|
|
49
|
+
- `score`: A quality score from 0-100
|
|
50
|
+
- `issues`: An array of strings describing any issues found
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
### Basic Analysis
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
enact run acme/docs/analyzer --file docs/api.md
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Integration with CI
|
|
61
|
+
|
|
62
|
+
You can use this tool in your CI pipeline to enforce documentation standards.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
enact: "2.0.0"
|
|
2
|
+
name: acme/utils/greeter
|
|
3
|
+
description: Greets users by name
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
from: node:18-alpine
|
|
6
|
+
command: "echo 'Hello ${name}!'"
|
|
7
|
+
timeout: 30s
|
|
8
|
+
license: MIT
|
|
9
|
+
tags:
|
|
10
|
+
- greeting
|
|
11
|
+
- utility
|
|
12
|
+
inputSchema:
|
|
13
|
+
type: object
|
|
14
|
+
properties:
|
|
15
|
+
name:
|
|
16
|
+
type: string
|
|
17
|
+
description: The name to greet
|
|
18
|
+
required:
|
|
19
|
+
- name
|
|
20
|
+
outputSchema:
|
|
21
|
+
type: object
|
|
22
|
+
properties:
|
|
23
|
+
message:
|
|
24
|
+
type: string
|
|
25
|
+
env:
|
|
26
|
+
LOG_LEVEL:
|
|
27
|
+
description: Logging verbosity level
|
|
28
|
+
default: info
|
|
29
|
+
annotations:
|
|
30
|
+
readOnlyHint: true
|
|
31
|
+
idempotentHint: true
|
|
32
|
+
authors:
|
|
33
|
+
- name: Alice Developer
|
|
34
|
+
email: alice@example.com
|
|
35
|
+
examples:
|
|
36
|
+
- input:
|
|
37
|
+
name: World
|
|
38
|
+
output:
|
|
39
|
+
message: "Hello World!"
|
|
40
|
+
description: Basic greeting
|
|
@@ -0,0 +1,291 @@
|
|
|
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
|
+
ManifestLoadError,
|
|
6
|
+
findManifestFile,
|
|
7
|
+
hasManifest,
|
|
8
|
+
loadManifest,
|
|
9
|
+
loadManifestFromDir,
|
|
10
|
+
tryLoadManifest,
|
|
11
|
+
tryLoadManifestFromDir,
|
|
12
|
+
} from "../../src/manifest/loader";
|
|
13
|
+
|
|
14
|
+
const FIXTURES_DIR = join(import.meta.dir, "..", "fixtures");
|
|
15
|
+
const TEST_DIR = join(import.meta.dir, "temp-loader-test");
|
|
16
|
+
|
|
17
|
+
describe("manifest loader", () => {
|
|
18
|
+
beforeAll(() => {
|
|
19
|
+
// Create temp test directory
|
|
20
|
+
if (!existsSync(TEST_DIR)) {
|
|
21
|
+
mkdirSync(TEST_DIR, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterAll(() => {
|
|
26
|
+
// Cleanup
|
|
27
|
+
if (existsSync(TEST_DIR)) {
|
|
28
|
+
rmSync(TEST_DIR, { recursive: true, force: true });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("loadManifest", () => {
|
|
33
|
+
test("loads valid YAML manifest", () => {
|
|
34
|
+
const filePath = join(FIXTURES_DIR, "valid-tool.yaml");
|
|
35
|
+
const result = loadManifest(filePath);
|
|
36
|
+
|
|
37
|
+
expect(result.manifest.name).toBe("acme/utils/greeter");
|
|
38
|
+
expect(result.manifest.description).toBe("Greets users by name");
|
|
39
|
+
expect(result.manifest.version).toBe("1.0.0");
|
|
40
|
+
expect(result.format).toBe("yaml");
|
|
41
|
+
expect(result.filePath).toBe(filePath);
|
|
42
|
+
expect(result.body).toBeUndefined();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("loads valid Markdown manifest", () => {
|
|
46
|
+
const filePath = join(FIXTURES_DIR, "valid-tool.md");
|
|
47
|
+
const result = loadManifest(filePath);
|
|
48
|
+
|
|
49
|
+
expect(result.manifest.name).toBe("acme/docs/analyzer");
|
|
50
|
+
expect(result.manifest.description).toBe("Analyzes documentation for completeness");
|
|
51
|
+
expect(result.format).toBe("md");
|
|
52
|
+
expect(result.body).toBeDefined();
|
|
53
|
+
expect(result.body).toContain("# Documentation Analyzer");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("includes validation warnings", () => {
|
|
57
|
+
// Create a minimal manifest that will have warnings
|
|
58
|
+
const minimalPath = join(TEST_DIR, "minimal.yaml");
|
|
59
|
+
writeFileSync(
|
|
60
|
+
minimalPath,
|
|
61
|
+
`
|
|
62
|
+
name: test/tool
|
|
63
|
+
description: A minimal tool
|
|
64
|
+
`,
|
|
65
|
+
"utf-8"
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const result = loadManifest(minimalPath);
|
|
69
|
+
expect(result.manifest.name).toBe("test/tool");
|
|
70
|
+
expect(result.warnings).toBeDefined();
|
|
71
|
+
expect(result.warnings?.length).toBeGreaterThan(0);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("throws ManifestLoadError for non-existent file", () => {
|
|
75
|
+
const filePath = join(FIXTURES_DIR, "does-not-exist.yaml");
|
|
76
|
+
expect(() => loadManifest(filePath)).toThrow(ManifestLoadError);
|
|
77
|
+
expect(() => loadManifest(filePath)).toThrow("not found");
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("throws ManifestLoadError for invalid manifest", () => {
|
|
81
|
+
const filePath = join(FIXTURES_DIR, "invalid-tool.yaml");
|
|
82
|
+
expect(() => loadManifest(filePath)).toThrow(ManifestLoadError);
|
|
83
|
+
expect(() => loadManifest(filePath)).toThrow("validation failed");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("throws ManifestLoadError for malformed YAML", () => {
|
|
87
|
+
const malformedPath = join(TEST_DIR, "malformed.yaml");
|
|
88
|
+
writeFileSync(malformedPath, "name: [unclosed", "utf-8");
|
|
89
|
+
|
|
90
|
+
expect(() => loadManifest(malformedPath)).toThrow(ManifestLoadError);
|
|
91
|
+
expect(() => loadManifest(malformedPath)).toThrow("parse");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("error includes file path", () => {
|
|
95
|
+
const filePath = join(FIXTURES_DIR, "does-not-exist.yaml");
|
|
96
|
+
try {
|
|
97
|
+
loadManifest(filePath);
|
|
98
|
+
expect.unreachable("Should have thrown");
|
|
99
|
+
} catch (error) {
|
|
100
|
+
expect(error).toBeInstanceOf(ManifestLoadError);
|
|
101
|
+
expect((error as ManifestLoadError).filePath).toBe(filePath);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe("loadManifestFromDir", () => {
|
|
107
|
+
test("loads manifest from directory with enact.yaml", () => {
|
|
108
|
+
const testDir = join(TEST_DIR, "yaml-dir");
|
|
109
|
+
mkdirSync(testDir, { recursive: true });
|
|
110
|
+
writeFileSync(
|
|
111
|
+
join(testDir, "enact.yaml"),
|
|
112
|
+
`
|
|
113
|
+
name: test/yaml
|
|
114
|
+
description: Test YAML manifest
|
|
115
|
+
`,
|
|
116
|
+
"utf-8"
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const result = loadManifestFromDir(testDir);
|
|
120
|
+
expect(result.manifest.name).toBe("test/yaml");
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("loads manifest from directory with enact.md", () => {
|
|
124
|
+
const testDir = join(TEST_DIR, "md-dir");
|
|
125
|
+
mkdirSync(testDir, { recursive: true });
|
|
126
|
+
writeFileSync(
|
|
127
|
+
join(testDir, "enact.md"),
|
|
128
|
+
`---
|
|
129
|
+
name: test/md
|
|
130
|
+
description: Test Markdown manifest
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
# Documentation
|
|
134
|
+
`,
|
|
135
|
+
"utf-8"
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const result = loadManifestFromDir(testDir);
|
|
139
|
+
expect(result.manifest.name).toBe("test/md");
|
|
140
|
+
expect(result.format).toBe("md");
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test("prefers enact.md over enact.yaml", () => {
|
|
144
|
+
const testDir = join(TEST_DIR, "both-dir");
|
|
145
|
+
mkdirSync(testDir, { recursive: true });
|
|
146
|
+
|
|
147
|
+
// Create both files
|
|
148
|
+
writeFileSync(
|
|
149
|
+
join(testDir, "enact.md"),
|
|
150
|
+
`---
|
|
151
|
+
name: test/md-preferred
|
|
152
|
+
description: Markdown version
|
|
153
|
+
---
|
|
154
|
+
`,
|
|
155
|
+
"utf-8"
|
|
156
|
+
);
|
|
157
|
+
writeFileSync(
|
|
158
|
+
join(testDir, "enact.yaml"),
|
|
159
|
+
`
|
|
160
|
+
name: test/yaml-version
|
|
161
|
+
description: YAML version
|
|
162
|
+
`,
|
|
163
|
+
"utf-8"
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
const result = loadManifestFromDir(testDir);
|
|
167
|
+
expect(result.manifest.name).toBe("test/md-preferred");
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test("throws for directory without manifest", () => {
|
|
171
|
+
const emptyDir = join(TEST_DIR, "empty-dir");
|
|
172
|
+
mkdirSync(emptyDir, { recursive: true });
|
|
173
|
+
|
|
174
|
+
expect(() => loadManifestFromDir(emptyDir)).toThrow(ManifestLoadError);
|
|
175
|
+
expect(() => loadManifestFromDir(emptyDir)).toThrow("No manifest found");
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
describe("findManifestFile", () => {
|
|
180
|
+
test("finds enact.yaml", () => {
|
|
181
|
+
const testDir = join(TEST_DIR, "find-yaml");
|
|
182
|
+
mkdirSync(testDir, { recursive: true });
|
|
183
|
+
writeFileSync(join(testDir, "enact.yaml"), "name: test/find", "utf-8");
|
|
184
|
+
|
|
185
|
+
const result = findManifestFile(testDir);
|
|
186
|
+
expect(result).toBe(join(testDir, "enact.yaml"));
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test("finds enact.md", () => {
|
|
190
|
+
const testDir = join(TEST_DIR, "find-md");
|
|
191
|
+
mkdirSync(testDir, { recursive: true });
|
|
192
|
+
writeFileSync(join(testDir, "enact.md"), "---\nname: test/find\n---", "utf-8");
|
|
193
|
+
|
|
194
|
+
const result = findManifestFile(testDir);
|
|
195
|
+
expect(result).toBe(join(testDir, "enact.md"));
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test("returns null for empty directory", () => {
|
|
199
|
+
const testDir = join(TEST_DIR, "find-empty");
|
|
200
|
+
mkdirSync(testDir, { recursive: true });
|
|
201
|
+
|
|
202
|
+
const result = findManifestFile(testDir);
|
|
203
|
+
expect(result).toBeNull();
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
describe("hasManifest", () => {
|
|
208
|
+
test("returns true when manifest exists", () => {
|
|
209
|
+
const testDir = join(TEST_DIR, "has-manifest");
|
|
210
|
+
mkdirSync(testDir, { recursive: true });
|
|
211
|
+
writeFileSync(join(testDir, "enact.yaml"), "name: test/has", "utf-8");
|
|
212
|
+
|
|
213
|
+
expect(hasManifest(testDir)).toBe(true);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test("returns false when no manifest", () => {
|
|
217
|
+
const testDir = join(TEST_DIR, "no-manifest");
|
|
218
|
+
mkdirSync(testDir, { recursive: true });
|
|
219
|
+
|
|
220
|
+
expect(hasManifest(testDir)).toBe(false);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe("tryLoadManifest", () => {
|
|
225
|
+
test("returns manifest on success", () => {
|
|
226
|
+
const filePath = join(FIXTURES_DIR, "valid-tool.yaml");
|
|
227
|
+
const result = tryLoadManifest(filePath);
|
|
228
|
+
|
|
229
|
+
expect(result).not.toBeNull();
|
|
230
|
+
expect(result?.manifest.name).toBe("acme/utils/greeter");
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test("returns null on failure", () => {
|
|
234
|
+
const filePath = join(FIXTURES_DIR, "does-not-exist.yaml");
|
|
235
|
+
const result = tryLoadManifest(filePath);
|
|
236
|
+
|
|
237
|
+
expect(result).toBeNull();
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("returns null for invalid manifest", () => {
|
|
241
|
+
const filePath = join(FIXTURES_DIR, "invalid-tool.yaml");
|
|
242
|
+
const result = tryLoadManifest(filePath);
|
|
243
|
+
|
|
244
|
+
expect(result).toBeNull();
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
describe("tryLoadManifestFromDir", () => {
|
|
249
|
+
test("returns manifest on success", () => {
|
|
250
|
+
const testDir = join(TEST_DIR, "try-success");
|
|
251
|
+
mkdirSync(testDir, { recursive: true });
|
|
252
|
+
writeFileSync(
|
|
253
|
+
join(testDir, "enact.yaml"),
|
|
254
|
+
`
|
|
255
|
+
name: test/try
|
|
256
|
+
description: Test try loading
|
|
257
|
+
`,
|
|
258
|
+
"utf-8"
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
const result = tryLoadManifestFromDir(testDir);
|
|
262
|
+
expect(result).not.toBeNull();
|
|
263
|
+
expect(result?.manifest.name).toBe("test/try");
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
test("returns null for empty directory", () => {
|
|
267
|
+
const testDir = join(TEST_DIR, "try-empty");
|
|
268
|
+
mkdirSync(testDir, { recursive: true });
|
|
269
|
+
|
|
270
|
+
const result = tryLoadManifestFromDir(testDir);
|
|
271
|
+
expect(result).toBeNull();
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
describe("ManifestLoadError", () => {
|
|
276
|
+
test("has correct properties", () => {
|
|
277
|
+
const error = new ManifestLoadError("Test error", "/path/to/file.yaml");
|
|
278
|
+
|
|
279
|
+
expect(error.name).toBe("ManifestLoadError");
|
|
280
|
+
expect(error.message).toBe("Test error");
|
|
281
|
+
expect(error.filePath).toBe("/path/to/file.yaml");
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test("preserves original error", () => {
|
|
285
|
+
const original = new Error("Original error");
|
|
286
|
+
const error = new ManifestLoadError("Wrapped", "/path", original);
|
|
287
|
+
|
|
288
|
+
expect(error.originalError).toBe(original);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
});
|