├── .DS_Store ├── README.md ├── app ├── .gitignore ├── .vscode │ └── settings.json ├── app.json ├── app │ ├── +not-found.tsx │ ├── _layout.tsx │ └── index.tsx ├── assets │ ├── fonts │ │ └── SpaceMono-Regular.ttf │ └── images │ │ ├── adaptive-icon.png │ │ ├── favicon.png │ │ ├── icon.png │ │ ├── partial-react-logo.png │ │ ├── react-logo.png │ │ ├── react-logo@2x.png │ │ ├── react-logo@3x.png │ │ └── splash-icon.png ├── components │ ├── Collapsible.tsx │ ├── ExternalLink.tsx │ ├── HapticTab.tsx │ ├── HelloWave.tsx │ ├── ThemedText.tsx │ ├── ThemedView.tsx │ └── ui │ │ ├── IconSymbol.ios.tsx │ │ ├── IconSymbol.tsx │ │ ├── TabBarBackground.ios.tsx │ │ └── TabBarBackground.tsx ├── constants │ └── Colors.ts ├── eslint.config.js ├── hooks │ ├── useColorScheme.ts │ ├── useColorScheme.web.ts │ └── useThemeColor.ts ├── package.json ├── pnpm-lock.yaml ├── scripts │ └── reset-project.js ├── tsconfig.json └── utils │ ├── fetch.ts │ ├── polar.ts │ └── polyfills.ts └── server ├── .gitignore ├── README.md ├── package.json ├── pnpm-lock.yaml ├── public └── .well-known │ └── apple-app-site-association ├── src ├── index.ts ├── middlewares.ts └── polar.ts └── tsconfig.json /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Polar React Native Starter 2 | 3 | ## Setup a simple backend 4 | 5 | ```typescript 6 | import dotenv from "dotenv"; 7 | dotenv.config(); 8 | 9 | import { Hono } from "hono"; 10 | import { Checkout } from "@polar-sh/hono"; 11 | import { streamText } from "ai"; 12 | import { Ingestion } from "@polar-sh/ingestion"; 13 | import { LLMStrategy } from "@polar-sh/ingestion/strategies/LLM"; 14 | import { openai } from "@ai-sdk/openai"; 15 | import { serve } from "@hono/node-server"; 16 | import { hasSufficientCredits } from "./middlewares.js"; 17 | import { polarConfig } from "./polar.js"; 18 | 19 | const app = new Hono(); 20 | 21 | /// --- Checkout --- /// 22 | 23 | app.get( 24 | "/checkout", 25 | Checkout({ 26 | ...polarConfig, 27 | successUrl: process.env.POLAR_SUCCESS_URL, 28 | }) 29 | ); 30 | 31 | /// --- LLM --- /// 32 | 33 | const llmIngestion = Ingestion(polarConfig) 34 | .strategy(new LLMStrategy(openai("gpt-4o"))) 35 | .ingest("openai-usage"); 36 | 37 | app.post("/prompt", hasSufficientCredits, async (c) => { 38 | // You should obviously get this from an auth middleware or similar 39 | // but for this example we'll just use a fixed customer id 40 | const customerId = "09b8b19b-ff4a-4b3a-b12d-78ab168bf7bb"; 41 | 42 | const { messages } = await c.req.json(); 43 | 44 | const result = await streamText({ 45 | model: llmIngestion.client({ 46 | customerId, 47 | }), 48 | system: "You are a helpful assistant.", 49 | messages, 50 | }); 51 | 52 | return result.toDataStreamResponse({ 53 | headers: { 54 | "Content-Type": "application/octet-stream", 55 | "Content-Encoding": "none", 56 | }, 57 | }); 58 | }); 59 | 60 | app.get("/checkout_redirect", (c) => { 61 | // Redirect to the app 62 | 63 | // Use the .well-known/apple-app-site-association file to redirect to your app instead 64 | // This is just a small hack for the sake of the demo 65 | return c.redirect("exp://172.22.79.116:8081?checkout_redirect"); 66 | }); 67 | 68 | serve({ 69 | port: 8787, 70 | fetch: app.fetch, 71 | }); 72 | ``` 73 | 74 | #### Environment Variables 75 | 76 | ``` 77 | POLAR_ACCESS_TOKEN=... 78 | POLAR_SUCCESS_URL=https://your-domain.com/checkout_redirect 79 | POLAR_USAGE_METER_ID=... 80 | OPENAI_API_KEY=... 81 | ``` 82 | 83 | ### Add a credits check 84 | 85 | In order to make sure that users have sufficient credits, we can implement a simple middleware. 86 | 87 | ```typescript 88 | import { createMiddleware } from "hono/factory"; 89 | import { polar } from "./polar.js"; 90 | 91 | // You should obviously get this from an auth middleware or similar 92 | // but for this example we'll just use a fixed customer id 93 | const customerId = "09b8b19b-ff4a-4b3a-b12d-78ab168bf7bb"; 94 | 95 | export const hasSufficientCredits = createMiddleware(async (c, next) => { 96 | const meterId = process.env.POLAR_USAGE_METER_ID ?? ""; 97 | 98 | const customerMeter = await polar.customerMeters.list({ 99 | customerId, 100 | meterId, 101 | }); 102 | 103 | const hasCredits = customerMeter.result.items.some( 104 | (customerMeter) => customerMeter.balance > 0 105 | ); 106 | 107 | if (!hasCredits) { 108 | return c.json({ 109 | error: "Insufficient credits", 110 | status: 400, 111 | }); 112 | } 113 | 114 | await next(); 115 | }); 116 | ``` 117 | 118 | ## Register App Links 119 | 120 | ### Apple iOS 121 | 122 | Add a file to your domain at .well-known/apple-app-site-association to define the URLs your app handles. Prepend your App ID with your Team ID, which you can find on the Membership page of the Apple Developer Portal. 123 | 124 | ```json 125 | { 126 | "applinks": { 127 | "apps": [], 128 | "details": [ 129 | { 130 | "appIDs": [ 131 | "XXXXXXXXXX.com.example.MyApp1", 132 | "XXXXXXXXXX.com.example.MyApp1-Debug" 133 | ], 134 | "components": [ 135 | { 136 | "/checkout_redirect": "/checkout_redirect*", 137 | "comment": "Matches any URL whose path starts with /checkout_redirect" 138 | } 139 | ] 140 | } 141 | ] 142 | } 143 | } 144 | ``` 145 | 146 | ### Android 147 | 148 | You can learn more about adding App Links to your Expo Project [here](https://docs.expo.dev/linking/android-app-links/). 149 | 150 | ## Implement the flow in React Native 151 | 152 | ```tsx 153 | import { 154 | StyleSheet, 155 | TouchableOpacity, 156 | TextInput, 157 | FlatList, 158 | KeyboardAvoidingView, 159 | Platform, 160 | SafeAreaView, 161 | } from "react-native"; 162 | import * as Linking from "expo-linking"; 163 | import { fetch as expoFetch } from "expo/fetch"; 164 | import { ThemedText } from "@/components/ThemedText"; 165 | import { ThemedView } from "@/components/ThemedView"; 166 | import { useColorScheme } from "@/hooks/useColorScheme"; 167 | import { useChat } from "@ai-sdk/react"; 168 | import { useEffect, useRef } from "react"; 169 | 170 | export default function HomeScreen() { 171 | const listRef = useRef(null); 172 | const isDark = useColorScheme() === "dark"; 173 | 174 | const currentUrl = Linking.useURL(); 175 | 176 | const { messages, handleInputChange, input, handleSubmit, setMessages } = 177 | useChat({ 178 | fetch: expoFetch as unknown as typeof globalThis.fetch, 179 | api: process.env.EXPO_PUBLIC_API_BASE_URL + "/prompt", 180 | onError: (error) => { 181 | setMessages((messages) => [ 182 | ...messages, 183 | { 184 | id: Math.random().toString(), 185 | role: "assistant", 186 | content: "You have insufficient credits.", 187 | }, 188 | ]); 189 | }, 190 | }); 191 | 192 | useEffect(() => { 193 | if (currentUrl?.includes("?checkout_redirect")) { 194 | setMessages((messages) => [ 195 | ...messages, 196 | { 197 | id: Math.random().toString(), 198 | role: "assistant", 199 | content: 200 | "Thanks for your purchase! 10,000 credits has been added to your account.", 201 | }, 202 | ]); 203 | } 204 | }, [currentUrl, setMessages]); 205 | 206 | const renderMessage = ({ item }: { item: (typeof messages)[number] }) => ( 207 | 216 | {item.content} 217 | {item.content.includes("insufficient credits") && ( 218 | { 221 | // We're using a fixed Customer ID in the case of this demo 222 | const customerId = "09b8b19b-ff4a-4b3a-b12d-78ab168bf7bb"; 223 | const polarCreditsProductId = 224 | "6870a5f6-1ff8-4907-8fe4-52c5c492f65b"; 225 | 226 | const url = new URL( 227 | process.env.EXPO_PUBLIC_API_BASE_URL + "/checkout" 228 | ); 229 | 230 | url.searchParams.set("products", polarCreditsProductId); 231 | url.searchParams.set("customerId", customerId); 232 | Linking.openURL(url.toString()); 233 | }} 234 | > 235 | Please top up your account to continue. 236 | 237 | )} 238 | 239 | ); 240 | 241 | useEffect(() => { 242 | listRef.current?.scrollToEnd(); 243 | }, [messages]); 244 | 245 | return ( 246 | 250 | 251 | 252 | item.id} 257 | style={styles.listContainer} 258 | contentInset={{ bottom: 12 }} 259 | /> 260 | 261 | 267 | 274 | handleInputChange({ 275 | ...e, 276 | target: { 277 | ...e.target, 278 | value: e.nativeEvent.text, 279 | }, 280 | } as unknown as React.ChangeEvent) 281 | } 282 | onSubmitEditing={(e) => { 283 | handleSubmit(e); 284 | e.preventDefault(); 285 | }} 286 | placeholder="Ask anything..." 287 | placeholderTextColor={isDark ? "#666" : "#aaa"} 288 | autoFocus 289 | /> 290 | 295 | 300 | ↑ 301 | 302 | 303 | 304 | 305 | 306 | 307 | ); 308 | } 309 | ``` 310 | 311 | ### Environment Variables 312 | 313 | ``` 314 | EXPO_PUBLIC_POLAR_SERVER_ENVIRONMENT=sandbox 315 | EXPO_PUBLIC_API_BASE_URL=https://your-domain.com 316 | ``` 317 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | 6 | # Expo 7 | .expo/ 8 | dist/ 9 | web-build/ 10 | expo-env.d.ts 11 | 12 | # Native 13 | .kotlin/ 14 | *.orig.* 15 | *.jks 16 | *.p8 17 | *.p12 18 | *.key 19 | *.mobileprovision 20 | 21 | # Metro 22 | .metro-health-check* 23 | 24 | # debug 25 | npm-debug.* 26 | yarn-debug.* 27 | yarn-error.* 28 | 29 | # macOS 30 | .DS_Store 31 | *.pem 32 | 33 | # local env files 34 | .env*.local 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | 39 | app-example 40 | -------------------------------------------------------------------------------- /app/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll": "explicit", 4 | "source.organizeImports": "explicit", 5 | "source.sortMembers": "explicit" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "polar-react-native-starter", 4 | "slug": "polar-react-native-starter", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/images/icon.png", 8 | "scheme": "polarstarter", 9 | "userInterfaceStyle": "automatic", 10 | "newArchEnabled": true, 11 | "ios": { 12 | "supportsTablet": true, 13 | "bundleIdentifier": "com.polar.reactnative", 14 | "infoPlist": { 15 | "ITSAppUsesNonExemptEncryption": false 16 | } 17 | }, 18 | "android": { 19 | "adaptiveIcon": { 20 | "foregroundImage": "./assets/images/adaptive-icon.png", 21 | "backgroundColor": "#ffffff" 22 | }, 23 | "edgeToEdgeEnabled": true 24 | }, 25 | "web": { 26 | "bundler": "metro", 27 | "output": "static", 28 | "favicon": "./assets/images/favicon.png" 29 | }, 30 | "plugins": [ 31 | "expo-router", 32 | [ 33 | "expo-splash-screen", 34 | { 35 | "image": "./assets/images/splash-icon.png", 36 | "imageWidth": 200, 37 | "resizeMode": "contain", 38 | "backgroundColor": "#ffffff" 39 | } 40 | ] 41 | ], 42 | "experiments": { 43 | "typedRoutes": true 44 | }, 45 | "extra": { 46 | "router": {}, 47 | "eas": { 48 | "projectId": "d4fcc467-645d-460d-8320-1902baf35289" 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/app/+not-found.tsx: -------------------------------------------------------------------------------- 1 | import { Link, Stack } from 'expo-router'; 2 | import { StyleSheet } from 'react-native'; 3 | 4 | import { ThemedText } from '@/components/ThemedText'; 5 | import { ThemedView } from '@/components/ThemedView'; 6 | 7 | export default function NotFoundScreen() { 8 | return ( 9 | <> 10 | 11 | 12 | This screen does not exist. 13 | 14 | Go to home screen! 15 | 16 | 17 | 18 | ); 19 | } 20 | 21 | const styles = StyleSheet.create({ 22 | container: { 23 | flex: 1, 24 | alignItems: 'center', 25 | justifyContent: 'center', 26 | padding: 20, 27 | }, 28 | link: { 29 | marginTop: 15, 30 | paddingVertical: 15, 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /app/app/_layout.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | DarkTheme, 3 | DefaultTheme, 4 | ThemeProvider, 5 | } from "@react-navigation/native"; 6 | import { useFonts } from "expo-font"; 7 | import { Stack } from "expo-router"; 8 | import { StatusBar } from "expo-status-bar"; 9 | import "react-native-reanimated"; 10 | import { useColorScheme } from "@/hooks/useColorScheme"; 11 | import { SafeAreaView, Text, View } from "react-native"; 12 | import "@/utils/polyfills"; 13 | 14 | export default function RootLayout() { 15 | const colorScheme = useColorScheme(); 16 | const [loaded] = useFonts({ 17 | SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"), 18 | }); 19 | 20 | if (!loaded) { 21 | // Async font loading only occurs in development. 22 | return null; 23 | } 24 | 25 | return ( 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /app/app/index.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | StyleSheet, 3 | TouchableOpacity, 4 | TextInput, 5 | FlatList, 6 | KeyboardAvoidingView, 7 | Platform, 8 | SafeAreaView, 9 | } from "react-native"; 10 | import * as Linking from "expo-linking"; 11 | import { fetch as expoFetch } from "expo/fetch"; 12 | import { ThemedText } from "@/components/ThemedText"; 13 | import { ThemedView } from "@/components/ThemedView"; 14 | import { useColorScheme } from "@/hooks/useColorScheme"; 15 | import { useChat } from "@ai-sdk/react"; 16 | import { useEffect, useRef } from "react"; 17 | 18 | export default function HomeScreen() { 19 | const listRef = useRef(null); 20 | const isDark = useColorScheme() === "dark"; 21 | 22 | const currentUrl = Linking.useURL(); 23 | 24 | const { messages, handleInputChange, input, handleSubmit, setMessages } = 25 | useChat({ 26 | fetch: expoFetch as unknown as typeof globalThis.fetch, 27 | api: process.env.EXPO_PUBLIC_API_BASE_URL + "/prompt", 28 | onError: (error) => { 29 | setMessages((messages) => [ 30 | ...messages, 31 | { 32 | id: Math.random().toString(), 33 | role: "assistant", 34 | content: "You have insufficient credits.", 35 | }, 36 | ]); 37 | }, 38 | }); 39 | 40 | useEffect(() => { 41 | if (currentUrl?.includes("?checkout_redirect")) { 42 | setMessages((messages) => [ 43 | ...messages, 44 | { 45 | id: Math.random().toString(), 46 | role: "assistant", 47 | content: 48 | "Thanks for your purchase! 10,000 credits has been added to your account.", 49 | }, 50 | ]); 51 | } 52 | }, [currentUrl, setMessages]); 53 | 54 | const renderMessage = ({ item }: { item: (typeof messages)[number] }) => ( 55 | 64 | {item.content} 65 | {item.content.includes("insufficient credits") && ( 66 | { 69 | const customerId = "09b8b19b-ff4a-4b3a-b12d-78ab168bf7bb"; 70 | const polarCreditsProductId = 71 | "6870a5f6-1ff8-4907-8fe4-52c5c492f65b"; 72 | 73 | const url = new URL( 74 | process.env.EXPO_PUBLIC_API_BASE_URL + "/checkout" 75 | ); 76 | 77 | url.searchParams.set("products", polarCreditsProductId); 78 | url.searchParams.set("customerId", customerId); 79 | Linking.openURL(url.toString()); 80 | }} 81 | > 82 | Please top up your account to continue. 83 | 84 | )} 85 | 86 | ); 87 | 88 | useEffect(() => { 89 | listRef.current?.scrollToEnd(); 90 | }, [messages]); 91 | 92 | return ( 93 | 97 | 98 | 99 | item.id} 104 | style={styles.listContainer} 105 | contentInset={{ bottom: 12 }} 106 | /> 107 | 108 | 114 | 121 | handleInputChange({ 122 | ...e, 123 | target: { 124 | ...e.target, 125 | value: e.nativeEvent.text, 126 | }, 127 | } as unknown as React.ChangeEvent) 128 | } 129 | onSubmitEditing={(e) => { 130 | handleSubmit(e); 131 | e.preventDefault(); 132 | }} 133 | placeholder="Ask anything..." 134 | placeholderTextColor={isDark ? "#666" : "#aaa"} 135 | autoFocus 136 | /> 137 | 142 | 147 | ↑ 148 | 149 | 150 | 151 | 152 | 153 | 154 | ); 155 | } 156 | 157 | const styles = StyleSheet.create({ 158 | keyboardAvoid: { 159 | flex: 1, 160 | }, 161 | listContainer: { 162 | flex: 1, 163 | padding: 12, 164 | }, 165 | container: { 166 | flex: 1, 167 | }, 168 | messagesList: { 169 | flex: 1, 170 | padding: 12, 171 | }, 172 | messageContainer: { 173 | padding: 12, 174 | borderRadius: 100, 175 | maxWidth: "80%", 176 | marginVertical: 8, 177 | flexDirection: "column", 178 | gap: 8, 179 | }, 180 | botMessage: { 181 | alignSelf: "flex-start", 182 | }, 183 | userMessage: { 184 | alignSelf: "flex-end", 185 | }, 186 | inputContainer: { 187 | flexDirection: "row", 188 | gap: 12, 189 | padding: 16, 190 | borderTopLeftRadius: 20, 191 | borderTopRightRadius: 20, 192 | flexShrink: 0, 193 | }, 194 | input: { 195 | flex: 1, 196 | flexDirection: "row", 197 | flexGrow: 1, 198 | height: 30, 199 | }, 200 | sendButton: { 201 | backgroundColor: "#007AFF", 202 | width: 30, 203 | height: 30, 204 | flexDirection: "row", 205 | alignItems: "center", 206 | justifyContent: "center", 207 | borderRadius: 20, 208 | alignSelf: "flex-end", 209 | }, 210 | buttonText: { 211 | fontSize: 16, 212 | fontWeight: "medium", 213 | }, 214 | reactLogo: { 215 | height: 178, 216 | width: 290, 217 | bottom: 0, 218 | left: 0, 219 | position: "absolute", 220 | }, 221 | link: { 222 | color: "#007AFF", 223 | }, 224 | }); 225 | -------------------------------------------------------------------------------- /app/assets/fonts/SpaceMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/fonts/SpaceMono-Regular.ttf -------------------------------------------------------------------------------- /app/assets/images/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/images/adaptive-icon.png -------------------------------------------------------------------------------- /app/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/images/favicon.png -------------------------------------------------------------------------------- /app/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/images/icon.png -------------------------------------------------------------------------------- /app/assets/images/partial-react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/images/partial-react-logo.png -------------------------------------------------------------------------------- /app/assets/images/react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/images/react-logo.png -------------------------------------------------------------------------------- /app/assets/images/react-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/images/react-logo@2x.png -------------------------------------------------------------------------------- /app/assets/images/react-logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/images/react-logo@3x.png -------------------------------------------------------------------------------- /app/assets/images/splash-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polarsource/polar-react-native-starter/f9ce1a7c5d9a27fcbf419fc18e54d81f7423144b/app/assets/images/splash-icon.png -------------------------------------------------------------------------------- /app/components/Collapsible.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren, useState } from 'react'; 2 | import { StyleSheet, TouchableOpacity } from 'react-native'; 3 | 4 | import { ThemedText } from '@/components/ThemedText'; 5 | import { ThemedView } from '@/components/ThemedView'; 6 | import { IconSymbol } from '@/components/ui/IconSymbol'; 7 | import { Colors } from '@/constants/Colors'; 8 | import { useColorScheme } from '@/hooks/useColorScheme'; 9 | 10 | export function Collapsible({ children, title }: PropsWithChildren & { title: string }) { 11 | const [isOpen, setIsOpen] = useState(false); 12 | const theme = useColorScheme() ?? 'light'; 13 | 14 | return ( 15 | 16 | setIsOpen((value) => !value)} 19 | activeOpacity={0.8}> 20 | 27 | 28 | {title} 29 | 30 | {isOpen && {children}} 31 | 32 | ); 33 | } 34 | 35 | const styles = StyleSheet.create({ 36 | heading: { 37 | flexDirection: 'row', 38 | alignItems: 'center', 39 | gap: 6, 40 | }, 41 | content: { 42 | marginTop: 6, 43 | marginLeft: 24, 44 | }, 45 | }); 46 | -------------------------------------------------------------------------------- /app/components/ExternalLink.tsx: -------------------------------------------------------------------------------- 1 | import { Href, Link } from 'expo-router'; 2 | import { openBrowserAsync } from 'expo-web-browser'; 3 | import { type ComponentProps } from 'react'; 4 | import { Platform } from 'react-native'; 5 | 6 | type Props = Omit, 'href'> & { href: Href & string }; 7 | 8 | export function ExternalLink({ href, ...rest }: Props) { 9 | return ( 10 | { 15 | if (Platform.OS !== 'web') { 16 | // Prevent the default behavior of linking to the default browser on native. 17 | event.preventDefault(); 18 | // Open the link in an in-app browser. 19 | await openBrowserAsync(href); 20 | } 21 | }} 22 | /> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /app/components/HapticTab.tsx: -------------------------------------------------------------------------------- 1 | import { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs'; 2 | import { PlatformPressable } from '@react-navigation/elements'; 3 | import * as Haptics from 'expo-haptics'; 4 | 5 | export function HapticTab(props: BottomTabBarButtonProps) { 6 | return ( 7 | { 10 | if (process.env.EXPO_OS === 'ios') { 11 | // Add a soft haptic feedback when pressing down on the tabs. 12 | Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); 13 | } 14 | props.onPressIn?.(ev); 15 | }} 16 | /> 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /app/components/HelloWave.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { StyleSheet } from 'react-native'; 3 | import Animated, { 4 | useAnimatedStyle, 5 | useSharedValue, 6 | withRepeat, 7 | withSequence, 8 | withTiming, 9 | } from 'react-native-reanimated'; 10 | 11 | import { ThemedText } from '@/components/ThemedText'; 12 | 13 | export function HelloWave() { 14 | const rotationAnimation = useSharedValue(0); 15 | 16 | useEffect(() => { 17 | rotationAnimation.value = withRepeat( 18 | withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })), 19 | 4 // Run the animation 4 times 20 | ); 21 | }, [rotationAnimation]); 22 | 23 | const animatedStyle = useAnimatedStyle(() => ({ 24 | transform: [{ rotate: `${rotationAnimation.value}deg` }], 25 | })); 26 | 27 | return ( 28 | 29 | 👋 30 | 31 | ); 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | text: { 36 | fontSize: 28, 37 | lineHeight: 32, 38 | marginTop: -6, 39 | }, 40 | }); 41 | -------------------------------------------------------------------------------- /app/components/ThemedText.tsx: -------------------------------------------------------------------------------- 1 | import { StyleSheet, Text, type TextProps } from 'react-native'; 2 | 3 | import { useThemeColor } from '@/hooks/useThemeColor'; 4 | 5 | export type ThemedTextProps = TextProps & { 6 | lightColor?: string; 7 | darkColor?: string; 8 | type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link'; 9 | }; 10 | 11 | export function ThemedText({ 12 | style, 13 | lightColor, 14 | darkColor, 15 | type = 'default', 16 | ...rest 17 | }: ThemedTextProps) { 18 | const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text'); 19 | 20 | return ( 21 | 33 | ); 34 | } 35 | 36 | const styles = StyleSheet.create({ 37 | default: { 38 | fontSize: 16, 39 | lineHeight: 24, 40 | }, 41 | defaultSemiBold: { 42 | fontSize: 16, 43 | lineHeight: 24, 44 | fontWeight: '600', 45 | }, 46 | title: { 47 | fontSize: 32, 48 | fontWeight: 'bold', 49 | lineHeight: 32, 50 | }, 51 | subtitle: { 52 | fontSize: 20, 53 | fontWeight: 'bold', 54 | }, 55 | link: { 56 | lineHeight: 30, 57 | fontSize: 16, 58 | color: '#0a7ea4', 59 | }, 60 | }); 61 | -------------------------------------------------------------------------------- /app/components/ThemedView.tsx: -------------------------------------------------------------------------------- 1 | import { View, type ViewProps } from 'react-native'; 2 | 3 | import { useThemeColor } from '@/hooks/useThemeColor'; 4 | 5 | export type ThemedViewProps = ViewProps & { 6 | lightColor?: string; 7 | darkColor?: string; 8 | }; 9 | 10 | export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) { 11 | const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background'); 12 | 13 | return ; 14 | } 15 | -------------------------------------------------------------------------------- /app/components/ui/IconSymbol.ios.tsx: -------------------------------------------------------------------------------- 1 | import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols'; 2 | import { StyleProp, ViewStyle } from 'react-native'; 3 | 4 | export function IconSymbol({ 5 | name, 6 | size = 24, 7 | color, 8 | style, 9 | weight = 'regular', 10 | }: { 11 | name: SymbolViewProps['name']; 12 | size?: number; 13 | color: string; 14 | style?: StyleProp; 15 | weight?: SymbolWeight; 16 | }) { 17 | return ( 18 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /app/components/ui/IconSymbol.tsx: -------------------------------------------------------------------------------- 1 | // Fallback for using MaterialIcons on Android and web. 2 | 3 | import MaterialIcons from '@expo/vector-icons/MaterialIcons'; 4 | import { SymbolWeight, SymbolViewProps } from 'expo-symbols'; 5 | import { ComponentProps } from 'react'; 6 | import { OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native'; 7 | 8 | type IconMapping = Record['name']>; 9 | type IconSymbolName = keyof typeof MAPPING; 10 | 11 | /** 12 | * Add your SF Symbols to Material Icons mappings here. 13 | * - see Material Icons in the [Icons Directory](https://icons.expo.fyi). 14 | * - see SF Symbols in the [SF Symbols](https://developer.apple.com/sf-symbols/) app. 15 | */ 16 | const MAPPING = { 17 | 'house.fill': 'home', 18 | 'paperplane.fill': 'send', 19 | 'chevron.left.forwardslash.chevron.right': 'code', 20 | 'chevron.right': 'chevron-right', 21 | } as IconMapping; 22 | 23 | /** 24 | * An icon component that uses native SF Symbols on iOS, and Material Icons on Android and web. 25 | * This ensures a consistent look across platforms, and optimal resource usage. 26 | * Icon `name`s are based on SF Symbols and require manual mapping to Material Icons. 27 | */ 28 | export function IconSymbol({ 29 | name, 30 | size = 24, 31 | color, 32 | style, 33 | }: { 34 | name: IconSymbolName; 35 | size?: number; 36 | color: string | OpaqueColorValue; 37 | style?: StyleProp; 38 | weight?: SymbolWeight; 39 | }) { 40 | return ; 41 | } 42 | -------------------------------------------------------------------------------- /app/components/ui/TabBarBackground.ios.tsx: -------------------------------------------------------------------------------- 1 | import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; 2 | import { BlurView } from 'expo-blur'; 3 | import { StyleSheet } from 'react-native'; 4 | 5 | export default function BlurTabBarBackground() { 6 | return ( 7 | 14 | ); 15 | } 16 | 17 | export function useBottomTabOverflow() { 18 | return useBottomTabBarHeight(); 19 | } 20 | -------------------------------------------------------------------------------- /app/components/ui/TabBarBackground.tsx: -------------------------------------------------------------------------------- 1 | // This is a shim for web and Android where the tab bar is generally opaque. 2 | export default undefined; 3 | 4 | export function useBottomTabOverflow() { 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /app/constants/Colors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Below are the colors that are used in the app. The colors are defined in the light and dark mode. 3 | * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc. 4 | */ 5 | 6 | const tintColorLight = "#0a7ea4"; 7 | const tintColorDark = "#fff"; 8 | 9 | export const Colors = { 10 | light: { 11 | text: "#11181C", 12 | background: "#fff", 13 | tint: tintColorLight, 14 | icon: "#687076", 15 | tabIconDefault: "#687076", 16 | tabIconSelected: tintColorLight, 17 | }, 18 | dark: { 19 | text: "#ECEDEE", 20 | background: "#111", 21 | tint: tintColorDark, 22 | icon: "#9BA1A6", 23 | tabIconDefault: "#9BA1A6", 24 | tabIconSelected: tintColorDark, 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /app/eslint.config.js: -------------------------------------------------------------------------------- 1 | // https://docs.expo.dev/guides/using-eslint/ 2 | const { defineConfig } = require('eslint/config'); 3 | const expoConfig = require('eslint-config-expo/flat'); 4 | 5 | module.exports = defineConfig([ 6 | expoConfig, 7 | { 8 | ignores: ['dist/*'], 9 | }, 10 | ]); 11 | -------------------------------------------------------------------------------- /app/hooks/useColorScheme.ts: -------------------------------------------------------------------------------- 1 | export { useColorScheme } from 'react-native'; 2 | -------------------------------------------------------------------------------- /app/hooks/useColorScheme.web.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { useColorScheme as useRNColorScheme } from 'react-native'; 3 | 4 | /** 5 | * To support static rendering, this value needs to be re-calculated on the client side for web 6 | */ 7 | export function useColorScheme() { 8 | const [hasHydrated, setHasHydrated] = useState(false); 9 | 10 | useEffect(() => { 11 | setHasHydrated(true); 12 | }, []); 13 | 14 | const colorScheme = useRNColorScheme(); 15 | 16 | if (hasHydrated) { 17 | return colorScheme; 18 | } 19 | 20 | return 'light'; 21 | } 22 | -------------------------------------------------------------------------------- /app/hooks/useThemeColor.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Learn more about light and dark modes: 3 | * https://docs.expo.dev/guides/color-schemes/ 4 | */ 5 | 6 | import { Colors } from '@/constants/Colors'; 7 | import { useColorScheme } from '@/hooks/useColorScheme'; 8 | 9 | export function useThemeColor( 10 | props: { light?: string; dark?: string }, 11 | colorName: keyof typeof Colors.light & keyof typeof Colors.dark 12 | ) { 13 | const theme = useColorScheme() ?? 'light'; 14 | const colorFromProps = props[theme]; 15 | 16 | if (colorFromProps) { 17 | return colorFromProps; 18 | } else { 19 | return Colors[theme][colorName]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "polar-react-native-starter", 3 | "main": "expo-router/entry", 4 | "version": "1.0.0", 5 | "scripts": { 6 | "start": "expo start", 7 | "reset-project": "node ./scripts/reset-project.js", 8 | "android": "expo run:android", 9 | "ios": "expo run:ios", 10 | "web": "expo start --web", 11 | "lint": "expo lint" 12 | }, 13 | "dependencies": { 14 | "@ai-sdk/react": "^1.2.11", 15 | "@expo/vector-icons": "^14.1.0", 16 | "@polar-sh/sdk": "^0.32.13", 17 | "@react-navigation/bottom-tabs": "^7.3.10", 18 | "@react-navigation/elements": "^2.3.8", 19 | "@react-navigation/native": "^7.1.6", 20 | "@stardazed/streams-text-encoding": "^1.0.2", 21 | "@ungap/structured-clone": "^1.3.0", 22 | "expo": "~53.0.5", 23 | "expo-blur": "~14.1.4", 24 | "expo-constants": "~17.1.5", 25 | "expo-dev-client": "~5.1.8", 26 | "expo-font": "~13.3.0", 27 | "expo-haptics": "~14.1.4", 28 | "expo-image": "~2.1.6", 29 | "expo-linking": "~7.1.4", 30 | "expo-router": "~5.0.4", 31 | "expo-splash-screen": "~0.30.8", 32 | "expo-status-bar": "~2.2.3", 33 | "expo-symbols": "~0.4.4", 34 | "expo-system-ui": "~5.0.7", 35 | "expo-web-browser": "~14.1.6", 36 | "react": "19.0.0", 37 | "react-dom": "19.0.0", 38 | "react-native": "0.79.2", 39 | "react-native-gesture-handler": "~2.24.0", 40 | "react-native-reanimated": "~3.17.4", 41 | "react-native-safe-area-context": "5.4.0", 42 | "react-native-screens": "~4.10.0", 43 | "react-native-web": "~0.20.0", 44 | "react-native-webview": "13.13.5" 45 | }, 46 | "devDependencies": { 47 | "@babel/core": "^7.25.2", 48 | "@types/react": "~19.0.10", 49 | "eslint": "^9.25.0", 50 | "eslint-config-expo": "~9.2.0", 51 | "typescript": "~5.8.3" 52 | }, 53 | "private": true 54 | } 55 | -------------------------------------------------------------------------------- /app/scripts/reset-project.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * This script is used to reset the project to a blank state. 5 | * It deletes or moves the /app, /components, /hooks, /scripts, and /constants directories to /app-example based on user input and creates a new /app directory with an index.tsx and _layout.tsx file. 6 | * You can remove the `reset-project` script from package.json and safely delete this file after running it. 7 | */ 8 | 9 | const fs = require("fs"); 10 | const path = require("path"); 11 | const readline = require("readline"); 12 | 13 | const root = process.cwd(); 14 | const oldDirs = ["app", "components", "hooks", "constants", "scripts"]; 15 | const exampleDir = "app-example"; 16 | const newAppDir = "app"; 17 | const exampleDirPath = path.join(root, exampleDir); 18 | 19 | const indexContent = `import { Text, View } from "react-native"; 20 | 21 | export default function Index() { 22 | return ( 23 | 30 | Edit app/index.tsx to edit this screen. 31 | 32 | ); 33 | } 34 | `; 35 | 36 | const layoutContent = `import { Stack } from "expo-router"; 37 | 38 | export default function RootLayout() { 39 | return ; 40 | } 41 | `; 42 | 43 | const rl = readline.createInterface({ 44 | input: process.stdin, 45 | output: process.stdout, 46 | }); 47 | 48 | const moveDirectories = async (userInput) => { 49 | try { 50 | if (userInput === "y") { 51 | // Create the app-example directory 52 | await fs.promises.mkdir(exampleDirPath, { recursive: true }); 53 | console.log(`📁 /${exampleDir} directory created.`); 54 | } 55 | 56 | // Move old directories to new app-example directory or delete them 57 | for (const dir of oldDirs) { 58 | const oldDirPath = path.join(root, dir); 59 | if (fs.existsSync(oldDirPath)) { 60 | if (userInput === "y") { 61 | const newDirPath = path.join(root, exampleDir, dir); 62 | await fs.promises.rename(oldDirPath, newDirPath); 63 | console.log(`➡️ /${dir} moved to /${exampleDir}/${dir}.`); 64 | } else { 65 | await fs.promises.rm(oldDirPath, { recursive: true, force: true }); 66 | console.log(`❌ /${dir} deleted.`); 67 | } 68 | } else { 69 | console.log(`➡️ /${dir} does not exist, skipping.`); 70 | } 71 | } 72 | 73 | // Create new /app directory 74 | const newAppDirPath = path.join(root, newAppDir); 75 | await fs.promises.mkdir(newAppDirPath, { recursive: true }); 76 | console.log("\n📁 New /app directory created."); 77 | 78 | // Create index.tsx 79 | const indexPath = path.join(newAppDirPath, "index.tsx"); 80 | await fs.promises.writeFile(indexPath, indexContent); 81 | console.log("📄 app/index.tsx created."); 82 | 83 | // Create _layout.tsx 84 | const layoutPath = path.join(newAppDirPath, "_layout.tsx"); 85 | await fs.promises.writeFile(layoutPath, layoutContent); 86 | console.log("📄 app/_layout.tsx created."); 87 | 88 | console.log("\n✅ Project reset complete. Next steps:"); 89 | console.log( 90 | `1. Run \`npx expo start\` to start a development server.\n2. Edit app/index.tsx to edit the main screen.${ 91 | userInput === "y" 92 | ? `\n3. Delete the /${exampleDir} directory when you're done referencing it.` 93 | : "" 94 | }` 95 | ); 96 | } catch (error) { 97 | console.error(`❌ Error during script execution: ${error.message}`); 98 | } 99 | }; 100 | 101 | rl.question( 102 | "Do you want to move existing files to /app-example instead of deleting them? (Y/n): ", 103 | (answer) => { 104 | const userInput = answer.trim().toLowerCase() || "y"; 105 | if (userInput === "y" || userInput === "n") { 106 | moveDirectories(userInput).finally(() => rl.close()); 107 | } else { 108 | console.log("❌ Invalid input. Please enter 'Y' or 'N'."); 109 | rl.close(); 110 | } 111 | } 112 | ); 113 | -------------------------------------------------------------------------------- /app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "expo/tsconfig.base", 3 | "compilerOptions": { 4 | "strict": true, 5 | "paths": { 6 | "@/*": [ 7 | "./*" 8 | ] 9 | } 10 | }, 11 | "include": [ 12 | "**/*.ts", 13 | "**/*.tsx", 14 | ".expo/types/**/*.ts", 15 | "expo-env.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /app/utils/fetch.ts: -------------------------------------------------------------------------------- 1 | import Constants from "expo-constants"; 2 | 3 | export const generateAPIUrl = (relativePath: string) => { 4 | const origin = Constants.experienceUrl.replace("exp://", "http://"); 5 | 6 | const path = relativePath.startsWith("/") ? relativePath : `/${relativePath}`; 7 | 8 | if (process.env.NODE_ENV === "development") { 9 | return origin.concat(path); 10 | } 11 | 12 | if (!process.env.EXPO_PUBLIC_API_BASE_URL) { 13 | throw new Error( 14 | "EXPO_PUBLIC_API_BASE_URL environment variable is not defined" 15 | ); 16 | } 17 | 18 | return process.env.EXPO_PUBLIC_API_BASE_URL.concat(path); 19 | }; 20 | -------------------------------------------------------------------------------- /app/utils/polar.ts: -------------------------------------------------------------------------------- 1 | import { Polar } from "@polar-sh/sdk"; 2 | 3 | export const polar = new Polar({ 4 | accessToken: process.env.POLAR_ACCESS_TOKEN as string, 5 | server: process.env.POLAR_SERVER_ENVIRONMENT as "production" | "sandbox", 6 | }); 7 | -------------------------------------------------------------------------------- /app/utils/polyfills.ts: -------------------------------------------------------------------------------- 1 | import { Platform } from "react-native"; 2 | import structuredClone from "@ungap/structured-clone"; 3 | 4 | if (Platform.OS !== "web") { 5 | const setupPolyfills = async () => { 6 | const { polyfillGlobal } = await import( 7 | "react-native/Libraries/Utilities/PolyfillFunctions" 8 | ); 9 | 10 | const { TextEncoderStream, TextDecoderStream } = await import( 11 | "@stardazed/streams-text-encoding" 12 | ); 13 | 14 | if (!("structuredClone" in global)) { 15 | polyfillGlobal("structuredClone", () => structuredClone); 16 | } 17 | 18 | polyfillGlobal("TextEncoderStream", () => TextEncoderStream); 19 | polyfillGlobal("TextDecoderStream", () => TextDecoderStream); 20 | }; 21 | 22 | setupPolyfills(); 23 | } 24 | 25 | export {}; 26 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | # dev 2 | .yarn/ 3 | !.yarn/releases 4 | .vscode/* 5 | !.vscode/launch.json 6 | !.vscode/*.code-snippets 7 | .idea/workspace.xml 8 | .idea/usage.statistics.xml 9 | .idea/shelf 10 | 11 | # deps 12 | node_modules/ 13 | 14 | # env 15 | .env 16 | .env.production 17 | 18 | # logs 19 | logs/ 20 | *.log 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | pnpm-debug.log* 25 | lerna-debug.log* 26 | 27 | # misc 28 | .DS_Store 29 | -------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | npm install 3 | npm run dev 4 | ``` 5 | 6 | ``` 7 | open http://localhost:3000 8 | ``` 9 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "type": "module", 4 | "scripts": { 5 | "dev": "tsx watch src/index.ts", 6 | "build": "tsc", 7 | "start": "node dist/index.js" 8 | }, 9 | "dependencies": { 10 | "@ai-sdk/openai": "^1.3.21", 11 | "@hono/node-server": "^1.14.1", 12 | "@polar-sh/hono": "^0.3.0", 13 | "@polar-sh/ingestion": "^0.2.4", 14 | "@polar-sh/sdk": "^0.32.13", 15 | "ai": "^4.3.13", 16 | "dotenv": "^16.5.0", 17 | "hono": "^4.7.8", 18 | "zod": "^3.24.3" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^22.15.3", 22 | "tsx": "^4.19.4", 23 | "typescript": "^5.8.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /server/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@ai-sdk/openai': 12 | specifier: ^1.3.21 13 | version: 1.3.21(zod@3.24.3) 14 | '@hono/node-server': 15 | specifier: ^1.14.1 16 | version: 1.14.1(hono@4.7.8) 17 | '@polar-sh/hono': 18 | specifier: ^0.3.0 19 | version: 0.3.0(hono@4.7.8)(zod@3.24.3) 20 | '@polar-sh/ingestion': 21 | specifier: ^0.2.4 22 | version: 0.2.4(@aws-sdk/client-s3@3.800.0)(ai@4.3.13(react@19.1.0)(zod@3.24.3))(zod@3.24.3) 23 | '@polar-sh/sdk': 24 | specifier: ^0.32.13 25 | version: 0.32.13(zod@3.24.3) 26 | ai: 27 | specifier: ^4.3.13 28 | version: 4.3.13(react@19.1.0)(zod@3.24.3) 29 | dotenv: 30 | specifier: ^16.5.0 31 | version: 16.5.0 32 | hono: 33 | specifier: ^4.7.8 34 | version: 4.7.8 35 | zod: 36 | specifier: ^3.24.3 37 | version: 3.24.3 38 | devDependencies: 39 | '@types/node': 40 | specifier: ^22.15.3 41 | version: 22.15.3 42 | tsx: 43 | specifier: ^4.19.4 44 | version: 4.19.4 45 | typescript: 46 | specifier: ^5.8.3 47 | version: 5.8.3 48 | 49 | packages: 50 | 51 | '@ai-sdk/openai@1.3.21': 52 | resolution: {integrity: sha512-ipAhkRKUd2YaMmn7DAklX3N7Ywx/rCsJHVyb0V/lKRqPcc612qAFVbjg+Uve8QYJlbPxgfsM4s9JmCFp6PSdYw==} 53 | engines: {node: '>=18'} 54 | peerDependencies: 55 | zod: ^3.0.0 56 | 57 | '@ai-sdk/provider-utils@2.2.7': 58 | resolution: {integrity: sha512-kM0xS3GWg3aMChh9zfeM+80vEZfXzR3JEUBdycZLtbRZ2TRT8xOj3WodGHPb06sUK5yD7pAXC/P7ctsi2fvUGQ==} 59 | engines: {node: '>=18'} 60 | peerDependencies: 61 | zod: ^3.23.8 62 | 63 | '@ai-sdk/provider@1.1.3': 64 | resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==} 65 | engines: {node: '>=18'} 66 | 67 | '@ai-sdk/react@1.2.11': 68 | resolution: {integrity: sha512-+kPqLkJ3TWP6czaJPV+vzAKSUcKQ1598BUrcLHt56sH99+LhmIIW3ylZp0OfC3O6TR3eO1Lt0Yzw4R0mK6g9Gw==} 69 | engines: {node: '>=18'} 70 | peerDependencies: 71 | react: ^18 || ^19 || ^19.0.0-rc 72 | zod: ^3.23.8 73 | peerDependenciesMeta: 74 | zod: 75 | optional: true 76 | 77 | '@ai-sdk/ui-utils@1.2.10': 78 | resolution: {integrity: sha512-GUj+LBoAlRQF1dL/M49jtufGqtLOMApxTpCmVjoRpIPt/dFALVL9RfqfvxwztyIwbK+IxGzcYjSGRsrWrj+86g==} 79 | engines: {node: '>=18'} 80 | peerDependencies: 81 | zod: ^3.23.8 82 | 83 | '@aws-crypto/crc32@5.2.0': 84 | resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} 85 | engines: {node: '>=16.0.0'} 86 | 87 | '@aws-crypto/crc32c@5.2.0': 88 | resolution: {integrity: sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==} 89 | 90 | '@aws-crypto/sha1-browser@5.2.0': 91 | resolution: {integrity: sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==} 92 | 93 | '@aws-crypto/sha256-browser@5.2.0': 94 | resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} 95 | 96 | '@aws-crypto/sha256-js@5.2.0': 97 | resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} 98 | engines: {node: '>=16.0.0'} 99 | 100 | '@aws-crypto/supports-web-crypto@5.2.0': 101 | resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} 102 | 103 | '@aws-crypto/util@5.2.0': 104 | resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} 105 | 106 | '@aws-sdk/client-s3@3.800.0': 107 | resolution: {integrity: sha512-SE33Y1kbeErd5h7KlmgWs1iJ0kKi+/t9XilI6NPIb5J5TmPKVUT5gf3ywa9ZSaq1x7LiAbICm0IPEz6k0WEBbQ==} 108 | engines: {node: '>=18.0.0'} 109 | 110 | '@aws-sdk/client-sso@3.799.0': 111 | resolution: {integrity: sha512-/i/LG7AiWPmPxKCA2jnR2zaf7B3HYSTbxaZI21ElIz9wASlNAsKr8CnLY7qb50kOyXiNfQ834S5Q3Gl8dX9o3Q==} 112 | engines: {node: '>=18.0.0'} 113 | 114 | '@aws-sdk/core@3.799.0': 115 | resolution: {integrity: sha512-hkKF3Zpc6+H8GI1rlttYVRh9uEE77cqAzLmLpY3iu7sql8cZgPERRBfaFct8p1SaDyrksLNiboD1vKW58mbsYg==} 116 | engines: {node: '>=18.0.0'} 117 | 118 | '@aws-sdk/credential-provider-env@3.799.0': 119 | resolution: {integrity: sha512-vT/SSWtbUIOW/U21qgEySmmO44SFWIA7WeQPX1OrI8WJ5n7OEI23JWLHjLvHTkYmuZK6z1rPcv7HzRgmuGRibA==} 120 | engines: {node: '>=18.0.0'} 121 | 122 | '@aws-sdk/credential-provider-http@3.799.0': 123 | resolution: {integrity: sha512-2CjBpOWmhaPAExOgHnIB5nOkS5ef+mfRlJ1JC4nsnjAx0nrK4tk0XRE0LYz11P3+ue+a86cU8WTmBo+qjnGxPQ==} 124 | engines: {node: '>=18.0.0'} 125 | 126 | '@aws-sdk/credential-provider-ini@3.799.0': 127 | resolution: {integrity: sha512-M9ubILFxerqw4QJwk83MnjtZyoA2eNCiea5V+PzZeHlwk2PON/EnawKqy65x9/hMHGoSvvNuby7iMAmPptu7yw==} 128 | engines: {node: '>=18.0.0'} 129 | 130 | '@aws-sdk/credential-provider-node@3.799.0': 131 | resolution: {integrity: sha512-nd9fSJc0wUlgKUkIr2ldJhcIIrzJFS29AGZoyY22J3xih63nNDv61eTGVMsDZzHlV21XzMlPEljTR7axiimckg==} 132 | engines: {node: '>=18.0.0'} 133 | 134 | '@aws-sdk/credential-provider-process@3.799.0': 135 | resolution: {integrity: sha512-g8jmNs2k98WNHMYcea1YKA+7ao2Ma4w0P42Dz4YpcI155pQHxHx25RwbOG+rsAKuo3bKwkW53HVE/ZTKhcWFgw==} 136 | engines: {node: '>=18.0.0'} 137 | 138 | '@aws-sdk/credential-provider-sso@3.799.0': 139 | resolution: {integrity: sha512-lQv27QkNU9FJFZqEf5DIEN3uXEN409Iaym9WJzhOouGtxvTIAWiD23OYh1u8PvBdrordJGS2YddfQvhcmq9akw==} 140 | engines: {node: '>=18.0.0'} 141 | 142 | '@aws-sdk/credential-provider-web-identity@3.799.0': 143 | resolution: {integrity: sha512-8k1i9ut+BEg0QZ+I6UQMxGNR1T8paLmAOAZXU+nLQR0lcxS6lr8v+dqofgzQPuHLBkWNCr1Av1IKeL3bJjgU7g==} 144 | engines: {node: '>=18.0.0'} 145 | 146 | '@aws-sdk/middleware-bucket-endpoint@3.775.0': 147 | resolution: {integrity: sha512-qogMIpVChDYr4xiUNC19/RDSw/sKoHkAhouS6Skxiy6s27HBhow1L3Z1qVYXuBmOZGSWPU0xiyZCvOyWrv9s+Q==} 148 | engines: {node: '>=18.0.0'} 149 | 150 | '@aws-sdk/middleware-expect-continue@3.775.0': 151 | resolution: {integrity: sha512-Apd3owkIeUW5dnk3au9np2IdW2N0zc9NjTjHiH+Mx3zqwSrc+m+ANgJVgk9mnQjMzU/vb7VuxJ0eqdEbp5gYsg==} 152 | engines: {node: '>=18.0.0'} 153 | 154 | '@aws-sdk/middleware-flexible-checksums@3.799.0': 155 | resolution: {integrity: sha512-vBIAdDl2neaFiUMxyr7dAtX7m9Iw5c0bz7OirD0JGW0nYn0mBcqKpFZEU75ewA5p2+Cm7RQDdt6099ne3gj0WA==} 156 | engines: {node: '>=18.0.0'} 157 | 158 | '@aws-sdk/middleware-host-header@3.775.0': 159 | resolution: {integrity: sha512-tkSegM0Z6WMXpLB8oPys/d+umYIocvO298mGvcMCncpRl77L9XkvSLJIFzaHes+o7djAgIduYw8wKIMStFss2w==} 160 | engines: {node: '>=18.0.0'} 161 | 162 | '@aws-sdk/middleware-location-constraint@3.775.0': 163 | resolution: {integrity: sha512-8TMXEHZXZTFTckQLyBT5aEI8fX11HZcwZseRifvBKKpj0RZDk4F0EEYGxeNSPpUQ7n+PRWyfAEnnZNRdAj/1NQ==} 164 | engines: {node: '>=18.0.0'} 165 | 166 | '@aws-sdk/middleware-logger@3.775.0': 167 | resolution: {integrity: sha512-FaxO1xom4MAoUJsldmR92nT1G6uZxTdNYOFYtdHfd6N2wcNaTuxgjIvqzg5y7QIH9kn58XX/dzf1iTjgqUStZw==} 168 | engines: {node: '>=18.0.0'} 169 | 170 | '@aws-sdk/middleware-recursion-detection@3.775.0': 171 | resolution: {integrity: sha512-GLCzC8D0A0YDG5u3F5U03Vb9j5tcOEFhr8oc6PDk0k0vm5VwtZOE6LvK7hcCSoAB4HXyOUM0sQuXrbaAh9OwXA==} 172 | engines: {node: '>=18.0.0'} 173 | 174 | '@aws-sdk/middleware-sdk-s3@3.799.0': 175 | resolution: {integrity: sha512-Zwdge5NArgcJwPuGZwgfXY6XXkWEBmMS9dqu5g3DcfHmZUuSjQUqmOsDdSZlE3RFHrDAEbuGQlrFUE8zuwdKQA==} 176 | engines: {node: '>=18.0.0'} 177 | 178 | '@aws-sdk/middleware-ssec@3.775.0': 179 | resolution: {integrity: sha512-Iw1RHD8vfAWWPzBBIKaojO4GAvQkHOYIpKdAfis/EUSUmSa79QsnXnRqsdcE0mCB0Ylj23yi+ah4/0wh9FsekA==} 180 | engines: {node: '>=18.0.0'} 181 | 182 | '@aws-sdk/middleware-user-agent@3.799.0': 183 | resolution: {integrity: sha512-TropQZanbOTxa+p+Nl4fWkzlRhgFwDfW+Wb6TR3jZN7IXHNlPpgGFpdrgvBExhW/RBhqr+94OsR8Ou58lp3hhA==} 184 | engines: {node: '>=18.0.0'} 185 | 186 | '@aws-sdk/nested-clients@3.799.0': 187 | resolution: {integrity: sha512-zILlWh7asrcQG9JYMYgnvEQBfwmWKfED0yWCf3UNAmQcfS9wkCAWCgicNy/y5KvNvEYnHidsU117STtyuUNG5g==} 188 | engines: {node: '>=18.0.0'} 189 | 190 | '@aws-sdk/region-config-resolver@3.775.0': 191 | resolution: {integrity: sha512-40iH3LJjrQS3LKUJAl7Wj0bln7RFPEvUYKFxtP8a+oKFDO0F65F52xZxIJbPn6sHkxWDAnZlGgdjZXM3p2g5wQ==} 192 | engines: {node: '>=18.0.0'} 193 | 194 | '@aws-sdk/signature-v4-multi-region@3.800.0': 195 | resolution: {integrity: sha512-c71wZuiSUHNFCvcuqOv3jbqP+NquB2YKN4qX90OwYXEqUKn8F8fKJPpjjHjz1eK6qWKtECR4V/NTno2P70Yz/Q==} 196 | engines: {node: '>=18.0.0'} 197 | 198 | '@aws-sdk/token-providers@3.799.0': 199 | resolution: {integrity: sha512-/8iDjnsJs/D8AhGbDAmdF5oSHzE4jsDsM2RIIxmBAKTZXkaaclQBNX9CmAqLKQmO3IUMZsDH2KENHLVAk/N/mw==} 200 | engines: {node: '>=18.0.0'} 201 | 202 | '@aws-sdk/types@3.775.0': 203 | resolution: {integrity: sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA==} 204 | engines: {node: '>=18.0.0'} 205 | 206 | '@aws-sdk/util-arn-parser@3.723.0': 207 | resolution: {integrity: sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w==} 208 | engines: {node: '>=18.0.0'} 209 | 210 | '@aws-sdk/util-endpoints@3.787.0': 211 | resolution: {integrity: sha512-fd3zkiOkwnbdbN0Xp9TsP5SWrmv0SpT70YEdbb8wAj2DWQwiCmFszaSs+YCvhoCdmlR3Wl9Spu0pGpSAGKeYvQ==} 212 | engines: {node: '>=18.0.0'} 213 | 214 | '@aws-sdk/util-locate-window@3.723.0': 215 | resolution: {integrity: sha512-Yf2CS10BqK688DRsrKI/EO6B8ff5J86NXe4C+VCysK7UOgN0l1zOTeTukZ3H8Q9tYYX3oaF1961o8vRkFm7Nmw==} 216 | engines: {node: '>=18.0.0'} 217 | 218 | '@aws-sdk/util-user-agent-browser@3.775.0': 219 | resolution: {integrity: sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A==} 220 | 221 | '@aws-sdk/util-user-agent-node@3.799.0': 222 | resolution: {integrity: sha512-iXBk38RbIWPF5Nq9O4AnktORAzXovSVqWYClvS1qbE7ILsnTLJbagU9HlU25O2iV5COVh1qZkwuP5NHQ2yTEyw==} 223 | engines: {node: '>=18.0.0'} 224 | peerDependencies: 225 | aws-crt: '>=1.0.0' 226 | peerDependenciesMeta: 227 | aws-crt: 228 | optional: true 229 | 230 | '@aws-sdk/xml-builder@3.775.0': 231 | resolution: {integrity: sha512-b9NGO6FKJeLGYnV7Z1yvcP1TNU4dkD5jNsLWOF1/sygZoASaQhNOlaiJ/1OH331YQ1R1oWk38nBb0frsYkDsOQ==} 232 | engines: {node: '>=18.0.0'} 233 | 234 | '@esbuild/aix-ppc64@0.25.3': 235 | resolution: {integrity: sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==} 236 | engines: {node: '>=18'} 237 | cpu: [ppc64] 238 | os: [aix] 239 | 240 | '@esbuild/android-arm64@0.25.3': 241 | resolution: {integrity: sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==} 242 | engines: {node: '>=18'} 243 | cpu: [arm64] 244 | os: [android] 245 | 246 | '@esbuild/android-arm@0.25.3': 247 | resolution: {integrity: sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==} 248 | engines: {node: '>=18'} 249 | cpu: [arm] 250 | os: [android] 251 | 252 | '@esbuild/android-x64@0.25.3': 253 | resolution: {integrity: sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==} 254 | engines: {node: '>=18'} 255 | cpu: [x64] 256 | os: [android] 257 | 258 | '@esbuild/darwin-arm64@0.25.3': 259 | resolution: {integrity: sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==} 260 | engines: {node: '>=18'} 261 | cpu: [arm64] 262 | os: [darwin] 263 | 264 | '@esbuild/darwin-x64@0.25.3': 265 | resolution: {integrity: sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==} 266 | engines: {node: '>=18'} 267 | cpu: [x64] 268 | os: [darwin] 269 | 270 | '@esbuild/freebsd-arm64@0.25.3': 271 | resolution: {integrity: sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==} 272 | engines: {node: '>=18'} 273 | cpu: [arm64] 274 | os: [freebsd] 275 | 276 | '@esbuild/freebsd-x64@0.25.3': 277 | resolution: {integrity: sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==} 278 | engines: {node: '>=18'} 279 | cpu: [x64] 280 | os: [freebsd] 281 | 282 | '@esbuild/linux-arm64@0.25.3': 283 | resolution: {integrity: sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==} 284 | engines: {node: '>=18'} 285 | cpu: [arm64] 286 | os: [linux] 287 | 288 | '@esbuild/linux-arm@0.25.3': 289 | resolution: {integrity: sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==} 290 | engines: {node: '>=18'} 291 | cpu: [arm] 292 | os: [linux] 293 | 294 | '@esbuild/linux-ia32@0.25.3': 295 | resolution: {integrity: sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==} 296 | engines: {node: '>=18'} 297 | cpu: [ia32] 298 | os: [linux] 299 | 300 | '@esbuild/linux-loong64@0.25.3': 301 | resolution: {integrity: sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==} 302 | engines: {node: '>=18'} 303 | cpu: [loong64] 304 | os: [linux] 305 | 306 | '@esbuild/linux-mips64el@0.25.3': 307 | resolution: {integrity: sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==} 308 | engines: {node: '>=18'} 309 | cpu: [mips64el] 310 | os: [linux] 311 | 312 | '@esbuild/linux-ppc64@0.25.3': 313 | resolution: {integrity: sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==} 314 | engines: {node: '>=18'} 315 | cpu: [ppc64] 316 | os: [linux] 317 | 318 | '@esbuild/linux-riscv64@0.25.3': 319 | resolution: {integrity: sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==} 320 | engines: {node: '>=18'} 321 | cpu: [riscv64] 322 | os: [linux] 323 | 324 | '@esbuild/linux-s390x@0.25.3': 325 | resolution: {integrity: sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==} 326 | engines: {node: '>=18'} 327 | cpu: [s390x] 328 | os: [linux] 329 | 330 | '@esbuild/linux-x64@0.25.3': 331 | resolution: {integrity: sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==} 332 | engines: {node: '>=18'} 333 | cpu: [x64] 334 | os: [linux] 335 | 336 | '@esbuild/netbsd-arm64@0.25.3': 337 | resolution: {integrity: sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==} 338 | engines: {node: '>=18'} 339 | cpu: [arm64] 340 | os: [netbsd] 341 | 342 | '@esbuild/netbsd-x64@0.25.3': 343 | resolution: {integrity: sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==} 344 | engines: {node: '>=18'} 345 | cpu: [x64] 346 | os: [netbsd] 347 | 348 | '@esbuild/openbsd-arm64@0.25.3': 349 | resolution: {integrity: sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==} 350 | engines: {node: '>=18'} 351 | cpu: [arm64] 352 | os: [openbsd] 353 | 354 | '@esbuild/openbsd-x64@0.25.3': 355 | resolution: {integrity: sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==} 356 | engines: {node: '>=18'} 357 | cpu: [x64] 358 | os: [openbsd] 359 | 360 | '@esbuild/sunos-x64@0.25.3': 361 | resolution: {integrity: sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==} 362 | engines: {node: '>=18'} 363 | cpu: [x64] 364 | os: [sunos] 365 | 366 | '@esbuild/win32-arm64@0.25.3': 367 | resolution: {integrity: sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==} 368 | engines: {node: '>=18'} 369 | cpu: [arm64] 370 | os: [win32] 371 | 372 | '@esbuild/win32-ia32@0.25.3': 373 | resolution: {integrity: sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==} 374 | engines: {node: '>=18'} 375 | cpu: [ia32] 376 | os: [win32] 377 | 378 | '@esbuild/win32-x64@0.25.3': 379 | resolution: {integrity: sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==} 380 | engines: {node: '>=18'} 381 | cpu: [x64] 382 | os: [win32] 383 | 384 | '@hono/node-server@1.14.1': 385 | resolution: {integrity: sha512-vmbuM+HPinjWzPe7FFPWMMQMsbKE9gDPhaH0FFdqbGpkT5lp++tcWDTxwBl5EgS5y6JVgIaCdjeHRfQ4XRBRjQ==} 386 | engines: {node: '>=18.14.1'} 387 | peerDependencies: 388 | hono: ^4 389 | 390 | '@opentelemetry/api@1.9.0': 391 | resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} 392 | engines: {node: '>=8.0.0'} 393 | 394 | '@polar-sh/adapter-utils@0.2.0': 395 | resolution: {integrity: sha512-dSP4E8BgHyaGevYAaTRlNW8rJjR91GXP7InV2+WZ2je2+Oq8PJKo7sLWbpkkJp9zmRx1I88f76rk0XmCY8Aivg==} 396 | 397 | '@polar-sh/hono@0.3.0': 398 | resolution: {integrity: sha512-oQ1MwoHxvzN9bzkbUumLuwVze+qOBOlxU+qQ80AQVCNEi2L52IpEnBypUVnQptf/7KvllwhlQRIlx0+x3u/ikg==} 399 | engines: {node: '>=16'} 400 | peerDependencies: 401 | hono: ^4.6.16 402 | 403 | '@polar-sh/ingestion@0.2.4': 404 | resolution: {integrity: sha512-4CiT5jIMhkmg/GQPO64IiZtbUau2qHfWtiHu8RRzG/zPdPCszuYYW+H8go/WaZN/oSJJwD5Rtituk2GTHP0sHg==} 405 | engines: {node: '>=18'} 406 | peerDependencies: 407 | '@aws-sdk/client-s3': ^3.744.0 408 | ai: ^4.1.17 409 | 410 | '@polar-sh/sdk@0.32.13': 411 | resolution: {integrity: sha512-xBjcKRPWV2v5lX0DDIcF6pjItinBooPbUd0SynpmV7SNe0ibFgcNwyr85J68eG2QBU/U6SaHLxp09QgoA/gnEw==} 412 | hasBin: true 413 | peerDependencies: 414 | '@modelcontextprotocol/sdk': '>=1.5.0 <1.10.0' 415 | zod: '>= 3' 416 | peerDependenciesMeta: 417 | '@modelcontextprotocol/sdk': 418 | optional: true 419 | 420 | '@smithy/abort-controller@4.0.2': 421 | resolution: {integrity: sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw==} 422 | engines: {node: '>=18.0.0'} 423 | 424 | '@smithy/chunked-blob-reader-native@4.0.0': 425 | resolution: {integrity: sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig==} 426 | engines: {node: '>=18.0.0'} 427 | 428 | '@smithy/chunked-blob-reader@5.0.0': 429 | resolution: {integrity: sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw==} 430 | engines: {node: '>=18.0.0'} 431 | 432 | '@smithy/config-resolver@4.1.0': 433 | resolution: {integrity: sha512-8smPlwhga22pwl23fM5ew4T9vfLUCeFXlcqNOCD5M5h8VmNPNUE9j6bQSuRXpDSV11L/E/SwEBQuW8hr6+nS1A==} 434 | engines: {node: '>=18.0.0'} 435 | 436 | '@smithy/core@3.3.0': 437 | resolution: {integrity: sha512-r6gvs5OfRq/w+9unPm7B3po4rmWaGh0CIL/OwHntGGux7+RhOOZLGuurbeMgWV6W55ZuyMTypJLeH0vn/ZRaWQ==} 438 | engines: {node: '>=18.0.0'} 439 | 440 | '@smithy/credential-provider-imds@4.0.2': 441 | resolution: {integrity: sha512-32lVig6jCaWBHnY+OEQ6e6Vnt5vDHaLiydGrwYMW9tPqO688hPGTYRamYJ1EptxEC2rAwJrHWmPoKRBl4iTa8w==} 442 | engines: {node: '>=18.0.0'} 443 | 444 | '@smithy/eventstream-codec@4.0.2': 445 | resolution: {integrity: sha512-p+f2kLSK7ZrXVfskU/f5dzksKTewZk8pJLPvER3aFHPt76C2MxD9vNatSfLzzQSQB4FNO96RK4PSXfhD1TTeMQ==} 446 | engines: {node: '>=18.0.0'} 447 | 448 | '@smithy/eventstream-serde-browser@4.0.2': 449 | resolution: {integrity: sha512-CepZCDs2xgVUtH7ZZ7oDdZFH8e6Y2zOv8iiX6RhndH69nlojCALSKK+OXwZUgOtUZEUaZ5e1hULVCHYbCn7pug==} 450 | engines: {node: '>=18.0.0'} 451 | 452 | '@smithy/eventstream-serde-config-resolver@4.1.0': 453 | resolution: {integrity: sha512-1PI+WPZ5TWXrfj3CIoKyUycYynYJgZjuQo8U+sphneOtjsgrttYybdqESFReQrdWJ+LKt6NEdbYzmmfDBmjX2A==} 454 | engines: {node: '>=18.0.0'} 455 | 456 | '@smithy/eventstream-serde-node@4.0.2': 457 | resolution: {integrity: sha512-C5bJ/C6x9ENPMx2cFOirspnF9ZsBVnBMtP6BdPl/qYSuUawdGQ34Lq0dMcf42QTjUZgWGbUIZnz6+zLxJlb9aw==} 458 | engines: {node: '>=18.0.0'} 459 | 460 | '@smithy/eventstream-serde-universal@4.0.2': 461 | resolution: {integrity: sha512-St8h9JqzvnbB52FtckiHPN4U/cnXcarMniXRXTKn0r4b4XesZOGiAyUdj1aXbqqn1icSqBlzzUsCl6nPB018ng==} 462 | engines: {node: '>=18.0.0'} 463 | 464 | '@smithy/fetch-http-handler@5.0.2': 465 | resolution: {integrity: sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ==} 466 | engines: {node: '>=18.0.0'} 467 | 468 | '@smithy/hash-blob-browser@4.0.2': 469 | resolution: {integrity: sha512-3g188Z3DyhtzfBRxpZjU8R9PpOQuYsbNnyStc/ZVS+9nVX1f6XeNOa9IrAh35HwwIZg+XWk8bFVtNINVscBP+g==} 470 | engines: {node: '>=18.0.0'} 471 | 472 | '@smithy/hash-node@4.0.2': 473 | resolution: {integrity: sha512-VnTpYPnRUE7yVhWozFdlxcYknv9UN7CeOqSrMH+V877v4oqtVYuoqhIhtSjmGPvYrYnAkaM61sLMKHvxL138yg==} 474 | engines: {node: '>=18.0.0'} 475 | 476 | '@smithy/hash-stream-node@4.0.2': 477 | resolution: {integrity: sha512-POWDuTznzbIwlEXEvvXoPMS10y0WKXK790soe57tFRfvf4zBHyzE529HpZMqmDdwG9MfFflnyzndUQ8j78ZdSg==} 478 | engines: {node: '>=18.0.0'} 479 | 480 | '@smithy/invalid-dependency@4.0.2': 481 | resolution: {integrity: sha512-GatB4+2DTpgWPday+mnUkoumP54u/MDM/5u44KF9hIu8jF0uafZtQLcdfIKkIcUNuF/fBojpLEHZS/56JqPeXQ==} 482 | engines: {node: '>=18.0.0'} 483 | 484 | '@smithy/is-array-buffer@2.2.0': 485 | resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} 486 | engines: {node: '>=14.0.0'} 487 | 488 | '@smithy/is-array-buffer@4.0.0': 489 | resolution: {integrity: sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==} 490 | engines: {node: '>=18.0.0'} 491 | 492 | '@smithy/md5-js@4.0.2': 493 | resolution: {integrity: sha512-Hc0R8EiuVunUewCse2syVgA2AfSRco3LyAv07B/zCOMa+jpXI9ll+Q21Nc6FAlYPcpNcAXqBzMhNs1CD/pP2bA==} 494 | engines: {node: '>=18.0.0'} 495 | 496 | '@smithy/middleware-content-length@4.0.2': 497 | resolution: {integrity: sha512-hAfEXm1zU+ELvucxqQ7I8SszwQ4znWMbNv6PLMndN83JJN41EPuS93AIyh2N+gJ6x8QFhzSO6b7q2e6oClDI8A==} 498 | engines: {node: '>=18.0.0'} 499 | 500 | '@smithy/middleware-endpoint@4.1.1': 501 | resolution: {integrity: sha512-z5RmcHxjvScL+LwEDU2mTNCOhgUs4lu5PGdF1K36IPRmUHhNFxNxgenSB7smyDiYD4vdKQ7CAZtG5cUErqib9w==} 502 | engines: {node: '>=18.0.0'} 503 | 504 | '@smithy/middleware-retry@4.1.2': 505 | resolution: {integrity: sha512-qN/Mmxm8JWtFAjozJ8VSTM83KOX4cIks8UjDqqNkKIegzPrE5ZKPNCQ/DqUSIF90pue5a/NycNXnBod2NwvZZQ==} 506 | engines: {node: '>=18.0.0'} 507 | 508 | '@smithy/middleware-serde@4.0.3': 509 | resolution: {integrity: sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A==} 510 | engines: {node: '>=18.0.0'} 511 | 512 | '@smithy/middleware-stack@4.0.2': 513 | resolution: {integrity: sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ==} 514 | engines: {node: '>=18.0.0'} 515 | 516 | '@smithy/node-config-provider@4.0.2': 517 | resolution: {integrity: sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw==} 518 | engines: {node: '>=18.0.0'} 519 | 520 | '@smithy/node-http-handler@4.0.4': 521 | resolution: {integrity: sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g==} 522 | engines: {node: '>=18.0.0'} 523 | 524 | '@smithy/property-provider@4.0.2': 525 | resolution: {integrity: sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A==} 526 | engines: {node: '>=18.0.0'} 527 | 528 | '@smithy/protocol-http@5.1.0': 529 | resolution: {integrity: sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g==} 530 | engines: {node: '>=18.0.0'} 531 | 532 | '@smithy/querystring-builder@4.0.2': 533 | resolution: {integrity: sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q==} 534 | engines: {node: '>=18.0.0'} 535 | 536 | '@smithy/querystring-parser@4.0.2': 537 | resolution: {integrity: sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q==} 538 | engines: {node: '>=18.0.0'} 539 | 540 | '@smithy/service-error-classification@4.0.3': 541 | resolution: {integrity: sha512-FTbcajmltovWMjj3tksDQdD23b2w6gH+A0DYA1Yz3iSpjDj8fmkwy62UnXcWMy4d5YoMoSyLFHMfkEVEzbiN8Q==} 542 | engines: {node: '>=18.0.0'} 543 | 544 | '@smithy/shared-ini-file-loader@4.0.2': 545 | resolution: {integrity: sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw==} 546 | engines: {node: '>=18.0.0'} 547 | 548 | '@smithy/signature-v4@5.1.0': 549 | resolution: {integrity: sha512-4t5WX60sL3zGJF/CtZsUQTs3UrZEDO2P7pEaElrekbLqkWPYkgqNW1oeiNYC6xXifBnT9dVBOnNQRvOE9riU9w==} 550 | engines: {node: '>=18.0.0'} 551 | 552 | '@smithy/smithy-client@4.2.1': 553 | resolution: {integrity: sha512-fbniZef60QdsBc4ZY0iyI8xbFHIiC/QRtPi66iE4ufjiE/aaz7AfUXzcWMkpO8r+QhLeNRIfmPchIG+3/QDZ6g==} 554 | engines: {node: '>=18.0.0'} 555 | 556 | '@smithy/types@4.2.0': 557 | resolution: {integrity: sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==} 558 | engines: {node: '>=18.0.0'} 559 | 560 | '@smithy/url-parser@4.0.2': 561 | resolution: {integrity: sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ==} 562 | engines: {node: '>=18.0.0'} 563 | 564 | '@smithy/util-base64@4.0.0': 565 | resolution: {integrity: sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==} 566 | engines: {node: '>=18.0.0'} 567 | 568 | '@smithy/util-body-length-browser@4.0.0': 569 | resolution: {integrity: sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==} 570 | engines: {node: '>=18.0.0'} 571 | 572 | '@smithy/util-body-length-node@4.0.0': 573 | resolution: {integrity: sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==} 574 | engines: {node: '>=18.0.0'} 575 | 576 | '@smithy/util-buffer-from@2.2.0': 577 | resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} 578 | engines: {node: '>=14.0.0'} 579 | 580 | '@smithy/util-buffer-from@4.0.0': 581 | resolution: {integrity: sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==} 582 | engines: {node: '>=18.0.0'} 583 | 584 | '@smithy/util-config-provider@4.0.0': 585 | resolution: {integrity: sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==} 586 | engines: {node: '>=18.0.0'} 587 | 588 | '@smithy/util-defaults-mode-browser@4.0.9': 589 | resolution: {integrity: sha512-B8j0XsElvyhv6+5hlFf6vFV/uCSyLKcInpeXOGnOImX2mGXshE01RvPoGipTlRpIk53e6UfYj7WdDdgbVfXDZw==} 590 | engines: {node: '>=18.0.0'} 591 | 592 | '@smithy/util-defaults-mode-node@4.0.9': 593 | resolution: {integrity: sha512-wTDU8P/zdIf9DOpV5qm64HVgGRXvqjqB/fJZTEQbrz3s79JHM/E7XkMm/876Oq+ZLHJQgnXM9QHDo29dlM62eA==} 594 | engines: {node: '>=18.0.0'} 595 | 596 | '@smithy/util-endpoints@3.0.2': 597 | resolution: {integrity: sha512-6QSutU5ZyrpNbnd51zRTL7goojlcnuOB55+F9VBD+j8JpRY50IGamsjlycrmpn8PQkmJucFW8A0LSfXj7jjtLQ==} 598 | engines: {node: '>=18.0.0'} 599 | 600 | '@smithy/util-hex-encoding@4.0.0': 601 | resolution: {integrity: sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==} 602 | engines: {node: '>=18.0.0'} 603 | 604 | '@smithy/util-middleware@4.0.2': 605 | resolution: {integrity: sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ==} 606 | engines: {node: '>=18.0.0'} 607 | 608 | '@smithy/util-retry@4.0.3': 609 | resolution: {integrity: sha512-DPuYjZQDXmKr/sNvy9Spu8R/ESa2e22wXZzSAY6NkjOLj6spbIje/Aq8rT97iUMdDj0qHMRIe+bTxvlU74d9Ng==} 610 | engines: {node: '>=18.0.0'} 611 | 612 | '@smithy/util-stream@4.2.0': 613 | resolution: {integrity: sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ==} 614 | engines: {node: '>=18.0.0'} 615 | 616 | '@smithy/util-uri-escape@4.0.0': 617 | resolution: {integrity: sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==} 618 | engines: {node: '>=18.0.0'} 619 | 620 | '@smithy/util-utf8@2.3.0': 621 | resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} 622 | engines: {node: '>=14.0.0'} 623 | 624 | '@smithy/util-utf8@4.0.0': 625 | resolution: {integrity: sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==} 626 | engines: {node: '>=18.0.0'} 627 | 628 | '@smithy/util-waiter@4.0.3': 629 | resolution: {integrity: sha512-JtaY3FxmD+te+KSI2FJuEcfNC9T/DGGVf551babM7fAaXhjJUt7oSYurH1Devxd2+BOSUACCgt3buinx4UnmEA==} 630 | engines: {node: '>=18.0.0'} 631 | 632 | '@stablelib/base64@1.0.1': 633 | resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} 634 | 635 | '@types/diff-match-patch@1.0.36': 636 | resolution: {integrity: sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==} 637 | 638 | '@types/node@22.15.3': 639 | resolution: {integrity: sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==} 640 | 641 | ai@4.3.13: 642 | resolution: {integrity: sha512-cC5HXItuOwGykSMacCPzNp6+NMTxeuTjOenztVgSJhdC9Z4OrzBxwkyeDAf4h1QP938ZFi7IBdq3u4lxVoVmvw==} 643 | engines: {node: '>=18'} 644 | peerDependencies: 645 | react: ^18 || ^19 || ^19.0.0-rc 646 | zod: ^3.23.8 647 | peerDependenciesMeta: 648 | react: 649 | optional: true 650 | 651 | bowser@2.11.0: 652 | resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} 653 | 654 | chalk@5.4.1: 655 | resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} 656 | engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 657 | 658 | dequal@2.0.3: 659 | resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} 660 | engines: {node: '>=6'} 661 | 662 | diff-match-patch@1.0.5: 663 | resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} 664 | 665 | dotenv@16.5.0: 666 | resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} 667 | engines: {node: '>=12'} 668 | 669 | esbuild@0.25.3: 670 | resolution: {integrity: sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==} 671 | engines: {node: '>=18'} 672 | hasBin: true 673 | 674 | fast-sha256@1.3.0: 675 | resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} 676 | 677 | fast-xml-parser@4.4.1: 678 | resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} 679 | hasBin: true 680 | 681 | fsevents@2.3.3: 682 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 683 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 684 | os: [darwin] 685 | 686 | get-tsconfig@4.10.0: 687 | resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} 688 | 689 | hono@4.7.8: 690 | resolution: {integrity: sha512-PCibtFdxa7/Ldud9yddl1G81GjYaeMYYTq4ywSaNsYbB1Lug4mwtOMJf2WXykL0pntYwmpRJeOI3NmoDgD+Jxw==} 691 | engines: {node: '>=16.9.0'} 692 | 693 | json-schema@0.4.0: 694 | resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} 695 | 696 | jsondiffpatch@0.6.0: 697 | resolution: {integrity: sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==} 698 | engines: {node: ^18.0.0 || >=20.0.0} 699 | hasBin: true 700 | 701 | nanoid@3.3.11: 702 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} 703 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 704 | hasBin: true 705 | 706 | react@19.1.0: 707 | resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} 708 | engines: {node: '>=0.10.0'} 709 | 710 | resolve-pkg-maps@1.0.0: 711 | resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 712 | 713 | secure-json-parse@2.7.0: 714 | resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} 715 | 716 | standardwebhooks@1.0.0: 717 | resolution: {integrity: sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==} 718 | 719 | strnum@1.1.2: 720 | resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==} 721 | 722 | swr@2.3.3: 723 | resolution: {integrity: sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A==} 724 | peerDependencies: 725 | react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 726 | 727 | throttleit@2.1.0: 728 | resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} 729 | engines: {node: '>=18'} 730 | 731 | tslib@2.8.1: 732 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 733 | 734 | tsx@4.19.4: 735 | resolution: {integrity: sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==} 736 | engines: {node: '>=18.0.0'} 737 | hasBin: true 738 | 739 | typescript@5.8.3: 740 | resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} 741 | engines: {node: '>=14.17'} 742 | hasBin: true 743 | 744 | undici-types@6.21.0: 745 | resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} 746 | 747 | use-sync-external-store@1.5.0: 748 | resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} 749 | peerDependencies: 750 | react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 751 | 752 | uuid@9.0.1: 753 | resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} 754 | hasBin: true 755 | 756 | zod-to-json-schema@3.24.5: 757 | resolution: {integrity: sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==} 758 | peerDependencies: 759 | zod: ^3.24.1 760 | 761 | zod@3.24.3: 762 | resolution: {integrity: sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==} 763 | 764 | snapshots: 765 | 766 | '@ai-sdk/openai@1.3.21(zod@3.24.3)': 767 | dependencies: 768 | '@ai-sdk/provider': 1.1.3 769 | '@ai-sdk/provider-utils': 2.2.7(zod@3.24.3) 770 | zod: 3.24.3 771 | 772 | '@ai-sdk/provider-utils@2.2.7(zod@3.24.3)': 773 | dependencies: 774 | '@ai-sdk/provider': 1.1.3 775 | nanoid: 3.3.11 776 | secure-json-parse: 2.7.0 777 | zod: 3.24.3 778 | 779 | '@ai-sdk/provider@1.1.3': 780 | dependencies: 781 | json-schema: 0.4.0 782 | 783 | '@ai-sdk/react@1.2.11(react@19.1.0)(zod@3.24.3)': 784 | dependencies: 785 | '@ai-sdk/provider-utils': 2.2.7(zod@3.24.3) 786 | '@ai-sdk/ui-utils': 1.2.10(zod@3.24.3) 787 | react: 19.1.0 788 | swr: 2.3.3(react@19.1.0) 789 | throttleit: 2.1.0 790 | optionalDependencies: 791 | zod: 3.24.3 792 | 793 | '@ai-sdk/ui-utils@1.2.10(zod@3.24.3)': 794 | dependencies: 795 | '@ai-sdk/provider': 1.1.3 796 | '@ai-sdk/provider-utils': 2.2.7(zod@3.24.3) 797 | zod: 3.24.3 798 | zod-to-json-schema: 3.24.5(zod@3.24.3) 799 | 800 | '@aws-crypto/crc32@5.2.0': 801 | dependencies: 802 | '@aws-crypto/util': 5.2.0 803 | '@aws-sdk/types': 3.775.0 804 | tslib: 2.8.1 805 | 806 | '@aws-crypto/crc32c@5.2.0': 807 | dependencies: 808 | '@aws-crypto/util': 5.2.0 809 | '@aws-sdk/types': 3.775.0 810 | tslib: 2.8.1 811 | 812 | '@aws-crypto/sha1-browser@5.2.0': 813 | dependencies: 814 | '@aws-crypto/supports-web-crypto': 5.2.0 815 | '@aws-crypto/util': 5.2.0 816 | '@aws-sdk/types': 3.775.0 817 | '@aws-sdk/util-locate-window': 3.723.0 818 | '@smithy/util-utf8': 2.3.0 819 | tslib: 2.8.1 820 | 821 | '@aws-crypto/sha256-browser@5.2.0': 822 | dependencies: 823 | '@aws-crypto/sha256-js': 5.2.0 824 | '@aws-crypto/supports-web-crypto': 5.2.0 825 | '@aws-crypto/util': 5.2.0 826 | '@aws-sdk/types': 3.775.0 827 | '@aws-sdk/util-locate-window': 3.723.0 828 | '@smithy/util-utf8': 2.3.0 829 | tslib: 2.8.1 830 | 831 | '@aws-crypto/sha256-js@5.2.0': 832 | dependencies: 833 | '@aws-crypto/util': 5.2.0 834 | '@aws-sdk/types': 3.775.0 835 | tslib: 2.8.1 836 | 837 | '@aws-crypto/supports-web-crypto@5.2.0': 838 | dependencies: 839 | tslib: 2.8.1 840 | 841 | '@aws-crypto/util@5.2.0': 842 | dependencies: 843 | '@aws-sdk/types': 3.775.0 844 | '@smithy/util-utf8': 2.3.0 845 | tslib: 2.8.1 846 | 847 | '@aws-sdk/client-s3@3.800.0': 848 | dependencies: 849 | '@aws-crypto/sha1-browser': 5.2.0 850 | '@aws-crypto/sha256-browser': 5.2.0 851 | '@aws-crypto/sha256-js': 5.2.0 852 | '@aws-sdk/core': 3.799.0 853 | '@aws-sdk/credential-provider-node': 3.799.0 854 | '@aws-sdk/middleware-bucket-endpoint': 3.775.0 855 | '@aws-sdk/middleware-expect-continue': 3.775.0 856 | '@aws-sdk/middleware-flexible-checksums': 3.799.0 857 | '@aws-sdk/middleware-host-header': 3.775.0 858 | '@aws-sdk/middleware-location-constraint': 3.775.0 859 | '@aws-sdk/middleware-logger': 3.775.0 860 | '@aws-sdk/middleware-recursion-detection': 3.775.0 861 | '@aws-sdk/middleware-sdk-s3': 3.799.0 862 | '@aws-sdk/middleware-ssec': 3.775.0 863 | '@aws-sdk/middleware-user-agent': 3.799.0 864 | '@aws-sdk/region-config-resolver': 3.775.0 865 | '@aws-sdk/signature-v4-multi-region': 3.800.0 866 | '@aws-sdk/types': 3.775.0 867 | '@aws-sdk/util-endpoints': 3.787.0 868 | '@aws-sdk/util-user-agent-browser': 3.775.0 869 | '@aws-sdk/util-user-agent-node': 3.799.0 870 | '@aws-sdk/xml-builder': 3.775.0 871 | '@smithy/config-resolver': 4.1.0 872 | '@smithy/core': 3.3.0 873 | '@smithy/eventstream-serde-browser': 4.0.2 874 | '@smithy/eventstream-serde-config-resolver': 4.1.0 875 | '@smithy/eventstream-serde-node': 4.0.2 876 | '@smithy/fetch-http-handler': 5.0.2 877 | '@smithy/hash-blob-browser': 4.0.2 878 | '@smithy/hash-node': 4.0.2 879 | '@smithy/hash-stream-node': 4.0.2 880 | '@smithy/invalid-dependency': 4.0.2 881 | '@smithy/md5-js': 4.0.2 882 | '@smithy/middleware-content-length': 4.0.2 883 | '@smithy/middleware-endpoint': 4.1.1 884 | '@smithy/middleware-retry': 4.1.2 885 | '@smithy/middleware-serde': 4.0.3 886 | '@smithy/middleware-stack': 4.0.2 887 | '@smithy/node-config-provider': 4.0.2 888 | '@smithy/node-http-handler': 4.0.4 889 | '@smithy/protocol-http': 5.1.0 890 | '@smithy/smithy-client': 4.2.1 891 | '@smithy/types': 4.2.0 892 | '@smithy/url-parser': 4.0.2 893 | '@smithy/util-base64': 4.0.0 894 | '@smithy/util-body-length-browser': 4.0.0 895 | '@smithy/util-body-length-node': 4.0.0 896 | '@smithy/util-defaults-mode-browser': 4.0.9 897 | '@smithy/util-defaults-mode-node': 4.0.9 898 | '@smithy/util-endpoints': 3.0.2 899 | '@smithy/util-middleware': 4.0.2 900 | '@smithy/util-retry': 4.0.3 901 | '@smithy/util-stream': 4.2.0 902 | '@smithy/util-utf8': 4.0.0 903 | '@smithy/util-waiter': 4.0.3 904 | tslib: 2.8.1 905 | transitivePeerDependencies: 906 | - aws-crt 907 | 908 | '@aws-sdk/client-sso@3.799.0': 909 | dependencies: 910 | '@aws-crypto/sha256-browser': 5.2.0 911 | '@aws-crypto/sha256-js': 5.2.0 912 | '@aws-sdk/core': 3.799.0 913 | '@aws-sdk/middleware-host-header': 3.775.0 914 | '@aws-sdk/middleware-logger': 3.775.0 915 | '@aws-sdk/middleware-recursion-detection': 3.775.0 916 | '@aws-sdk/middleware-user-agent': 3.799.0 917 | '@aws-sdk/region-config-resolver': 3.775.0 918 | '@aws-sdk/types': 3.775.0 919 | '@aws-sdk/util-endpoints': 3.787.0 920 | '@aws-sdk/util-user-agent-browser': 3.775.0 921 | '@aws-sdk/util-user-agent-node': 3.799.0 922 | '@smithy/config-resolver': 4.1.0 923 | '@smithy/core': 3.3.0 924 | '@smithy/fetch-http-handler': 5.0.2 925 | '@smithy/hash-node': 4.0.2 926 | '@smithy/invalid-dependency': 4.0.2 927 | '@smithy/middleware-content-length': 4.0.2 928 | '@smithy/middleware-endpoint': 4.1.1 929 | '@smithy/middleware-retry': 4.1.2 930 | '@smithy/middleware-serde': 4.0.3 931 | '@smithy/middleware-stack': 4.0.2 932 | '@smithy/node-config-provider': 4.0.2 933 | '@smithy/node-http-handler': 4.0.4 934 | '@smithy/protocol-http': 5.1.0 935 | '@smithy/smithy-client': 4.2.1 936 | '@smithy/types': 4.2.0 937 | '@smithy/url-parser': 4.0.2 938 | '@smithy/util-base64': 4.0.0 939 | '@smithy/util-body-length-browser': 4.0.0 940 | '@smithy/util-body-length-node': 4.0.0 941 | '@smithy/util-defaults-mode-browser': 4.0.9 942 | '@smithy/util-defaults-mode-node': 4.0.9 943 | '@smithy/util-endpoints': 3.0.2 944 | '@smithy/util-middleware': 4.0.2 945 | '@smithy/util-retry': 4.0.3 946 | '@smithy/util-utf8': 4.0.0 947 | tslib: 2.8.1 948 | transitivePeerDependencies: 949 | - aws-crt 950 | 951 | '@aws-sdk/core@3.799.0': 952 | dependencies: 953 | '@aws-sdk/types': 3.775.0 954 | '@smithy/core': 3.3.0 955 | '@smithy/node-config-provider': 4.0.2 956 | '@smithy/property-provider': 4.0.2 957 | '@smithy/protocol-http': 5.1.0 958 | '@smithy/signature-v4': 5.1.0 959 | '@smithy/smithy-client': 4.2.1 960 | '@smithy/types': 4.2.0 961 | '@smithy/util-middleware': 4.0.2 962 | fast-xml-parser: 4.4.1 963 | tslib: 2.8.1 964 | 965 | '@aws-sdk/credential-provider-env@3.799.0': 966 | dependencies: 967 | '@aws-sdk/core': 3.799.0 968 | '@aws-sdk/types': 3.775.0 969 | '@smithy/property-provider': 4.0.2 970 | '@smithy/types': 4.2.0 971 | tslib: 2.8.1 972 | 973 | '@aws-sdk/credential-provider-http@3.799.0': 974 | dependencies: 975 | '@aws-sdk/core': 3.799.0 976 | '@aws-sdk/types': 3.775.0 977 | '@smithy/fetch-http-handler': 5.0.2 978 | '@smithy/node-http-handler': 4.0.4 979 | '@smithy/property-provider': 4.0.2 980 | '@smithy/protocol-http': 5.1.0 981 | '@smithy/smithy-client': 4.2.1 982 | '@smithy/types': 4.2.0 983 | '@smithy/util-stream': 4.2.0 984 | tslib: 2.8.1 985 | 986 | '@aws-sdk/credential-provider-ini@3.799.0': 987 | dependencies: 988 | '@aws-sdk/core': 3.799.0 989 | '@aws-sdk/credential-provider-env': 3.799.0 990 | '@aws-sdk/credential-provider-http': 3.799.0 991 | '@aws-sdk/credential-provider-process': 3.799.0 992 | '@aws-sdk/credential-provider-sso': 3.799.0 993 | '@aws-sdk/credential-provider-web-identity': 3.799.0 994 | '@aws-sdk/nested-clients': 3.799.0 995 | '@aws-sdk/types': 3.775.0 996 | '@smithy/credential-provider-imds': 4.0.2 997 | '@smithy/property-provider': 4.0.2 998 | '@smithy/shared-ini-file-loader': 4.0.2 999 | '@smithy/types': 4.2.0 1000 | tslib: 2.8.1 1001 | transitivePeerDependencies: 1002 | - aws-crt 1003 | 1004 | '@aws-sdk/credential-provider-node@3.799.0': 1005 | dependencies: 1006 | '@aws-sdk/credential-provider-env': 3.799.0 1007 | '@aws-sdk/credential-provider-http': 3.799.0 1008 | '@aws-sdk/credential-provider-ini': 3.799.0 1009 | '@aws-sdk/credential-provider-process': 3.799.0 1010 | '@aws-sdk/credential-provider-sso': 3.799.0 1011 | '@aws-sdk/credential-provider-web-identity': 3.799.0 1012 | '@aws-sdk/types': 3.775.0 1013 | '@smithy/credential-provider-imds': 4.0.2 1014 | '@smithy/property-provider': 4.0.2 1015 | '@smithy/shared-ini-file-loader': 4.0.2 1016 | '@smithy/types': 4.2.0 1017 | tslib: 2.8.1 1018 | transitivePeerDependencies: 1019 | - aws-crt 1020 | 1021 | '@aws-sdk/credential-provider-process@3.799.0': 1022 | dependencies: 1023 | '@aws-sdk/core': 3.799.0 1024 | '@aws-sdk/types': 3.775.0 1025 | '@smithy/property-provider': 4.0.2 1026 | '@smithy/shared-ini-file-loader': 4.0.2 1027 | '@smithy/types': 4.2.0 1028 | tslib: 2.8.1 1029 | 1030 | '@aws-sdk/credential-provider-sso@3.799.0': 1031 | dependencies: 1032 | '@aws-sdk/client-sso': 3.799.0 1033 | '@aws-sdk/core': 3.799.0 1034 | '@aws-sdk/token-providers': 3.799.0 1035 | '@aws-sdk/types': 3.775.0 1036 | '@smithy/property-provider': 4.0.2 1037 | '@smithy/shared-ini-file-loader': 4.0.2 1038 | '@smithy/types': 4.2.0 1039 | tslib: 2.8.1 1040 | transitivePeerDependencies: 1041 | - aws-crt 1042 | 1043 | '@aws-sdk/credential-provider-web-identity@3.799.0': 1044 | dependencies: 1045 | '@aws-sdk/core': 3.799.0 1046 | '@aws-sdk/nested-clients': 3.799.0 1047 | '@aws-sdk/types': 3.775.0 1048 | '@smithy/property-provider': 4.0.2 1049 | '@smithy/types': 4.2.0 1050 | tslib: 2.8.1 1051 | transitivePeerDependencies: 1052 | - aws-crt 1053 | 1054 | '@aws-sdk/middleware-bucket-endpoint@3.775.0': 1055 | dependencies: 1056 | '@aws-sdk/types': 3.775.0 1057 | '@aws-sdk/util-arn-parser': 3.723.0 1058 | '@smithy/node-config-provider': 4.0.2 1059 | '@smithy/protocol-http': 5.1.0 1060 | '@smithy/types': 4.2.0 1061 | '@smithy/util-config-provider': 4.0.0 1062 | tslib: 2.8.1 1063 | 1064 | '@aws-sdk/middleware-expect-continue@3.775.0': 1065 | dependencies: 1066 | '@aws-sdk/types': 3.775.0 1067 | '@smithy/protocol-http': 5.1.0 1068 | '@smithy/types': 4.2.0 1069 | tslib: 2.8.1 1070 | 1071 | '@aws-sdk/middleware-flexible-checksums@3.799.0': 1072 | dependencies: 1073 | '@aws-crypto/crc32': 5.2.0 1074 | '@aws-crypto/crc32c': 5.2.0 1075 | '@aws-crypto/util': 5.2.0 1076 | '@aws-sdk/core': 3.799.0 1077 | '@aws-sdk/types': 3.775.0 1078 | '@smithy/is-array-buffer': 4.0.0 1079 | '@smithy/node-config-provider': 4.0.2 1080 | '@smithy/protocol-http': 5.1.0 1081 | '@smithy/types': 4.2.0 1082 | '@smithy/util-middleware': 4.0.2 1083 | '@smithy/util-stream': 4.2.0 1084 | '@smithy/util-utf8': 4.0.0 1085 | tslib: 2.8.1 1086 | 1087 | '@aws-sdk/middleware-host-header@3.775.0': 1088 | dependencies: 1089 | '@aws-sdk/types': 3.775.0 1090 | '@smithy/protocol-http': 5.1.0 1091 | '@smithy/types': 4.2.0 1092 | tslib: 2.8.1 1093 | 1094 | '@aws-sdk/middleware-location-constraint@3.775.0': 1095 | dependencies: 1096 | '@aws-sdk/types': 3.775.0 1097 | '@smithy/types': 4.2.0 1098 | tslib: 2.8.1 1099 | 1100 | '@aws-sdk/middleware-logger@3.775.0': 1101 | dependencies: 1102 | '@aws-sdk/types': 3.775.0 1103 | '@smithy/types': 4.2.0 1104 | tslib: 2.8.1 1105 | 1106 | '@aws-sdk/middleware-recursion-detection@3.775.0': 1107 | dependencies: 1108 | '@aws-sdk/types': 3.775.0 1109 | '@smithy/protocol-http': 5.1.0 1110 | '@smithy/types': 4.2.0 1111 | tslib: 2.8.1 1112 | 1113 | '@aws-sdk/middleware-sdk-s3@3.799.0': 1114 | dependencies: 1115 | '@aws-sdk/core': 3.799.0 1116 | '@aws-sdk/types': 3.775.0 1117 | '@aws-sdk/util-arn-parser': 3.723.0 1118 | '@smithy/core': 3.3.0 1119 | '@smithy/node-config-provider': 4.0.2 1120 | '@smithy/protocol-http': 5.1.0 1121 | '@smithy/signature-v4': 5.1.0 1122 | '@smithy/smithy-client': 4.2.1 1123 | '@smithy/types': 4.2.0 1124 | '@smithy/util-config-provider': 4.0.0 1125 | '@smithy/util-middleware': 4.0.2 1126 | '@smithy/util-stream': 4.2.0 1127 | '@smithy/util-utf8': 4.0.0 1128 | tslib: 2.8.1 1129 | 1130 | '@aws-sdk/middleware-ssec@3.775.0': 1131 | dependencies: 1132 | '@aws-sdk/types': 3.775.0 1133 | '@smithy/types': 4.2.0 1134 | tslib: 2.8.1 1135 | 1136 | '@aws-sdk/middleware-user-agent@3.799.0': 1137 | dependencies: 1138 | '@aws-sdk/core': 3.799.0 1139 | '@aws-sdk/types': 3.775.0 1140 | '@aws-sdk/util-endpoints': 3.787.0 1141 | '@smithy/core': 3.3.0 1142 | '@smithy/protocol-http': 5.1.0 1143 | '@smithy/types': 4.2.0 1144 | tslib: 2.8.1 1145 | 1146 | '@aws-sdk/nested-clients@3.799.0': 1147 | dependencies: 1148 | '@aws-crypto/sha256-browser': 5.2.0 1149 | '@aws-crypto/sha256-js': 5.2.0 1150 | '@aws-sdk/core': 3.799.0 1151 | '@aws-sdk/middleware-host-header': 3.775.0 1152 | '@aws-sdk/middleware-logger': 3.775.0 1153 | '@aws-sdk/middleware-recursion-detection': 3.775.0 1154 | '@aws-sdk/middleware-user-agent': 3.799.0 1155 | '@aws-sdk/region-config-resolver': 3.775.0 1156 | '@aws-sdk/types': 3.775.0 1157 | '@aws-sdk/util-endpoints': 3.787.0 1158 | '@aws-sdk/util-user-agent-browser': 3.775.0 1159 | '@aws-sdk/util-user-agent-node': 3.799.0 1160 | '@smithy/config-resolver': 4.1.0 1161 | '@smithy/core': 3.3.0 1162 | '@smithy/fetch-http-handler': 5.0.2 1163 | '@smithy/hash-node': 4.0.2 1164 | '@smithy/invalid-dependency': 4.0.2 1165 | '@smithy/middleware-content-length': 4.0.2 1166 | '@smithy/middleware-endpoint': 4.1.1 1167 | '@smithy/middleware-retry': 4.1.2 1168 | '@smithy/middleware-serde': 4.0.3 1169 | '@smithy/middleware-stack': 4.0.2 1170 | '@smithy/node-config-provider': 4.0.2 1171 | '@smithy/node-http-handler': 4.0.4 1172 | '@smithy/protocol-http': 5.1.0 1173 | '@smithy/smithy-client': 4.2.1 1174 | '@smithy/types': 4.2.0 1175 | '@smithy/url-parser': 4.0.2 1176 | '@smithy/util-base64': 4.0.0 1177 | '@smithy/util-body-length-browser': 4.0.0 1178 | '@smithy/util-body-length-node': 4.0.0 1179 | '@smithy/util-defaults-mode-browser': 4.0.9 1180 | '@smithy/util-defaults-mode-node': 4.0.9 1181 | '@smithy/util-endpoints': 3.0.2 1182 | '@smithy/util-middleware': 4.0.2 1183 | '@smithy/util-retry': 4.0.3 1184 | '@smithy/util-utf8': 4.0.0 1185 | tslib: 2.8.1 1186 | transitivePeerDependencies: 1187 | - aws-crt 1188 | 1189 | '@aws-sdk/region-config-resolver@3.775.0': 1190 | dependencies: 1191 | '@aws-sdk/types': 3.775.0 1192 | '@smithy/node-config-provider': 4.0.2 1193 | '@smithy/types': 4.2.0 1194 | '@smithy/util-config-provider': 4.0.0 1195 | '@smithy/util-middleware': 4.0.2 1196 | tslib: 2.8.1 1197 | 1198 | '@aws-sdk/signature-v4-multi-region@3.800.0': 1199 | dependencies: 1200 | '@aws-sdk/middleware-sdk-s3': 3.799.0 1201 | '@aws-sdk/types': 3.775.0 1202 | '@smithy/protocol-http': 5.1.0 1203 | '@smithy/signature-v4': 5.1.0 1204 | '@smithy/types': 4.2.0 1205 | tslib: 2.8.1 1206 | 1207 | '@aws-sdk/token-providers@3.799.0': 1208 | dependencies: 1209 | '@aws-sdk/nested-clients': 3.799.0 1210 | '@aws-sdk/types': 3.775.0 1211 | '@smithy/property-provider': 4.0.2 1212 | '@smithy/shared-ini-file-loader': 4.0.2 1213 | '@smithy/types': 4.2.0 1214 | tslib: 2.8.1 1215 | transitivePeerDependencies: 1216 | - aws-crt 1217 | 1218 | '@aws-sdk/types@3.775.0': 1219 | dependencies: 1220 | '@smithy/types': 4.2.0 1221 | tslib: 2.8.1 1222 | 1223 | '@aws-sdk/util-arn-parser@3.723.0': 1224 | dependencies: 1225 | tslib: 2.8.1 1226 | 1227 | '@aws-sdk/util-endpoints@3.787.0': 1228 | dependencies: 1229 | '@aws-sdk/types': 3.775.0 1230 | '@smithy/types': 4.2.0 1231 | '@smithy/util-endpoints': 3.0.2 1232 | tslib: 2.8.1 1233 | 1234 | '@aws-sdk/util-locate-window@3.723.0': 1235 | dependencies: 1236 | tslib: 2.8.1 1237 | 1238 | '@aws-sdk/util-user-agent-browser@3.775.0': 1239 | dependencies: 1240 | '@aws-sdk/types': 3.775.0 1241 | '@smithy/types': 4.2.0 1242 | bowser: 2.11.0 1243 | tslib: 2.8.1 1244 | 1245 | '@aws-sdk/util-user-agent-node@3.799.0': 1246 | dependencies: 1247 | '@aws-sdk/middleware-user-agent': 3.799.0 1248 | '@aws-sdk/types': 3.775.0 1249 | '@smithy/node-config-provider': 4.0.2 1250 | '@smithy/types': 4.2.0 1251 | tslib: 2.8.1 1252 | 1253 | '@aws-sdk/xml-builder@3.775.0': 1254 | dependencies: 1255 | '@smithy/types': 4.2.0 1256 | tslib: 2.8.1 1257 | 1258 | '@esbuild/aix-ppc64@0.25.3': 1259 | optional: true 1260 | 1261 | '@esbuild/android-arm64@0.25.3': 1262 | optional: true 1263 | 1264 | '@esbuild/android-arm@0.25.3': 1265 | optional: true 1266 | 1267 | '@esbuild/android-x64@0.25.3': 1268 | optional: true 1269 | 1270 | '@esbuild/darwin-arm64@0.25.3': 1271 | optional: true 1272 | 1273 | '@esbuild/darwin-x64@0.25.3': 1274 | optional: true 1275 | 1276 | '@esbuild/freebsd-arm64@0.25.3': 1277 | optional: true 1278 | 1279 | '@esbuild/freebsd-x64@0.25.3': 1280 | optional: true 1281 | 1282 | '@esbuild/linux-arm64@0.25.3': 1283 | optional: true 1284 | 1285 | '@esbuild/linux-arm@0.25.3': 1286 | optional: true 1287 | 1288 | '@esbuild/linux-ia32@0.25.3': 1289 | optional: true 1290 | 1291 | '@esbuild/linux-loong64@0.25.3': 1292 | optional: true 1293 | 1294 | '@esbuild/linux-mips64el@0.25.3': 1295 | optional: true 1296 | 1297 | '@esbuild/linux-ppc64@0.25.3': 1298 | optional: true 1299 | 1300 | '@esbuild/linux-riscv64@0.25.3': 1301 | optional: true 1302 | 1303 | '@esbuild/linux-s390x@0.25.3': 1304 | optional: true 1305 | 1306 | '@esbuild/linux-x64@0.25.3': 1307 | optional: true 1308 | 1309 | '@esbuild/netbsd-arm64@0.25.3': 1310 | optional: true 1311 | 1312 | '@esbuild/netbsd-x64@0.25.3': 1313 | optional: true 1314 | 1315 | '@esbuild/openbsd-arm64@0.25.3': 1316 | optional: true 1317 | 1318 | '@esbuild/openbsd-x64@0.25.3': 1319 | optional: true 1320 | 1321 | '@esbuild/sunos-x64@0.25.3': 1322 | optional: true 1323 | 1324 | '@esbuild/win32-arm64@0.25.3': 1325 | optional: true 1326 | 1327 | '@esbuild/win32-ia32@0.25.3': 1328 | optional: true 1329 | 1330 | '@esbuild/win32-x64@0.25.3': 1331 | optional: true 1332 | 1333 | '@hono/node-server@1.14.1(hono@4.7.8)': 1334 | dependencies: 1335 | hono: 4.7.8 1336 | 1337 | '@opentelemetry/api@1.9.0': {} 1338 | 1339 | '@polar-sh/adapter-utils@0.2.0(zod@3.24.3)': 1340 | dependencies: 1341 | '@polar-sh/sdk': 0.32.13(zod@3.24.3) 1342 | transitivePeerDependencies: 1343 | - '@modelcontextprotocol/sdk' 1344 | - zod 1345 | 1346 | '@polar-sh/hono@0.3.0(hono@4.7.8)(zod@3.24.3)': 1347 | dependencies: 1348 | '@polar-sh/adapter-utils': 0.2.0(zod@3.24.3) 1349 | '@polar-sh/sdk': 0.32.13(zod@3.24.3) 1350 | hono: 4.7.8 1351 | transitivePeerDependencies: 1352 | - '@modelcontextprotocol/sdk' 1353 | - zod 1354 | 1355 | '@polar-sh/ingestion@0.2.4(@aws-sdk/client-s3@3.800.0)(ai@4.3.13(react@19.1.0)(zod@3.24.3))(zod@3.24.3)': 1356 | dependencies: 1357 | '@aws-sdk/client-s3': 3.800.0 1358 | '@polar-sh/sdk': 0.32.13(zod@3.24.3) 1359 | ai: 4.3.13(react@19.1.0)(zod@3.24.3) 1360 | transitivePeerDependencies: 1361 | - '@modelcontextprotocol/sdk' 1362 | - zod 1363 | 1364 | '@polar-sh/sdk@0.32.13(zod@3.24.3)': 1365 | dependencies: 1366 | standardwebhooks: 1.0.0 1367 | zod: 3.24.3 1368 | 1369 | '@smithy/abort-controller@4.0.2': 1370 | dependencies: 1371 | '@smithy/types': 4.2.0 1372 | tslib: 2.8.1 1373 | 1374 | '@smithy/chunked-blob-reader-native@4.0.0': 1375 | dependencies: 1376 | '@smithy/util-base64': 4.0.0 1377 | tslib: 2.8.1 1378 | 1379 | '@smithy/chunked-blob-reader@5.0.0': 1380 | dependencies: 1381 | tslib: 2.8.1 1382 | 1383 | '@smithy/config-resolver@4.1.0': 1384 | dependencies: 1385 | '@smithy/node-config-provider': 4.0.2 1386 | '@smithy/types': 4.2.0 1387 | '@smithy/util-config-provider': 4.0.0 1388 | '@smithy/util-middleware': 4.0.2 1389 | tslib: 2.8.1 1390 | 1391 | '@smithy/core@3.3.0': 1392 | dependencies: 1393 | '@smithy/middleware-serde': 4.0.3 1394 | '@smithy/protocol-http': 5.1.0 1395 | '@smithy/types': 4.2.0 1396 | '@smithy/util-body-length-browser': 4.0.0 1397 | '@smithy/util-middleware': 4.0.2 1398 | '@smithy/util-stream': 4.2.0 1399 | '@smithy/util-utf8': 4.0.0 1400 | tslib: 2.8.1 1401 | 1402 | '@smithy/credential-provider-imds@4.0.2': 1403 | dependencies: 1404 | '@smithy/node-config-provider': 4.0.2 1405 | '@smithy/property-provider': 4.0.2 1406 | '@smithy/types': 4.2.0 1407 | '@smithy/url-parser': 4.0.2 1408 | tslib: 2.8.1 1409 | 1410 | '@smithy/eventstream-codec@4.0.2': 1411 | dependencies: 1412 | '@aws-crypto/crc32': 5.2.0 1413 | '@smithy/types': 4.2.0 1414 | '@smithy/util-hex-encoding': 4.0.0 1415 | tslib: 2.8.1 1416 | 1417 | '@smithy/eventstream-serde-browser@4.0.2': 1418 | dependencies: 1419 | '@smithy/eventstream-serde-universal': 4.0.2 1420 | '@smithy/types': 4.2.0 1421 | tslib: 2.8.1 1422 | 1423 | '@smithy/eventstream-serde-config-resolver@4.1.0': 1424 | dependencies: 1425 | '@smithy/types': 4.2.0 1426 | tslib: 2.8.1 1427 | 1428 | '@smithy/eventstream-serde-node@4.0.2': 1429 | dependencies: 1430 | '@smithy/eventstream-serde-universal': 4.0.2 1431 | '@smithy/types': 4.2.0 1432 | tslib: 2.8.1 1433 | 1434 | '@smithy/eventstream-serde-universal@4.0.2': 1435 | dependencies: 1436 | '@smithy/eventstream-codec': 4.0.2 1437 | '@smithy/types': 4.2.0 1438 | tslib: 2.8.1 1439 | 1440 | '@smithy/fetch-http-handler@5.0.2': 1441 | dependencies: 1442 | '@smithy/protocol-http': 5.1.0 1443 | '@smithy/querystring-builder': 4.0.2 1444 | '@smithy/types': 4.2.0 1445 | '@smithy/util-base64': 4.0.0 1446 | tslib: 2.8.1 1447 | 1448 | '@smithy/hash-blob-browser@4.0.2': 1449 | dependencies: 1450 | '@smithy/chunked-blob-reader': 5.0.0 1451 | '@smithy/chunked-blob-reader-native': 4.0.0 1452 | '@smithy/types': 4.2.0 1453 | tslib: 2.8.1 1454 | 1455 | '@smithy/hash-node@4.0.2': 1456 | dependencies: 1457 | '@smithy/types': 4.2.0 1458 | '@smithy/util-buffer-from': 4.0.0 1459 | '@smithy/util-utf8': 4.0.0 1460 | tslib: 2.8.1 1461 | 1462 | '@smithy/hash-stream-node@4.0.2': 1463 | dependencies: 1464 | '@smithy/types': 4.2.0 1465 | '@smithy/util-utf8': 4.0.0 1466 | tslib: 2.8.1 1467 | 1468 | '@smithy/invalid-dependency@4.0.2': 1469 | dependencies: 1470 | '@smithy/types': 4.2.0 1471 | tslib: 2.8.1 1472 | 1473 | '@smithy/is-array-buffer@2.2.0': 1474 | dependencies: 1475 | tslib: 2.8.1 1476 | 1477 | '@smithy/is-array-buffer@4.0.0': 1478 | dependencies: 1479 | tslib: 2.8.1 1480 | 1481 | '@smithy/md5-js@4.0.2': 1482 | dependencies: 1483 | '@smithy/types': 4.2.0 1484 | '@smithy/util-utf8': 4.0.0 1485 | tslib: 2.8.1 1486 | 1487 | '@smithy/middleware-content-length@4.0.2': 1488 | dependencies: 1489 | '@smithy/protocol-http': 5.1.0 1490 | '@smithy/types': 4.2.0 1491 | tslib: 2.8.1 1492 | 1493 | '@smithy/middleware-endpoint@4.1.1': 1494 | dependencies: 1495 | '@smithy/core': 3.3.0 1496 | '@smithy/middleware-serde': 4.0.3 1497 | '@smithy/node-config-provider': 4.0.2 1498 | '@smithy/shared-ini-file-loader': 4.0.2 1499 | '@smithy/types': 4.2.0 1500 | '@smithy/url-parser': 4.0.2 1501 | '@smithy/util-middleware': 4.0.2 1502 | tslib: 2.8.1 1503 | 1504 | '@smithy/middleware-retry@4.1.2': 1505 | dependencies: 1506 | '@smithy/node-config-provider': 4.0.2 1507 | '@smithy/protocol-http': 5.1.0 1508 | '@smithy/service-error-classification': 4.0.3 1509 | '@smithy/smithy-client': 4.2.1 1510 | '@smithy/types': 4.2.0 1511 | '@smithy/util-middleware': 4.0.2 1512 | '@smithy/util-retry': 4.0.3 1513 | tslib: 2.8.1 1514 | uuid: 9.0.1 1515 | 1516 | '@smithy/middleware-serde@4.0.3': 1517 | dependencies: 1518 | '@smithy/types': 4.2.0 1519 | tslib: 2.8.1 1520 | 1521 | '@smithy/middleware-stack@4.0.2': 1522 | dependencies: 1523 | '@smithy/types': 4.2.0 1524 | tslib: 2.8.1 1525 | 1526 | '@smithy/node-config-provider@4.0.2': 1527 | dependencies: 1528 | '@smithy/property-provider': 4.0.2 1529 | '@smithy/shared-ini-file-loader': 4.0.2 1530 | '@smithy/types': 4.2.0 1531 | tslib: 2.8.1 1532 | 1533 | '@smithy/node-http-handler@4.0.4': 1534 | dependencies: 1535 | '@smithy/abort-controller': 4.0.2 1536 | '@smithy/protocol-http': 5.1.0 1537 | '@smithy/querystring-builder': 4.0.2 1538 | '@smithy/types': 4.2.0 1539 | tslib: 2.8.1 1540 | 1541 | '@smithy/property-provider@4.0.2': 1542 | dependencies: 1543 | '@smithy/types': 4.2.0 1544 | tslib: 2.8.1 1545 | 1546 | '@smithy/protocol-http@5.1.0': 1547 | dependencies: 1548 | '@smithy/types': 4.2.0 1549 | tslib: 2.8.1 1550 | 1551 | '@smithy/querystring-builder@4.0.2': 1552 | dependencies: 1553 | '@smithy/types': 4.2.0 1554 | '@smithy/util-uri-escape': 4.0.0 1555 | tslib: 2.8.1 1556 | 1557 | '@smithy/querystring-parser@4.0.2': 1558 | dependencies: 1559 | '@smithy/types': 4.2.0 1560 | tslib: 2.8.1 1561 | 1562 | '@smithy/service-error-classification@4.0.3': 1563 | dependencies: 1564 | '@smithy/types': 4.2.0 1565 | 1566 | '@smithy/shared-ini-file-loader@4.0.2': 1567 | dependencies: 1568 | '@smithy/types': 4.2.0 1569 | tslib: 2.8.1 1570 | 1571 | '@smithy/signature-v4@5.1.0': 1572 | dependencies: 1573 | '@smithy/is-array-buffer': 4.0.0 1574 | '@smithy/protocol-http': 5.1.0 1575 | '@smithy/types': 4.2.0 1576 | '@smithy/util-hex-encoding': 4.0.0 1577 | '@smithy/util-middleware': 4.0.2 1578 | '@smithy/util-uri-escape': 4.0.0 1579 | '@smithy/util-utf8': 4.0.0 1580 | tslib: 2.8.1 1581 | 1582 | '@smithy/smithy-client@4.2.1': 1583 | dependencies: 1584 | '@smithy/core': 3.3.0 1585 | '@smithy/middleware-endpoint': 4.1.1 1586 | '@smithy/middleware-stack': 4.0.2 1587 | '@smithy/protocol-http': 5.1.0 1588 | '@smithy/types': 4.2.0 1589 | '@smithy/util-stream': 4.2.0 1590 | tslib: 2.8.1 1591 | 1592 | '@smithy/types@4.2.0': 1593 | dependencies: 1594 | tslib: 2.8.1 1595 | 1596 | '@smithy/url-parser@4.0.2': 1597 | dependencies: 1598 | '@smithy/querystring-parser': 4.0.2 1599 | '@smithy/types': 4.2.0 1600 | tslib: 2.8.1 1601 | 1602 | '@smithy/util-base64@4.0.0': 1603 | dependencies: 1604 | '@smithy/util-buffer-from': 4.0.0 1605 | '@smithy/util-utf8': 4.0.0 1606 | tslib: 2.8.1 1607 | 1608 | '@smithy/util-body-length-browser@4.0.0': 1609 | dependencies: 1610 | tslib: 2.8.1 1611 | 1612 | '@smithy/util-body-length-node@4.0.0': 1613 | dependencies: 1614 | tslib: 2.8.1 1615 | 1616 | '@smithy/util-buffer-from@2.2.0': 1617 | dependencies: 1618 | '@smithy/is-array-buffer': 2.2.0 1619 | tslib: 2.8.1 1620 | 1621 | '@smithy/util-buffer-from@4.0.0': 1622 | dependencies: 1623 | '@smithy/is-array-buffer': 4.0.0 1624 | tslib: 2.8.1 1625 | 1626 | '@smithy/util-config-provider@4.0.0': 1627 | dependencies: 1628 | tslib: 2.8.1 1629 | 1630 | '@smithy/util-defaults-mode-browser@4.0.9': 1631 | dependencies: 1632 | '@smithy/property-provider': 4.0.2 1633 | '@smithy/smithy-client': 4.2.1 1634 | '@smithy/types': 4.2.0 1635 | bowser: 2.11.0 1636 | tslib: 2.8.1 1637 | 1638 | '@smithy/util-defaults-mode-node@4.0.9': 1639 | dependencies: 1640 | '@smithy/config-resolver': 4.1.0 1641 | '@smithy/credential-provider-imds': 4.0.2 1642 | '@smithy/node-config-provider': 4.0.2 1643 | '@smithy/property-provider': 4.0.2 1644 | '@smithy/smithy-client': 4.2.1 1645 | '@smithy/types': 4.2.0 1646 | tslib: 2.8.1 1647 | 1648 | '@smithy/util-endpoints@3.0.2': 1649 | dependencies: 1650 | '@smithy/node-config-provider': 4.0.2 1651 | '@smithy/types': 4.2.0 1652 | tslib: 2.8.1 1653 | 1654 | '@smithy/util-hex-encoding@4.0.0': 1655 | dependencies: 1656 | tslib: 2.8.1 1657 | 1658 | '@smithy/util-middleware@4.0.2': 1659 | dependencies: 1660 | '@smithy/types': 4.2.0 1661 | tslib: 2.8.1 1662 | 1663 | '@smithy/util-retry@4.0.3': 1664 | dependencies: 1665 | '@smithy/service-error-classification': 4.0.3 1666 | '@smithy/types': 4.2.0 1667 | tslib: 2.8.1 1668 | 1669 | '@smithy/util-stream@4.2.0': 1670 | dependencies: 1671 | '@smithy/fetch-http-handler': 5.0.2 1672 | '@smithy/node-http-handler': 4.0.4 1673 | '@smithy/types': 4.2.0 1674 | '@smithy/util-base64': 4.0.0 1675 | '@smithy/util-buffer-from': 4.0.0 1676 | '@smithy/util-hex-encoding': 4.0.0 1677 | '@smithy/util-utf8': 4.0.0 1678 | tslib: 2.8.1 1679 | 1680 | '@smithy/util-uri-escape@4.0.0': 1681 | dependencies: 1682 | tslib: 2.8.1 1683 | 1684 | '@smithy/util-utf8@2.3.0': 1685 | dependencies: 1686 | '@smithy/util-buffer-from': 2.2.0 1687 | tslib: 2.8.1 1688 | 1689 | '@smithy/util-utf8@4.0.0': 1690 | dependencies: 1691 | '@smithy/util-buffer-from': 4.0.0 1692 | tslib: 2.8.1 1693 | 1694 | '@smithy/util-waiter@4.0.3': 1695 | dependencies: 1696 | '@smithy/abort-controller': 4.0.2 1697 | '@smithy/types': 4.2.0 1698 | tslib: 2.8.1 1699 | 1700 | '@stablelib/base64@1.0.1': {} 1701 | 1702 | '@types/diff-match-patch@1.0.36': {} 1703 | 1704 | '@types/node@22.15.3': 1705 | dependencies: 1706 | undici-types: 6.21.0 1707 | 1708 | ai@4.3.13(react@19.1.0)(zod@3.24.3): 1709 | dependencies: 1710 | '@ai-sdk/provider': 1.1.3 1711 | '@ai-sdk/provider-utils': 2.2.7(zod@3.24.3) 1712 | '@ai-sdk/react': 1.2.11(react@19.1.0)(zod@3.24.3) 1713 | '@ai-sdk/ui-utils': 1.2.10(zod@3.24.3) 1714 | '@opentelemetry/api': 1.9.0 1715 | jsondiffpatch: 0.6.0 1716 | zod: 3.24.3 1717 | optionalDependencies: 1718 | react: 19.1.0 1719 | 1720 | bowser@2.11.0: {} 1721 | 1722 | chalk@5.4.1: {} 1723 | 1724 | dequal@2.0.3: {} 1725 | 1726 | diff-match-patch@1.0.5: {} 1727 | 1728 | dotenv@16.5.0: {} 1729 | 1730 | esbuild@0.25.3: 1731 | optionalDependencies: 1732 | '@esbuild/aix-ppc64': 0.25.3 1733 | '@esbuild/android-arm': 0.25.3 1734 | '@esbuild/android-arm64': 0.25.3 1735 | '@esbuild/android-x64': 0.25.3 1736 | '@esbuild/darwin-arm64': 0.25.3 1737 | '@esbuild/darwin-x64': 0.25.3 1738 | '@esbuild/freebsd-arm64': 0.25.3 1739 | '@esbuild/freebsd-x64': 0.25.3 1740 | '@esbuild/linux-arm': 0.25.3 1741 | '@esbuild/linux-arm64': 0.25.3 1742 | '@esbuild/linux-ia32': 0.25.3 1743 | '@esbuild/linux-loong64': 0.25.3 1744 | '@esbuild/linux-mips64el': 0.25.3 1745 | '@esbuild/linux-ppc64': 0.25.3 1746 | '@esbuild/linux-riscv64': 0.25.3 1747 | '@esbuild/linux-s390x': 0.25.3 1748 | '@esbuild/linux-x64': 0.25.3 1749 | '@esbuild/netbsd-arm64': 0.25.3 1750 | '@esbuild/netbsd-x64': 0.25.3 1751 | '@esbuild/openbsd-arm64': 0.25.3 1752 | '@esbuild/openbsd-x64': 0.25.3 1753 | '@esbuild/sunos-x64': 0.25.3 1754 | '@esbuild/win32-arm64': 0.25.3 1755 | '@esbuild/win32-ia32': 0.25.3 1756 | '@esbuild/win32-x64': 0.25.3 1757 | 1758 | fast-sha256@1.3.0: {} 1759 | 1760 | fast-xml-parser@4.4.1: 1761 | dependencies: 1762 | strnum: 1.1.2 1763 | 1764 | fsevents@2.3.3: 1765 | optional: true 1766 | 1767 | get-tsconfig@4.10.0: 1768 | dependencies: 1769 | resolve-pkg-maps: 1.0.0 1770 | 1771 | hono@4.7.8: {} 1772 | 1773 | json-schema@0.4.0: {} 1774 | 1775 | jsondiffpatch@0.6.0: 1776 | dependencies: 1777 | '@types/diff-match-patch': 1.0.36 1778 | chalk: 5.4.1 1779 | diff-match-patch: 1.0.5 1780 | 1781 | nanoid@3.3.11: {} 1782 | 1783 | react@19.1.0: {} 1784 | 1785 | resolve-pkg-maps@1.0.0: {} 1786 | 1787 | secure-json-parse@2.7.0: {} 1788 | 1789 | standardwebhooks@1.0.0: 1790 | dependencies: 1791 | '@stablelib/base64': 1.0.1 1792 | fast-sha256: 1.3.0 1793 | 1794 | strnum@1.1.2: {} 1795 | 1796 | swr@2.3.3(react@19.1.0): 1797 | dependencies: 1798 | dequal: 2.0.3 1799 | react: 19.1.0 1800 | use-sync-external-store: 1.5.0(react@19.1.0) 1801 | 1802 | throttleit@2.1.0: {} 1803 | 1804 | tslib@2.8.1: {} 1805 | 1806 | tsx@4.19.4: 1807 | dependencies: 1808 | esbuild: 0.25.3 1809 | get-tsconfig: 4.10.0 1810 | optionalDependencies: 1811 | fsevents: 2.3.3 1812 | 1813 | typescript@5.8.3: {} 1814 | 1815 | undici-types@6.21.0: {} 1816 | 1817 | use-sync-external-store@1.5.0(react@19.1.0): 1818 | dependencies: 1819 | react: 19.1.0 1820 | 1821 | uuid@9.0.1: {} 1822 | 1823 | zod-to-json-schema@3.24.5(zod@3.24.3): 1824 | dependencies: 1825 | zod: 3.24.3 1826 | 1827 | zod@3.24.3: {} 1828 | -------------------------------------------------------------------------------- /server/public/.well-known/apple-app-site-association: -------------------------------------------------------------------------------- 1 | { 2 | "applinks": { 3 | "apps": [], 4 | "details": [ 5 | { 6 | "appIDs": [ 7 | "A28BC3DEF9.com.example.MyApp1", 8 | "A28BC3DEF9.com.example.MyApp1-Debug" 9 | ], 10 | "components": [ 11 | { 12 | "/": "/checkout_redirect*", 13 | "comment": "Matches any URL whose path starts with /checkout_redirect" 14 | } 15 | ] 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /server/src/index.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | dotenv.config(); 3 | 4 | import { Hono } from "hono"; 5 | import { Checkout } from "@polar-sh/hono"; 6 | import { streamText } from "ai"; 7 | import { Ingestion } from "@polar-sh/ingestion"; 8 | import { LLMStrategy } from "@polar-sh/ingestion/strategies/LLM"; 9 | import { openai } from "@ai-sdk/openai"; 10 | import { serve } from "@hono/node-server"; 11 | import { hasSufficientCredits } from "./middlewares.js"; 12 | import { polarConfig } from "./polar.js"; 13 | 14 | const app = new Hono(); 15 | 16 | /// --- Checkout --- /// 17 | 18 | app.get( 19 | "/checkout", 20 | Checkout({ 21 | ...polarConfig, 22 | successUrl: process.env.POLAR_SUCCESS_URL, 23 | }) 24 | ); 25 | 26 | /// --- LLM --- /// 27 | 28 | const llmIngestion = Ingestion(polarConfig) 29 | .strategy(new LLMStrategy(openai("gpt-4o"))) 30 | .ingest("openai-usage"); 31 | 32 | app.post("/prompt", hasSufficientCredits, async (c) => { 33 | // You should obviously get this from an auth middleware or similar 34 | // but for this example we'll just use a fixed customer id 35 | const customerId = "09b8b19b-ff4a-4b3a-b12d-78ab168bf7bb"; 36 | 37 | const { messages } = await c.req.json(); 38 | 39 | const result = await streamText({ 40 | model: llmIngestion.client({ 41 | customerId, 42 | }), 43 | system: "You are a helpful assistant.", 44 | messages, 45 | }); 46 | 47 | return result.toDataStreamResponse({ 48 | headers: { 49 | "Content-Type": "application/octet-stream", 50 | "Content-Encoding": "none", 51 | }, 52 | }); 53 | }); 54 | 55 | app.get("/checkout_redirect", (c) => { 56 | // Redirect to the app 57 | 58 | // Use the .well-known/apple-app-site-association file to redirect to your app instead 59 | // This is just a small hack for the sake of the demo 60 | return c.redirect("exp://172.22.79.116:8081?checkout_redirect"); 61 | }); 62 | 63 | serve({ 64 | port: 8787, 65 | fetch: app.fetch, 66 | }); 67 | -------------------------------------------------------------------------------- /server/src/middlewares.ts: -------------------------------------------------------------------------------- 1 | import { createMiddleware } from "hono/factory"; 2 | import { polar } from "./polar.js"; 3 | 4 | // You should obviously get this from an auth middleware or similar 5 | // but for this example we'll just use a fixed customer id 6 | const customerId = "09b8b19b-ff4a-4b3a-b12d-78ab168bf7bb"; 7 | 8 | export const hasSufficientCredits = createMiddleware(async (c, next) => { 9 | const meterId = process.env.POLAR_USAGE_METER_ID ?? ""; 10 | 11 | const customerMeter = await polar.customerMeters.list({ 12 | customerId, 13 | meterId, 14 | }); 15 | 16 | const hasCredits = customerMeter.result.items.some( 17 | (customerMeter) => customerMeter.balance > 0 18 | ); 19 | 20 | if (!hasCredits) { 21 | return c.json({ 22 | error: "Insufficient credits", 23 | status: 400, 24 | }); 25 | } 26 | 27 | await next(); 28 | }); 29 | -------------------------------------------------------------------------------- /server/src/polar.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | 3 | dotenv.config(); 4 | 5 | import { Polar } from "@polar-sh/sdk"; 6 | 7 | export const polarConfig = { 8 | accessToken: process.env.POLAR_ACCESS_TOKEN, 9 | server: "sandbox", 10 | } as const; 11 | 12 | export const polar = new Polar(polarConfig); 13 | -------------------------------------------------------------------------------- /server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "NodeNext", 5 | "strict": true, 6 | "verbatimModuleSyntax": true, 7 | "moduleResolution": "NodeNext", 8 | "skipLibCheck": true, 9 | "types": ["node"], 10 | "jsx": "react-jsx", 11 | "jsxImportSource": "hono/jsx", 12 | "outDir": "./dist" 13 | }, 14 | "exclude": ["node_modules"] 15 | } 16 | --------------------------------------------------------------------------------