|
1 | 1 | /** |
2 | | - * The API — the single source of truth. |
3 | | - * |
4 | | - * Endpoints are defined once as an Effect `HttpApi`; the typed server, the |
5 | | - * OpenAPI document (`/openapi.json`), and downstream artifacts (MCP, CLI) all |
6 | | - * derive from this. Runs as a pure web fetch handler on Cloudflare Workers. |
| 2 | + * The REST API — defined once as an Effect HttpApi. The typed server and the |
| 3 | + * OpenAPI document (/openapi.json) both derive from this. Runs as a pure web |
| 4 | + * fetch handler on Cloudflare Workers. |
7 | 5 | */ |
8 | | -import { Effect, FileSystem, Layer, Path, Schema } from "effect"; |
| 6 | +import { FileSystem, Layer, Path } from "effect"; |
9 | 7 | import { Etag, HttpPlatform } from "effect/unstable/http"; |
10 | 8 | import * as HttpRouter from "effect/unstable/http/HttpRouter"; |
11 | 9 | import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi"; |
12 | | -import { detect } from "../src/lib/detect.ts"; |
13 | | - |
14 | | -// Response shape (top-level typed; per-format detail kept loose for now). |
15 | | -const DetectionResult = Schema.Struct({ |
16 | | - domain: Schema.String, |
17 | | - found: Schema.Array(Schema.String), |
18 | | - apiCatalog: Schema.optional(Schema.Unknown), |
19 | | - apiSchema: Schema.optional(Schema.Unknown), |
20 | | - mcp: Schema.Array(Schema.Unknown), |
21 | | - agentCard: Schema.optional(Schema.Unknown), |
22 | | - agentSkills: Schema.optional(Schema.Unknown), |
23 | | - llmsTxt: Schema.Boolean, |
24 | | - errors: Schema.Array(Schema.String), |
25 | | -}); |
| 10 | +import * as OpenApi from "effect/unstable/httpapi/OpenApi"; |
| 11 | +import { DetectionResult, DetectParams, runDetect } from "./operations.ts"; |
26 | 12 |
|
27 | 13 | const Detect = HttpApiEndpoint.get("detect", "/api/:domain/detect", { |
28 | | - params: Schema.Struct({ domain: Schema.String }), |
| 14 | + params: DetectParams, |
29 | 15 | success: DetectionResult, |
30 | 16 | }); |
31 | 17 |
|
32 | | -export const Api = HttpApi.make("integrations.sh").add( |
33 | | - HttpApiGroup.make("detect").add(Detect), |
34 | | -); |
| 18 | +export const Api = HttpApi.make("integrations.sh") |
| 19 | + .add(HttpApiGroup.make("detect").add(Detect)) |
| 20 | + .annotate(OpenApi.Title, "integrations.sh") |
| 21 | + .annotate(OpenApi.Version, "0.1.0") |
| 22 | + .annotate( |
| 23 | + OpenApi.Description, |
| 24 | + "Discover how to integrate with any service — APIs, MCP servers, GraphQL, CLIs — and detect what a domain exposes to agents.", |
| 25 | + ); |
35 | 26 |
|
36 | 27 | const DetectGroup = HttpApiBuilder.group(Api, "detect", (handlers) => |
37 | | - handlers.handle("detect", (req: { readonly params: { readonly domain: string } }) => |
38 | | - Effect.promise(() => detect(req.params.domain.trim().toLowerCase()) as Promise<typeof DetectionResult.Type>), |
39 | | - ), |
| 28 | + handlers.handle("detect", (req: { readonly params: { readonly domain: string } }) => runDetect(req.params.domain)), |
40 | 29 | ); |
41 | 30 |
|
42 | 31 | const Platform = Layer.mergeAll(Path.layer, Etag.layerWeak, HttpPlatform.layer).pipe( |
|
0 commit comments