@kirrosh/apitool 0.4.3
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/.github/workflows/ci.yml +27 -0
- package/.github/workflows/release.yml +97 -0
- package/.mcp.json +9 -0
- package/APITOOL.md +195 -0
- package/BACKLOG.md +62 -0
- package/CHANGELOG.md +88 -0
- package/LICENSE +21 -0
- package/README.md +105 -0
- package/bun.lock +291 -0
- package/docs/GLOSSARY.md +182 -0
- package/docs/INDEX.md +21 -0
- package/docs/agent.md +135 -0
- package/docs/archive/APITOOL-pre-M22.md +831 -0
- package/docs/archive/BACKLOG-AI-NATIVE.md +56 -0
- package/docs/archive/M1-M2-parser-runner.md +216 -0
- package/docs/archive/M4-M7-reporter-cli.md +179 -0
- package/docs/archive/M5-M7-storage-junit.md +300 -0
- package/docs/archive/M6-webui.md +339 -0
- package/docs/ci.md +274 -0
- package/docs/generation-issues.md +67 -0
- package/generated/.env.yaml +3 -0
- package/install.ps1 +80 -0
- package/install.sh +113 -0
- package/package.json +46 -0
- package/scripts/run-mocked-tests.ts +45 -0
- package/seed-demo.ts +53 -0
- package/self-tests/auth.yaml +18 -0
- package/self-tests/collections-crud.yaml +46 -0
- package/self-tests/environments-crud.yaml +48 -0
- package/self-tests/export.yaml +32 -0
- package/self-tests/runs.yaml +16 -0
- package/src/bun-types.d.ts +5 -0
- package/src/cli/commands/add-api.ts +51 -0
- package/src/cli/commands/ai-generate.ts +106 -0
- package/src/cli/commands/chat.ts +43 -0
- package/src/cli/commands/ci-init.ts +126 -0
- package/src/cli/commands/collections.ts +41 -0
- package/src/cli/commands/coverage.ts +65 -0
- package/src/cli/commands/doctor.ts +127 -0
- package/src/cli/commands/envs.ts +218 -0
- package/src/cli/commands/init.ts +84 -0
- package/src/cli/commands/mcp.ts +16 -0
- package/src/cli/commands/run.ts +137 -0
- package/src/cli/commands/runs.ts +108 -0
- package/src/cli/commands/serve.ts +22 -0
- package/src/cli/commands/update.ts +142 -0
- package/src/cli/commands/validate.ts +18 -0
- package/src/cli/index.ts +500 -0
- package/src/cli/output.ts +24 -0
- package/src/cli/runtime.ts +7 -0
- package/src/core/agent/agent-loop.ts +116 -0
- package/src/core/agent/context-manager.ts +41 -0
- package/src/core/agent/system-prompt.ts +33 -0
- package/src/core/agent/tools/diagnose-failure.ts +51 -0
- package/src/core/agent/tools/explore-api.ts +40 -0
- package/src/core/agent/tools/index.ts +48 -0
- package/src/core/agent/tools/manage-environment.ts +40 -0
- package/src/core/agent/tools/query-results.ts +40 -0
- package/src/core/agent/tools/run-tests.ts +38 -0
- package/src/core/agent/tools/send-request.ts +44 -0
- package/src/core/agent/tools/validate-tests.ts +23 -0
- package/src/core/agent/types.ts +22 -0
- package/src/core/generator/ai/ai-generator.ts +61 -0
- package/src/core/generator/ai/llm-client.ts +159 -0
- package/src/core/generator/ai/output-parser.ts +307 -0
- package/src/core/generator/ai/prompt-builder.ts +153 -0
- package/src/core/generator/ai/types.ts +56 -0
- package/src/core/generator/coverage-scanner.ts +87 -0
- package/src/core/generator/data-factory.ts +115 -0
- package/src/core/generator/index.ts +10 -0
- package/src/core/generator/openapi-reader.ts +142 -0
- package/src/core/generator/schema-utils.ts +52 -0
- package/src/core/generator/serializer.ts +189 -0
- package/src/core/generator/types.ts +47 -0
- package/src/core/parser/filter.ts +14 -0
- package/src/core/parser/index.ts +21 -0
- package/src/core/parser/schema.ts +175 -0
- package/src/core/parser/types.ts +50 -0
- package/src/core/parser/variables.ts +146 -0
- package/src/core/parser/yaml-parser.ts +85 -0
- package/src/core/reporter/console.ts +175 -0
- package/src/core/reporter/index.ts +23 -0
- package/src/core/reporter/json.ts +9 -0
- package/src/core/reporter/junit.ts +78 -0
- package/src/core/reporter/types.ts +12 -0
- package/src/core/runner/assertions.ts +172 -0
- package/src/core/runner/execute-run.ts +75 -0
- package/src/core/runner/executor.ts +150 -0
- package/src/core/runner/http-client.ts +69 -0
- package/src/core/runner/index.ts +12 -0
- package/src/core/runner/types.ts +48 -0
- package/src/core/setup-api.ts +97 -0
- package/src/core/utils.ts +9 -0
- package/src/db/queries.ts +868 -0
- package/src/db/schema.ts +215 -0
- package/src/mcp/server.ts +47 -0
- package/src/mcp/tools/ci-init.ts +57 -0
- package/src/mcp/tools/coverage-analysis.ts +58 -0
- package/src/mcp/tools/explore-api.ts +84 -0
- package/src/mcp/tools/generate-missing-tests.ts +80 -0
- package/src/mcp/tools/generate-tests-guide.ts +353 -0
- package/src/mcp/tools/manage-environment.ts +123 -0
- package/src/mcp/tools/manage-server.ts +87 -0
- package/src/mcp/tools/query-db.ts +141 -0
- package/src/mcp/tools/run-tests.ts +66 -0
- package/src/mcp/tools/save-test-suite.ts +164 -0
- package/src/mcp/tools/send-request.ts +53 -0
- package/src/mcp/tools/setup-api.ts +49 -0
- package/src/mcp/tools/validate-tests.ts +42 -0
- package/src/tui/chat-ui.ts +150 -0
- package/src/web/routes/api.ts +234 -0
- package/src/web/routes/dashboard.ts +348 -0
- package/src/web/routes/runs.ts +64 -0
- package/src/web/schemas.ts +121 -0
- package/src/web/server.ts +134 -0
- package/src/web/static/htmx.min.js +1 -0
- package/src/web/static/style.css +265 -0
- package/src/web/views/layout.ts +46 -0
- package/src/web/views/results.ts +209 -0
- package/tests/agent/agent-loop.test.ts +61 -0
- package/tests/agent/context-manager.test.ts +59 -0
- package/tests/agent/system-prompt.test.ts +42 -0
- package/tests/agent/tools/diagnose-failure.test.ts +85 -0
- package/tests/agent/tools/explore-api.test.ts +59 -0
- package/tests/agent/tools/manage-environment.test.ts +78 -0
- package/tests/agent/tools/query-results.test.ts +77 -0
- package/tests/agent/tools/run-tests.test.ts +89 -0
- package/tests/agent/tools/send-request.test.ts +78 -0
- package/tests/agent/tools/validate-tests.test.ts +59 -0
- package/tests/ai/ai-generator.integration.test.ts +131 -0
- package/tests/ai/llm-client.test.ts +145 -0
- package/tests/ai/output-parser.test.ts +132 -0
- package/tests/ai/prompt-builder.test.ts +67 -0
- package/tests/ai/types.test.ts +55 -0
- package/tests/cli/args.test.ts +63 -0
- package/tests/cli/chat.test.ts +38 -0
- package/tests/cli/ci-init.test.ts +112 -0
- package/tests/cli/commands.test.ts +316 -0
- package/tests/cli/coverage.test.ts +58 -0
- package/tests/cli/doctor.test.ts +39 -0
- package/tests/cli/envs.test.ts +181 -0
- package/tests/cli/init.test.ts +80 -0
- package/tests/cli/runs.test.ts +94 -0
- package/tests/cli/safe-run.test.ts +103 -0
- package/tests/cli/update.test.ts +32 -0
- package/tests/core/generator/schema-utils.test.ts +108 -0
- package/tests/core/parser/nested-assertions.test.ts +80 -0
- package/tests/core/runner/root-body-assertions.test.ts +70 -0
- package/tests/db/chat-queries.test.ts +88 -0
- package/tests/db/chat-schema.test.ts +37 -0
- package/tests/db/environments.test.ts +131 -0
- package/tests/db/queries.test.ts +409 -0
- package/tests/db/schema.test.ts +141 -0
- package/tests/fixtures/.env.yaml +3 -0
- package/tests/fixtures/auth-token-test.yaml +8 -0
- package/tests/fixtures/bail/suite-a.yaml +6 -0
- package/tests/fixtures/bail/suite-b.yaml +6 -0
- package/tests/fixtures/crud.yaml +35 -0
- package/tests/fixtures/invalid-missing-name.yaml +5 -0
- package/tests/fixtures/invalid-no-method.yaml +6 -0
- package/tests/fixtures/petstore-auth.json +295 -0
- package/tests/fixtures/petstore-simple.json +151 -0
- package/tests/fixtures/post-only.yaml +12 -0
- package/tests/fixtures/simple.yaml +6 -0
- package/tests/fixtures/valid/.env.yaml +1 -0
- package/tests/fixtures/valid/a.yaml +5 -0
- package/tests/fixtures/valid/b.yml +5 -0
- package/tests/generator/coverage-scanner.test.ts +129 -0
- package/tests/generator/data-factory.test.ts +133 -0
- package/tests/generator/openapi-reader.test.ts +131 -0
- package/tests/integration/auth-flow.test.ts +217 -0
- package/tests/mcp/coverage-analysis.test.ts +64 -0
- package/tests/mcp/explore-api-schemas.test.ts +105 -0
- package/tests/mcp/explore-api.test.ts +49 -0
- package/tests/mcp/generate-missing-tests.test.ts +69 -0
- package/tests/mcp/manage-environment.test.ts +89 -0
- package/tests/mcp/save-test-suite.test.ts +116 -0
- package/tests/mcp/send-request.test.ts +79 -0
- package/tests/mcp/setup-api.test.ts +106 -0
- package/tests/mcp/tools.test.ts +248 -0
- package/tests/parser/schema.test.ts +134 -0
- package/tests/parser/variables.test.ts +227 -0
- package/tests/parser/yaml-parser.test.ts +69 -0
- package/tests/reporter/console.test.ts +256 -0
- package/tests/reporter/json.test.ts +98 -0
- package/tests/reporter/junit.test.ts +284 -0
- package/tests/runner/assertions.test.ts +262 -0
- package/tests/runner/executor.test.ts +310 -0
- package/tests/runner/http-client.test.ts +138 -0
- package/tests/web/routes.test.ts +160 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { resolve, join } from "path";
|
|
2
|
+
import { mkdirSync, writeFileSync } from "fs";
|
|
3
|
+
import { getDb } from "../db/schema.ts";
|
|
4
|
+
import { createCollection, deleteCollection, upsertEnvironment, findCollectionByNameOrId, normalizePath } from "../db/queries.ts";
|
|
5
|
+
import { readOpenApiSpec, extractEndpoints } from "./generator/index.ts";
|
|
6
|
+
import { toYaml } from "../cli/commands/envs.ts";
|
|
7
|
+
|
|
8
|
+
export interface SetupApiOptions {
|
|
9
|
+
name: string;
|
|
10
|
+
spec?: string;
|
|
11
|
+
dir?: string;
|
|
12
|
+
envVars?: Record<string, string>;
|
|
13
|
+
dbPath?: string;
|
|
14
|
+
force?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface SetupApiResult {
|
|
18
|
+
created: true;
|
|
19
|
+
collectionId: number;
|
|
20
|
+
testPath: string;
|
|
21
|
+
baseUrl: string;
|
|
22
|
+
specEndpoints: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function setupApi(options: SetupApiOptions): Promise<SetupApiResult> {
|
|
26
|
+
const { name, spec, dbPath } = options;
|
|
27
|
+
|
|
28
|
+
getDb(dbPath);
|
|
29
|
+
|
|
30
|
+
// Validate name uniqueness (or force-replace)
|
|
31
|
+
const existing = findCollectionByNameOrId(name);
|
|
32
|
+
if (existing) {
|
|
33
|
+
if (options.force) {
|
|
34
|
+
deleteCollection(existing.id, true);
|
|
35
|
+
} else {
|
|
36
|
+
throw new Error(`API '${name}' already exists (id=${existing.id})`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Sanitize name for directory use
|
|
41
|
+
const dirName = name.replace(/[^a-zA-Z0-9_\-\.]/g, "-").toLowerCase();
|
|
42
|
+
const baseDir = resolve(options.dir ?? `./apis/${dirName}/`);
|
|
43
|
+
const testPath = join(baseDir, "tests");
|
|
44
|
+
|
|
45
|
+
// Create directories
|
|
46
|
+
mkdirSync(testPath, { recursive: true });
|
|
47
|
+
|
|
48
|
+
// Try to load and validate spec, extract base_url
|
|
49
|
+
let openapiSpec: string | null = null;
|
|
50
|
+
let baseUrl = "";
|
|
51
|
+
let endpointCount = 0;
|
|
52
|
+
if (spec) {
|
|
53
|
+
const doc = await readOpenApiSpec(spec);
|
|
54
|
+
openapiSpec = spec;
|
|
55
|
+
if ((doc as any).servers?.[0]?.url) {
|
|
56
|
+
baseUrl = (doc as any).servers[0].url;
|
|
57
|
+
}
|
|
58
|
+
endpointCount = extractEndpoints(doc).length;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Build environment variables
|
|
62
|
+
const envVars: Record<string, string> = {};
|
|
63
|
+
if (baseUrl) envVars.base_url = baseUrl;
|
|
64
|
+
if (options.envVars) {
|
|
65
|
+
Object.assign(envVars, options.envVars);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Write .env.yaml in base_dir
|
|
69
|
+
if (Object.keys(envVars).length > 0) {
|
|
70
|
+
const envFilePath = join(baseDir, ".env.yaml");
|
|
71
|
+
writeFileSync(envFilePath, toYaml(envVars) + "\n", "utf-8");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const normalizedTestPath = normalizePath(testPath);
|
|
75
|
+
const normalizedBaseDir = normalizePath(baseDir);
|
|
76
|
+
|
|
77
|
+
// Create collection in DB
|
|
78
|
+
const collectionId = createCollection({
|
|
79
|
+
name,
|
|
80
|
+
base_dir: normalizedBaseDir,
|
|
81
|
+
test_path: normalizedTestPath,
|
|
82
|
+
openapi_spec: openapiSpec ?? undefined,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Create a scoped "default" environment in DB
|
|
86
|
+
if (Object.keys(envVars).length > 0) {
|
|
87
|
+
upsertEnvironment("default", envVars, collectionId);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
created: true,
|
|
92
|
+
collectionId,
|
|
93
|
+
testPath: normalizedTestPath,
|
|
94
|
+
baseUrl,
|
|
95
|
+
specEndpoints: endpointCount,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function getByPath(obj: unknown, path: string, defaultVal?: unknown): unknown {
|
|
2
|
+
const keys = path.split(".");
|
|
3
|
+
let result: unknown = obj;
|
|
4
|
+
for (const key of keys) {
|
|
5
|
+
result = (result as Record<string, unknown>)?.[key];
|
|
6
|
+
if (result === undefined) return defaultVal;
|
|
7
|
+
}
|
|
8
|
+
return result;
|
|
9
|
+
}
|