api_ianmenethil_comrouter.ts18 matches
1/**
2* request-gateway.ts — Hono-based request gateway for the v2 API server.
3* Now properly integrated with middleware chains for consistent request processing.
4*/
4950/**
51* OpenAPI Operation interface
52*/
53interface OpenAPIOperation {
54operationId?: string;
55summary?: string;
174175/**
176* Register a handler for an OpenAPI operation ID
177*/
178registerHandler(operationId: string, handler: RouteHandler): this {
217case GatewayRouteType.BROWSER:
218default:
219return "/api/v1";
220}
221}
222223/**
224* Register OpenAPI routes from specification
225*/
226registerOpenApiRoutes(spec: any): this {
227if (!spec.paths) return this;
228233}
234235const operation = operationData as OpenAPIOperation;
236const operationId = operation.operationId;
237if (!operationId) continue;
243}
244245// Determine route type from OpenAPI extensions or path
246const routeType = this.determineRouteType(path, operation);
247248// Convert OpenAPI path to Hono path format
249const honoPath = path.replace(/\{([^}]+)\}/g, ":$1");
250272* Determine route type from path and operation
273*/
274private determineRouteType(path: string, operation: OpenAPIOperation): GatewayRouteType {
275// Check OpenAPI extensions first
276if (operation["x-route-type"]) {
277return operation["x-route-type"] as GatewayRouteType;
294295/**
296* Extract authentication requirement from OpenAPI operation
297*/
298private extractAuthRequirement(operation: OpenAPIOperation): AuthMethod {
299if (!operation.security || operation.security.length === 0) {
300return "none";
306307if (securitySchemes.includes("bearerAuth")) return "jwt";
308if (securitySchemes.includes("apiKey")) return "apiKey";
309if (securitySchemes.includes("oauth2")) return "oauth";
310if (securitySchemes.includes("basicAuth")) return "basic";
370*/
371serve(port = 8000): void {
372console.log(`🚀 API Gateway starting on port ${port}`);
373console.log(`📚 API Documentation: ${APP_CONFIG.server.BASE_URL}/docs`);
374console.log(`🔗 API Base URL: ${APP_CONFIG.server.BASE_URL}/api/v1`);
375console.log("");
376console.log("Middleware chains configured:");
api_ianmenethil_comtavilyClient.ts42 matches
1/**
2* tavily-client.ts - Tavily API integration client for v2
3*/
45import { z } from "z";
67// --- Tavily Search Schema (based on actual API documentation) ---
8export const TavilySearchSchema = z.object({
9query: z.string().min(1, "Search query cannot be empty"),
31export type TavilySearchInput = z.infer<typeof TavilySearchSchema>;
3233// --- Tavily Extract Schema (based on actual API documentation) ---
34export const TavilyExtractSchema = z.object({
35urls: z.union([
45export type TavilyExtractInput = z.infer<typeof TavilyExtractSchema>;
4647// --- Tavily Crawl Schema (based on actual API documentation) ---
48export const TavilyCrawlInputSchema = z.object({
49url: z.string().url("Root URL to begin crawling is required"),
76export type TavilyCrawlInput = z.infer<typeof TavilyCrawlInputSchema>;
7778// --- Tavily Map Schema (based on actual API documentation) ---
79export const TavilyMapInputSchema = z.object({
80url: z.string().url("Root URL to begin mapping is required"),
81max_depth: z.number().int().min(1).optional().default(1),
101});
102103export type TavilyMapInput = z.infer<typeof TavilyMapInputSchema>;
104105// API configuration
106function getTavilyApiKey(): string {
107const key = Deno.env.get("TAVILY_API_KEY") || "";
108if (!key) {
109throw new Error("Configuration error: invalid or missing TAVILY_API_KEY");
110}
111return key;
112}
113114const TAVILY_API_BASE_URL = "https://api.tavily.com";
115116/**
117* Perform a search using the Tavily API.
118*/
119export async function performTavilySearch(input: TavilySearchInput): Promise<unknown> {
120const apiKey = getTavilyApiKey();
121const options = {
122method: "POST",
123headers: {
124"Authorization": `Bearer ${apiKey}`,
125"Content-Type": "application/json",
126},
128};
129130const response = await fetch(`${TAVILY_API_BASE_URL}/search`, options);
131132if (!response.ok) {
136} catch {
137console.error(
138`Failed to parse error response from Tavily API for search: ${response.status} - ${response.statusText}`,
139);
140}
146147/**
148* Perform an extract using the Tavily API.
149*/
150export async function performTavilyExtract(input: TavilyExtractInput): Promise<unknown> {
151const apiKey = getTavilyApiKey();
152153// Ensure urls is always an array for the API
154const apiInput = {
155...input,
156urls: Array.isArray(input.urls) ? input.urls : [input.urls],
160method: "POST",
161headers: {
162"Authorization": `Bearer ${apiKey}`,
163"Content-Type": "application/json",
164},
165body: JSON.stringify(apiInput),
166};
167168const response = await fetch(`${TAVILY_API_BASE_URL}/extract`, options);
169170if (!response.ok) {
174} catch {
175console.error(
176`Failed to parse error response from Tavily API for extract: ${response.status} - ${response.statusText}`,
177);
178}
184185/**
186* Perform a crawl using the Tavily API (BETA).
187*/
188export async function performTavilyCrawl(input: TavilyCrawlInput): Promise<unknown> {
189const apiKey = getTavilyApiKey();
190191// Convert empty arrays to null as per API documentation
192const apiInput = {
193...input,
194select_paths: input.select_paths?.length ? input.select_paths : null,
202method: "POST",
203headers: {
204"Authorization": `Bearer ${apiKey}`,
205"Content-Type": "application/json",
206},
207body: JSON.stringify(apiInput),
208};
209210const response = await fetch(`${TAVILY_API_BASE_URL}/crawl`, options);
211212if (!response.ok) {
216} catch {
217console.error(
218`Failed to parse error response from Tavily API for crawl: ${response.status} - ${response.statusText}`,
219);
220}
226227/**
228* Perform a site map using the Tavily API (BETA).
229*/
230export async function performTavilyMap(input: TavilyMapInput): Promise<unknown> {
231const apiKey = getTavilyApiKey();
232233// Convert empty arrays to null as per API documentation
234const apiInput = {
235...input,
236select_paths: input.select_paths?.length ? input.select_paths : null,
244method: "POST",
245headers: {
246"Authorization": `Bearer ${apiKey}`,
247"Content-Type": "application/json",
248},
249body: JSON.stringify(apiInput),
250};
251252const response = await fetch(`${TAVILY_API_BASE_URL}/map`, options);
253254if (!response.ok) {
258} catch {
259console.error(
260`Failed to parse error response from Tavily API for map: ${response.status} - ${response.statusText}`,
261);
262}
api_ianmenethil_comopenaiClient.ts2 matches
1// Future implementation of OpenAI client for API calls
2import { OpenAI } from "openai";
34const openai = new OpenAI({
5apiKey: Deno.env.get("OPENAI_API_KEY"),
6});
7
api_ianmenethil_comfirecrawlClient.ts20 matches
1// F:\zApps\valtown.servers\APIServer\src\external-apis\firecrawl-client.ts
23import FirecrawlApp from "firecrawl";
94export type ScraperInput = z.infer<typeof ScraperSchema>;
9596// Map schema - Based on actual Firecrawl API documentation
97export const FirecrawlMapInputSchema = z.object({
98url: z.string().url("Invalid URL format"),
99search: z.string().optional(),
105});
106107export type FirecrawlMapInput = z.infer<typeof FirecrawlMapInputSchema>;
108109function getApiKey(): string {
110const key = Deno.env.get("FIRECRAWL_API_KEY") || "";
111if (!key) {
112throw new Error("Configuration error: invalid or missing FIRECRAWL_API_KEY");
113}
114return key;
116117function getFirecrawlClient(): FirecrawlApp {
118const apiKey = getApiKey();
119return new FirecrawlApp({ apiKey });
120}
121122/**
123* Fetch content via the Firecrawl API scrape endpoint.
124* Handles single page scraping with all supported options.
125*/
126export async function fetchFromFirecrawlAPI(
127input: ScraperInput,
128): Promise<unknown> {
170171/**
172* Perform a map operation using the Firecrawl API.
173* Maps all URLs from a website using Firecrawl's dedicated map endpoint.
174*/
175export async function performFirecrawlMap(
176input: FirecrawlMapInput,
177): Promise<unknown> {
178const firecrawl = getFirecrawlClient();
181// Use the dedicated map method from FirecrawlApp
182// Note: The FirecrawlApp SDK might need to be updated to support the map endpoint
183// If the SDK doesn't have a map method, we'll need to make a direct API call
184185// Check if FirecrawlApp has a map method
195});
196} else {
197// Fallback to direct API call if SDK doesn't support map
198const apiKey = getApiKey();
199const response = await fetch("https://api.firecrawl.dev/v1/map", {
200method: "POST",
201headers: {
202"Authorization": `Bearer ${apiKey}`,
203"Content-Type": "application/json",
204},
212} catch {
213console.error(
214`Failed to parse error response from Firecrawl API for map: ${response.status} - ${response.statusText}`,
215);
216}
api_ianmenethil_comserviceRegistry.ts13 matches
1314// Documentation services - Updated to use handler functions
15import { getOpenAPIJSON, getOpenAPIYAML } from "../handlers/openapiService.ts";
16import { getSwaggerUI } from "../handlers/swaggerService.ts";
17import { getRedoc } from "../handlers/redoclyService.ts";
21import { proxyGetHandler, proxyPostHandler } from "../handlers/proxyService.ts";
2223// External API services
24import {
25tavilyCrawlHandler,
27tavilyMapHandler,
28tavilySearchHandler,
29} from "../handlers/tavilyApiService.ts";
30import { firecrawlMapHandler, firecrawlScrapeHandler } from "../handlers/firecrawlApiService.ts";
31import { getApiInfo, getVersion } from "../handlers/infoService.ts";
32import { getHash } from "../handlers/hashService.ts";
338485// === Documentation Handlers - Now using imported functions ===
86getOpenAPIJSON,
87getOpenAPIYAML,
88getSwaggerUI,
89getRedoc,
95proxyPost: proxyPostHandler,
9697// === External API Handlers ===
98tavilySearch: tavilySearchHandler,
99tavilyExtract: tavilyExtractHandler,
104105// Info and Version Handlers (Implemented)
106getApiInfo,
107getVersion,
108191"handleSpotifyCallback",
192],
193"Documentation": ["getOpenAPIJSON", "getOpenAPIYAML", "getSwaggerUI", "getRedoc"],
194"Utility (Echo)": ["echoGet", "echoPost"],
195"Utility (Proxy)": ["proxyGet", "proxyPost"],
196"External API (Tavily)": ["tavilySearch", "tavilyExtract", "tavilyCrawl", "tavilyMap"],
197"External API (Firecrawl)": ["firecrawlScrape", "firecrawlMap"],
198"Info": ["getApiInfo", "getVersion"],
199};
200
api_ianmenethil_comservicesConfig.ts13 matches
1// F:\zApps\valtown.servers\APIServer\src\config\services.config.ts
2export const EXTERNAL_SERVICES_CONFIG = {
3TAVILY: {
4API_KEY: Deno.env.get("TAVILY_API_KEY"),
5BASE_URL: "https://api.tavily.com",
6TIMEOUT: 30000,
7ENABLED: !!Deno.env.get("TAVILY_API_KEY"),
8},
9FIRECRAWL: {
10API_KEY: Deno.env.get("FIRECRAWL_API_KEY"),
11BASE_URL: "https://api.firecrawl.dev",
12TIMEOUT: 60000,
13ENABLED: !!Deno.env.get("FIRECRAWL_API_KEY"),
14},
15OPENAI: {
16API_KEY: Deno.env.get("OPENAI_API_KEY"),
17BASE_URL: "https://api.openai.com/v1",
18TIMEOUT: 30000,
19ENABLED: !!Deno.env.get("OPENAI_API_KEY"),
20},
21RESEND: {
22API_KEY: Deno.env.get("RESEND_API_KEY"),
23BASE_URL: "https://api.resend.com",
24TIMEOUT: 30000,
25ENABLED: !!Deno.env.get("RESEND_API_KEY"),
26},
27};
api_ianmenethil_comsecurityConfig.ts2 matches
111} as Record<string, { windowMs: number; maxRequests: number }>,
112113/* OAuth & internal API limits */
114oauth: { windowMs: 900_000, maxAttempts: 5 },
115internal: { windowMs: 60_000, maxRequests: 1_000, burstLimit: 50 },
116117/* Response shaping */
118standardHeaders: true,
119legacyHeaders: false,
api_ianmenethil_comsecurityTypes.ts2 matches
1// F:\zApps\valtown.servers\APIServer\src\core\security.types.ts
2/**
3* Unified Security Types
241242/**
243* Internal API rate limit configuration
244*/
245export interface InternalRateLimit {
api_ianmenethil_comrequestTypes.ts5 matches
1// F:\zApps\valtown.servers\APIServer\src\core\request.types.ts
23import type {
70userAgent?: string;
71plugin?: string;
72openApiPath?: string;
73openApiOperation?: unknown;
74metadata?: Record<string, unknown>;
75}
80}
8182export interface OpenAPIOperationExtension {
83"x-rate-limit"?: RouteRateLimitConfig;
84"x-auth-required"?: boolean;
100handler: RouteHandler;
101middleware: MiddlewareHandler[];
102auth: AuthMethod | "none" | "jwt" | "apiKey" | "oauth";
103plugin?: string;
104rateLimit?: RouteRateLimitConfig;
1// F:\zApps\valtown.servers\APIServer\src\config\header.types.ts
2/**
3* CORS configuration types