fetch-socialsfetchMastodon.tsx2 matches
2324// Step 1: Look up the account ID
25const accountLookupUrl = `https://${MASTODON_INSTANCE}/api/v1/accounts/lookup?acct=${MASTODON_USERNAME}`;
26console.log("Looking up account ID...");
2737// Step 2: Fetch recent posts (statuses)
38const statusesUrl =
39`https://${MASTODON_INSTANCE}/api/v1/accounts/${accountId}/statuses?limit=40&exclude_replies=true&exclude_reblogs=true`;
40console.log("Fetching recent posts...");
41
flyFlyApiClient.ts13 matches
1// Fly.io API client and HTTP endpoints
2import { Hono } from "https://esm.sh/hono@3.11.7";
39});
1011// Types for Fly.io API responses
12interface FlyApp {
13id: string;
47}
4849// Base API client functions that can be imported by other files
50export class FlyApiClient {
51private token: string;
52private baseUrl = 'https://api.machines.dev/v1';
5354constructor() {
6970if (!response.ok) {
71throw new Error(`Fly.io API error: ${response.status} ${response.statusText}`);
72}
73104app.get('/apps', async (c) => {
105try {
106const client = new FlyApiClient();
107const orgSlug = c.req.query('org_slug') || 'personal';
108const apps = await client.getApps(orgSlug);
115app.get('/apps/:appName', async (c) => {
116try {
117const client = new FlyApiClient();
118const appName = c.req.param('appName');
119const app = await client.getApp(appName);
126app.get('/apps/:appName/machines', async (c) => {
127try {
128const client = new FlyApiClient();
129const appName = c.req.param('appName');
130const machines = await client.getMachines(appName);
137app.get('/apps/:appName/machines/:machineId', async (c) => {
138try {
139const client = new FlyApiClient();
140const appName = c.req.param('appName');
141const machineId = c.req.param('machineId');
149app.get('/apps/:appName/machines/:machineId/events', async (c) => {
150try {
151const client = new FlyApiClient();
152const appName = c.req.param('appName');
153const machineId = c.req.param('machineId');
159});
160161// Root endpoint with API documentation
162app.get('/', (c) => {
163return c.json({
164message: 'Fly.io API Proxy',
165endpoints: {
166'GET /apps': 'List all apps (optional ?org_slug=personal)',
1import { FlyApiClient } from "./FlyApiClient.ts";
23export default async function(req: Request): Promise<Response> {
4try {
5const client = new FlyApiClient();
6const response = await client.getApps();
7const apps = response.apps || [];
1920export interface AppConfig {
21anthropicApiKey: string;
22mcpServers: MCPServer[];
23selectedModel: string;
36export default function App() {
37const [config, setConfig] = useState<AppConfig>({
38anthropicApiKey: "",
39mcpServers: DEFAULT_MCP_SERVERS,
40selectedModel: "claude-3-5-sonnet-20241022",
45// Load config from localStorage on mount
46useEffect(() => {
47const savedApiKey = localStorage.getItem("anthropic_api_key");
48const savedMcpServers = localStorage.getItem("mcp_servers");
49const savedMessages = localStorage.getItem("chat_messages");
5152setConfig({
53anthropicApiKey: savedApiKey || "",
54mcpServers: savedMcpServers ? JSON.parse(savedMcpServers) : DEFAULT_MCP_SERVERS,
55selectedModel: savedModel || "claude-3-5-sonnet-20241022",
66}
6768// Show settings if no API key is configured
69if (!savedApiKey) {
70setShowSettings(true);
71}
74// Save config to localStorage when it changes
75useEffect(() => {
76if (config.anthropicApiKey) {
77localStorage.setItem("anthropic_api_key", config.anthropicApiKey);
78}
79localStorage.setItem("mcp_servers", JSON.stringify(config.mcpServers));
1# Anthropic Streaming Chat with MCP
23A mobile-optimized single page chat application that uses the Anthropic Messages API with **real-time streaming** and MCP (Model Context Protocol) server support.
45Source: https://www.val.town/x/c15r/Chat
16- **⏹️ Stream control** - Stop streaming at any time with the stop button
17- Full-screen mobile-optimized chat interface
18- Direct client-side Anthropic API integration with server-side streaming proxy
19- **Model selection** - Choose between different Claude models (3.5 Sonnet, 3.5 Haiku, 3 Opus, etc.) without clearing chat history
20- Configurable MCP servers with localStorage persistence
5960The app stores configuration and chat history in localStorage:
61- `anthropic_api_key`: Your Anthropic API key
62- `selected_model`: The chosen Claude model (defaults to claude-3-5-sonnet-20241022)
63- `mcp_servers`: Array of configured MCP servers
64- `chat_messages`: Complete chat history (persists between page loads)
6566## API Endpoints
6768- `POST /api/chat/stream` - Real-time streaming chat responses (SSE)
69- `POST /api/chat` - Non-streaming chat responses (fallback)
70- `POST /api/test-mcp` - Test MCP server connectivity and protocol compliance
7172## Usage
73741. Open the app at the provided URL
752. Click "Settings" in the footer to configure your Anthropic API key and select your preferred Claude model
763. Add/remove/toggle MCP servers as needed
774. Use the "Test" button next to each MCP server to verify connectivity (shows ✅ for success, ❌ for errors)
100- **Auto-scroll**: Messages automatically scroll to bottom during streaming
101- **Auto-resize**: Input field grows with content
102- **Error Handling**: Clear error messages for API issues with stream recovery
103- **Loading States**: Visual feedback during API calls and streaming
104- **Structured Responses**: MCP tool use and results are displayed in organized, collapsible sections
105- **Clean Interface**: Maximized chat area with no header, footer contains all controls
55});
5657// API Routes with middleware
58app.route('/api/auth', authRoutes);
5960// Protected product routes (some require auth, some don't)
61app.use('/api/products/*', optionalAuthMiddleware); // Optional auth for viewing
62app.route('/api/products', productRoutes);
6364// TODO: Add other route modules
65// app.use('/api/orders/*', authMiddleware);
66// app.use('/api/orders/*', customerMiddleware);
67// app.route('/api/orders', orderRoutes);
6869// app.use('/api/solutions/*', optionalAuthMiddleware);
70// app.route('/api/solutions', solutionRoutes);
7172// app.use('/api/admin/*', authMiddleware);
73// app.use('/api/admin/*', adminMiddleware);
74// app.route('/api/admin', adminRoutes);
7576// Serve static files from frontend and shared directories
89user: null, // Will be populated by frontend auth check
90config: {
91apiUrl: '/api',
92stripePublishableKey: Deno.env.get('STRIPE_PUBLISHABLE_KEY') || '',
93companyName: 'IoT Solutions Company',
127app.get("*", async c => {
128try {
129// For SPA routing, serve the main index.html for all non-API routes
130const path = c.req.path;
131
132// Skip API routes and static files
133if (path.startsWith('/api/') ||
134path.startsWith('/frontend/') ||
135path.startsWith('/shared/') ||
146user: null,
147config: {
148apiUrl: '/api',
149stripePublishableKey: Deno.env.get('STRIPE_PUBLISHABLE_KEY') || '',
150companyName: 'IoT Solutions Company',
Test2products.ts12 matches
910/**
11* GET /api/products
12* Search and filter products with pagination
13*/
4344/**
45* GET /api/products/featured
46* Get featured products
47*/
6667/**
68* GET /api/products/categories
69* Get all product categories
70*/
8485/**
86* GET /api/products/:id
87* Get product details by ID
88*/
110111/**
112* GET /api/products/sku/:sku
113* Get product details by SKU
114*/
136137/**
138* POST /api/products
139* Create a new product (admin only)
140*/
174175/**
176* PUT /api/products/:id
177* Update a product (admin only)
178*/
230231/**
232* PATCH /api/products/:id/stock
233* Update product stock quantity (admin only)
234*/
294295/**
296* DELETE /api/products/:id
297* Soft delete a product (admin only)
298*/
332333/**
334* GET /api/products/:id/related
335* Get related products (same category)
336*/
369370/**
371* GET /api/products/category/:slug
372* Get products by category slug
373*/
408409/**
410* POST /api/products/bulk-update
411* Bulk update products (admin only)
412*/
1112/**
13* POST /api/auth/register
14* Register a new user account
15*/
7778/**
79* POST /api/auth/login
80* Authenticate user and return JWT token
81*/
128129/**
130* POST /api/auth/refresh
131* Refresh JWT token using refresh token
132*/
170171/**
172* POST /api/auth/forgot-password
173* Send password reset email
174*/
216217/**
218* POST /api/auth/reset-password
219* Reset password using reset token
220*/
272273/**
274* POST /api/auth/change-password
275* Change password for authenticated user
276*/
328329/**
330* GET /api/auth/me
331* Get current user profile
332*/
359360/**
361* PUT /api/auth/profile
362* Update user profile
363*/
3import type { PaymentIntent, CheckoutRequest } from '../../shared/types.ts';
45// Stripe API wrapper (simplified for Val Town)
6export class StripeService {
7private apiKey: string;
8private baseUrl = 'https://api.stripe.com/v1';
910constructor() {
11this.apiKey = Deno.env.get('STRIPE_SECRET_KEY') || '';
12if (!this.apiKey) {
13console.warn('STRIPE_SECRET_KEY not found in environment variables');
14}
19*/
20async createPaymentIntent(amount: number, currency = 'usd', metadata?: Record<string, string>): Promise<PaymentIntent> {
21if (!this.apiKey) {
22throw new Error('Stripe API key not configured');
23}
2438method: 'POST',
39headers: {
40'Authorization': `Bearer ${this.apiKey}`,
41'Content-Type': 'application/x-www-form-urlencoded',
42},
46if (!response.ok) {
47const error = await response.json();
48throw new Error(`Stripe API error: ${error.error?.message || 'Unknown error'}`);
49}
5062*/
63async retrievePaymentIntent(paymentIntentId: string): Promise<any> {
64if (!this.apiKey) {
65throw new Error('Stripe API key not configured');
66}
6768const response = await fetch(`${this.baseUrl}/payment_intents/${paymentIntentId}`, {
69headers: {
70'Authorization': `Bearer ${this.apiKey}`,
71},
72});
74if (!response.ok) {
75const error = await response.json();
76throw new Error(`Stripe API error: ${error.error?.message || 'Unknown error'}`);
77}
7884*/
85async confirmPaymentIntent(paymentIntentId: string, paymentMethodId: string): Promise<any> {
86if (!this.apiKey) {
87throw new Error('Stripe API key not configured');
88}
8995method: 'POST',
96headers: {
97'Authorization': `Bearer ${this.apiKey}`,
98'Content-Type': 'application/x-www-form-urlencoded',
99},
103if (!response.ok) {
104const error = await response.json();
105throw new Error(`Stripe API error: ${error.error?.message || 'Unknown error'}`);
106}
107113*/
114async createCustomer(email: string, name?: string, metadata?: Record<string, string>): Promise<any> {
115if (!this.apiKey) {
116throw new Error('Stripe API key not configured');
117}
118134method: 'POST',
135headers: {
136'Authorization': `Bearer ${this.apiKey}`,
137'Content-Type': 'application/x-www-form-urlencoded',
138},
142if (!response.ok) {
143const error = await response.json();
144throw new Error(`Stripe API error: ${error.error?.message || 'Unknown error'}`);
145}
146152*/
153async createRefund(paymentIntentId: string, amount?: number, reason?: string): Promise<any> {
154if (!this.apiKey) {
155throw new Error('Stripe API key not configured');
156}
157171method: 'POST',
172headers: {
173'Authorization': `Bearer ${this.apiKey}`,
174'Content-Type': 'application/x-www-form-urlencoded',
175},
179if (!response.ok) {
180const error = await response.json();
181throw new Error(`Stripe API error: ${error.error?.message || 'Unknown error'}`);
182}
183