ugly-app 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +18 -0
- package/.env.example +9 -0
- package/.yarn-metadata.json +113 -0
- package/README.md +709 -0
- package/dist/cli/authCommands.d.ts +6 -0
- package/dist/cli/authCommands.d.ts.map +1 -0
- package/dist/cli/authCommands.js +50 -0
- package/dist/cli/authCommands.js.map +1 -0
- package/dist/cli/build.d.ts +2 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/build.js +26 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/configure.d.ts +2 -0
- package/dist/cli/configure.d.ts.map +1 -0
- package/dist/cli/configure.js +53 -0
- package/dist/cli/configure.js.map +1 -0
- package/dist/cli/dev.d.ts +2 -0
- package/dist/cli/dev.d.ts.map +1 -0
- package/dist/cli/dev.js +66 -0
- package/dist/cli/dev.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +340 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/initDb.d.ts +2 -0
- package/dist/cli/initDb.d.ts.map +1 -0
- package/dist/cli/initDb.js +110 -0
- package/dist/cli/initDb.js.map +1 -0
- package/dist/cli/logQuery.d.ts +12 -0
- package/dist/cli/logQuery.d.ts.map +1 -0
- package/dist/cli/logQuery.js +176 -0
- package/dist/cli/logQuery.js.map +1 -0
- package/dist/cli/migrate.d.ts +4 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/migrate.js +62 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/publishAssets.d.ts +6 -0
- package/dist/cli/publishAssets.d.ts.map +1 -0
- package/dist/cli/publishAssets.js +87 -0
- package/dist/cli/publishAssets.js.map +1 -0
- package/dist/cli/purgeAssets.d.ts +2 -0
- package/dist/cli/purgeAssets.d.ts.map +1 -0
- package/dist/cli/purgeAssets.js +36 -0
- package/dist/cli/purgeAssets.js.map +1 -0
- package/dist/cli/scaffold.d.ts +2 -0
- package/dist/cli/scaffold.d.ts.map +1 -0
- package/dist/cli/scaffold.js +37 -0
- package/dist/cli/scaffold.js.map +1 -0
- package/dist/cli/serverLogQuery.d.ts +6 -0
- package/dist/cli/serverLogQuery.d.ts.map +1 -0
- package/dist/cli/serverLogQuery.js +76 -0
- package/dist/cli/serverLogQuery.js.map +1 -0
- package/dist/cli/storageClient.d.ts +3 -0
- package/dist/cli/storageClient.d.ts.map +1 -0
- package/dist/cli/storageClient.js +22 -0
- package/dist/cli/storageClient.js.map +1 -0
- package/dist/cli/uglyappConfig.d.ts +29 -0
- package/dist/cli/uglyappConfig.d.ts.map +1 -0
- package/dist/cli/uglyappConfig.js +125 -0
- package/dist/cli/uglyappConfig.js.map +1 -0
- package/dist/client/AppProvider.d.ts +32 -0
- package/dist/client/AppProvider.d.ts.map +1 -0
- package/dist/client/AppProvider.js +126 -0
- package/dist/client/AppProvider.js.map +1 -0
- package/dist/client/ErrorLog.d.ts +16 -0
- package/dist/client/ErrorLog.d.ts.map +1 -0
- package/dist/client/ErrorLog.js +28 -0
- package/dist/client/ErrorLog.js.map +1 -0
- package/dist/client/FeedbackContext.d.ts +7 -0
- package/dist/client/FeedbackContext.d.ts.map +1 -0
- package/dist/client/FeedbackContext.js +15 -0
- package/dist/client/FeedbackContext.js.map +1 -0
- package/dist/client/Logger.d.ts +2 -0
- package/dist/client/Logger.d.ts.map +1 -0
- package/dist/client/Logger.js +72 -0
- package/dist/client/Logger.js.map +1 -0
- package/dist/client/LoginPopup.d.ts +7 -0
- package/dist/client/LoginPopup.d.ts.map +1 -0
- package/dist/client/LoginPopup.js +55 -0
- package/dist/client/LoginPopup.js.map +1 -0
- package/dist/client/Router.d.ts +56 -0
- package/dist/client/Router.d.ts.map +1 -0
- package/dist/client/Router.js +224 -0
- package/dist/client/Router.js.map +1 -0
- package/dist/client/Screenshot.d.ts +7 -0
- package/dist/client/Screenshot.d.ts.map +1 -0
- package/dist/client/Screenshot.js +54 -0
- package/dist/client/Screenshot.js.map +1 -0
- package/dist/client/ViewFlipper.d.ts +16 -0
- package/dist/client/ViewFlipper.d.ts.map +1 -0
- package/dist/client/ViewFlipper.js +156 -0
- package/dist/client/ViewFlipper.js.map +1 -0
- package/dist/client/animation/Animated.d.ts +14 -0
- package/dist/client/animation/Animated.d.ts.map +1 -0
- package/dist/client/animation/Animated.js +97 -0
- package/dist/client/animation/Animated.js.map +1 -0
- package/dist/client/animation/animatedValue.d.ts +41 -0
- package/dist/client/animation/animatedValue.d.ts.map +1 -0
- package/dist/client/animation/animatedValue.js +123 -0
- package/dist/client/animation/animatedValue.js.map +1 -0
- package/dist/client/animations/FadeIn.d.ts +6 -0
- package/dist/client/animations/FadeIn.d.ts.map +1 -0
- package/dist/client/animations/FadeIn.js +24 -0
- package/dist/client/animations/FadeIn.js.map +1 -0
- package/dist/client/animations/SlideFromBottom.d.ts +6 -0
- package/dist/client/animations/SlideFromBottom.d.ts.map +1 -0
- package/dist/client/animations/SlideFromBottom.js +24 -0
- package/dist/client/animations/SlideFromBottom.js.map +1 -0
- package/dist/client/animations/SlideFromRight.d.ts +6 -0
- package/dist/client/animations/SlideFromRight.d.ts.map +1 -0
- package/dist/client/animations/SlideFromRight.js +24 -0
- package/dist/client/animations/SlideFromRight.js.map +1 -0
- package/dist/client/audio/AudioPlayer.d.ts +11 -0
- package/dist/client/audio/AudioPlayer.d.ts.map +1 -0
- package/dist/client/audio/AudioPlayer.js +51 -0
- package/dist/client/audio/AudioPlayer.js.map +1 -0
- package/dist/client/audio/AudioRecorder.d.ts +11 -0
- package/dist/client/audio/AudioRecorder.d.ts.map +1 -0
- package/dist/client/audio/AudioRecorder.js +66 -0
- package/dist/client/audio/AudioRecorder.js.map +1 -0
- package/dist/client/audio/audioPlayer.worklet.d.ts +2 -0
- package/dist/client/audio/audioPlayer.worklet.d.ts.map +1 -0
- package/dist/client/audio/audioPlayer.worklet.js +46 -0
- package/dist/client/audio/audioPlayer.worklet.js.map +1 -0
- package/dist/client/audio/useSTT.d.ts +19 -0
- package/dist/client/audio/useSTT.d.ts.map +1 -0
- package/dist/client/audio/useSTT.js +91 -0
- package/dist/client/audio/useSTT.js.map +1 -0
- package/dist/client/audio/useTTS.d.ts +17 -0
- package/dist/client/audio/useTTS.d.ts.map +1 -0
- package/dist/client/audio/useTTS.js +70 -0
- package/dist/client/audio/useTTS.js.map +1 -0
- package/dist/client/components/Button.d.ts +22 -0
- package/dist/client/components/Button.d.ts.map +1 -0
- package/dist/client/components/Button.js +27 -0
- package/dist/client/components/Button.js.map +1 -0
- package/dist/client/components/Card.d.ts +8 -0
- package/dist/client/components/Card.d.ts.map +1 -0
- package/dist/client/components/Card.js +6 -0
- package/dist/client/components/Card.js.map +1 -0
- package/dist/client/components/EnumInput.d.ts +16 -0
- package/dist/client/components/EnumInput.d.ts.map +1 -0
- package/dist/client/components/EnumInput.js +11 -0
- package/dist/client/components/EnumInput.js.map +1 -0
- package/dist/client/components/FeedbackButton.d.ts +9 -0
- package/dist/client/components/FeedbackButton.d.ts.map +1 -0
- package/dist/client/components/FeedbackButton.js +112 -0
- package/dist/client/components/FeedbackButton.js.map +1 -0
- package/dist/client/components/Header.d.ts +10 -0
- package/dist/client/components/Header.d.ts.map +1 -0
- package/dist/client/components/Header.js +12 -0
- package/dist/client/components/Header.js.map +1 -0
- package/dist/client/components/Image.d.ts +20 -0
- package/dist/client/components/Image.d.ts.map +1 -0
- package/dist/client/components/Image.js +12 -0
- package/dist/client/components/Image.js.map +1 -0
- package/dist/client/components/Input.d.ts +14 -0
- package/dist/client/components/Input.d.ts.map +1 -0
- package/dist/client/components/Input.js +19 -0
- package/dist/client/components/Input.js.map +1 -0
- package/dist/client/components/Modal.d.ts +9 -0
- package/dist/client/components/Modal.d.ts.map +1 -0
- package/dist/client/components/Modal.js +19 -0
- package/dist/client/components/Modal.js.map +1 -0
- package/dist/client/components/PageLayout.d.ts +9 -0
- package/dist/client/components/PageLayout.d.ts.map +1 -0
- package/dist/client/components/PageLayout.js +6 -0
- package/dist/client/components/PageLayout.js.map +1 -0
- package/dist/client/components/Panel.d.ts +8 -0
- package/dist/client/components/Panel.d.ts.map +1 -0
- package/dist/client/components/Panel.js +5 -0
- package/dist/client/components/Panel.js.map +1 -0
- package/dist/client/components/PopupPanel.d.ts +9 -0
- package/dist/client/components/PopupPanel.d.ts.map +1 -0
- package/dist/client/components/PopupPanel.js +5 -0
- package/dist/client/components/PopupPanel.js.map +1 -0
- package/dist/client/components/Pressable.d.ts +14 -0
- package/dist/client/components/Pressable.d.ts.map +1 -0
- package/dist/client/components/Pressable.js +8 -0
- package/dist/client/components/Pressable.js.map +1 -0
- package/dist/client/components/ScrollView.d.ts +9 -0
- package/dist/client/components/ScrollView.d.ts.map +1 -0
- package/dist/client/components/ScrollView.js +7 -0
- package/dist/client/components/ScrollView.js.map +1 -0
- package/dist/client/components/SettingGroup.d.ts +10 -0
- package/dist/client/components/SettingGroup.d.ts.map +1 -0
- package/dist/client/components/SettingGroup.js +8 -0
- package/dist/client/components/SettingGroup.js.map +1 -0
- package/dist/client/components/Text.d.ts +21 -0
- package/dist/client/components/Text.d.ts.map +1 -0
- package/dist/client/components/Text.js +43 -0
- package/dist/client/components/Text.js.map +1 -0
- package/dist/client/components/Toast.d.ts +10 -0
- package/dist/client/components/Toast.d.ts.map +1 -0
- package/dist/client/components/Toast.js +21 -0
- package/dist/client/components/Toast.js.map +1 -0
- package/dist/client/components/View.d.ts +9 -0
- package/dist/client/components/View.d.ts.map +1 -0
- package/dist/client/components/View.js +5 -0
- package/dist/client/components/View.js.map +1 -0
- package/dist/client/components/index.d.ts +33 -0
- package/dist/client/components/index.d.ts.map +1 -0
- package/dist/client/components/index.js +17 -0
- package/dist/client/components/index.js.map +1 -0
- package/dist/client/components/zIndex.d.ts +10 -0
- package/dist/client/components/zIndex.d.ts.map +1 -0
- package/dist/client/components/zIndex.js +12 -0
- package/dist/client/components/zIndex.js.map +1 -0
- package/dist/client/createSocket.d.ts +26 -0
- package/dist/client/createSocket.d.ts.map +1 -0
- package/dist/client/createSocket.js +138 -0
- package/dist/client/createSocket.js.map +1 -0
- package/dist/client/index.d.ts +27 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +20 -0
- package/dist/client/index.js.map +1 -0
- package/dist/playwright/index.d.ts +16 -0
- package/dist/playwright/index.d.ts.map +1 -0
- package/dist/playwright/index.js +32 -0
- package/dist/playwright/index.js.map +1 -0
- package/dist/server/App.d.ts +43 -0
- package/dist/server/App.d.ts.map +1 -0
- package/dist/server/App.js +215 -0
- package/dist/server/App.js.map +1 -0
- package/dist/server/Auth.d.ts +21 -0
- package/dist/server/Auth.d.ts.map +1 -0
- package/dist/server/Auth.js +171 -0
- package/dist/server/Auth.js.map +1 -0
- package/dist/server/Cache.d.ts +38 -0
- package/dist/server/Cache.d.ts.map +1 -0
- package/dist/server/Cache.js +113 -0
- package/dist/server/Cache.js.map +1 -0
- package/dist/server/ChangeStream.d.ts +22 -0
- package/dist/server/ChangeStream.d.ts.map +1 -0
- package/dist/server/ChangeStream.js +93 -0
- package/dist/server/ChangeStream.js.map +1 -0
- package/dist/server/DB.d.ts +17 -0
- package/dist/server/DB.d.ts.map +1 -0
- package/dist/server/DB.js +442 -0
- package/dist/server/DB.js.map +1 -0
- package/dist/server/Email.d.ts +22 -0
- package/dist/server/Email.d.ts.map +1 -0
- package/dist/server/Email.js +64 -0
- package/dist/server/Email.js.map +1 -0
- package/dist/server/EmailTemplate.d.ts +17 -0
- package/dist/server/EmailTemplate.d.ts.map +1 -0
- package/dist/server/EmailTemplate.js +29 -0
- package/dist/server/EmailTemplate.js.map +1 -0
- package/dist/server/FeedbackReport.d.ts +19 -0
- package/dist/server/FeedbackReport.d.ts.map +1 -0
- package/dist/server/FeedbackReport.js +94 -0
- package/dist/server/FeedbackReport.js.map +1 -0
- package/dist/server/ImageGen.d.ts +5 -0
- package/dist/server/ImageGen.d.ts.map +1 -0
- package/dist/server/ImageGen.js +5 -0
- package/dist/server/ImageGen.js.map +1 -0
- package/dist/server/Logging.d.ts +59 -0
- package/dist/server/Logging.d.ts.map +1 -0
- package/dist/server/Logging.js +293 -0
- package/dist/server/Logging.js.map +1 -0
- package/dist/server/Nats.d.ts +56 -0
- package/dist/server/Nats.d.ts.map +1 -0
- package/dist/server/Nats.js +162 -0
- package/dist/server/Nats.js.map +1 -0
- package/dist/server/NatsStore.d.ts +26 -0
- package/dist/server/NatsStore.d.ts.map +1 -0
- package/dist/server/NatsStore.js +86 -0
- package/dist/server/NatsStore.js.map +1 -0
- package/dist/server/PushNotification.d.ts +33 -0
- package/dist/server/PushNotification.d.ts.map +1 -0
- package/dist/server/PushNotification.js +131 -0
- package/dist/server/PushNotification.js.map +1 -0
- package/dist/server/RateLimit.d.ts +28 -0
- package/dist/server/RateLimit.d.ts.map +1 -0
- package/dist/server/RateLimit.js +101 -0
- package/dist/server/RateLimit.js.map +1 -0
- package/dist/server/Redis.d.ts +61 -0
- package/dist/server/Redis.d.ts.map +1 -0
- package/dist/server/Redis.js +226 -0
- package/dist/server/Redis.js.map +1 -0
- package/dist/server/Router.d.ts +27 -0
- package/dist/server/Router.d.ts.map +1 -0
- package/dist/server/Router.js +71 -0
- package/dist/server/Router.js.map +1 -0
- package/dist/server/Socket.d.ts +8 -0
- package/dist/server/Socket.d.ts.map +1 -0
- package/dist/server/Socket.js +278 -0
- package/dist/server/Socket.js.map +1 -0
- package/dist/server/SpendTracker.d.ts +18 -0
- package/dist/server/SpendTracker.d.ts.map +1 -0
- package/dist/server/SpendTracker.js +110 -0
- package/dist/server/SpendTracker.js.map +1 -0
- package/dist/server/Storage.d.ts +16 -0
- package/dist/server/Storage.d.ts.map +1 -0
- package/dist/server/Storage.js +95 -0
- package/dist/server/Storage.js.map +1 -0
- package/dist/server/TextGen.d.ts +5 -0
- package/dist/server/TextGen.d.ts.map +1 -0
- package/dist/server/TextGen.js +6 -0
- package/dist/server/TextGen.js.map +1 -0
- package/dist/server/WorkerQueue.d.ts +27 -0
- package/dist/server/WorkerQueue.d.ts.map +1 -0
- package/dist/server/WorkerQueue.js +147 -0
- package/dist/server/WorkerQueue.js.map +1 -0
- package/dist/server/ai/ImageGenClient.d.ts +6 -0
- package/dist/server/ai/ImageGenClient.d.ts.map +1 -0
- package/dist/server/ai/ImageGenClient.js +29 -0
- package/dist/server/ai/ImageGenClient.js.map +1 -0
- package/dist/server/ai/ProviderBalance.d.ts +15 -0
- package/dist/server/ai/ProviderBalance.d.ts.map +1 -0
- package/dist/server/ai/ProviderBalance.js +110 -0
- package/dist/server/ai/ProviderBalance.js.map +1 -0
- package/dist/server/ai/ProviderSelector.d.ts +13 -0
- package/dist/server/ai/ProviderSelector.d.ts.map +1 -0
- package/dist/server/ai/ProviderSelector.js +25 -0
- package/dist/server/ai/ProviderSelector.js.map +1 -0
- package/dist/server/ai/TextGenClient.d.ts +9 -0
- package/dist/server/ai/TextGenClient.d.ts.map +1 -0
- package/dist/server/ai/TextGenClient.js +72 -0
- package/dist/server/ai/TextGenClient.js.map +1 -0
- package/dist/server/ai/fallbacks.d.ts +9 -0
- package/dist/server/ai/fallbacks.d.ts.map +1 -0
- package/dist/server/ai/fallbacks.js +77 -0
- package/dist/server/ai/fallbacks.js.map +1 -0
- package/dist/server/ai/index.d.ts +12 -0
- package/dist/server/ai/index.d.ts.map +1 -0
- package/dist/server/ai/index.js +37 -0
- package/dist/server/ai/index.js.map +1 -0
- package/dist/server/ai/providers/Claude.d.ts +3 -0
- package/dist/server/ai/providers/Claude.d.ts.map +1 -0
- package/dist/server/ai/providers/Claude.js +124 -0
- package/dist/server/ai/providers/Claude.js.map +1 -0
- package/dist/server/ai/providers/FAL.d.ts +3 -0
- package/dist/server/ai/providers/FAL.d.ts.map +1 -0
- package/dist/server/ai/providers/FAL.js +24 -0
- package/dist/server/ai/providers/FAL.js.map +1 -0
- package/dist/server/ai/providers/Fireworks.d.ts +3 -0
- package/dist/server/ai/providers/Fireworks.d.ts.map +1 -0
- package/dist/server/ai/providers/Fireworks.js +79 -0
- package/dist/server/ai/providers/Fireworks.js.map +1 -0
- package/dist/server/ai/providers/Google.d.ts +3 -0
- package/dist/server/ai/providers/Google.d.ts.map +1 -0
- package/dist/server/ai/providers/Google.js +105 -0
- package/dist/server/ai/providers/Google.js.map +1 -0
- package/dist/server/ai/providers/GoogleImage.d.ts +3 -0
- package/dist/server/ai/providers/GoogleImage.d.ts.map +1 -0
- package/dist/server/ai/providers/GoogleImage.js +24 -0
- package/dist/server/ai/providers/GoogleImage.js.map +1 -0
- package/dist/server/ai/providers/Groq.d.ts +3 -0
- package/dist/server/ai/providers/Groq.d.ts.map +1 -0
- package/dist/server/ai/providers/Groq.js +99 -0
- package/dist/server/ai/providers/Groq.js.map +1 -0
- package/dist/server/ai/providers/Kie.d.ts +3 -0
- package/dist/server/ai/providers/Kie.d.ts.map +1 -0
- package/dist/server/ai/providers/Kie.js +79 -0
- package/dist/server/ai/providers/Kie.js.map +1 -0
- package/dist/server/ai/providers/KieImage.d.ts +3 -0
- package/dist/server/ai/providers/KieImage.d.ts.map +1 -0
- package/dist/server/ai/providers/KieImage.js +50 -0
- package/dist/server/ai/providers/KieImage.js.map +1 -0
- package/dist/server/ai/providers/OpenAIText.d.ts +3 -0
- package/dist/server/ai/providers/OpenAIText.d.ts.map +1 -0
- package/dist/server/ai/providers/OpenAIText.js +103 -0
- package/dist/server/ai/providers/OpenAIText.js.map +1 -0
- package/dist/server/ai/providers/Together.d.ts +3 -0
- package/dist/server/ai/providers/Together.d.ts.map +1 -0
- package/dist/server/ai/providers/Together.js +99 -0
- package/dist/server/ai/providers/Together.js.map +1 -0
- package/dist/server/ai/providers/TogetherImage.d.ts +3 -0
- package/dist/server/ai/providers/TogetherImage.d.ts.map +1 -0
- package/dist/server/ai/providers/TogetherImage.js +24 -0
- package/dist/server/ai/providers/TogetherImage.js.map +1 -0
- package/dist/server/ai/providers/Wavespeed.d.ts +3 -0
- package/dist/server/ai/providers/Wavespeed.d.ts.map +1 -0
- package/dist/server/ai/providers/Wavespeed.js +53 -0
- package/dist/server/ai/providers/Wavespeed.js.map +1 -0
- package/dist/server/ai/registry.d.ts +10 -0
- package/dist/server/ai/registry.d.ts.map +1 -0
- package/dist/server/ai/registry.js +26 -0
- package/dist/server/ai/registry.js.map +1 -0
- package/dist/server/ai/types.d.ts +67 -0
- package/dist/server/ai/types.d.ts.map +1 -0
- package/dist/server/ai/types.js +17 -0
- package/dist/server/ai/types.js.map +1 -0
- package/dist/server/audio/STTStream.d.ts +12 -0
- package/dist/server/audio/STTStream.d.ts.map +1 -0
- package/dist/server/audio/STTStream.js +59 -0
- package/dist/server/audio/STTStream.js.map +1 -0
- package/dist/server/audio/TTSStream.d.ts +16 -0
- package/dist/server/audio/TTSStream.d.ts.map +1 -0
- package/dist/server/audio/TTSStream.js +151 -0
- package/dist/server/audio/TTSStream.js.map +1 -0
- package/dist/server/audio/index.d.ts +5 -0
- package/dist/server/audio/index.d.ts.map +1 -0
- package/dist/server/audio/index.js +14 -0
- package/dist/server/audio/index.js.map +1 -0
- package/dist/server/audio/resample.d.ts +7 -0
- package/dist/server/audio/resample.d.ts.map +1 -0
- package/dist/server/audio/resample.js +17 -0
- package/dist/server/audio/resample.js.map +1 -0
- package/dist/server/audio/stt/GroqWhisper.d.ts +3 -0
- package/dist/server/audio/stt/GroqWhisper.d.ts.map +1 -0
- package/dist/server/audio/stt/GroqWhisper.js +91 -0
- package/dist/server/audio/stt/GroqWhisper.js.map +1 -0
- package/dist/server/audio/stt/registry.d.ts +5 -0
- package/dist/server/audio/stt/registry.d.ts.map +1 -0
- package/dist/server/audio/stt/registry.js +11 -0
- package/dist/server/audio/stt/registry.js.map +1 -0
- package/dist/server/audio/stt/types.d.ts +25 -0
- package/dist/server/audio/stt/types.d.ts.map +1 -0
- package/dist/server/audio/stt/types.js +2 -0
- package/dist/server/audio/stt/types.js.map +1 -0
- package/dist/server/audio/stt/vad.d.ts +18 -0
- package/dist/server/audio/stt/vad.d.ts.map +1 -0
- package/dist/server/audio/stt/vad.js +90 -0
- package/dist/server/audio/stt/vad.js.map +1 -0
- package/dist/server/audio/tts/InWorld.d.ts +3 -0
- package/dist/server/audio/tts/InWorld.d.ts.map +1 -0
- package/dist/server/audio/tts/InWorld.js +147 -0
- package/dist/server/audio/tts/InWorld.js.map +1 -0
- package/dist/server/audio/tts/providers/Azure.d.ts +3 -0
- package/dist/server/audio/tts/providers/Azure.d.ts.map +1 -0
- package/dist/server/audio/tts/providers/Azure.js +31 -0
- package/dist/server/audio/tts/providers/Azure.js.map +1 -0
- package/dist/server/audio/tts/registry.d.ts +6 -0
- package/dist/server/audio/tts/registry.d.ts.map +1 -0
- package/dist/server/audio/tts/registry.js +12 -0
- package/dist/server/audio/tts/registry.js.map +1 -0
- package/dist/server/audio/tts/types.d.ts +20 -0
- package/dist/server/audio/tts/types.d.ts.map +1 -0
- package/dist/server/audio/tts/types.js +2 -0
- package/dist/server/audio/tts/types.js.map +1 -0
- package/dist/server/billing/BillingGateway.d.ts +40 -0
- package/dist/server/billing/BillingGateway.d.ts.map +1 -0
- package/dist/server/billing/BillingGateway.js +116 -0
- package/dist/server/billing/BillingGateway.js.map +1 -0
- package/dist/server/billing/BillingLedger.d.ts +67 -0
- package/dist/server/billing/BillingLedger.d.ts.map +1 -0
- package/dist/server/billing/BillingLedger.js +214 -0
- package/dist/server/billing/BillingLedger.js.map +1 -0
- package/dist/server/billing/CreditStore.d.ts +58 -0
- package/dist/server/billing/CreditStore.d.ts.map +1 -0
- package/dist/server/billing/CreditStore.js +112 -0
- package/dist/server/billing/CreditStore.js.map +1 -0
- package/dist/server/billing/LimitEnforcer.d.ts +73 -0
- package/dist/server/billing/LimitEnforcer.d.ts.map +1 -0
- package/dist/server/billing/LimitEnforcer.js +276 -0
- package/dist/server/billing/LimitEnforcer.js.map +1 -0
- package/dist/server/billing/UserLimitCache.d.ts +35 -0
- package/dist/server/billing/UserLimitCache.d.ts.map +1 -0
- package/dist/server/billing/UserLimitCache.js +91 -0
- package/dist/server/billing/UserLimitCache.js.map +1 -0
- package/dist/server/billing/index.d.ts +6 -0
- package/dist/server/billing/index.d.ts.map +1 -0
- package/dist/server/billing/index.js +4 -0
- package/dist/server/billing/index.js.map +1 -0
- package/dist/server/billing/types.d.ts +95 -0
- package/dist/server/billing/types.d.ts.map +1 -0
- package/dist/server/billing/types.js +19 -0
- package/dist/server/billing/types.js.map +1 -0
- package/dist/server/embeddings/EmbeddingClient.d.ts +8 -0
- package/dist/server/embeddings/EmbeddingClient.d.ts.map +1 -0
- package/dist/server/embeddings/EmbeddingClient.js +30 -0
- package/dist/server/embeddings/EmbeddingClient.js.map +1 -0
- package/dist/server/embeddings/index.d.ts +5 -0
- package/dist/server/embeddings/index.d.ts.map +1 -0
- package/dist/server/embeddings/index.js +6 -0
- package/dist/server/embeddings/index.js.map +1 -0
- package/dist/server/embeddings/providers/OpenAI.d.ts +3 -0
- package/dist/server/embeddings/providers/OpenAI.d.ts.map +1 -0
- package/dist/server/embeddings/providers/OpenAI.js +28 -0
- package/dist/server/embeddings/providers/OpenAI.js.map +1 -0
- package/dist/server/embeddings/registry.d.ts +7 -0
- package/dist/server/embeddings/registry.d.ts.map +1 -0
- package/dist/server/embeddings/registry.js +15 -0
- package/dist/server/embeddings/registry.js.map +1 -0
- package/dist/server/embeddings/types.d.ts +12 -0
- package/dist/server/embeddings/types.d.ts.map +1 -0
- package/dist/server/embeddings/types.js +2 -0
- package/dist/server/embeddings/types.js.map +1 -0
- package/dist/server/index.d.ts +59 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +41 -0
- package/dist/server/index.js.map +1 -0
- package/dist/shared/Api.d.ts +40 -0
- package/dist/shared/Api.d.ts.map +1 -0
- package/dist/shared/Api.js +30 -0
- package/dist/shared/Api.js.map +1 -0
- package/dist/shared/Audio.d.ts +108 -0
- package/dist/shared/Audio.d.ts.map +1 -0
- package/dist/shared/Audio.js +3 -0
- package/dist/shared/Audio.js.map +1 -0
- package/dist/shared/DB.d.ts +339 -0
- package/dist/shared/DB.d.ts.map +1 -0
- package/dist/shared/DB.js +51 -0
- package/dist/shared/DB.js.map +1 -0
- package/dist/shared/Errors.d.ts +10 -0
- package/dist/shared/Errors.d.ts.map +1 -0
- package/dist/shared/Errors.js +19 -0
- package/dist/shared/Errors.js.map +1 -0
- package/dist/shared/FeedbackReport.d.ts +38 -0
- package/dist/shared/FeedbackReport.d.ts.map +1 -0
- package/dist/shared/FeedbackReport.js +14 -0
- package/dist/shared/FeedbackReport.js.map +1 -0
- package/dist/shared/Router.d.ts +28 -0
- package/dist/shared/Router.d.ts.map +1 -0
- package/dist/shared/Router.js +82 -0
- package/dist/shared/Router.js.map +1 -0
- package/dist/shared/Socket.d.ts +26 -0
- package/dist/shared/Socket.d.ts.map +1 -0
- package/dist/shared/Socket.js +2 -0
- package/dist/shared/Socket.js.map +1 -0
- package/dist/shared/index.d.ts +28 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +61 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/webrtc/index.d.ts +14 -0
- package/dist/webrtc/index.d.ts.map +1 -0
- package/dist/webrtc/index.js +24 -0
- package/dist/webrtc/index.js.map +1 -0
- package/package.json +97 -0
- package/templates/.claude/skills/assets.md +39 -0
- package/templates/.claude/skills/check-errors.md +35 -0
- package/templates/.claude/skills/check-feedback.md +23 -0
- package/templates/.claude/skills/check-perf.md +22 -0
- package/templates/.claude/skills/create-test-users.md +34 -0
- package/templates/.claude/skills/extend-api.md +37 -0
- package/templates/.claude/skills/fix-code.md +5 -0
- package/templates/.claude/skills/fix-errors.md +9 -0
- package/templates/.claude/skills/fix-feedback.md +8 -0
- package/templates/.claude/skills/fix-perf.md +8 -0
- package/templates/.claude/skills/uploads.md +38 -0
- package/templates/.claude/skills/use-ai.md +49 -0
- package/templates/.env.example +49 -0
- package/templates/.husky/pre-commit +2 -0
- package/templates/CLAUDE.md +199 -0
- package/templates/client/App.tsx +33 -0
- package/templates/client/index.html +14 -0
- package/templates/client/main.tsx +52 -0
- package/templates/client/pages/AuthDemoPage.tsx +85 -0
- package/templates/client/pages/HomePage.tsx +111 -0
- package/templates/client/pages/SearchPage.tsx +48 -0
- package/templates/client/pages/UserPage.tsx +33 -0
- package/templates/client/router.ts +4 -0
- package/templates/docker-compose.yml +50 -0
- package/templates/index.html +14 -0
- package/templates/package.json +56 -0
- package/templates/playwright.config.ts +21 -0
- package/templates/server/index.ts +24 -0
- package/templates/shared/api.ts +36 -0
- package/templates/shared/collections.ts +11 -0
- package/templates/shared/dbIndexes.ts +11 -0
- package/templates/shared/pages.ts +8 -0
- package/templates/vite.config.ts +17 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
const WAV_HEADER_BYTES = 44;
|
|
2
|
+
const inworldVisemeNameSet = new Set([
|
|
3
|
+
'aei',
|
|
4
|
+
'o',
|
|
5
|
+
'bmp',
|
|
6
|
+
'fv',
|
|
7
|
+
'l',
|
|
8
|
+
'r',
|
|
9
|
+
'th',
|
|
10
|
+
'qw',
|
|
11
|
+
'ee',
|
|
12
|
+
'cdgknstxyz',
|
|
13
|
+
'sil',
|
|
14
|
+
]);
|
|
15
|
+
function parseOffsetSeconds(offset) {
|
|
16
|
+
if (typeof offset === 'number')
|
|
17
|
+
return offset;
|
|
18
|
+
// Handle "0.5s" format
|
|
19
|
+
const s = offset.trim();
|
|
20
|
+
if (s.endsWith('s'))
|
|
21
|
+
return parseFloat(s.slice(0, -1));
|
|
22
|
+
return parseFloat(s);
|
|
23
|
+
}
|
|
24
|
+
function parseVisemesFromAlignment(alignment) {
|
|
25
|
+
const visemes = [];
|
|
26
|
+
for (const wordEntry of alignment) {
|
|
27
|
+
if (!wordEntry.phoneticDetails)
|
|
28
|
+
continue;
|
|
29
|
+
for (const detail of wordEntry.phoneticDetails) {
|
|
30
|
+
if (!detail.phones)
|
|
31
|
+
continue;
|
|
32
|
+
for (const phone of detail.phones) {
|
|
33
|
+
if (inworldVisemeNameSet.has(phone.visemeSymbol)) {
|
|
34
|
+
visemes.push({
|
|
35
|
+
name: phone.visemeSymbol,
|
|
36
|
+
startMs: phone.startTimeSeconds * 1000,
|
|
37
|
+
durationMs: phone.durationSeconds * 1000,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return visemes;
|
|
44
|
+
}
|
|
45
|
+
export const inworldTTSProvider = {
|
|
46
|
+
name: 'inworld',
|
|
47
|
+
// Note: this provider also requires INWORLD_API_SECRET env var.
|
|
48
|
+
// The TTSProvider interface only supports one apiKeyEnv; selectTTSProvider()
|
|
49
|
+
// checks INWORLD_API_KEY, and the stream() method will throw at runtime if
|
|
50
|
+
// INWORLD_API_SECRET is also missing.
|
|
51
|
+
apiKeyEnv: 'INWORLD_API_KEY',
|
|
52
|
+
async *stream(text, voice, options) {
|
|
53
|
+
const apiKey = process.env.INWORLD_API_KEY;
|
|
54
|
+
const apiSecret = process.env.INWORLD_API_SECRET;
|
|
55
|
+
if (!apiKey)
|
|
56
|
+
throw new Error('[InWorld] INWORLD_API_KEY is required');
|
|
57
|
+
if (!apiSecret)
|
|
58
|
+
throw new Error('[InWorld] INWORLD_API_SECRET is required');
|
|
59
|
+
const basicAuth = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');
|
|
60
|
+
const requestBody = {
|
|
61
|
+
text,
|
|
62
|
+
voiceId: voice,
|
|
63
|
+
modelId: 'inworld-tts-1.5-mini',
|
|
64
|
+
audioConfig: {
|
|
65
|
+
audioEncoding: 'LINEAR16',
|
|
66
|
+
sampleRateHertz: 24000,
|
|
67
|
+
},
|
|
68
|
+
timestampType: 'WORD',
|
|
69
|
+
};
|
|
70
|
+
const response = await fetch('https://api.inworld.ai/tts/v1/voice:stream', {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
headers: {
|
|
73
|
+
'Authorization': `Basic ${basicAuth}`,
|
|
74
|
+
'Content-Type': 'application/json',
|
|
75
|
+
},
|
|
76
|
+
body: JSON.stringify(requestBody),
|
|
77
|
+
});
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
const errorText = await response.text();
|
|
80
|
+
throw new Error(`[InWorld] TTS request failed ${response.status}: ${errorText}`);
|
|
81
|
+
}
|
|
82
|
+
if (!response.body) {
|
|
83
|
+
throw new Error('[InWorld] Response body is empty');
|
|
84
|
+
}
|
|
85
|
+
const reader = response.body.getReader();
|
|
86
|
+
const decoder = new TextDecoder();
|
|
87
|
+
let lineBuffer = '';
|
|
88
|
+
const processLine = (line) => {
|
|
89
|
+
if (!line.trim())
|
|
90
|
+
return null;
|
|
91
|
+
let parsed;
|
|
92
|
+
try {
|
|
93
|
+
parsed = JSON.parse(line);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
throw new Error(`[InWorld] Failed to parse NDJSON line: ${line}`);
|
|
97
|
+
}
|
|
98
|
+
if (!parsed.audioContent)
|
|
99
|
+
return null;
|
|
100
|
+
const wavBuffer = Buffer.from(parsed.audioContent, 'base64');
|
|
101
|
+
const audio = wavBuffer.subarray(WAV_HEADER_BYTES);
|
|
102
|
+
const alignment = parsed.timestampInfo?.wordAlignment;
|
|
103
|
+
if (alignment && alignment.length > 0) {
|
|
104
|
+
// Report timing for the first word in this chunk; additional words in the alignment are not yielded separately
|
|
105
|
+
const first = alignment[0];
|
|
106
|
+
const startSec = parseOffsetSeconds(first.startOffset);
|
|
107
|
+
const endSec = parseOffsetSeconds(first.endOffset);
|
|
108
|
+
const chunk = {
|
|
109
|
+
audio,
|
|
110
|
+
word: first.word,
|
|
111
|
+
startMs: startSec * 1000,
|
|
112
|
+
durationMs: (endSec - startSec) * 1000,
|
|
113
|
+
};
|
|
114
|
+
// Parse viseme data only when requested — opt-in to avoid parsing cost on latency-sensitive paths
|
|
115
|
+
if (options?.requestVisemes) {
|
|
116
|
+
const visemes = parseVisemesFromAlignment(alignment);
|
|
117
|
+
if (visemes.length > 0) {
|
|
118
|
+
chunk.visemes = visemes;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return chunk;
|
|
122
|
+
}
|
|
123
|
+
return { audio };
|
|
124
|
+
};
|
|
125
|
+
while (true) {
|
|
126
|
+
const { done, value } = await reader.read();
|
|
127
|
+
if (done)
|
|
128
|
+
break;
|
|
129
|
+
lineBuffer += decoder.decode(value, { stream: true });
|
|
130
|
+
let newlineIndex;
|
|
131
|
+
while ((newlineIndex = lineBuffer.indexOf('\n')) !== -1) {
|
|
132
|
+
const line = lineBuffer.slice(0, newlineIndex);
|
|
133
|
+
lineBuffer = lineBuffer.slice(newlineIndex + 1);
|
|
134
|
+
const chunk = processLine(line);
|
|
135
|
+
if (chunk)
|
|
136
|
+
yield chunk;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Process any remaining content
|
|
140
|
+
if (lineBuffer.trim()) {
|
|
141
|
+
const chunk = processLine(lineBuffer);
|
|
142
|
+
if (chunk)
|
|
143
|
+
yield chunk;
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=InWorld.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InWorld.js","sourceRoot":"","sources":["../../../../src/server/audio/tts/InWorld.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Azure.d.ts","sourceRoot":"","sources":["../../../../../src/server/audio/tts/providers/Azure.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAY,WAAW,EAAE,MAAM,aAAa,CAAC;AAMzD,eAAO,MAAM,gBAAgB,EAAE,WAmC9B,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function endpoint(region) {
|
|
2
|
+
return `https://${region}.tts.speech.microsoft.com/cognitiveservices/v1`;
|
|
3
|
+
}
|
|
4
|
+
export const azureTTSProvider = {
|
|
5
|
+
name: 'azure',
|
|
6
|
+
apiKeyEnv: 'AZURE_TTS_KEY',
|
|
7
|
+
async *stream(text, voice) {
|
|
8
|
+
const apiKey = process.env['AZURE_TTS_KEY'];
|
|
9
|
+
const region = process.env['AZURE_TTS_REGION'];
|
|
10
|
+
if (!apiKey || !region) {
|
|
11
|
+
throw new Error('[AzureTTS] AZURE_TTS_KEY and AZURE_TTS_REGION env vars required');
|
|
12
|
+
}
|
|
13
|
+
const ssml = `<speak version="1.0" xml:lang="en-US"><voice name="${voice}"><prosody rate="0%">${text}</prosody></voice></speak>`;
|
|
14
|
+
const res = await fetch(endpoint(region), {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
headers: {
|
|
17
|
+
'Ocp-Apim-Subscription-Key': apiKey,
|
|
18
|
+
'Content-Type': 'application/ssml+xml',
|
|
19
|
+
'X-Microsoft-OutputFormat': 'raw-24khz-16bit-mono-pcm',
|
|
20
|
+
'User-Agent': 'ugly-app/tts',
|
|
21
|
+
},
|
|
22
|
+
body: ssml,
|
|
23
|
+
});
|
|
24
|
+
if (!res.ok) {
|
|
25
|
+
throw new Error(`[AzureTTS] API error ${res.status}: ${await res.text()}`);
|
|
26
|
+
}
|
|
27
|
+
const buffer = await res.arrayBuffer();
|
|
28
|
+
yield { audio: Buffer.from(buffer) };
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=Azure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Azure.js","sourceRoot":"","sources":["../../../../../src/server/audio/tts/providers/Azure.ts"],"names":[],"mappings":"AAGA,SAAS,QAAQ,CAAC,MAAc;IAC9B,OAAO,WAAW,MAAM,gDAAgD,CAAC;AAC3E,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAgB;IAC3C,IAAI,EAAE,OAAO;IACb,SAAS,EAAE,eAAe;IAE1B,KAAK,CAAC,CAAC,MAAM,CAAC,IAAY,EAAE,KAAa;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,sDAAsD,KAAK,wBAAwB,IAAI,4BAA4B,CAAC;QAEjI,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;YACxC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,2BAA2B,EAAE,MAAM;gBACnC,cAAc,EAAE,sBAAsB;gBACtC,0BAA0B,EAAE,0BAA0B;gBACtD,YAAY,EAAE,cAAc;aAC7B;YACD,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAC1D,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACvC,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TTSProvider } from './types.js';
|
|
2
|
+
export declare function registerTTSProvider(provider: TTSProvider): void;
|
|
3
|
+
/** Returns first provider that has its API key configured */
|
|
4
|
+
export declare function selectTTSProvider(): TTSProvider | undefined;
|
|
5
|
+
export declare function getAllTTSProviders(): TTSProvider[];
|
|
6
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../src/server/audio/tts/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAE/D;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,SAAS,CAE3D;AAED,wBAAgB,kBAAkB,IAAI,WAAW,EAAE,CAElD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const providers = [];
|
|
2
|
+
export function registerTTSProvider(provider) {
|
|
3
|
+
providers.unshift(provider); // Registered last = tried first (allows overrides)
|
|
4
|
+
}
|
|
5
|
+
/** Returns first provider that has its API key configured */
|
|
6
|
+
export function selectTTSProvider() {
|
|
7
|
+
return providers.find((p) => !!process.env[p.apiKeyEnv]);
|
|
8
|
+
}
|
|
9
|
+
export function getAllTTSProviders() {
|
|
10
|
+
return [...providers];
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/server/audio/tts/registry.ts"],"names":[],"mappings":"AAGA,MAAM,SAAS,GAAkB,EAAE,CAAC;AAEpC,MAAM,UAAU,mBAAmB,CAAC,QAAqB;IACvD,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,mDAAmD;AAClF,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,iBAAiB;IAC/B,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TTSViseme } from '../../../shared/Audio.js';
|
|
2
|
+
export interface TTSChunk {
|
|
3
|
+
audio: Buffer;
|
|
4
|
+
word?: string;
|
|
5
|
+
startMs?: number;
|
|
6
|
+
durationMs?: number;
|
|
7
|
+
/** Viseme data — only populated when requestVisemes was true and provider supports it */
|
|
8
|
+
visemes?: TTSViseme[];
|
|
9
|
+
}
|
|
10
|
+
export interface TTSStreamOptions {
|
|
11
|
+
/** Request viseme data for lip sync. Default false — omit for lower latency */
|
|
12
|
+
requestVisemes?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface TTSProvider {
|
|
15
|
+
name: string;
|
|
16
|
+
apiKeyEnv: string;
|
|
17
|
+
/** Streams PCM16 audio chunks for the given text and voice */
|
|
18
|
+
stream(text: string, voice: string, options?: TTSStreamOptions): AsyncGenerator<TTSChunk>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/audio/tts/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yFAAyF;IACzF,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,MAAM,CACJ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,gBAAgB,GACzB,cAAc,CAAC,QAAQ,CAAC,CAAC;CAC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/server/audio/tts/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { LedgerDB } from './BillingLedger.js';
|
|
2
|
+
import type { CreditDB } from './CreditStore.js';
|
|
3
|
+
import type { BillingConfig, BillingRecord, ChargeParams, GetUserLimits, GlobalThresholdCallback, HistoryFilters, SpendFilters, UserThresholdCallback } from './types.js';
|
|
4
|
+
export declare class BillingGateway {
|
|
5
|
+
private readonly config;
|
|
6
|
+
private readonly ledger;
|
|
7
|
+
private readonly userLimits;
|
|
8
|
+
private readonly enforcer;
|
|
9
|
+
private readonly credits;
|
|
10
|
+
private readonly marginMultiplier;
|
|
11
|
+
constructor(db: LedgerDB, config: BillingConfig, creditDb?: CreditDB);
|
|
12
|
+
setUserLimitHook(fn: GetUserLimits): void;
|
|
13
|
+
setUserThresholdCallback(fn: UserThresholdCallback): void;
|
|
14
|
+
setGlobalThresholdCallback(fn: GlobalThresholdCallback): void;
|
|
15
|
+
invalidateUserLimit(userId: string): void;
|
|
16
|
+
invalidateAllUserLimits(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Grant pre-paid credits to a user.
|
|
19
|
+
* Credits are used as a fallback when rate limits are exceeded.
|
|
20
|
+
* Throws if no creditDb was provided at initialization.
|
|
21
|
+
*/
|
|
22
|
+
grantCredit(userId: string, amountUsd: number): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Get the current credit balance for a user.
|
|
25
|
+
* Returns 0 if no creditDb was provided or if the user has no credits.
|
|
26
|
+
*/
|
|
27
|
+
getCreditBalance(userId: string): Promise<number>;
|
|
28
|
+
/**
|
|
29
|
+
* Invalidate the cached credit balance for a user (e.g. after an external grant).
|
|
30
|
+
*/
|
|
31
|
+
invalidateCreditCache(userId: string): void;
|
|
32
|
+
charge(params: ChargeParams): Promise<BillingRecord>;
|
|
33
|
+
getWindowSpend(windowMs: number, filters?: SpendFilters): Promise<number>;
|
|
34
|
+
getHistory(filters?: HistoryFilters): Promise<BillingRecord[]>;
|
|
35
|
+
start(): Promise<void>;
|
|
36
|
+
shutdown(): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
export declare function initBillingGateway(db: LedgerDB, config: BillingConfig, creditDb?: CreditDB): BillingGateway;
|
|
39
|
+
export declare function getBillingGateway(): BillingGateway;
|
|
40
|
+
//# sourceMappingURL=BillingGateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BillingGateway.d.ts","sourceRoot":"","sources":["../../../src/server/billing/BillingGateway.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,YAAY,EACZ,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAIpB,qBAAa,cAAc;IASvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IARzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAGxC,EAAE,EAAE,QAAQ,EACK,MAAM,EAAE,aAAa,EACtC,QAAQ,CAAC,EAAE,QAAQ;IAwCrB,gBAAgB,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;IAIzC,wBAAwB,CAAC,EAAE,EAAE,qBAAqB,GAAG,IAAI;IAIzD,0BAA0B,CAAC,EAAE,EAAE,uBAAuB,GAAG,IAAI;IAI7D,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIzC,uBAAuB,IAAI,IAAI;IAI/B;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASnE;;;OAGG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKvD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIrC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAkB1D,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE,UAAU,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIxD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC;AAQD,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,aAAa,EACrB,QAAQ,CAAC,EAAE,QAAQ,GAClB,cAAc,CAMhB;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAOlD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import { BillingLedger } from './BillingLedger.js';
|
|
3
|
+
import { CreditStore } from './CreditStore.js';
|
|
4
|
+
import { LimitEnforcer } from './LimitEnforcer.js';
|
|
5
|
+
import { BillingValidationError } from './types.js';
|
|
6
|
+
import { UserLimitCache } from './UserLimitCache.js';
|
|
7
|
+
export class BillingGateway {
|
|
8
|
+
config;
|
|
9
|
+
ledger;
|
|
10
|
+
userLimits;
|
|
11
|
+
enforcer;
|
|
12
|
+
credits;
|
|
13
|
+
marginMultiplier;
|
|
14
|
+
constructor(db, config, creditDb) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
if (!Number.isFinite(config.global.hourlyUsd) ||
|
|
17
|
+
config.global.hourlyUsd <= 0) {
|
|
18
|
+
throw new BillingValidationError(`config.global.hourlyUsd must be a finite positive number, got ${String(config.global.hourlyUsd)}`);
|
|
19
|
+
}
|
|
20
|
+
if (config.profitMarginPct !== undefined &&
|
|
21
|
+
(config.profitMarginPct < 0 || !Number.isFinite(config.profitMarginPct))) {
|
|
22
|
+
throw new BillingValidationError(`config.profitMarginPct must be a non-negative finite number, got ${String(config.profitMarginPct)}`);
|
|
23
|
+
}
|
|
24
|
+
this.marginMultiplier = 1 + (config.profitMarginPct ?? 0);
|
|
25
|
+
this.ledger = new BillingLedger(db, config.reconcileIntervalMs ?? 300_000);
|
|
26
|
+
this.userLimits = new UserLimitCache(3_600_000, config.userLimitCacheSize ?? 10_000);
|
|
27
|
+
this.credits = creditDb ? new CreditStore(creditDb) : null;
|
|
28
|
+
this.enforcer = new LimitEnforcer(this.ledger, this.userLimits, config, this.credits);
|
|
29
|
+
}
|
|
30
|
+
setUserLimitHook(fn) {
|
|
31
|
+
this.userLimits.setHook(fn);
|
|
32
|
+
}
|
|
33
|
+
setUserThresholdCallback(fn) {
|
|
34
|
+
this.enforcer.setUserThresholdCallback(fn);
|
|
35
|
+
}
|
|
36
|
+
setGlobalThresholdCallback(fn) {
|
|
37
|
+
this.enforcer.setGlobalThresholdCallback(fn);
|
|
38
|
+
}
|
|
39
|
+
invalidateUserLimit(userId) {
|
|
40
|
+
this.userLimits.invalidate(userId);
|
|
41
|
+
}
|
|
42
|
+
invalidateAllUserLimits() {
|
|
43
|
+
this.userLimits.invalidateAll();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Grant pre-paid credits to a user.
|
|
47
|
+
* Credits are used as a fallback when rate limits are exceeded.
|
|
48
|
+
* Throws if no creditDb was provided at initialization.
|
|
49
|
+
*/
|
|
50
|
+
async grantCredit(userId, amountUsd) {
|
|
51
|
+
if (!this.credits) {
|
|
52
|
+
throw new BillingValidationError('grantCredit() requires a creditDb to be passed to initBillingGateway()');
|
|
53
|
+
}
|
|
54
|
+
await this.credits.grant(userId, amountUsd);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the current credit balance for a user.
|
|
58
|
+
* Returns 0 if no creditDb was provided or if the user has no credits.
|
|
59
|
+
*/
|
|
60
|
+
async getCreditBalance(userId) {
|
|
61
|
+
if (!this.credits)
|
|
62
|
+
return 0;
|
|
63
|
+
return this.credits.getBalance(userId);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Invalidate the cached credit balance for a user (e.g. after an external grant).
|
|
67
|
+
*/
|
|
68
|
+
invalidateCreditCache(userId) {
|
|
69
|
+
this.credits?.invalidate(userId);
|
|
70
|
+
}
|
|
71
|
+
async charge(params) {
|
|
72
|
+
// Apply profit margin to the raw provider cost before any checks or persistence
|
|
73
|
+
const costUsd = params.costUsd * this.marginMultiplier;
|
|
74
|
+
const adjustedParams = { ...params, costUsd };
|
|
75
|
+
await this.enforcer.check(adjustedParams);
|
|
76
|
+
const record = {
|
|
77
|
+
...adjustedParams,
|
|
78
|
+
provider: params.provider.trim().toLowerCase(),
|
|
79
|
+
id: nanoid(),
|
|
80
|
+
timestamp: Date.now(),
|
|
81
|
+
};
|
|
82
|
+
this.ledger.add(record);
|
|
83
|
+
return record;
|
|
84
|
+
}
|
|
85
|
+
getWindowSpend(windowMs, filters) {
|
|
86
|
+
return this.ledger.getWindowSpend(windowMs, filters);
|
|
87
|
+
}
|
|
88
|
+
getHistory(filters) {
|
|
89
|
+
return this.ledger.getHistory(filters);
|
|
90
|
+
}
|
|
91
|
+
async start() {
|
|
92
|
+
await this.enforcer.init();
|
|
93
|
+
this.ledger.start();
|
|
94
|
+
}
|
|
95
|
+
async shutdown() {
|
|
96
|
+
await this.ledger.shutdown();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Singleton
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
let _instance = null;
|
|
103
|
+
export function initBillingGateway(db, config, creditDb) {
|
|
104
|
+
if (_instance) {
|
|
105
|
+
void _instance.shutdown();
|
|
106
|
+
}
|
|
107
|
+
_instance = new BillingGateway(db, config, creditDb);
|
|
108
|
+
return _instance;
|
|
109
|
+
}
|
|
110
|
+
export function getBillingGateway() {
|
|
111
|
+
if (!_instance) {
|
|
112
|
+
throw new BillingValidationError('BillingGateway is not initialized. Call initBillingGateway() first.');
|
|
113
|
+
}
|
|
114
|
+
return _instance;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=BillingGateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BillingGateway.js","sourceRoot":"","sources":["../../../src/server/billing/BillingGateway.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { BillingRecord, BillingType, HistoryFilters, SpendFilters } from './types.js';
|
|
2
|
+
export interface StoredBillingRecord {
|
|
3
|
+
id: string;
|
|
4
|
+
version: number;
|
|
5
|
+
created: Date;
|
|
6
|
+
updated: Date;
|
|
7
|
+
userId?: string;
|
|
8
|
+
provider: string;
|
|
9
|
+
model: string;
|
|
10
|
+
type: BillingType;
|
|
11
|
+
costUsd: number;
|
|
12
|
+
inputTokens?: number;
|
|
13
|
+
outputTokens?: number;
|
|
14
|
+
imageCount?: number;
|
|
15
|
+
imageWidth?: number;
|
|
16
|
+
imageHeight?: number;
|
|
17
|
+
imageSteps?: number;
|
|
18
|
+
audioSeconds?: number;
|
|
19
|
+
timestamp: number;
|
|
20
|
+
}
|
|
21
|
+
export interface LedgerDB {
|
|
22
|
+
/** Upsert a billing record by id (idempotent). */
|
|
23
|
+
setDoc(id: string, doc: StoredBillingRecord): Promise<void>;
|
|
24
|
+
/** Query billing records with a MongoDB-style filter. */
|
|
25
|
+
getDocs(filter: Record<string, unknown>, options?: {
|
|
26
|
+
sort?: Record<string, 1 | -1>;
|
|
27
|
+
limit?: number;
|
|
28
|
+
skip?: number;
|
|
29
|
+
}): Promise<StoredBillingRecord[]>;
|
|
30
|
+
}
|
|
31
|
+
export declare class BillingLedger {
|
|
32
|
+
private readonly db;
|
|
33
|
+
private readonly reconcileIntervalMs;
|
|
34
|
+
private pending;
|
|
35
|
+
private timer;
|
|
36
|
+
constructor(db: LedgerDB, reconcileIntervalMs?: number);
|
|
37
|
+
/** Expose pending buffer size (for testing). */
|
|
38
|
+
pendingCount(): number;
|
|
39
|
+
/** Synchronously append a record to the in-memory buffer. */
|
|
40
|
+
add(record: BillingRecord): void;
|
|
41
|
+
/**
|
|
42
|
+
* Sum costUsd for records in [now-windowMs, now], combining DB + in-memory pending.
|
|
43
|
+
* Pending records are NOT in DB yet — no double-counting.
|
|
44
|
+
*/
|
|
45
|
+
getWindowSpend(windowMs: number, filters?: SpendFilters): Promise<number>;
|
|
46
|
+
/**
|
|
47
|
+
* Upsert all pending records to MongoDB, then clear the buffer.
|
|
48
|
+
* Atomic snapshot: concurrent adds after the snapshot are safe.
|
|
49
|
+
* On failure: failed records are prepended back to pending.
|
|
50
|
+
*/
|
|
51
|
+
reconcile(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Query billing history merging DB records and in-memory pending.
|
|
54
|
+
* Sorted by timestamp DESC, id ASC. Limit/skip applied to merged result.
|
|
55
|
+
*/
|
|
56
|
+
getHistory(filters?: HistoryFilters): Promise<BillingRecord[]>;
|
|
57
|
+
/** Start the periodic reconcile timer. */
|
|
58
|
+
start(): void;
|
|
59
|
+
/** Stop the timer and flush pending records to DB. */
|
|
60
|
+
shutdown(): Promise<void>;
|
|
61
|
+
}
|
|
62
|
+
export declare const WINDOW_MS: {
|
|
63
|
+
readonly HOUR: 3600000;
|
|
64
|
+
readonly DAY: number;
|
|
65
|
+
readonly WEEK: number;
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=BillingLedger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BillingLedger.d.ts","sourceRoot":"","sources":["../../../src/server/billing/BillingLedger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACb,MAAM,YAAY,CAAC;AAQpB,MAAM,WAAW,mBAAmB;IAElC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IAEd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,QAAQ;IACvB,kDAAkD;IAClD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,yDAAyD;IACzD,OAAO,CACL,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GACA,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;CACnC;AAMD,qBAAa,aAAa;IAKtB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IALtC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,KAAK,CAA+C;gBAGzC,EAAE,EAAE,QAAQ,EACZ,mBAAmB,GAAE,MAAgB;IAGxD,gDAAgD;IAChD,YAAY,IAAI,MAAM;IAItB,6DAA6D;IAC7D,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAuBhC;;;OAGG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC;IA+BlB;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAiChC;;;OAGG;IACG,UAAU,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAkDxE,0CAA0C;IAC1C,KAAK,IAAI,IAAI;IAOb,sDAAsD;IAChD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAOhC;AA6BD,eAAO,MAAM,SAAS;;;;CAIZ,CAAC"}
|