@fentaris/cli 0.1.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/LICENSE.txt +21 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +870 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +150 -0
- package/dist/index.test.js.map +1 -0
- package/package.json +48 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright 2026 gabriele cipriani
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type SpawnOptions } from "node:child_process";
|
|
3
|
+
type CliOptions = Record<string, string | boolean>;
|
|
4
|
+
type CliCommand = {
|
|
5
|
+
name: string;
|
|
6
|
+
args: string[];
|
|
7
|
+
options: CliOptions;
|
|
8
|
+
};
|
|
9
|
+
type PackageManager = "pnpm" | "npm" | "bun";
|
|
10
|
+
type CommandResult = {
|
|
11
|
+
code: number;
|
|
12
|
+
};
|
|
13
|
+
type ProcessRunner = (command: string, args: string[], options?: SpawnOptions) => Promise<CommandResult>;
|
|
14
|
+
type ExecProbe = (command: string, args?: string[]) => boolean;
|
|
15
|
+
export type Prompt = {
|
|
16
|
+
text(question: string, options?: {
|
|
17
|
+
secret?: boolean;
|
|
18
|
+
defaultValue?: string;
|
|
19
|
+
}): Promise<string>;
|
|
20
|
+
select<T extends string>(question: string, choices: T[]): Promise<T>;
|
|
21
|
+
confirm(question: string): Promise<boolean>;
|
|
22
|
+
close(): void;
|
|
23
|
+
};
|
|
24
|
+
export type Runtime = {
|
|
25
|
+
cwd: string;
|
|
26
|
+
env: NodeJS.ProcessEnv;
|
|
27
|
+
out: Pick<typeof console, "log" | "error">;
|
|
28
|
+
runner: ProcessRunner;
|
|
29
|
+
probe: ExecProbe;
|
|
30
|
+
prompt: Prompt;
|
|
31
|
+
};
|
|
32
|
+
type TemplateInput = {
|
|
33
|
+
projectName: string;
|
|
34
|
+
packageManager: PackageManager;
|
|
35
|
+
port: number;
|
|
36
|
+
proxyPath: string;
|
|
37
|
+
authKey: string;
|
|
38
|
+
guestApiKey: string;
|
|
39
|
+
adminApiKey: string;
|
|
40
|
+
};
|
|
41
|
+
type ProjectConfig = {
|
|
42
|
+
name: string;
|
|
43
|
+
packageManager: PackageManager;
|
|
44
|
+
entrypoint: string;
|
|
45
|
+
port: number;
|
|
46
|
+
path: string;
|
|
47
|
+
authDir: string;
|
|
48
|
+
upstreams?: Array<{
|
|
49
|
+
name: string;
|
|
50
|
+
type: "stdio" | "http";
|
|
51
|
+
url?: string;
|
|
52
|
+
command?: string;
|
|
53
|
+
args?: string[];
|
|
54
|
+
}>;
|
|
55
|
+
};
|
|
56
|
+
type ProjectDiscovery = {
|
|
57
|
+
root: string;
|
|
58
|
+
configPath: string;
|
|
59
|
+
config: ProjectConfig;
|
|
60
|
+
};
|
|
61
|
+
export declare function main(argv: string[], runtime?: Runtime): Promise<number>;
|
|
62
|
+
export declare function parseCommand(argv: string[]): CliCommand;
|
|
63
|
+
export declare function resolveProjectName(provided: string | undefined, prompt: Prompt): Promise<string>;
|
|
64
|
+
export declare function ensureEmptyTargetDirectory(targetDir: string): Promise<void>;
|
|
65
|
+
export declare function selectPackageManager(probe: ExecProbe, prompt: Prompt): Promise<PackageManager>;
|
|
66
|
+
export declare function renderTemplate(input: TemplateInput): {
|
|
67
|
+
files: Record<string, string>;
|
|
68
|
+
authKey: string;
|
|
69
|
+
guestApiKey: string;
|
|
70
|
+
adminApiKey: string;
|
|
71
|
+
};
|
|
72
|
+
export declare function discoverProject(fromDir: string): Promise<ProjectDiscovery>;
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
3
|
+
import { constants as fsConstants } from "node:fs";
|
|
4
|
+
import { access, copyFile, mkdir, readdir, readFile, stat, writeFile, } from "node:fs/promises";
|
|
5
|
+
import { createInterface } from "node:readline/promises";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { FentarisAuth } from "@fentaris/core";
|
|
9
|
+
const supportedPackageManagers = ["pnpm", "npm", "bun"];
|
|
10
|
+
const authDir = ".fentaris/auth";
|
|
11
|
+
const buildDir = ".fentaris/build";
|
|
12
|
+
const remoteMcpUrl = "https://mcp.specification.website/mcp";
|
|
13
|
+
const cliVersion = "0.1.0";
|
|
14
|
+
export async function main(argv, runtime = defaultRuntime()) {
|
|
15
|
+
const command = parseCommand(argv);
|
|
16
|
+
try {
|
|
17
|
+
await route(command, runtime);
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
runtime.out.error(style.fail(error instanceof Error ? error.message : String(error)));
|
|
22
|
+
return 1;
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
runtime.prompt.close();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function parseCommand(argv) {
|
|
29
|
+
const args = [];
|
|
30
|
+
const options = {};
|
|
31
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
32
|
+
const arg = argv[index];
|
|
33
|
+
if (!arg.startsWith("--")) {
|
|
34
|
+
args.push(arg);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const name = arg.slice(2);
|
|
38
|
+
const value = argv[index + 1];
|
|
39
|
+
if (!value || value.startsWith("--")) {
|
|
40
|
+
options[name] = true;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
options[name] = value;
|
|
44
|
+
index += 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { name: args[0] ?? "help", args: args.slice(1), options };
|
|
48
|
+
}
|
|
49
|
+
async function route(command, runtime) {
|
|
50
|
+
if (command.name === "help" || command.options.help === true) {
|
|
51
|
+
printHelp(runtime);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (command.name === "version") {
|
|
55
|
+
runtime.out.log(cliVersion);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (command.name === "auth") {
|
|
59
|
+
await runLegacyAuth(command, runtime);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (command.name === "secrets") {
|
|
63
|
+
await runSecrets(command, runtime);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (command.name === "init") {
|
|
67
|
+
await runInit(command, runtime);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (command.name === "doctor") {
|
|
71
|
+
await runDoctor(command, runtime);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (command.name === "check") {
|
|
75
|
+
await runCheck(command, runtime);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (command.name === "dev") {
|
|
79
|
+
await runDev(command, runtime);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (command.name === "build") {
|
|
83
|
+
await runBuild(command, runtime);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
throw new Error(`Unknown command "${command.name}". Run fentaris help.`);
|
|
87
|
+
}
|
|
88
|
+
async function runInit(command, runtime) {
|
|
89
|
+
const projectName = await resolveProjectName(command.args[0], runtime.prompt);
|
|
90
|
+
const targetDir = path.resolve(runtime.cwd, projectName);
|
|
91
|
+
await ensureEmptyTargetDirectory(targetDir);
|
|
92
|
+
const packageManager = await selectPackageManager(runtime.probe, runtime.prompt);
|
|
93
|
+
const template = renderTemplate({
|
|
94
|
+
projectName,
|
|
95
|
+
packageManager,
|
|
96
|
+
port: numberOption(command.options, "port", 4000),
|
|
97
|
+
proxyPath: stringOption(command.options, "path", "/mcp"),
|
|
98
|
+
authKey: randomToken("fentaris-auth"),
|
|
99
|
+
guestApiKey: randomToken("guest"),
|
|
100
|
+
adminApiKey: randomToken("admin"),
|
|
101
|
+
});
|
|
102
|
+
section(runtime, "Create Project");
|
|
103
|
+
await writeTemplate(targetDir, template.files);
|
|
104
|
+
await initTemplateAuth(path.join(targetDir, authDir), template.authKey, template.guestApiKey, template.adminApiKey);
|
|
105
|
+
runtime.out.log(style.pass(`Created ${projectName}`));
|
|
106
|
+
section(runtime, "Install");
|
|
107
|
+
if (command.options["skip-install"] === true) {
|
|
108
|
+
runtime.out.log(style.warn("Skipped dependency install by request."));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
await runPackageInstall(packageManager, targetDir, runtime.runner);
|
|
112
|
+
runtime.out.log(style.pass(`Installed dependencies with ${packageManager}`));
|
|
113
|
+
}
|
|
114
|
+
section(runtime, "Git");
|
|
115
|
+
await runtime.runner("git", ["init"], { cwd: targetDir, stdio: "ignore" });
|
|
116
|
+
runtime.out.log(style.pass("Initialized git repository"));
|
|
117
|
+
section(runtime, "Doctor");
|
|
118
|
+
const doctorResults = await getDoctorResults({ ...runtime, cwd: targetDir }, false);
|
|
119
|
+
printHealthResults(runtime, doctorResults);
|
|
120
|
+
section(runtime, "Next Steps");
|
|
121
|
+
runtime.out.log(`Demo guest API key: ${template.guestApiKey}`);
|
|
122
|
+
runtime.out.log(`Demo admin API key: ${template.adminApiKey}`);
|
|
123
|
+
runtime.out.log(nextSteps([`cd ${projectName}`, "fentaris dev"]));
|
|
124
|
+
}
|
|
125
|
+
export async function resolveProjectName(provided, prompt) {
|
|
126
|
+
const value = provided?.trim() || (await prompt.text("Project name"));
|
|
127
|
+
if (!value.trim()) {
|
|
128
|
+
throw new Error("Project name is required.");
|
|
129
|
+
}
|
|
130
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(value)) {
|
|
131
|
+
throw new Error("Project name may only contain letters, numbers, dots, underscores, and hyphens.");
|
|
132
|
+
}
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
export async function ensureEmptyTargetDirectory(targetDir) {
|
|
136
|
+
try {
|
|
137
|
+
const current = await readdir(targetDir);
|
|
138
|
+
if (current.length > 0) {
|
|
139
|
+
throw new Error(`Fentaris can only initialize into a new or empty directory: ${targetDir}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if (isNodeError(error, "ENOENT")) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export async function selectPackageManager(probe, prompt) {
|
|
150
|
+
const available = supportedPackageManagers.filter((manager) => probe(manager, ["--version"]));
|
|
151
|
+
if (available.length === 0) {
|
|
152
|
+
throw new Error("No supported package manager found. Install pnpm, npm, or bun.");
|
|
153
|
+
}
|
|
154
|
+
if (available.length === 1) {
|
|
155
|
+
return available[0];
|
|
156
|
+
}
|
|
157
|
+
return prompt.select("Package manager", available);
|
|
158
|
+
}
|
|
159
|
+
async function runDoctor(command, runtime) {
|
|
160
|
+
section(runtime, "Doctor");
|
|
161
|
+
const results = await getDoctorResults(runtime, command.options.fix === true);
|
|
162
|
+
printHealthResults(runtime, results);
|
|
163
|
+
if (hasFailure(results) || (command.options.strict === true && hasWarning(results))) {
|
|
164
|
+
throw new Error("Doctor reported issues.");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async function getDoctorResults(runtime, shouldFix) {
|
|
168
|
+
const results = [
|
|
169
|
+
{
|
|
170
|
+
group: "Runtime",
|
|
171
|
+
label: "Node.js",
|
|
172
|
+
status: Number(process.versions.node.split(".")[0]) >= 20 ? "pass" : "fail",
|
|
173
|
+
detail: `Detected ${process.versions.node}; Fentaris requires Node 20 or newer.`,
|
|
174
|
+
},
|
|
175
|
+
...supportedPackageManagers.map((manager) => ({
|
|
176
|
+
group: "Runtime",
|
|
177
|
+
label: manager,
|
|
178
|
+
status: runtime.probe(manager, ["--version"]) ? "pass" : "warn",
|
|
179
|
+
detail: runtime.probe(manager, ["--version"]) ? "Available" : "Not found",
|
|
180
|
+
})),
|
|
181
|
+
{
|
|
182
|
+
group: "Runtime",
|
|
183
|
+
label: "git",
|
|
184
|
+
status: runtime.probe("git", ["--version"]) ? "pass" : "fail",
|
|
185
|
+
detail: runtime.probe("git", ["--version"]) ? "Available" : "Required for project initialization.",
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
group: "Runtime",
|
|
189
|
+
label: "Docker",
|
|
190
|
+
status: runtime.probe("docker", ["--version"]) ? "pass" : "warn",
|
|
191
|
+
detail: runtime.probe("docker", ["--version"]) ? "Available" : "Optional for future container workflows.",
|
|
192
|
+
},
|
|
193
|
+
await cliDirectoryResult(runtime.cwd),
|
|
194
|
+
await writableResult(runtime.cwd),
|
|
195
|
+
await portResult(numberOption({}, "port", 4000)),
|
|
196
|
+
];
|
|
197
|
+
if (shouldFix) {
|
|
198
|
+
for (const result of results.filter((item) => item.fix)) {
|
|
199
|
+
if (await runtime.prompt.confirm(`Apply fix for ${result.label}?`)) {
|
|
200
|
+
await result.fix?.();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return results;
|
|
205
|
+
}
|
|
206
|
+
async function runCheck(command, runtime) {
|
|
207
|
+
section(runtime, "Project Check");
|
|
208
|
+
const project = await discoverProject(runtime.cwd);
|
|
209
|
+
const results = await getProjectCheckResults(project, command.options.offline === true);
|
|
210
|
+
printHealthResults(runtime, results);
|
|
211
|
+
if (hasFailure(results) || (command.options.strict === true && hasWarning(results))) {
|
|
212
|
+
throw new Error("Project check reported issues.");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
async function getProjectCheckResults(project, offline) {
|
|
216
|
+
const expectedFiles = [
|
|
217
|
+
"package.json",
|
|
218
|
+
"tsconfig.json",
|
|
219
|
+
"fentaris.config.json",
|
|
220
|
+
".env.example",
|
|
221
|
+
".gitignore",
|
|
222
|
+
project.config.entrypoint,
|
|
223
|
+
path.join(project.config.authDir, "credentials.enc.json"),
|
|
224
|
+
path.join(project.config.authDir, "upstream-auth.json"),
|
|
225
|
+
];
|
|
226
|
+
const results = [];
|
|
227
|
+
for (const file of expectedFiles) {
|
|
228
|
+
results.push({
|
|
229
|
+
group: "Files",
|
|
230
|
+
label: file,
|
|
231
|
+
status: (await exists(path.join(project.root, file))) ? "pass" : "fail",
|
|
232
|
+
detail: (await exists(path.join(project.root, file))) ? "Found" : "Missing",
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
const packageJson = await readJson(path.join(project.root, "package.json"));
|
|
236
|
+
results.push({
|
|
237
|
+
group: "Package",
|
|
238
|
+
label: "package metadata",
|
|
239
|
+
status: hasPackageMetadata(packageJson) ? "pass" : "fail",
|
|
240
|
+
detail: hasPackageMetadata(packageJson) ? "Fentaris scripts and dependency are present." : "Expected @fentaris/core dependency and dev/build scripts.",
|
|
241
|
+
});
|
|
242
|
+
results.push({
|
|
243
|
+
group: "Auth",
|
|
244
|
+
label: "local auth references",
|
|
245
|
+
status: project.config.authDir === authDir ? "pass" : "warn",
|
|
246
|
+
detail: `Using ${project.config.authDir}`,
|
|
247
|
+
});
|
|
248
|
+
for (const upstream of project.config.upstreams ?? []) {
|
|
249
|
+
if (offline) {
|
|
250
|
+
results.push({ group: "MCP", label: upstream.name, status: "warn", detail: "Skipped connectivity in offline mode." });
|
|
251
|
+
}
|
|
252
|
+
else if (upstream.type === "http" && upstream.url) {
|
|
253
|
+
results.push(await httpUpstreamResult(upstream.name, upstream.url));
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
results.push({
|
|
257
|
+
group: "MCP",
|
|
258
|
+
label: upstream.name,
|
|
259
|
+
status: upstream.command ? "pass" : "fail",
|
|
260
|
+
detail: upstream.command ? `Configured stdio command ${upstream.command}` : "Missing stdio command.",
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return results;
|
|
265
|
+
}
|
|
266
|
+
async function runDev(_command, runtime) {
|
|
267
|
+
const project = await discoverProject(runtime.cwd);
|
|
268
|
+
section(runtime, "Dev");
|
|
269
|
+
runtime.out.log(style.pass(`Starting ${project.config.name} at http://localhost:${project.config.port}${project.config.path}`));
|
|
270
|
+
await runPackageScript(project.config.packageManager, project.root, "dev", runtime.runner);
|
|
271
|
+
}
|
|
272
|
+
async function runBuild(_command, runtime) {
|
|
273
|
+
const project = await discoverProject(runtime.cwd);
|
|
274
|
+
const results = await getProjectCheckResults(project, true);
|
|
275
|
+
if (hasFailure(results)) {
|
|
276
|
+
printHealthResults(runtime, results);
|
|
277
|
+
throw new Error("Build requires a valid Fentaris project.");
|
|
278
|
+
}
|
|
279
|
+
section(runtime, "Build");
|
|
280
|
+
await runPackageScript(project.config.packageManager, project.root, "build", runtime.runner);
|
|
281
|
+
const outputDir = path.join(project.root, buildDir);
|
|
282
|
+
await mkdir(outputDir, { recursive: true });
|
|
283
|
+
await copyFile(path.join(project.root, "package.json"), path.join(outputDir, "package.json"));
|
|
284
|
+
await writeFile(path.join(outputDir, "manifest.json"), JSON.stringify({
|
|
285
|
+
name: project.config.name,
|
|
286
|
+
entrypoint: project.config.entrypoint,
|
|
287
|
+
createdBy: `fentaris ${cliVersion}`,
|
|
288
|
+
}, null, 2));
|
|
289
|
+
runtime.out.log(style.pass(`Build output: ${path.relative(runtime.cwd, outputDir)}`));
|
|
290
|
+
runtime.out.log(`Runtime entrypoint: ${project.config.entrypoint}`);
|
|
291
|
+
}
|
|
292
|
+
async function runSecrets(command, runtime) {
|
|
293
|
+
const [action, reference] = command.args;
|
|
294
|
+
if (action !== "set" || !reference) {
|
|
295
|
+
throw new Error("Usage: fentaris secrets set <reference> [--user <id> | --group <id>]");
|
|
296
|
+
}
|
|
297
|
+
if (typeof command.options.user === "string" && typeof command.options.group === "string") {
|
|
298
|
+
throw new Error("Use either --user or --group, not both.");
|
|
299
|
+
}
|
|
300
|
+
const project = await discoverProject(runtime.cwd);
|
|
301
|
+
const key = await authKeyFromRuntime(runtime, command.options);
|
|
302
|
+
const value = typeof command.options.value === "string" ? command.options.value : await runtime.prompt.text(`Secret value for ${reference}`, { secret: true });
|
|
303
|
+
await storeCredential(path.join(project.root, project.config.authDir), key, reference, value, command.options);
|
|
304
|
+
section(runtime, "Secrets");
|
|
305
|
+
runtime.out.log(style.pass(`Stored ${reference} as ${secretScope(command.options)} credential.`));
|
|
306
|
+
runtime.out.log("Value: <redacted>");
|
|
307
|
+
}
|
|
308
|
+
async function runLegacyAuth(command, runtime) {
|
|
309
|
+
const [action] = command.args;
|
|
310
|
+
if (action === "init") {
|
|
311
|
+
await initAuth(command.options, runtime);
|
|
312
|
+
}
|
|
313
|
+
else if (action === "set-api-key") {
|
|
314
|
+
await setApiKey(command.options, runtime);
|
|
315
|
+
}
|
|
316
|
+
else if (action === "set-credential") {
|
|
317
|
+
await setCredential(command.options, runtime);
|
|
318
|
+
}
|
|
319
|
+
else if (action === "inspect") {
|
|
320
|
+
await inspectAuth(command.options, runtime);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
printHelp(runtime);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
async function initAuth(options, runtime) {
|
|
327
|
+
const dir = required(options, "dir");
|
|
328
|
+
const key = required(options, "key");
|
|
329
|
+
await mkdir(dir, { recursive: true });
|
|
330
|
+
await writeCredentials(dir, key, { users: {}, groups: {}, defaults: {} });
|
|
331
|
+
await writeFile(path.join(dir, "upstream-auth.json"), JSON.stringify({ servers: {} }, null, 2));
|
|
332
|
+
runtime.out.log(style.pass(`Initialized local auth files in ${dir}`));
|
|
333
|
+
}
|
|
334
|
+
async function setApiKey(options, runtime) {
|
|
335
|
+
const dir = required(options, "dir");
|
|
336
|
+
const key = required(options, "key");
|
|
337
|
+
const userId = required(options, "user");
|
|
338
|
+
const apiKey = required(options, "api-key");
|
|
339
|
+
const credentials = await readCredentials(dir, key);
|
|
340
|
+
const user = credentials.users[userId] ?? { apiKeys: [], credentials: {} };
|
|
341
|
+
const hashed = FentarisAuth.hashApiKey(apiKey);
|
|
342
|
+
credentials.users[userId] = {
|
|
343
|
+
...user,
|
|
344
|
+
apiKeys: user.apiKeys.includes(hashed) ? user.apiKeys : [...user.apiKeys, hashed],
|
|
345
|
+
};
|
|
346
|
+
await writeCredentials(dir, key, credentials);
|
|
347
|
+
runtime.out.log(style.pass(`Stored API key hash for user ${userId}`));
|
|
348
|
+
}
|
|
349
|
+
async function setCredential(options, runtime) {
|
|
350
|
+
const dir = required(options, "dir");
|
|
351
|
+
const key = required(options, "key");
|
|
352
|
+
const reference = required(options, "ref");
|
|
353
|
+
const value = required(options, "value");
|
|
354
|
+
await storeCredential(dir, key, reference, value, options);
|
|
355
|
+
runtime.out.log(style.pass(`Stored credential ${reference}`));
|
|
356
|
+
}
|
|
357
|
+
async function storeCredential(dir, key, reference, value, options) {
|
|
358
|
+
const credentials = await readCredentials(dir, key);
|
|
359
|
+
if (typeof options.user === "string") {
|
|
360
|
+
const user = credentials.users[options.user] ?? { apiKeys: [], credentials: {} };
|
|
361
|
+
credentials.users[options.user] = { ...user, credentials: { ...user.credentials, [reference]: value } };
|
|
362
|
+
}
|
|
363
|
+
else if (typeof options.group === "string") {
|
|
364
|
+
credentials.groups[options.group] = { ...(credentials.groups[options.group] ?? {}), [reference]: value };
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
credentials.defaults[reference] = value;
|
|
368
|
+
}
|
|
369
|
+
await writeCredentials(dir, key, credentials);
|
|
370
|
+
}
|
|
371
|
+
async function inspectAuth(options, runtime) {
|
|
372
|
+
const dir = required(options, "dir");
|
|
373
|
+
const key = required(options, "key");
|
|
374
|
+
const credentials = await readCredentials(dir, key);
|
|
375
|
+
const upstreamAuth = JSON.parse(await readFile(path.join(dir, "upstream-auth.json"), "utf8"));
|
|
376
|
+
runtime.out.log(JSON.stringify({
|
|
377
|
+
credentials: {
|
|
378
|
+
users: Object.fromEntries(Object.entries(credentials.users).map(([userId, userEntry]) => [
|
|
379
|
+
userId,
|
|
380
|
+
{
|
|
381
|
+
apiKeys: userEntry.apiKeys.map(() => "<redacted>"),
|
|
382
|
+
credentials: redactRecord(userEntry.credentials),
|
|
383
|
+
},
|
|
384
|
+
])),
|
|
385
|
+
groups: Object.fromEntries(Object.entries(credentials.groups).map(([groupId, values]) => [groupId, redactRecord(values)])),
|
|
386
|
+
defaults: redactRecord(credentials.defaults),
|
|
387
|
+
},
|
|
388
|
+
upstreamAuth,
|
|
389
|
+
}, null, 2));
|
|
390
|
+
}
|
|
391
|
+
export function renderTemplate(input) {
|
|
392
|
+
return {
|
|
393
|
+
authKey: input.authKey,
|
|
394
|
+
guestApiKey: input.guestApiKey,
|
|
395
|
+
adminApiKey: input.adminApiKey,
|
|
396
|
+
files: {
|
|
397
|
+
"package.json": JSON.stringify({
|
|
398
|
+
name: input.projectName,
|
|
399
|
+
version: "0.1.0",
|
|
400
|
+
private: true,
|
|
401
|
+
type: "module",
|
|
402
|
+
scripts: {
|
|
403
|
+
dev: "tsx src/index.ts",
|
|
404
|
+
build: "tsc -p tsconfig.json",
|
|
405
|
+
start: "node dist/index.js",
|
|
406
|
+
},
|
|
407
|
+
dependencies: {
|
|
408
|
+
"@modelcontextprotocol/server-filesystem": "latest",
|
|
409
|
+
"@fentaris/core": "latest",
|
|
410
|
+
tsx: "latest",
|
|
411
|
+
},
|
|
412
|
+
devDependencies: {
|
|
413
|
+
typescript: "latest",
|
|
414
|
+
},
|
|
415
|
+
}, null, 2),
|
|
416
|
+
"tsconfig.json": JSON.stringify({
|
|
417
|
+
compilerOptions: {
|
|
418
|
+
target: "ES2022",
|
|
419
|
+
module: "NodeNext",
|
|
420
|
+
moduleResolution: "NodeNext",
|
|
421
|
+
strict: true,
|
|
422
|
+
esModuleInterop: true,
|
|
423
|
+
skipLibCheck: true,
|
|
424
|
+
outDir: "dist",
|
|
425
|
+
rootDir: "src",
|
|
426
|
+
},
|
|
427
|
+
include: ["src"],
|
|
428
|
+
}, null, 2),
|
|
429
|
+
"fentaris.config.json": JSON.stringify({
|
|
430
|
+
name: input.projectName,
|
|
431
|
+
packageManager: input.packageManager,
|
|
432
|
+
entrypoint: "src/index.ts",
|
|
433
|
+
port: input.port,
|
|
434
|
+
path: input.proxyPath,
|
|
435
|
+
authDir,
|
|
436
|
+
upstreams: [
|
|
437
|
+
{
|
|
438
|
+
name: "demo-files",
|
|
439
|
+
type: "stdio",
|
|
440
|
+
command: "npx",
|
|
441
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", "./demo-files"],
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
name: "specification",
|
|
445
|
+
type: "http",
|
|
446
|
+
url: remoteMcpUrl,
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
}, null, 2),
|
|
450
|
+
".env.example": [
|
|
451
|
+
`FENTARIS_AUTH_KEY=${input.authKey}`,
|
|
452
|
+
`FENTARIS_GUEST_API_KEY=${input.guestApiKey}`,
|
|
453
|
+
`FENTARIS_ADMIN_API_KEY=${input.adminApiKey}`,
|
|
454
|
+
`FENTARIS_PORT=${input.port}`,
|
|
455
|
+
`FENTARIS_PATH=${input.proxyPath}`,
|
|
456
|
+
"",
|
|
457
|
+
].join("\n"),
|
|
458
|
+
".gitignore": [
|
|
459
|
+
"node_modules/",
|
|
460
|
+
"dist/",
|
|
461
|
+
".env",
|
|
462
|
+
".env.*",
|
|
463
|
+
"!.env.example",
|
|
464
|
+
".fentaris/auth/",
|
|
465
|
+
".fentaris/build/",
|
|
466
|
+
"*.log",
|
|
467
|
+
"",
|
|
468
|
+
].join("\n"),
|
|
469
|
+
"src/index.ts": renderEntrypoint(input),
|
|
470
|
+
"demo-files/README.md": "# Fentaris demo files\n\nThis directory is intentionally scoped for the demo filesystem MCP server.\n",
|
|
471
|
+
},
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
function renderEntrypoint(input) {
|
|
475
|
+
return `import {
|
|
476
|
+
McpProxy,
|
|
477
|
+
McpServer,
|
|
478
|
+
MemoryRateLimitStore,
|
|
479
|
+
FentarisAuth,
|
|
480
|
+
Policy,
|
|
481
|
+
SlidingWindowRateLimiter,
|
|
482
|
+
StdioTransport,
|
|
483
|
+
StreamableHttpMcpTransport,
|
|
484
|
+
group,
|
|
485
|
+
rateLimitMiddleware,
|
|
486
|
+
user,
|
|
487
|
+
} from "@fentaris/core";
|
|
488
|
+
|
|
489
|
+
const port = Number(process.env.FENTARIS_PORT ?? ${input.port});
|
|
490
|
+
const proxyPath = process.env.FENTARIS_PATH ?? "${input.proxyPath}";
|
|
491
|
+
const authKey = process.env.FENTARIS_AUTH_KEY ?? "${input.authKey}";
|
|
492
|
+
|
|
493
|
+
const auth = await FentarisAuth.local({
|
|
494
|
+
dir: ".fentaris/auth",
|
|
495
|
+
key: authKey,
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
const guest = user("guest", { displayName: "Guest Demo User" });
|
|
499
|
+
const admin = user("admin", { displayName: "Admin Demo User" });
|
|
500
|
+
|
|
501
|
+
const limitedPolicy = new Policy({ name: "limited-demo" })
|
|
502
|
+
.server("demo-files")
|
|
503
|
+
.allow("list_allowed_directories")
|
|
504
|
+
.server("demo-files")
|
|
505
|
+
.allow("list_directory")
|
|
506
|
+
.server("specification")
|
|
507
|
+
.allow("*");
|
|
508
|
+
|
|
509
|
+
const adminPolicy = Policy.allowAll("admin-full-access");
|
|
510
|
+
const limiter = new SlidingWindowRateLimiter({
|
|
511
|
+
store: new MemoryRateLimitStore(),
|
|
512
|
+
maxPerWindow: 30,
|
|
513
|
+
windowMs: 60_000,
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
const proxy = new McpProxy({
|
|
517
|
+
port,
|
|
518
|
+
path: proxyPath,
|
|
519
|
+
auth,
|
|
520
|
+
groups: [
|
|
521
|
+
group({ id: "limited", users: [guest], policy: limitedPolicy }),
|
|
522
|
+
group({ id: "admins", users: [admin], policy: adminPolicy }),
|
|
523
|
+
],
|
|
524
|
+
servers: [
|
|
525
|
+
new McpServer({
|
|
526
|
+
name: "demo-files",
|
|
527
|
+
transport: new StdioTransport({
|
|
528
|
+
command: "npx",
|
|
529
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", "./demo-files"],
|
|
530
|
+
}),
|
|
531
|
+
}),
|
|
532
|
+
new McpServer({
|
|
533
|
+
name: "specification",
|
|
534
|
+
transport: new StreamableHttpMcpTransport({
|
|
535
|
+
url: "${remoteMcpUrl}",
|
|
536
|
+
}),
|
|
537
|
+
}),
|
|
538
|
+
],
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
proxy.use(rateLimitMiddleware({ limiter }));
|
|
542
|
+
|
|
543
|
+
await proxy.start(() => {
|
|
544
|
+
console.log(\`Fentaris proxy listening at http://localhost:\${port}\${proxyPath}\`);
|
|
545
|
+
console.log("Use x-fentaris-api-key with the generated guest or admin key.");
|
|
546
|
+
});
|
|
547
|
+
`;
|
|
548
|
+
}
|
|
549
|
+
async function writeTemplate(targetDir, files) {
|
|
550
|
+
for (const [relativePath, contents] of Object.entries(files)) {
|
|
551
|
+
const filePath = path.join(targetDir, relativePath);
|
|
552
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
553
|
+
await writeFile(filePath, contents);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
async function initTemplateAuth(dir, key, guestApiKey, adminApiKey) {
|
|
557
|
+
await mkdir(dir, { recursive: true });
|
|
558
|
+
await writeCredentials(dir, key, {
|
|
559
|
+
users: {
|
|
560
|
+
guest: { apiKeys: [FentarisAuth.hashApiKey(guestApiKey)], credentials: {} },
|
|
561
|
+
admin: { apiKeys: [FentarisAuth.hashApiKey(adminApiKey)], credentials: {} },
|
|
562
|
+
},
|
|
563
|
+
groups: { limited: {} },
|
|
564
|
+
defaults: {},
|
|
565
|
+
});
|
|
566
|
+
await writeFile(path.join(dir, "upstream-auth.json"), JSON.stringify({ servers: {}, credentialConflict: "first" }, null, 2));
|
|
567
|
+
}
|
|
568
|
+
export async function discoverProject(fromDir) {
|
|
569
|
+
let current = path.resolve(fromDir);
|
|
570
|
+
while (true) {
|
|
571
|
+
const configPath = path.join(current, "fentaris.config.json");
|
|
572
|
+
if (await exists(configPath)) {
|
|
573
|
+
const config = validateProjectConfig(await readJson(configPath), configPath);
|
|
574
|
+
return { root: current, configPath, config };
|
|
575
|
+
}
|
|
576
|
+
const parent = path.dirname(current);
|
|
577
|
+
if (parent === current) {
|
|
578
|
+
throw new Error("No Fentaris project found. Run this command inside a generated Fentaris project.");
|
|
579
|
+
}
|
|
580
|
+
current = parent;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
function validateProjectConfig(value, configPath) {
|
|
584
|
+
if (!value || typeof value !== "object") {
|
|
585
|
+
throw new Error(`Invalid Fentaris config at ${configPath}`);
|
|
586
|
+
}
|
|
587
|
+
const config = value;
|
|
588
|
+
if (!config.name || !config.packageManager || !config.entrypoint || !config.port || !config.path || !config.authDir) {
|
|
589
|
+
throw new Error(`Invalid Fentaris config at ${configPath}`);
|
|
590
|
+
}
|
|
591
|
+
if (!supportedPackageManagers.includes(config.packageManager)) {
|
|
592
|
+
throw new Error(`Unsupported package manager in ${configPath}`);
|
|
593
|
+
}
|
|
594
|
+
return {
|
|
595
|
+
name: config.name,
|
|
596
|
+
packageManager: config.packageManager,
|
|
597
|
+
entrypoint: config.entrypoint,
|
|
598
|
+
port: config.port,
|
|
599
|
+
path: config.path,
|
|
600
|
+
authDir: config.authDir,
|
|
601
|
+
upstreams: Array.isArray(config.upstreams) ? config.upstreams : [],
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
async function runPackageInstall(packageManager, cwd, runner) {
|
|
605
|
+
const result = await runner(packageManager, packageManager === "npm" ? ["install"] : ["install"], { cwd, stdio: "inherit" });
|
|
606
|
+
if (result.code !== 0) {
|
|
607
|
+
throw new Error(`${packageManager} install failed.`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
async function runPackageScript(packageManager, cwd, script, runner) {
|
|
611
|
+
const args = packageManager === "npm" ? ["run", script] : script === "dev" ? ["dev"] : ["run", script];
|
|
612
|
+
const result = await runner(packageManager, args, { cwd, stdio: "inherit" });
|
|
613
|
+
if (result.code !== 0) {
|
|
614
|
+
throw new Error(`${packageManager} ${script} failed.`);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
async function writableResult(dir) {
|
|
618
|
+
const writable = await canAccess(dir, fsConstants.W_OK);
|
|
619
|
+
return {
|
|
620
|
+
group: "Filesystem",
|
|
621
|
+
label: "CLI writable directory",
|
|
622
|
+
status: writable ? "pass" : "fail",
|
|
623
|
+
detail: writable ? `Writable: ${dir}` : `Cannot write to ${dir}`,
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
async function cliDirectoryResult(cwd) {
|
|
627
|
+
const cliDir = path.join(cwd, ".fentaris");
|
|
628
|
+
const present = await exists(cliDir);
|
|
629
|
+
return {
|
|
630
|
+
group: "Filesystem",
|
|
631
|
+
label: "CLI local directory",
|
|
632
|
+
status: present ? "pass" : "warn",
|
|
633
|
+
detail: present ? `Found ${cliDir}` : `Missing ${cliDir}; doctor --fix can create it.`,
|
|
634
|
+
fix: async () => {
|
|
635
|
+
await mkdir(cliDir, { recursive: true });
|
|
636
|
+
},
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
async function portResult(port) {
|
|
640
|
+
return {
|
|
641
|
+
group: "Network",
|
|
642
|
+
label: `localhost:${port}`,
|
|
643
|
+
status: "pass",
|
|
644
|
+
detail: "Port check is deferred to runtime startup.",
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
async function httpUpstreamResult(name, url) {
|
|
648
|
+
if (!url.startsWith("https://")) {
|
|
649
|
+
return {
|
|
650
|
+
group: "MCP",
|
|
651
|
+
label: name,
|
|
652
|
+
status: "warn",
|
|
653
|
+
detail: `Configured non-HTTPS HTTP upstream ${url}.`,
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
try {
|
|
657
|
+
const controller = new AbortController();
|
|
658
|
+
const timeout = setTimeout(() => controller.abort(), 5_000);
|
|
659
|
+
const response = await fetch(url, { method: "HEAD", signal: controller.signal });
|
|
660
|
+
clearTimeout(timeout);
|
|
661
|
+
return {
|
|
662
|
+
group: "MCP",
|
|
663
|
+
label: name,
|
|
664
|
+
status: response.ok || response.status === 405 ? "pass" : "fail",
|
|
665
|
+
detail: `Connectivity checked for ${url}; tool discovery will run when the project starts.`,
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
catch (error) {
|
|
669
|
+
return {
|
|
670
|
+
group: "MCP",
|
|
671
|
+
label: name,
|
|
672
|
+
status: "fail",
|
|
673
|
+
detail: `Unable to reach ${url}: ${error instanceof Error ? error.message : String(error)}`,
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
function printHealthResults(runtime, results) {
|
|
678
|
+
const groups = Array.from(new Set(results.map((result) => result.group)));
|
|
679
|
+
for (const groupName of groups) {
|
|
680
|
+
runtime.out.log(style.heading(groupName));
|
|
681
|
+
for (const result of results.filter((item) => item.group === groupName)) {
|
|
682
|
+
runtime.out.log(`${marker(result.status)} ${result.label}: ${result.detail}`);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
const failCount = results.filter((result) => result.status === "fail").length;
|
|
686
|
+
const warnCount = results.filter((result) => result.status === "warn").length;
|
|
687
|
+
runtime.out.log(summary(results.length - failCount - warnCount, warnCount, failCount));
|
|
688
|
+
}
|
|
689
|
+
function hasFailure(results) {
|
|
690
|
+
return results.some((result) => result.status === "fail");
|
|
691
|
+
}
|
|
692
|
+
function hasWarning(results) {
|
|
693
|
+
return results.some((result) => result.status === "warn");
|
|
694
|
+
}
|
|
695
|
+
function hasPackageMetadata(value) {
|
|
696
|
+
if (!value || typeof value !== "object") {
|
|
697
|
+
return false;
|
|
698
|
+
}
|
|
699
|
+
const packageJson = value;
|
|
700
|
+
return Boolean(packageJson.dependencies?.["@fentaris/core"] && packageJson.scripts?.dev && packageJson.scripts?.build);
|
|
701
|
+
}
|
|
702
|
+
function section(runtime, title) {
|
|
703
|
+
runtime.out.log(style.heading(title));
|
|
704
|
+
}
|
|
705
|
+
const color = {
|
|
706
|
+
green: "\u001b[32m",
|
|
707
|
+
yellow: "\u001b[33m",
|
|
708
|
+
red: "\u001b[31m",
|
|
709
|
+
cyan: "\u001b[36m",
|
|
710
|
+
bold: "\u001b[1m",
|
|
711
|
+
reset: "\u001b[0m",
|
|
712
|
+
};
|
|
713
|
+
const style = {
|
|
714
|
+
heading: (value) => `${color.bold}${color.cyan}${value}${color.reset}`,
|
|
715
|
+
pass: (value) => `${color.green}✓ ${value}${color.reset}`,
|
|
716
|
+
warn: (value) => `${color.yellow}! ${value}${color.reset}`,
|
|
717
|
+
fail: (value) => `${color.red}✗ ${value}${color.reset}`,
|
|
718
|
+
};
|
|
719
|
+
function marker(status) {
|
|
720
|
+
if (status === "pass") {
|
|
721
|
+
return style.pass("");
|
|
722
|
+
}
|
|
723
|
+
if (status === "warn") {
|
|
724
|
+
return style.warn("");
|
|
725
|
+
}
|
|
726
|
+
return style.fail("");
|
|
727
|
+
}
|
|
728
|
+
function summary(pass, warn, fail) {
|
|
729
|
+
return `Summary: ${pass} pass, ${warn} warn, ${fail} fail`;
|
|
730
|
+
}
|
|
731
|
+
function nextSteps(steps) {
|
|
732
|
+
return ["Next steps:", ...steps.map((step, index) => ` ${index + 1}. ${step}`)].join("\n");
|
|
733
|
+
}
|
|
734
|
+
async function authKeyFromRuntime(runtime, options) {
|
|
735
|
+
if (typeof options.key === "string") {
|
|
736
|
+
return options.key;
|
|
737
|
+
}
|
|
738
|
+
if (typeof runtime.env.FENTARIS_AUTH_KEY === "string" && runtime.env.FENTARIS_AUTH_KEY.trim()) {
|
|
739
|
+
return runtime.env.FENTARIS_AUTH_KEY;
|
|
740
|
+
}
|
|
741
|
+
return runtime.prompt.text("Local auth encryption key", { secret: true });
|
|
742
|
+
}
|
|
743
|
+
function secretScope(options) {
|
|
744
|
+
if (typeof options.user === "string") {
|
|
745
|
+
return `user ${options.user}`;
|
|
746
|
+
}
|
|
747
|
+
if (typeof options.group === "string") {
|
|
748
|
+
return `group ${options.group}`;
|
|
749
|
+
}
|
|
750
|
+
return "default";
|
|
751
|
+
}
|
|
752
|
+
async function readCredentials(dir, key) {
|
|
753
|
+
return FentarisAuth.decryptCredentials(JSON.parse(await readFile(path.join(dir, "credentials.enc.json"), "utf8")), key);
|
|
754
|
+
}
|
|
755
|
+
async function writeCredentials(dir, key, credentials) {
|
|
756
|
+
await writeFile(path.join(dir, "credentials.enc.json"), JSON.stringify(FentarisAuth.encryptCredentials(credentials, key), null, 2));
|
|
757
|
+
}
|
|
758
|
+
function defaultRuntime() {
|
|
759
|
+
return {
|
|
760
|
+
cwd: process.cwd(),
|
|
761
|
+
env: process.env,
|
|
762
|
+
out: console,
|
|
763
|
+
runner: runProcess,
|
|
764
|
+
probe: (command, args = ["--version"]) => spawnSync(command, args, { stdio: "ignore" }).status === 0,
|
|
765
|
+
prompt: createPrompt(),
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
function createPrompt() {
|
|
769
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
770
|
+
return {
|
|
771
|
+
async text(question, options = {}) {
|
|
772
|
+
const answer = await rl.question(`${question}${options.defaultValue ? ` (${options.defaultValue})` : ""}: `);
|
|
773
|
+
return answer.trim() || options.defaultValue || "";
|
|
774
|
+
},
|
|
775
|
+
async select(question, choices) {
|
|
776
|
+
const answer = await rl.question(`${question} (${choices.join("/")}): `);
|
|
777
|
+
const selected = choices.find((choice) => choice === answer.trim());
|
|
778
|
+
if (!selected) {
|
|
779
|
+
throw new Error(`Expected one of: ${choices.join(", ")}`);
|
|
780
|
+
}
|
|
781
|
+
return selected;
|
|
782
|
+
},
|
|
783
|
+
async confirm(question) {
|
|
784
|
+
const answer = await rl.question(`${question} [y/N]: `);
|
|
785
|
+
return answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes";
|
|
786
|
+
},
|
|
787
|
+
close() {
|
|
788
|
+
rl.close();
|
|
789
|
+
},
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
function runProcess(command, args, options = {}) {
|
|
793
|
+
return new Promise((resolve) => {
|
|
794
|
+
const child = spawn(command, args, options);
|
|
795
|
+
child.on("close", (code) => resolve({ code: code ?? 1 }));
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
function required(options, name) {
|
|
799
|
+
const value = options[name];
|
|
800
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
801
|
+
throw new Error(`Missing required --${name}`);
|
|
802
|
+
}
|
|
803
|
+
return value;
|
|
804
|
+
}
|
|
805
|
+
function stringOption(options, name, defaultValue) {
|
|
806
|
+
const value = options[name];
|
|
807
|
+
return typeof value === "string" && value.trim() ? value : defaultValue;
|
|
808
|
+
}
|
|
809
|
+
function numberOption(options, name, defaultValue) {
|
|
810
|
+
const value = options[name];
|
|
811
|
+
if (typeof value !== "string") {
|
|
812
|
+
return defaultValue;
|
|
813
|
+
}
|
|
814
|
+
const parsed = Number(value);
|
|
815
|
+
return Number.isFinite(parsed) ? parsed : defaultValue;
|
|
816
|
+
}
|
|
817
|
+
function randomToken(prefix) {
|
|
818
|
+
return `${prefix}-${Math.random().toString(36).slice(2, 10)}${Date.now().toString(36)}`;
|
|
819
|
+
}
|
|
820
|
+
function redactRecord(record) {
|
|
821
|
+
return Object.fromEntries(Object.keys(record).map((key) => [key, "<redacted>"]));
|
|
822
|
+
}
|
|
823
|
+
async function exists(filePath) {
|
|
824
|
+
try {
|
|
825
|
+
await stat(filePath);
|
|
826
|
+
return true;
|
|
827
|
+
}
|
|
828
|
+
catch (error) {
|
|
829
|
+
if (isNodeError(error, "ENOENT")) {
|
|
830
|
+
return false;
|
|
831
|
+
}
|
|
832
|
+
throw error;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
async function canAccess(filePath, mode) {
|
|
836
|
+
try {
|
|
837
|
+
await access(filePath, mode);
|
|
838
|
+
return true;
|
|
839
|
+
}
|
|
840
|
+
catch {
|
|
841
|
+
return false;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
async function readJson(filePath) {
|
|
845
|
+
return JSON.parse(await readFile(filePath, "utf8"));
|
|
846
|
+
}
|
|
847
|
+
function isNodeError(error, code) {
|
|
848
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
849
|
+
}
|
|
850
|
+
function printHelp(runtime) {
|
|
851
|
+
runtime.out.log(`Usage:
|
|
852
|
+
fentaris init [project-name] [--skip-install]
|
|
853
|
+
fentaris dev
|
|
854
|
+
fentaris check [--offline] [--strict]
|
|
855
|
+
fentaris doctor [--fix]
|
|
856
|
+
fentaris build
|
|
857
|
+
fentaris secrets set <reference> [--user <id> | --group <id>]
|
|
858
|
+
|
|
859
|
+
Legacy local auth:
|
|
860
|
+
fentaris auth init --dir .fentaris/auth --key <key>
|
|
861
|
+
fentaris auth set-api-key --dir .fentaris/auth --key <key> --user <id> --api-key <secret>
|
|
862
|
+
fentaris auth set-credential --dir .fentaris/auth --key <key> --ref <name> --value <secret> [--user <id> | --group <id>]
|
|
863
|
+
fentaris auth inspect --dir .fentaris/auth --key <key>`);
|
|
864
|
+
}
|
|
865
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
|
|
866
|
+
main(process.argv.slice(2)).then((code) => {
|
|
867
|
+
process.exitCode = code;
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAqB,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EACL,MAAM,EACN,QAAQ,EACR,KAAK,EACL,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAyB,MAAM,gBAAgB,CAAC;AAsDrE,MAAM,wBAAwB,GAAqB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAC1E,MAAM,OAAO,GAAG,gBAAgB,CAAC;AACjC,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AACnC,MAAM,YAAY,GAAG,uCAAuC,CAAC;AAC7D,MAAM,UAAU,GAAG,OAAO,CAAC;AAE3B,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAc,EAAE,OAAO,GAAG,cAAc,EAAE;IACnE,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,CAAC;IACX,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,OAAO,GAAe,EAAE,CAAC;IAE/B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YACtB,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;AACnE,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,OAAmB,EAAE,OAAgB;IACxD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC7D,SAAS,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,MAAM,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,CAAC,IAAI,uBAAuB,CAAC,CAAC;AAC3E,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,OAAmB,EAAE,OAAgB;IAC1D,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9E,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACzD,MAAM,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAE5C,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,cAAc,CAAC;QAC9B,WAAW;QACX,cAAc;QACd,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC;QACjD,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;QACxD,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC;QACrC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;QACjC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;KAClC,CAAC,CAAC;IAEH,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACnC,MAAM,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpH,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,WAAW,EAAE,CAAC,CAAC,CAAC;IAEtD,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC5B,IAAI,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,MAAM,iBAAiB,CAAC,cAAc,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,cAAc,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACxB,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC;IAE1D,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3B,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC,CAAC;IACpF,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAE3C,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,uBAAuB,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,uBAAuB,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,WAAW,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,QAA4B,EAAE,MAAc;IACnF,MAAM,KAAK,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IACtE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,SAAiB;IAChE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,+DAA+D,SAAS,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAgB,EAAE,MAAc;IACzE,MAAM,SAAS,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9F,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,OAAmB,EAAE,OAAgB;IAC5D,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;IAC9E,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAgB,EAAE,SAAkB;IAClE,MAAM,OAAO,GAAmB;QAC9B;YACE,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAC3E,MAAM,EAAE,YAAY,OAAO,CAAC,QAAQ,CAAC,IAAI,uCAAuC;SACjF;QACD,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAgB,EAAE,CAAC,CAAC;YAC1D,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAC/D,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW;SAC1E,CAAC,CAAC;QACH;YACE,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAC7D,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,sCAAsC;SACnG;QACD;YACE,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAChE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,0CAA0C;SAC1G;QACD,MAAM,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC;QACrC,MAAM,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC;QACjC,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;KACjD,CAAC;IAEF,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACxD,IAAI,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBACnE,MAAM,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,OAAmB,EAAE,OAAgB;IAC3D,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;IACxF,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,OAAyB,EAAE,OAAgB;IAC/E,MAAM,aAAa,GAAG;QACpB,cAAc;QACd,eAAe;QACf,sBAAsB;QACtB,cAAc;QACd,YAAY;QACZ,OAAO,CAAC,MAAM,CAAC,UAAU;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,sBAAsB,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,oBAAoB,CAAC;KACxD,CAAC;IACF,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,OAAO;YACd,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YACvE,MAAM,EAAE,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC5E,CAAC,CAAC;IACL,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;IAC5E,OAAO,CAAC,IAAI,CAAC;QACX,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,kBAAkB;QACzB,MAAM,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QACzD,MAAM,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAC,2DAA2D;KACvJ,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC;QACX,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,uBAAuB;QAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QAC5D,MAAM,EAAE,SAAS,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE;KAC1C,CAAC,CAAC;IAEH,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;QACtD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,uCAAuC,EAAE,CAAC,CAAC;QACxH,CAAC;aAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,MAAM,kBAAkB,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,QAAQ,CAAC,IAAI;gBACpB,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;gBAC1C,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,4BAA4B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,wBAAwB;aACrG,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,QAAoB,EAAE,OAAgB;IAC1D,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnD,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACxB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,MAAM,CAAC,IAAI,wBAAwB,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAChI,MAAM,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7F,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,QAAoB,EAAE,OAAgB;IAC5D,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1B,MAAM,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7F,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACpD,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAC9F,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EACrC,IAAI,CAAC,SAAS,CACZ;QACE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;QACzB,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU;QACrC,SAAS,EAAE,YAAY,UAAU,EAAE;KACpC,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAmB,EAAE,OAAgB;IAC7D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IACzC,IAAI,MAAM,KAAK,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IAED,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC1F,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/J,MAAM,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/G,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,SAAS,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,OAAmB,EAAE,OAAgB;IAChE,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAC9B,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;SAAM,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QACpC,MAAM,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;SAAM,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;QACvC,MAAM,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,SAAS,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,OAAmB,EAAE,OAAgB;IAC3D,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1E,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,OAAmB,EAAE,OAAgB;IAC5D,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC3E,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC/C,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG;QAC1B,GAAG,IAAI;QACP,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC;KAClF,CAAC;IACF,MAAM,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,MAAM,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,OAAmB,EAAE,OAAgB;IAChE,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,GAAW,EAAE,SAAiB,EAAE,KAAa,EAAE,OAAmB;IAC5G,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAEpD,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;QACjF,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;IAC1G,CAAC;SAAM,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC7C,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;IAC3G,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;IAC1C,CAAC;IAED,MAAM,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAmB,EAAE,OAAgB;IAC9D,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,EAAE,MAAM,CAAC,CAAY,CAAC;IAEzG,OAAO,CAAC,GAAG,CAAC,GAAG,CACb,IAAI,CAAC,SAAS,CACZ;QACE,WAAW,EAAE;YACX,KAAK,EAAE,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC;gBAC7D,MAAM;gBACN;oBACE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC;oBAClD,WAAW,EAAE,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC;iBACjD;aACF,CAAC,CACH;YACD,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1H,QAAQ,EAAE,YAAY,CAAC,WAAW,CAAC,QAAQ,CAAC;SAC7C;QACD,YAAY;KACb,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,KAAK,EAAE;YACL,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;gBACE,IAAI,EAAE,KAAK,CAAC,WAAW;gBACvB,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE;oBACP,GAAG,EAAE,kBAAkB;oBACvB,KAAK,EAAE,sBAAsB;oBAC7B,KAAK,EAAE,oBAAoB;iBAC5B;gBACD,YAAY,EAAE;oBACZ,yCAAyC,EAAE,QAAQ;oBACnD,gBAAgB,EAAE,QAAQ;oBAC1B,GAAG,EAAE,QAAQ;iBACd;gBACD,eAAe,EAAE;oBACf,UAAU,EAAE,QAAQ;iBACrB;aACF,EACD,IAAI,EACJ,CAAC,CACF;YACD,eAAe,EAAE,IAAI,CAAC,SAAS,CAC7B;gBACE,eAAe,EAAE;oBACf,MAAM,EAAE,QAAQ;oBAChB,MAAM,EAAE,UAAU;oBAClB,gBAAgB,EAAE,UAAU;oBAC5B,MAAM,EAAE,IAAI;oBACZ,eAAe,EAAE,IAAI;oBACrB,YAAY,EAAE,IAAI;oBAClB,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,KAAK;iBACf;gBACD,OAAO,EAAE,CAAC,KAAK,CAAC;aACjB,EACD,IAAI,EACJ,CAAC,CACF;YACD,sBAAsB,EAAE,IAAI,CAAC,SAAS,CACpC;gBACE,IAAI,EAAE,KAAK,CAAC,WAAW;gBACvB,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,UAAU,EAAE,cAAc;gBAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,SAAS;gBACrB,OAAO;gBACP,SAAS,EAAE;oBACT;wBACE,IAAI,EAAE,YAAY;wBAClB,IAAI,EAAE,OAAO;wBACb,OAAO,EAAE,KAAK;wBACd,IAAI,EAAE,CAAC,IAAI,EAAE,yCAAyC,EAAE,cAAc,CAAC;qBACxE;oBACD;wBACE,IAAI,EAAE,eAAe;wBACrB,IAAI,EAAE,MAAM;wBACZ,GAAG,EAAE,YAAY;qBAClB;iBACF;aACF,EACD,IAAI,EACJ,CAAC,CACF;YACD,cAAc,EAAE;gBACd,qBAAqB,KAAK,CAAC,OAAO,EAAE;gBACpC,0BAA0B,KAAK,CAAC,WAAW,EAAE;gBAC7C,0BAA0B,KAAK,CAAC,WAAW,EAAE;gBAC7C,iBAAiB,KAAK,CAAC,IAAI,EAAE;gBAC7B,iBAAiB,KAAK,CAAC,SAAS,EAAE;gBAClC,EAAE;aACH,CAAC,IAAI,CAAC,IAAI,CAAC;YACZ,YAAY,EAAE;gBACZ,eAAe;gBACf,OAAO;gBACP,MAAM;gBACN,QAAQ;gBACR,eAAe;gBACf,iBAAiB;gBACjB,kBAAkB;gBAClB,OAAO;gBACP,EAAE;aACH,CAAC,IAAI,CAAC,IAAI,CAAC;YACZ,cAAc,EAAE,gBAAgB,CAAC,KAAK,CAAC;YACvC,sBAAsB,EAAE,uGAAuG;SAChI;KACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAoB;IAC5C,OAAO;;;;;;;;;;;;;;mDAc0C,KAAK,CAAC,IAAI;kDACX,KAAK,CAAC,SAAS;oDACb,KAAK,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA4CjD,YAAY;;;;;;;;;;;;CAY3B,CAAC;AACF,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,KAA6B;IAC3E,KAAK,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,GAAW,EAAE,WAAmB,EAAE,WAAmB;IAChG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE;QAC/B,KAAK,EAAE;YACL,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE;YAC3E,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE;SAC5E;QACD,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACvB,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC;IACH,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/H,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAe;IACnD,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;QAC9D,IAAI,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC;YAC7E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAC/C,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,kFAAkF,CAAC,CAAC;QACtG,CAAC;QACD,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,UAAkB;IAC/D,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,MAAM,GAAG,KAA+B,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpH,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;KACnE,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,cAA8B,EAAE,GAAW,EAAE,MAAqB;IACjG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,cAAc,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7H,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,GAAG,cAAc,kBAAkB,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,cAA8B,EAAE,GAAW,EAAE,MAAc,EAAE,MAAqB;IAChH,MAAM,IAAI,GAAG,cAAc,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,GAAG,cAAc,IAAI,MAAM,UAAU,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAW;IACvC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,KAAK,EAAE,wBAAwB;QAC/B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QAClC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC,CAAC,mBAAmB,GAAG,EAAE;KACjE,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACrC,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,KAAK,EAAE,qBAAqB;QAC5B,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QACjC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC,WAAW,MAAM,+BAA+B;QACtF,GAAG,EAAE,KAAK,IAAI,EAAE;YACd,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,OAAO;QACL,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,aAAa,IAAI,EAAE;QAC1B,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,4CAA4C;KACrD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,IAAY,EAAE,GAAW;IACzD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,sCAAsC,GAAG,GAAG;SACrD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QACjF,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAChE,MAAM,EAAE,4BAA4B,GAAG,oDAAoD;SAC5F,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,mBAAmB,GAAG,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SAC5F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAgB,EAAE,OAAuB;IACnE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1E,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1C,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,CAAC;YACxE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAC9E,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,SAAS,GAAG,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,UAAU,CAAC,OAAuB;IACzC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,UAAU,CAAC,OAAuB;IACzC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,WAAW,GAAG,KAAoF,CAAC;IACzG,OAAO,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,gBAAgB,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACzH,CAAC;AAED,SAAS,OAAO,CAAC,OAAgB,EAAE,KAAa;IAC9C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,KAAK,GAAG;IACZ,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,WAAW;CACnB,CAAC;AAEF,MAAM,KAAK,GAAG;IACZ,OAAO,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE;IAC9E,IAAI,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE;IACjE,IAAI,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE;IAClE,IAAI,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE;CAChE,CAAC;AAEF,SAAS,MAAM,CAAC,MAAoB;IAClC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,OAAO,CAAC,IAAY,EAAE,IAAY,EAAE,IAAY;IACvD,OAAO,YAAY,IAAI,UAAU,IAAI,UAAU,IAAI,OAAO,CAAC;AAC7D,CAAC;AAED,SAAS,SAAS,CAAC,KAAe;IAChC,OAAO,CAAC,aAAa,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9F,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,OAAgB,EAAE,OAAmB;IACrE,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC,GAAG,CAAC;IACrB,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9F,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACvC,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,WAAW,CAAC,OAAmB;IACtC,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,SAAS,OAAO,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,GAAW;IACrD,OAAO,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,EAAE,MAAM,CAAC,CAAY,EAAE,GAAG,CAAC,CAAC;AACrI,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,GAAW,EAAE,WAA6B;IACrF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACtI,CAAC;AAED,SAAS,cAAc;IACrB,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,GAAG,EAAE,OAAO;QACZ,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC;QACpG,MAAM,EAAE,YAAY,EAAE;KACvB,CAAC;AACJ,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,EAAE;YAC/B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAC7G,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO;YAC5B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACzE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,QAAQ;YACpB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,UAAU,CAAC,CAAC;YACxD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;QACtF,CAAC;QACD,KAAK;YACH,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,IAAc,EAAE,UAAwB,EAAE;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,OAAmB,EAAE,IAAY;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,OAAmB,EAAE,IAAY,EAAE,YAAoB;IAC3E,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC;AAC1E,CAAC;AAED,SAAS,YAAY,CAAC,OAAmB,EAAE,IAAY,EAAE,YAAoB;IAC3E,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;AACzD,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,SAAS,YAAY,CAAC,MAA8B;IAClD,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,QAAgB;IACpC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,IAAY;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAY,CAAC;AACjE,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAE,IAAY;IAC/C,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;AAC1E,CAAC;AAED,SAAS,SAAS,CAAC,OAAgB;IACjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;;;;;;;;;;;;yDAYuC,CAAC,CAAC;AAC3D,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QACxC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { mkdtemp, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { FentarisAuth } from "@fentaris/core";
|
|
6
|
+
import { discoverProject, ensureEmptyTargetDirectory, main, parseCommand, renderTemplate, resolveProjectName, selectPackageManager } from "./index.js";
|
|
7
|
+
function prompt(values = []) {
|
|
8
|
+
return {
|
|
9
|
+
text: vi.fn(async () => values.shift() ?? ""),
|
|
10
|
+
select: async (_question, choices) => choices[0],
|
|
11
|
+
confirm: vi.fn(async () => true),
|
|
12
|
+
close: vi.fn(),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function runtime(cwd, probes = {}) {
|
|
16
|
+
const calls = [];
|
|
17
|
+
return {
|
|
18
|
+
cwd,
|
|
19
|
+
env: { FENTARIS_AUTH_KEY: "test-key" },
|
|
20
|
+
out: { log: vi.fn(), error: vi.fn() },
|
|
21
|
+
runner: vi.fn(async (command, args, options) => {
|
|
22
|
+
calls.push({ command, args, cwd: options?.cwd });
|
|
23
|
+
return { code: 0 };
|
|
24
|
+
}),
|
|
25
|
+
probe: vi.fn((command) => probes[command] ?? false),
|
|
26
|
+
prompt: prompt(["secret-value"]),
|
|
27
|
+
calls,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
describe("command routing helpers", () => {
|
|
31
|
+
it("parses nested commands and options", () => {
|
|
32
|
+
expect(parseCommand(["secrets", "set", "github.token", "--user", "alice"])).toEqual({
|
|
33
|
+
name: "secrets",
|
|
34
|
+
args: ["set", "github.token"],
|
|
35
|
+
options: { user: "alice" },
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
it("resolves provided and prompted project names", async () => {
|
|
39
|
+
await expect(resolveProjectName("my-app", prompt())).resolves.toBe("my-app");
|
|
40
|
+
await expect(resolveProjectName(undefined, prompt(["asked-app"]))).resolves.toBe("asked-app");
|
|
41
|
+
});
|
|
42
|
+
it("rejects non-empty target directories", async () => {
|
|
43
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
44
|
+
await writeFile(join(dir, "existing.txt"), "content");
|
|
45
|
+
await expect(ensureEmptyTargetDirectory(dir)).rejects.toThrow("new or empty");
|
|
46
|
+
});
|
|
47
|
+
it("selects a package manager without prompting when only one exists", async () => {
|
|
48
|
+
await expect(selectPackageManager((command) => command === "pnpm", prompt())).resolves.toBe("pnpm");
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("project template", () => {
|
|
52
|
+
it("renders expected files and ignores local secrets", () => {
|
|
53
|
+
const rendered = renderTemplate({
|
|
54
|
+
projectName: "demo",
|
|
55
|
+
packageManager: "pnpm",
|
|
56
|
+
port: 4000,
|
|
57
|
+
proxyPath: "/mcp",
|
|
58
|
+
authKey: "auth-key",
|
|
59
|
+
guestApiKey: "guest-key",
|
|
60
|
+
adminApiKey: "admin-key",
|
|
61
|
+
});
|
|
62
|
+
expect(Object.keys(rendered.files).sort()).toEqual([
|
|
63
|
+
".env.example",
|
|
64
|
+
".gitignore",
|
|
65
|
+
"demo-files/README.md",
|
|
66
|
+
"fentaris.config.json",
|
|
67
|
+
"package.json",
|
|
68
|
+
"src/index.ts",
|
|
69
|
+
"tsconfig.json",
|
|
70
|
+
]);
|
|
71
|
+
expect(rendered.files[".gitignore"]).toContain(".fentaris/auth/");
|
|
72
|
+
expect(rendered.files["src/index.ts"]).toContain("https://mcp.specification.website/mcp");
|
|
73
|
+
expect(rendered.files["src/index.ts"]).toContain("rateLimitMiddleware");
|
|
74
|
+
expect(rendered.files["src/index.ts"]).toContain("admin-full-access");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe("project commands", () => {
|
|
78
|
+
it("initializes a project with dry-run install and git commands", async () => {
|
|
79
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
80
|
+
const rt = runtime(dir, { pnpm: true, git: true, docker: false });
|
|
81
|
+
await expect(main(["init", "demo", "--skip-install"], rt)).resolves.toBe(0);
|
|
82
|
+
const config = JSON.parse(await readFile(join(dir, "demo", "fentaris.config.json"), "utf8"));
|
|
83
|
+
expect(config.name).toBe("demo");
|
|
84
|
+
expect(rt.calls.some((call) => call.command === "git" && call.args[0] === "init")).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
it("discovers projects from nested directories", async () => {
|
|
87
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
88
|
+
const srcDir = join(dir, "src", "nested");
|
|
89
|
+
await mkdir(srcDir, { recursive: true });
|
|
90
|
+
await writeFile(join(dir, "fentaris.config.json"), JSON.stringify({ name: "demo", packageManager: "pnpm", entrypoint: "src/index.ts", port: 4000, path: "/mcp", authDir: ".fentaris/auth" }));
|
|
91
|
+
await expect(discoverProject(srcDir)).resolves.toMatchObject({ root: dir });
|
|
92
|
+
});
|
|
93
|
+
it("runs dev through the discovered package manager", async () => {
|
|
94
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
95
|
+
const rt = runtime(dir, { pnpm: true, git: true, docker: true });
|
|
96
|
+
await expect(main(["init", "demo", "--skip-install"], rt)).resolves.toBe(0);
|
|
97
|
+
rt.cwd = join(dir, "demo", "src");
|
|
98
|
+
await expect(main(["dev"], rt)).resolves.toBe(0);
|
|
99
|
+
expect(rt.calls.some((call) => call.command === "pnpm" && call.args.join(" ") === "dev")).toBe(true);
|
|
100
|
+
});
|
|
101
|
+
it("builds a deterministic local artifact", async () => {
|
|
102
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
103
|
+
const rt = runtime(dir, { pnpm: true, git: true, docker: true });
|
|
104
|
+
await expect(main(["init", "demo", "--skip-install"], rt)).resolves.toBe(0);
|
|
105
|
+
rt.cwd = join(dir, "demo");
|
|
106
|
+
await expect(main(["build"], rt)).resolves.toBe(0);
|
|
107
|
+
const manifest = JSON.parse(await readFile(join(dir, "demo", ".fentaris", "build", "manifest.json"), "utf8"));
|
|
108
|
+
expect(manifest.entrypoint).toBe("src/index.ts");
|
|
109
|
+
expect(rt.calls.some((call) => call.command === "pnpm" && call.args.join(" ") === "run build")).toBe(true);
|
|
110
|
+
});
|
|
111
|
+
it("validates check modes and strict warning exit behavior", async () => {
|
|
112
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
113
|
+
const rt = runtime(dir, { pnpm: true, git: true, docker: false });
|
|
114
|
+
await expect(main(["init", "demo", "--skip-install"], rt)).resolves.toBe(0);
|
|
115
|
+
rt.cwd = join(dir, "demo");
|
|
116
|
+
await expect(main(["check", "--offline"], rt)).resolves.toBe(0);
|
|
117
|
+
await expect(main(["check", "--offline", "--strict"], rt)).resolves.toBe(1);
|
|
118
|
+
await expect(main(["doctor", "--strict"], rt)).resolves.toBe(1);
|
|
119
|
+
});
|
|
120
|
+
it("prompts before applying doctor fixes", async () => {
|
|
121
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
122
|
+
const rt = runtime(dir, { pnpm: true, git: true, docker: true });
|
|
123
|
+
await expect(main(["doctor", "--fix"], rt)).resolves.toBe(0);
|
|
124
|
+
expect(rt.prompt.confirm).toHaveBeenCalledWith("Apply fix for CLI local directory?");
|
|
125
|
+
await expect(readdir(join(dir, ".fentaris"))).resolves.toEqual([]);
|
|
126
|
+
});
|
|
127
|
+
it("does not expose deploy before it is implemented", async () => {
|
|
128
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
129
|
+
const rt = runtime(dir);
|
|
130
|
+
await expect(main(["deploy"], rt)).resolves.toBe(1);
|
|
131
|
+
expect(rt.out.error).toHaveBeenCalledWith(expect.stringContaining('Unknown command "deploy"'));
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe("secrets", () => {
|
|
135
|
+
it("stores redacted user secrets in FentarisAuth-compatible credentials", async () => {
|
|
136
|
+
const dir = await mkdtemp(join(tmpdir(), "fentaris-cli-"));
|
|
137
|
+
const project = join(dir, "project");
|
|
138
|
+
const authDir = join(project, ".fentaris", "auth");
|
|
139
|
+
await mkdir(authDir, { recursive: true });
|
|
140
|
+
await writeFile(join(project, "fentaris.config.json"), JSON.stringify({ name: "demo", packageManager: "pnpm", entrypoint: "src/index.ts", port: 4000, path: "/mcp", authDir: ".fentaris/auth" }));
|
|
141
|
+
await writeFile(join(authDir, "credentials.enc.json"), JSON.stringify(FentarisAuth.encryptCredentials({ users: {}, groups: {}, defaults: {} }, "test-key")));
|
|
142
|
+
await writeFile(join(authDir, "upstream-auth.json"), JSON.stringify({ servers: {} }));
|
|
143
|
+
const rt = runtime(project);
|
|
144
|
+
await expect(main(["secrets", "set", "github.token", "--user", "alice"], rt)).resolves.toBe(0);
|
|
145
|
+
const credentials = FentarisAuth.decryptCredentials(JSON.parse(await readFile(join(authDir, "credentials.enc.json"), "utf8")), "test-key");
|
|
146
|
+
expect(credentials.users.alice?.credentials["github.token"]).toBe("secret-value");
|
|
147
|
+
expect(rt.out.log).toHaveBeenCalledWith("Value: <redacted>");
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fentaris/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Fentaris MCP Proxy - CLI",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"fentaris": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@fentaris/core": "0.1.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/node": "^25.9.1",
|
|
18
|
+
"vitest": "^4.1.7"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"fentaris",
|
|
22
|
+
"mcp",
|
|
23
|
+
"proxy",
|
|
24
|
+
"cli",
|
|
25
|
+
"create"
|
|
26
|
+
],
|
|
27
|
+
"author": "Gabriele Cipriani",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"type": "module",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/fentaris-io/fentaris.git",
|
|
33
|
+
"directory": "packages/cli"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/fentaris-io/fentaris#readme",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/fentaris-io/fentaris/issues"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"dev": "tsc --watch",
|
|
44
|
+
"build": "tsc",
|
|
45
|
+
"test": "vitest run src",
|
|
46
|
+
"clean": "rm -rf dist"
|
|
47
|
+
}
|
|
48
|
+
}
|