@enactprotocol/shared 2.0.0 → 2.0.2
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/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 +17 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +26 -0
- 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 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- 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 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- 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 +112 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +232 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/version.d.ts +62 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +259 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +2 -2
- package/src/config.ts +36 -2
- package/src/index.ts +1 -0
- package/tests/config.test.ts +190 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest loader - combines parsing and validation
|
|
3
|
+
*
|
|
4
|
+
* Provides high-level functions to load tool manifests from files
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
7
|
+
import { basename, join } from "node:path";
|
|
8
|
+
import { MANIFEST_FILES } from "../types/manifest";
|
|
9
|
+
import { ManifestParseError, parseManifestAuto } from "./parser";
|
|
10
|
+
import { validateManifest } from "./validator";
|
|
11
|
+
/**
|
|
12
|
+
* Error thrown when loading a manifest fails
|
|
13
|
+
*/
|
|
14
|
+
export class ManifestLoadError extends Error {
|
|
15
|
+
filePath;
|
|
16
|
+
originalError;
|
|
17
|
+
constructor(message, filePath, originalError) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.filePath = filePath;
|
|
20
|
+
this.originalError = originalError;
|
|
21
|
+
this.name = "ManifestLoadError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Load a manifest from a file path
|
|
26
|
+
*
|
|
27
|
+
* @param filePath - Path to the manifest file (enact.yaml, enact.yml, or enact.md)
|
|
28
|
+
* @returns LoadedManifest with validated manifest and metadata
|
|
29
|
+
* @throws ManifestLoadError if file doesn't exist, parse fails, or validation fails
|
|
30
|
+
*/
|
|
31
|
+
export function loadManifest(filePath) {
|
|
32
|
+
// Check file exists
|
|
33
|
+
if (!existsSync(filePath)) {
|
|
34
|
+
throw new ManifestLoadError(`Manifest file not found: ${filePath}`, filePath);
|
|
35
|
+
}
|
|
36
|
+
// Read file content
|
|
37
|
+
let content;
|
|
38
|
+
try {
|
|
39
|
+
content = readFileSync(filePath, "utf-8");
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw new ManifestLoadError(`Failed to read manifest file: ${error.message}`, filePath, error);
|
|
43
|
+
}
|
|
44
|
+
// Parse the manifest
|
|
45
|
+
let parsed;
|
|
46
|
+
try {
|
|
47
|
+
parsed = parseManifestAuto(content, basename(filePath));
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (error instanceof ManifestParseError) {
|
|
51
|
+
throw new ManifestLoadError(`Failed to parse manifest: ${error.message}`, filePath, error);
|
|
52
|
+
}
|
|
53
|
+
throw new ManifestLoadError(`Failed to parse manifest: ${error.message}`, filePath, error);
|
|
54
|
+
}
|
|
55
|
+
// Validate the manifest
|
|
56
|
+
const validation = validateManifest(parsed.manifest);
|
|
57
|
+
if (!validation.valid) {
|
|
58
|
+
const errorMessages = validation.errors?.map((e) => ` - ${e.path}: ${e.message}`).join("\n") ?? "";
|
|
59
|
+
throw new ManifestLoadError(`Manifest validation failed:\n${errorMessages}`, filePath);
|
|
60
|
+
}
|
|
61
|
+
// Build result
|
|
62
|
+
const result = {
|
|
63
|
+
manifest: parsed.manifest,
|
|
64
|
+
format: parsed.format,
|
|
65
|
+
filePath,
|
|
66
|
+
};
|
|
67
|
+
if (parsed.body) {
|
|
68
|
+
result.body = parsed.body;
|
|
69
|
+
}
|
|
70
|
+
if (validation.warnings && validation.warnings.length > 0) {
|
|
71
|
+
result.warnings = validation.warnings;
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Find and load a manifest from a directory
|
|
77
|
+
*
|
|
78
|
+
* Searches for enact.md, enact.yaml, or enact.yml in the given directory
|
|
79
|
+
*
|
|
80
|
+
* @param dir - Directory to search for manifest
|
|
81
|
+
* @returns LoadedManifest if found
|
|
82
|
+
* @throws ManifestLoadError if no manifest found or loading fails
|
|
83
|
+
*/
|
|
84
|
+
export function loadManifestFromDir(dir) {
|
|
85
|
+
// Try each manifest filename in order of preference
|
|
86
|
+
for (const filename of MANIFEST_FILES) {
|
|
87
|
+
const filePath = join(dir, filename);
|
|
88
|
+
if (existsSync(filePath)) {
|
|
89
|
+
return loadManifest(filePath);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
throw new ManifestLoadError(`No manifest found in directory: ${dir}. Expected one of: ${MANIFEST_FILES.join(", ")}`, dir);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Find a manifest file in a directory without loading it
|
|
96
|
+
*
|
|
97
|
+
* @param dir - Directory to search
|
|
98
|
+
* @returns Path to manifest file or null if not found
|
|
99
|
+
*/
|
|
100
|
+
export function findManifestFile(dir) {
|
|
101
|
+
for (const filename of MANIFEST_FILES) {
|
|
102
|
+
const filePath = join(dir, filename);
|
|
103
|
+
if (existsSync(filePath)) {
|
|
104
|
+
return filePath;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if a directory contains a manifest file
|
|
111
|
+
*
|
|
112
|
+
* @param dir - Directory to check
|
|
113
|
+
* @returns true if a manifest file exists
|
|
114
|
+
*/
|
|
115
|
+
export function hasManifest(dir) {
|
|
116
|
+
return findManifestFile(dir) !== null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Try to load a manifest, returning null instead of throwing
|
|
120
|
+
*
|
|
121
|
+
* @param filePath - Path to the manifest file
|
|
122
|
+
* @returns LoadedManifest or null if loading fails
|
|
123
|
+
*/
|
|
124
|
+
export function tryLoadManifest(filePath) {
|
|
125
|
+
try {
|
|
126
|
+
return loadManifest(filePath);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Try to load a manifest from a directory, returning null instead of throwing
|
|
134
|
+
*
|
|
135
|
+
* @param dir - Directory to search
|
|
136
|
+
* @returns LoadedManifest or null if no manifest found or loading fails
|
|
137
|
+
*/
|
|
138
|
+
export function tryLoadManifestFromDir(dir) {
|
|
139
|
+
try {
|
|
140
|
+
return loadManifestFromDir(dir);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/manifest/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAML and Markdown parser for Enact tool manifests
|
|
3
|
+
*
|
|
4
|
+
* Handles parsing of:
|
|
5
|
+
* - enact.yaml files (pure YAML)
|
|
6
|
+
* - enact.md files (YAML frontmatter + Markdown body)
|
|
7
|
+
*/
|
|
8
|
+
import type { ParsedManifest } from "../types/manifest";
|
|
9
|
+
/**
|
|
10
|
+
* Error thrown when parsing fails
|
|
11
|
+
*/
|
|
12
|
+
export declare class ManifestParseError extends Error {
|
|
13
|
+
readonly originalError: Error | undefined;
|
|
14
|
+
constructor(message: string, originalError?: Error);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parse format type
|
|
18
|
+
*/
|
|
19
|
+
export type ManifestFormat = "yaml" | "md";
|
|
20
|
+
/**
|
|
21
|
+
* Extract YAML frontmatter from Markdown content
|
|
22
|
+
*
|
|
23
|
+
* @param content - The full Markdown file content
|
|
24
|
+
* @returns Object with frontmatter YAML and body Markdown, or null if no frontmatter
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractFrontmatter(content: string): {
|
|
27
|
+
frontmatter: string;
|
|
28
|
+
body: string;
|
|
29
|
+
} | null;
|
|
30
|
+
/**
|
|
31
|
+
* Parse YAML content into a ToolManifest object
|
|
32
|
+
*
|
|
33
|
+
* @param yamlContent - Raw YAML string
|
|
34
|
+
* @returns Parsed object (not yet validated)
|
|
35
|
+
* @throws ManifestParseError if YAML parsing fails
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseYaml(yamlContent: string): Record<string, unknown>;
|
|
38
|
+
/**
|
|
39
|
+
* Parse a manifest from content string
|
|
40
|
+
*
|
|
41
|
+
* @param content - The file content (YAML or Markdown with frontmatter)
|
|
42
|
+
* @param format - The format of the content ('yaml' or 'md')
|
|
43
|
+
* @returns ParsedManifest with manifest object and optional body
|
|
44
|
+
* @throws ManifestParseError if parsing fails
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseManifest(content: string, format: ManifestFormat): ParsedManifest;
|
|
47
|
+
/**
|
|
48
|
+
* Detect manifest format from filename
|
|
49
|
+
*
|
|
50
|
+
* @param filename - The manifest filename
|
|
51
|
+
* @returns The detected format
|
|
52
|
+
* @throws ManifestParseError if format cannot be detected
|
|
53
|
+
*/
|
|
54
|
+
export declare function detectFormat(filename: string): ManifestFormat;
|
|
55
|
+
/**
|
|
56
|
+
* Parse manifest content with automatic format detection
|
|
57
|
+
*
|
|
58
|
+
* @param content - The file content
|
|
59
|
+
* @param filename - The filename (for format detection)
|
|
60
|
+
* @returns ParsedManifest
|
|
61
|
+
* @throws ManifestParseError if parsing fails
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseManifestAuto(content: string, filename: string): ParsedManifest;
|
|
64
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/manifest/parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,mBAAmB,CAAC;AAEtE;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAgB,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;gBAErC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,KAAK;CAKnD;AAQD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,IAAI,CAAC;AAE3C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAcP;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBtE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,cAAc,CAsCrF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAc7D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAGnF"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAML and Markdown parser for Enact tool manifests
|
|
3
|
+
*
|
|
4
|
+
* Handles parsing of:
|
|
5
|
+
* - enact.yaml files (pure YAML)
|
|
6
|
+
* - enact.md files (YAML frontmatter + Markdown body)
|
|
7
|
+
*/
|
|
8
|
+
import yaml from "js-yaml";
|
|
9
|
+
/**
|
|
10
|
+
* Error thrown when parsing fails
|
|
11
|
+
*/
|
|
12
|
+
export class ManifestParseError extends Error {
|
|
13
|
+
originalError;
|
|
14
|
+
constructor(message, originalError) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "ManifestParseError";
|
|
17
|
+
this.originalError = originalError;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Regex to match YAML frontmatter in Markdown files
|
|
22
|
+
* Matches content between --- delimiters at the start of the file
|
|
23
|
+
*/
|
|
24
|
+
const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
25
|
+
/**
|
|
26
|
+
* Extract YAML frontmatter from Markdown content
|
|
27
|
+
*
|
|
28
|
+
* @param content - The full Markdown file content
|
|
29
|
+
* @returns Object with frontmatter YAML and body Markdown, or null if no frontmatter
|
|
30
|
+
*/
|
|
31
|
+
export function extractFrontmatter(content) {
|
|
32
|
+
const match = content.match(FRONTMATTER_REGEX);
|
|
33
|
+
if (!match) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const frontmatter = match[1];
|
|
37
|
+
const body = match[2];
|
|
38
|
+
return {
|
|
39
|
+
frontmatter: frontmatter ? frontmatter.trim() : "",
|
|
40
|
+
body: body ? body.trim() : "",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parse YAML content into a ToolManifest object
|
|
45
|
+
*
|
|
46
|
+
* @param yamlContent - Raw YAML string
|
|
47
|
+
* @returns Parsed object (not yet validated)
|
|
48
|
+
* @throws ManifestParseError if YAML parsing fails
|
|
49
|
+
*/
|
|
50
|
+
export function parseYaml(yamlContent) {
|
|
51
|
+
try {
|
|
52
|
+
const parsed = yaml.load(yamlContent);
|
|
53
|
+
if (parsed === null || parsed === undefined) {
|
|
54
|
+
throw new ManifestParseError("YAML content is empty or null");
|
|
55
|
+
}
|
|
56
|
+
if (typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
57
|
+
throw new ManifestParseError("YAML content must be an object, not an array or primitive");
|
|
58
|
+
}
|
|
59
|
+
return parsed;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof ManifestParseError) {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
const yamlError = error;
|
|
66
|
+
throw new ManifestParseError(`Failed to parse YAML: ${yamlError.message}`, yamlError);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Parse a manifest from content string
|
|
71
|
+
*
|
|
72
|
+
* @param content - The file content (YAML or Markdown with frontmatter)
|
|
73
|
+
* @param format - The format of the content ('yaml' or 'md')
|
|
74
|
+
* @returns ParsedManifest with manifest object and optional body
|
|
75
|
+
* @throws ManifestParseError if parsing fails
|
|
76
|
+
*/
|
|
77
|
+
export function parseManifest(content, format) {
|
|
78
|
+
if (!content || content.trim() === "") {
|
|
79
|
+
throw new ManifestParseError("Manifest content is empty");
|
|
80
|
+
}
|
|
81
|
+
if (format === "yaml") {
|
|
82
|
+
const parsed = parseYaml(content);
|
|
83
|
+
return {
|
|
84
|
+
manifest: parsed,
|
|
85
|
+
format: "yaml",
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Handle Markdown format
|
|
89
|
+
const extracted = extractFrontmatter(content);
|
|
90
|
+
if (!extracted) {
|
|
91
|
+
throw new ManifestParseError("Markdown file must contain YAML frontmatter between --- delimiters");
|
|
92
|
+
}
|
|
93
|
+
if (!extracted.frontmatter) {
|
|
94
|
+
throw new ManifestParseError("YAML frontmatter is empty");
|
|
95
|
+
}
|
|
96
|
+
const parsed = parseYaml(extracted.frontmatter);
|
|
97
|
+
const result = {
|
|
98
|
+
manifest: parsed,
|
|
99
|
+
format: "md",
|
|
100
|
+
};
|
|
101
|
+
if (extracted.body) {
|
|
102
|
+
result.body = extracted.body;
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Detect manifest format from filename
|
|
108
|
+
*
|
|
109
|
+
* @param filename - The manifest filename
|
|
110
|
+
* @returns The detected format
|
|
111
|
+
* @throws ManifestParseError if format cannot be detected
|
|
112
|
+
*/
|
|
113
|
+
export function detectFormat(filename) {
|
|
114
|
+
const lower = filename.toLowerCase();
|
|
115
|
+
if (lower.endsWith(".yaml") || lower.endsWith(".yml")) {
|
|
116
|
+
return "yaml";
|
|
117
|
+
}
|
|
118
|
+
if (lower.endsWith(".md")) {
|
|
119
|
+
return "md";
|
|
120
|
+
}
|
|
121
|
+
throw new ManifestParseError(`Cannot detect manifest format from filename: ${filename}. Expected .yaml, .yml, or .md extension.`);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Parse manifest content with automatic format detection
|
|
125
|
+
*
|
|
126
|
+
* @param content - The file content
|
|
127
|
+
* @param filename - The filename (for format detection)
|
|
128
|
+
* @returns ParsedManifest
|
|
129
|
+
* @throws ManifestParseError if parsing fails
|
|
130
|
+
*/
|
|
131
|
+
export function parseManifestAuto(content, filename) {
|
|
132
|
+
const format = detectFormat(filename);
|
|
133
|
+
return parseManifest(content, format);
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/manifest/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest validator using Zod
|
|
3
|
+
*
|
|
4
|
+
* Validates that parsed manifests conform to the Enact specification
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod/v4";
|
|
7
|
+
import type { ToolManifest, ValidationResult } from "../types/manifest";
|
|
8
|
+
/**
|
|
9
|
+
* Complete tool manifest schema
|
|
10
|
+
*/
|
|
11
|
+
declare const ToolManifestSchema: z.ZodObject<{
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
description: z.ZodString;
|
|
14
|
+
enact: z.ZodOptional<z.ZodString>;
|
|
15
|
+
version: z.ZodOptional<z.ZodString>;
|
|
16
|
+
from: z.ZodOptional<z.ZodString>;
|
|
17
|
+
command: z.ZodOptional<z.ZodString>;
|
|
18
|
+
timeout: z.ZodOptional<z.ZodString>;
|
|
19
|
+
license: z.ZodOptional<z.ZodString>;
|
|
20
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
21
|
+
inputSchema: z.ZodOptional<z.ZodObject<{
|
|
22
|
+
type: z.ZodOptional<z.ZodString>;
|
|
23
|
+
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
24
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
25
|
+
items: z.ZodOptional<z.ZodUnknown>;
|
|
26
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
27
|
+
description: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$loose>>;
|
|
29
|
+
outputSchema: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
type: z.ZodOptional<z.ZodString>;
|
|
31
|
+
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
32
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
33
|
+
items: z.ZodOptional<z.ZodUnknown>;
|
|
34
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
35
|
+
description: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$loose>>;
|
|
37
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
38
|
+
description: z.ZodString;
|
|
39
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
40
|
+
default: z.ZodOptional<z.ZodString>;
|
|
41
|
+
}, z.core.$strip>>>;
|
|
42
|
+
annotations: z.ZodOptional<z.ZodObject<{
|
|
43
|
+
title: z.ZodOptional<z.ZodString>;
|
|
44
|
+
readOnlyHint: z.ZodOptional<z.ZodBoolean>;
|
|
45
|
+
destructiveHint: z.ZodOptional<z.ZodBoolean>;
|
|
46
|
+
idempotentHint: z.ZodOptional<z.ZodBoolean>;
|
|
47
|
+
openWorldHint: z.ZodOptional<z.ZodBoolean>;
|
|
48
|
+
}, z.core.$strip>>;
|
|
49
|
+
resources: z.ZodOptional<z.ZodObject<{
|
|
50
|
+
memory: z.ZodOptional<z.ZodString>;
|
|
51
|
+
gpu: z.ZodOptional<z.ZodString>;
|
|
52
|
+
disk: z.ZodOptional<z.ZodString>;
|
|
53
|
+
}, z.core.$strip>>;
|
|
54
|
+
doc: z.ZodOptional<z.ZodString>;
|
|
55
|
+
authors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
56
|
+
name: z.ZodString;
|
|
57
|
+
email: z.ZodOptional<z.ZodString>;
|
|
58
|
+
url: z.ZodOptional<z.ZodString>;
|
|
59
|
+
}, z.core.$strip>>>;
|
|
60
|
+
examples: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
61
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
62
|
+
output: z.ZodOptional<z.ZodUnknown>;
|
|
63
|
+
description: z.ZodOptional<z.ZodString>;
|
|
64
|
+
}, z.core.$strip>>>;
|
|
65
|
+
}, z.core.$loose>;
|
|
66
|
+
/**
|
|
67
|
+
* Validate a tool manifest
|
|
68
|
+
*
|
|
69
|
+
* @param manifest - The manifest to validate (parsed but unvalidated)
|
|
70
|
+
* @returns ValidationResult with valid flag, errors, and warnings
|
|
71
|
+
*/
|
|
72
|
+
export declare function validateManifest(manifest: unknown): ValidationResult;
|
|
73
|
+
/**
|
|
74
|
+
* Validate and return the typed manifest
|
|
75
|
+
* Throws if validation fails
|
|
76
|
+
*
|
|
77
|
+
* @param manifest - The manifest to validate
|
|
78
|
+
* @returns The validated ToolManifest
|
|
79
|
+
* @throws Error if validation fails
|
|
80
|
+
*/
|
|
81
|
+
export declare function validateManifestStrict(manifest: unknown): ToolManifest;
|
|
82
|
+
/**
|
|
83
|
+
* Check if a string is a valid tool name
|
|
84
|
+
*/
|
|
85
|
+
export declare function isValidToolName(name: string): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Check if a string is a valid semver version
|
|
88
|
+
*/
|
|
89
|
+
export declare function isValidVersion(version: string): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Check if a string is a valid Go duration
|
|
92
|
+
*/
|
|
93
|
+
export declare function isValidTimeout(timeout: string): boolean;
|
|
94
|
+
export { ToolManifestSchema };
|
|
95
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,KAAK,EACV,YAAY,EAEZ,gBAAgB,EAEjB,MAAM,mBAAmB,CAAC;AAkF3B;;GAEG;AACH,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiDR,CAAC;AA+FjB;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,CAkBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,GAAG,YAAY,CAStE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|