@muskanmeet/invoicing-design-system 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/.cache/replit/env/latest +78 -0
- package/.cache/replit/env/latest.json +1 -0
- package/.cache/replit/modules/nodejs-20.res +1 -0
- package/.cache/replit/modules/python-3.11.res +1 -0
- package/.cache/replit/modules/replit-rtld-loader.res +1 -0
- package/.cache/replit/modules/replit.res +1 -0
- package/.cache/replit/modules.stamp +0 -0
- package/.cache/replit/nix/dotreplitenv.json +1 -0
- package/.cache/replit/toolchain.json +1 -0
- package/.cache/typescript/5.9/package-lock.json +50 -0
- package/.cache/typescript/5.9/package.json +1 -0
- package/.config/nextjs-nodejs/config.json +7 -0
- package/.eslintrc.json +3 -0
- package/.local/.commit_message +31 -0
- package/.local/secondary_skills/LICENSE.txt +21 -0
- package/.local/secondary_skills/ad-creative/.fingerprint +1 -0
- package/.local/secondary_skills/ad-creative/SKILL.md +872 -0
- package/.local/secondary_skills/ai-recruiter/.fingerprint +1 -0
- package/.local/secondary_skills/ai-recruiter/SKILL.md +1087 -0
- package/.local/secondary_skills/ai-sdr/.fingerprint +1 -0
- package/.local/secondary_skills/ai-sdr/SKILL.md +204 -0
- package/.local/secondary_skills/ai-secretary/.fingerprint +1 -0
- package/.local/secondary_skills/ai-secretary/SKILL.md +1132 -0
- package/.local/secondary_skills/branding-generator/.fingerprint +1 -0
- package/.local/secondary_skills/branding-generator/SKILL.md +286 -0
- package/.local/secondary_skills/competitive-analysis/.fingerprint +1 -0
- package/.local/secondary_skills/competitive-analysis/SKILL.md +429 -0
- package/.local/secondary_skills/content-machine/.fingerprint +1 -0
- package/.local/secondary_skills/content-machine/SKILL.md +321 -0
- package/.local/secondary_skills/deep-research/.fingerprint +1 -0
- package/.local/secondary_skills/deep-research/SKILL.md +517 -0
- package/.local/secondary_skills/design-thinker/.fingerprint +1 -0
- package/.local/secondary_skills/design-thinker/SKILL.md +327 -0
- package/.local/secondary_skills/excel-generator/.fingerprint +1 -0
- package/.local/secondary_skills/excel-generator/SKILL.md +954 -0
- package/.local/secondary_skills/excel-generator/financial-models.md +289 -0
- package/.local/secondary_skills/file-converter/.fingerprint +1 -0
- package/.local/secondary_skills/file-converter/SKILL.md +823 -0
- package/.local/secondary_skills/flashcard-generator/.fingerprint +1 -0
- package/.local/secondary_skills/flashcard-generator/SKILL.md +233 -0
- package/.local/secondary_skills/geo/.fingerprint +1 -0
- package/.local/secondary_skills/geo/SKILL.md +378 -0
- package/.local/secondary_skills/geo/references/content-patterns.md +158 -0
- package/.local/secondary_skills/geo/references/platform-notes.md +128 -0
- package/.local/secondary_skills/geo/references/scorecard.md +113 -0
- package/.local/secondary_skills/geo/references/technical-checklist.md +257 -0
- package/.local/secondary_skills/github-solution-finder/.fingerprint +1 -0
- package/.local/secondary_skills/github-solution-finder/SKILL.md +174 -0
- package/.local/secondary_skills/infographic-builder/.fingerprint +1 -0
- package/.local/secondary_skills/infographic-builder/SKILL.md +317 -0
- package/.local/secondary_skills/infographic-builder/antv-syntax.md +470 -0
- package/.local/secondary_skills/infographic-builder/react-fallback.md +210 -0
- package/.local/secondary_skills/insurance-optimizer/.fingerprint +1 -0
- package/.local/secondary_skills/insurance-optimizer/SKILL.md +209 -0
- package/.local/secondary_skills/interview-prep/.fingerprint +1 -0
- package/.local/secondary_skills/interview-prep/SKILL.md +349 -0
- package/.local/secondary_skills/invoice-generator/.fingerprint +1 -0
- package/.local/secondary_skills/invoice-generator/SKILL.md +527 -0
- package/.local/secondary_skills/legal-contract/.fingerprint +1 -0
- package/.local/secondary_skills/legal-contract/SKILL.md +977 -0
- package/.local/secondary_skills/meal-planner/.fingerprint +1 -0
- package/.local/secondary_skills/meal-planner/SKILL.md +517 -0
- package/.local/secondary_skills/personal-shopper/.fingerprint +1 -0
- package/.local/secondary_skills/personal-shopper/SKILL.md +361 -0
- package/.local/secondary_skills/photo-editor/.fingerprint +1 -0
- package/.local/secondary_skills/photo-editor/SKILL.md +605 -0
- package/.local/secondary_skills/podcast-generator/.fingerprint +1 -0
- package/.local/secondary_skills/podcast-generator/SKILL.md +560 -0
- package/.local/secondary_skills/podcast-marketing/.fingerprint +1 -0
- package/.local/secondary_skills/podcast-marketing/SKILL.md +550 -0
- package/.local/secondary_skills/podcast-marketing/audio-processing.md +530 -0
- package/.local/secondary_skills/podcast-marketing/content-atoms.md +253 -0
- package/.local/secondary_skills/podcast-marketing/content-calendar.md +318 -0
- package/.local/secondary_skills/podcast-marketing/content-templates.md +325 -0
- package/.local/secondary_skills/podcast-marketing/quote-cards.md +238 -0
- package/.local/secondary_skills/podcast-marketing/rss-and-batch.md +359 -0
- package/.local/secondary_skills/podcast-marketing/video-clips.md +660 -0
- package/.local/secondary_skills/podcast-marketing/youtube-processing.md +328 -0
- package/.local/secondary_skills/product-manager/.fingerprint +1 -0
- package/.local/secondary_skills/product-manager/SKILL.md +272 -0
- package/.local/secondary_skills/programmatic-seo/.fingerprint +1 -0
- package/.local/secondary_skills/programmatic-seo/SKILL.md +1207 -0
- package/.local/secondary_skills/real-estate-analyzer/.fingerprint +1 -0
- package/.local/secondary_skills/real-estate-analyzer/SKILL.md +786 -0
- package/.local/secondary_skills/recipe-creator/.fingerprint +1 -0
- package/.local/secondary_skills/recipe-creator/SKILL.md +259 -0
- package/.local/secondary_skills/recreate-screenshot/.fingerprint +1 -0
- package/.local/secondary_skills/recreate-screenshot/SKILL.md +215 -0
- package/.local/secondary_skills/replit-migration-guardrails/.fingerprint +1 -0
- package/.local/secondary_skills/replit-migration-guardrails/SKILL.md +55 -0
- package/.local/secondary_skills/replit-migration-guardrails/references/base44.md +47 -0
- package/.local/secondary_skills/replit-migration-guardrails/references/vercel.md +78 -0
- package/.local/secondary_skills/resume-maker/.fingerprint +1 -0
- package/.local/secondary_skills/resume-maker/SKILL.md +790 -0
- package/.local/secondary_skills/seo-auditor/.fingerprint +1 -0
- package/.local/secondary_skills/seo-auditor/SKILL.md +448 -0
- package/.local/secondary_skills/skill-creator/.fingerprint +1 -0
- package/.local/secondary_skills/skill-creator/SKILL.md +214 -0
- package/.local/secondary_skills/skill-finder/.fingerprint +1 -0
- package/.local/secondary_skills/skill-finder/SKILL.md +299 -0
- package/.local/secondary_skills/stock-analyzer/.fingerprint +1 -0
- package/.local/secondary_skills/stock-analyzer/SKILL.md +798 -0
- package/.local/secondary_skills/storyboard/.fingerprint +1 -0
- package/.local/secondary_skills/storyboard/SKILL.md +558 -0
- package/.local/secondary_skills/supplier-research/.fingerprint +1 -0
- package/.local/secondary_skills/supplier-research/SKILL.md +213 -0
- package/.local/secondary_skills/tax-reviewer/.fingerprint +1 -0
- package/.local/secondary_skills/tax-reviewer/SKILL.md +131 -0
- package/.local/secondary_skills/travel-assistant/.fingerprint +1 -0
- package/.local/secondary_skills/travel-assistant/SKILL.md +667 -0
- package/.local/secondary_skills/video-editing/.fingerprint +1 -0
- package/.local/secondary_skills/video-editing/SKILL.md +705 -0
- package/.local/secondary_skills/video-editing/dead-space-and-chunking.md +1081 -0
- package/.local/secondary_skills/video-editing/operations.md +1719 -0
- package/.local/secondary_skills/video-editing/virality-scoring.md +1212 -0
- package/.local/secondary_skills/video-editing/voiceover.md +788 -0
- package/.local/secondary_skills/website-cloning/.fingerprint +1 -0
- package/.local/secondary_skills/website-cloning/SKILL.md +544 -0
- package/.local/secondary_skills/website-cloning/extraction.md +1207 -0
- package/.local/secondary_skills/website-cloning/pitfalls.md +297 -0
- package/.local/skills/LICENSE.txt +21 -0
- package/.local/skills/agent-inbox/.fingerprint +1 -0
- package/.local/skills/agent-inbox/SKILL.md +128 -0
- package/.local/skills/artifacts/.fingerprint +1 -0
- package/.local/skills/artifacts/SKILL.md +21 -0
- package/.local/skills/artifacts/artifacts/automation/artifact.yaml +40 -0
- package/.local/skills/artifacts/artifacts/automation/files/package.json.template +47 -0
- package/.local/skills/artifacts/artifacts/automation/files/scripts/build.sh +6 -0
- package/.local/skills/artifacts/artifacts/automation/files/scripts/inngest.sh +18 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/global.d.ts +1 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/mastra/agents/agent.ts +89 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/mastra/index.ts +212 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/mastra/inngest/client.ts +17 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/mastra/inngest/index.ts +214 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/mastra/storage/index.ts +8 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/mastra/tools/exampleTool.ts +71 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/mastra/workflows/workflow.ts +203 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/triggers/cronTriggers.ts +61 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/triggers/exampleConnectorTrigger.ts +153 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/triggers/slackTriggers.ts +638 -0
- package/.local/skills/artifacts/artifacts/automation/files/src/triggers/telegramTriggers.ts +94 -0
- package/.local/skills/artifacts/artifacts/automation/files/tests/testCronAutomation.ts +86 -0
- package/.local/skills/artifacts/artifacts/automation/files/tests/testWebhookAutomation.ts +118 -0
- package/.local/skills/artifacts/artifacts/automation/files/tsconfig.json +26 -0
- package/.local/skills/artifacts/artifacts/data-visualization/artifact.yaml +48 -0
- package/.local/skills/artifacts/artifacts/expo/OWNERS +2 -0
- package/.local/skills/artifacts/artifacts/expo/artifact.yaml +47 -0
- package/.local/skills/artifacts/artifacts/expo/files/app/(tabs)/_layout.tsx +86 -0
- package/.local/skills/artifacts/artifacts/expo/files/app/(tabs)/index.tsx +28 -0
- package/.local/skills/artifacts/artifacts/expo/files/app/+not-found.tsx +45 -0
- package/.local/skills/artifacts/artifacts/expo/files/app/_layout.tsx +60 -0
- package/.local/skills/artifacts/artifacts/expo/files/app.json.template +38 -0
- package/.local/skills/artifacts/artifacts/expo/files/assets/images/icon.png +0 -0
- package/.local/skills/artifacts/artifacts/expo/files/babel.config.js +6 -0
- package/.local/skills/artifacts/artifacts/expo/files/components/ErrorBoundary.tsx +54 -0
- package/.local/skills/artifacts/artifacts/expo/files/components/ErrorFallback.tsx +278 -0
- package/.local/skills/artifacts/artifacts/expo/files/components/KeyboardAwareScrollViewCompat.tsx +29 -0
- package/.local/skills/artifacts/artifacts/expo/files/constants/colors.ts +59 -0
- package/.local/skills/artifacts/artifacts/expo/files/hooks/useColors.ts +24 -0
- package/.local/skills/artifacts/artifacts/expo/files/metro.config.js +3 -0
- package/.local/skills/artifacts/artifacts/expo/files/package.json.template +58 -0
- package/.local/skills/artifacts/artifacts/expo/files/scripts/build.js +573 -0
- package/.local/skills/artifacts/artifacts/expo/files/server/serve.js +135 -0
- package/.local/skills/artifacts/artifacts/expo/files/server/templates/landing-page.html +460 -0
- package/.local/skills/artifacts/artifacts/expo/files/tsconfig.json +23 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/artifact.yaml +15 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/components.json +21 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/index.html +31 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/mockupPreviewPlugin.ts +199 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/package.json.template +75 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/public/favicon.svg +3 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/.generated/mockup-components.ts +3 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/App.tsx +146 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/accordion.tsx +55 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/alert-dialog.tsx +139 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/alert.tsx +59 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/aspect-ratio.tsx +5 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/avatar.tsx +50 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/badge.tsx +43 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/breadcrumb.tsx +115 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/button-group.tsx +83 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/button.tsx +65 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/calendar.tsx +213 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/card.tsx +76 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/carousel.tsx +260 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/chart.tsx +367 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/checkbox.tsx +28 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/collapsible.tsx +11 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/command.tsx +153 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/context-menu.tsx +198 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/dialog.tsx +120 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/drawer.tsx +116 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/dropdown-menu.tsx +201 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/empty.tsx +104 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/field.tsx +244 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/form.tsx +176 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/hover-card.tsx +27 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/input-group.tsx +168 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/input-otp.tsx +69 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/input.tsx +22 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/item.tsx +193 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/kbd.tsx +28 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/label.tsx +26 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/menubar.tsx +254 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/navigation-menu.tsx +128 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/pagination.tsx +117 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/popover.tsx +31 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/progress.tsx +28 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/radio-group.tsx +42 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/resizable.tsx +45 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/scroll-area.tsx +46 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/select.tsx +159 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/separator.tsx +29 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/sheet.tsx +140 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/sidebar.tsx +727 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/skeleton.tsx +15 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/slider.tsx +26 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/sonner.tsx +31 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/spinner.tsx +16 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/switch.tsx +27 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/table.tsx +120 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/tabs.tsx +53 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/textarea.tsx +22 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/toast.tsx +127 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/toaster.tsx +33 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/toggle-group.tsx +61 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/toggle.tsx +43 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/components/ui/tooltip.tsx +32 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/hooks/use-mobile.tsx +19 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/hooks/use-toast.ts +189 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/index.css +158 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/lib/utils.ts +6 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/src/main.tsx +5 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/tsconfig.json +20 -0
- package/.local/skills/artifacts/artifacts/mockup-sandbox/files/vite.config.ts +72 -0
- package/.local/skills/artifacts/artifacts/react-vite/artifact.yaml +41 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/components.json +20 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/index.html.template +24 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/package.json.template +77 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/public/favicon.svg +3 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/public/robots.txt +2 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/App.tsx +42 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/accordion.tsx +55 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/alert-dialog.tsx +139 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/alert.tsx +59 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/aspect-ratio.tsx +5 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/avatar.tsx +50 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/badge.tsx +43 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/breadcrumb.tsx +115 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/button-group.tsx +83 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/button.tsx +65 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/calendar.tsx +213 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/card.tsx +76 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/carousel.tsx +260 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/chart.tsx +367 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/checkbox.tsx +28 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/collapsible.tsx +11 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/command.tsx +153 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/context-menu.tsx +198 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/dialog.tsx +120 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/drawer.tsx +116 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/dropdown-menu.tsx +201 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/empty.tsx +104 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/field.tsx +244 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/form.tsx +176 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/hover-card.tsx +27 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/input-group.tsx +168 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/input-otp.tsx +69 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/input.tsx +22 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/item.tsx +193 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/kbd.tsx +28 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/label.tsx +26 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/menubar.tsx +254 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/navigation-menu.tsx +128 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/pagination.tsx +117 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/popover.tsx +31 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/progress.tsx +28 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/radio-group.tsx +42 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/resizable.tsx +45 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/scroll-area.tsx +46 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/select.tsx +159 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/separator.tsx +29 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/sheet.tsx +140 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/sidebar.tsx +727 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/skeleton.tsx +15 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/slider.tsx +26 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/sonner.tsx +31 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/spinner.tsx +16 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/switch.tsx +27 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/table.tsx +120 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/tabs.tsx +53 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/textarea.tsx +22 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/toast.tsx +127 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/toaster.tsx +33 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/toggle-group.tsx +61 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/toggle.tsx +43 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/components/ui/tooltip.tsx +32 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/hooks/use-mobile.tsx +19 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/hooks/use-toast.ts +191 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/index.css +393 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/lib/utils.ts +6 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/main.tsx +5 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/src/pages/not-found.tsx +21 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/tsconfig.json +22 -0
- package/.local/skills/artifacts/artifacts/react-vite/files/vite.config.ts +75 -0
- package/.local/skills/artifacts/artifacts/slides/artifact.yaml +33 -0
- package/.local/skills/artifacts/artifacts/slides/files/index.html.template +46 -0
- package/.local/skills/artifacts/artifacts/slides/files/package.json.template +30 -0
- package/.local/skills/artifacts/artifacts/slides/files/public/favicon.svg +3 -0
- package/.local/skills/artifacts/artifacts/slides/files/scripts/validate-slides.ts +193 -0
- package/.local/skills/artifacts/artifacts/slides/files/src/App.tsx +251 -0
- package/.local/skills/artifacts/artifacts/slides/files/src/data/slides-manifest.json +1 -0
- package/.local/skills/artifacts/artifacts/slides/files/src/data/slidesManifestSchema.ts +33 -0
- package/.local/skills/artifacts/artifacts/slides/files/src/index.css +48 -0
- package/.local/skills/artifacts/artifacts/slides/files/src/main.tsx +14 -0
- package/.local/skills/artifacts/artifacts/slides/files/src/slideLoader.ts +51 -0
- package/.local/skills/artifacts/artifacts/slides/files/tsconfig.json +17 -0
- package/.local/skills/artifacts/artifacts/slides/files/vite.config.ts +74 -0
- package/.local/skills/artifacts/artifacts/video-js/artifact.yaml +38 -0
- package/.local/skills/artifacts/artifacts/video-js/files/index.html.template +27 -0
- package/.local/skills/artifacts/artifacts/video-js/files/package.json.template +36 -0
- package/.local/skills/artifacts/artifacts/video-js/files/public/favicon.svg +3 -0
- package/.local/skills/artifacts/artifacts/video-js/files/scripts/validate-recording.sh +38 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/App.tsx +5 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/components/video/ReplitLoadingScene.tsx +105 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/components/video/VideoTemplate.tsx +30 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/components/video/index.ts +1 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/hooks/use-mobile.tsx +19 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/index.css +50 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/lib/utils.ts +6 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/lib/video/animations.ts +239 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/lib/video/hooks.ts +104 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/lib/video/index.ts +19 -0
- package/.local/skills/artifacts/artifacts/video-js/files/src/main.tsx +5 -0
- package/.local/skills/artifacts/artifacts/video-js/files/tsconfig.json +16 -0
- package/.local/skills/artifacts/artifacts/video-js/files/vite.config.ts +79 -0
- package/.local/skills/artifacts/bootstrap-legacy.js +115 -0
- package/.local/skills/artifacts/bootstrap.js +118 -0
- package/.local/skills/artifacts/references/multi-artifact-creation.md +94 -0
- package/.local/skills/canvas/.fingerprint +1 -0
- package/.local/skills/canvas/SKILL.md +534 -0
- package/.local/skills/canvas/__init__.py +1 -0
- package/.local/skills/code_review/.fingerprint +1 -0
- package/.local/skills/code_review/SKILL.md +82 -0
- package/.local/skills/database/.fingerprint +1 -0
- package/.local/skills/database/SKILL.md +351 -0
- package/.local/skills/database/references/database-migrations-on-publish.md +57 -0
- package/.local/skills/delegation/.fingerprint +1 -0
- package/.local/skills/delegation/SKILL.md +200 -0
- package/.local/skills/deployment/.fingerprint +1 -0
- package/.local/skills/deployment/SKILL.md +261 -0
- package/.local/skills/deployment/references/deployment-failure-debugging.md +243 -0
- package/.local/skills/deployment/references/deployment-logs.md +147 -0
- package/.local/skills/design/.fingerprint +1 -0
- package/.local/skills/design/SKILL.md +235 -0
- package/.local/skills/design-exploration/.fingerprint +1 -0
- package/.local/skills/design-exploration/SKILL.md +95 -0
- package/.local/skills/diagnostics/.fingerprint +1 -0
- package/.local/skills/diagnostics/SKILL.md +122 -0
- package/.local/skills/environment-secrets/.fingerprint +1 -0
- package/.local/skills/environment-secrets/SKILL.md +201 -0
- package/.local/skills/expo/.fingerprint +1 -0
- package/.local/skills/expo/OWNERS +2 -0
- package/.local/skills/expo/SKILL.md +298 -0
- package/.local/skills/expo/references/design_and_aesthetics.md +141 -0
- package/.local/skills/expo/references/device_features_and_permissions.md +48 -0
- package/.local/skills/expo/references/first_build.md +114 -0
- package/.local/skills/expo/references/react_context.md +54 -0
- package/.local/skills/external_apis/.fingerprint +1 -0
- package/.local/skills/external_apis/SKILL.md +25 -0
- package/.local/skills/external_apis/references/brave.md +116 -0
- package/.local/skills/external_apis/references/elevenlabs.md +44 -0
- package/.local/skills/external_apis/references/exa.md +34 -0
- package/.local/skills/external_apis/references/firecrawl.md +37 -0
- package/.local/skills/external_apis/references/nano_banana.md +33 -0
- package/.local/skills/follow-up-tasks/.fingerprint +1 -0
- package/.local/skills/follow-up-tasks/SKILL.md +80 -0
- package/.local/skills/image-search/.fingerprint +1 -0
- package/.local/skills/image-search/SKILL.md +150 -0
- package/.local/skills/integrations/.fingerprint +1 -0
- package/.local/skills/integrations/SKILL.md +205 -0
- package/.local/skills/media-generation/.fingerprint +1 -0
- package/.local/skills/media-generation/SKILL.md +170 -0
- package/.local/skills/media-generation/audio_generation.md +138 -0
- package/.local/skills/media-generation/video_generation.md +82 -0
- package/.local/skills/mockup-extract/.fingerprint +1 -0
- package/.local/skills/mockup-extract/SKILL.md +123 -0
- package/.local/skills/mockup-graduate/.fingerprint +1 -0
- package/.local/skills/mockup-graduate/SKILL.md +97 -0
- package/.local/skills/mockup-sandbox/.fingerprint +1 -0
- package/.local/skills/mockup-sandbox/SKILL.md +750 -0
- package/.local/skills/package-management/.fingerprint +1 -0
- package/.local/skills/package-management/SKILL.md +264 -0
- package/.local/skills/post_merge_setup/.fingerprint +1 -0
- package/.local/skills/post_merge_setup/SKILL.md +102 -0
- package/.local/skills/project_tasks/.fingerprint +1 -0
- package/.local/skills/project_tasks/SKILL.md +361 -0
- package/.local/skills/query-integration-data/.fingerprint +1 -0
- package/.local/skills/query-integration-data/SKILL.md +385 -0
- package/.local/skills/react-vite/.fingerprint +1 -0
- package/.local/skills/react-vite/SKILL.md +110 -0
- package/.local/skills/react-vite/references/frontend_general_rules.md +66 -0
- package/.local/skills/react-vite/references/seo.md +158 -0
- package/.local/skills/remove-image-background/.fingerprint +1 -0
- package/.local/skills/remove-image-background/SKILL.md +55 -0
- package/.local/skills/repl_setup/.fingerprint +1 -0
- package/.local/skills/repl_setup/SKILL.md +90 -0
- package/.local/skills/repl_setup/references/angular.md +103 -0
- package/.local/skills/repl_setup/references/react_vite.md +121 -0
- package/.local/skills/repl_setup/references/vue.md +102 -0
- package/.local/skills/replit-docs/.fingerprint +1 -0
- package/.local/skills/replit-docs/SKILL.md +81 -0
- package/.local/skills/revenuecat/.fingerprint +1 -0
- package/.local/skills/revenuecat/SKILL.md +133 -0
- package/.local/skills/revenuecat/references/initial-setup.md +566 -0
- package/.local/skills/revenuecat/references/replit-revenuecat-sdk-docs.md +279 -0
- package/.local/skills/revenuecat/references/subsequent-management.md +63 -0
- package/.local/skills/security_scan/.fingerprint +1 -0
- package/.local/skills/security_scan/SKILL.md +51 -0
- package/.local/skills/skill-authoring/.fingerprint +1 -0
- package/.local/skills/skill-authoring/SKILL.md +99 -0
- package/.local/skills/slides/.fingerprint +1 -0
- package/.local/skills/slides/SKILL.md +523 -0
- package/.local/skills/slides/references/brand_research.md +86 -0
- package/.local/skills/slides/references/export_failures.md +36 -0
- package/.local/skills/slides/references/exporting.md +49 -0
- package/.local/skills/slides/references/importing.md +40 -0
- package/.local/skills/slides/references/visual_qa.md +121 -0
- package/.local/skills/slides/templates/90s-board-deck.md +285 -0
- package/.local/skills/slides/templates/academic-lecture.md +437 -0
- package/.local/skills/slides/templates/adventure-outdoor.md +845 -0
- package/.local/skills/slides/templates/analytics-dashboard.md +407 -0
- package/.local/skills/slides/templates/annual-report-cover.md +592 -0
- package/.local/skills/slides/templates/apple-minimal.md +570 -0
- package/.local/skills/slides/templates/architecture-studio.md +339 -0
- package/.local/skills/slides/templates/arctic-expedition.md +582 -0
- package/.local/skills/slides/templates/arctic-minimal.md +364 -0
- package/.local/skills/slides/templates/art-deco.md +308 -0
- package/.local/skills/slides/templates/artisan-ceramics.md +659 -0
- package/.local/skills/slides/templates/artisan-food.md +709 -0
- package/.local/skills/slides/templates/artisanal-chalkboard.md +623 -0
- package/.local/skills/slides/templates/astronomy-log.md +562 -0
- package/.local/skills/slides/templates/aurora-expedition.md +754 -0
- package/.local/skills/slides/templates/automotive-electric.md +339 -0
- package/.local/skills/slides/templates/bauhaus-avant-garde.md +443 -0
- package/.local/skills/slides/templates/bioluminescent-sea.md +814 -0
- package/.local/skills/slides/templates/biophilic-urban.md +565 -0
- package/.local/skills/slides/templates/blackboard-chalk.md +517 -0
- package/.local/skills/slides/templates/blueprint.md +478 -0
- package/.local/skills/slides/templates/botanical-index.md +822 -0
- package/.local/skills/slides/templates/botanical-wellness.md +611 -0
- package/.local/skills/slides/templates/brand-book-page.md +466 -0
- package/.local/skills/slides/templates/brutalist-concrete.md +362 -0
- package/.local/skills/slides/templates/brutalist-studio.md +325 -0
- package/.local/skills/slides/templates/brutalist-web-punk.md +591 -0
- package/.local/skills/slides/templates/celestial-observatory.md +453 -0
- package/.local/skills/slides/templates/ceramics-artisan.md +740 -0
- package/.local/skills/slides/templates/cinema-verite.md +415 -0
- package/.local/skills/slides/templates/claymorphism.md +737 -0
- package/.local/skills/slides/templates/collage-zine.md +357 -0
- package/.local/skills/slides/templates/copper-sage.md +325 -0
- package/.local/skills/slides/templates/coral-reef.md +508 -0
- package/.local/skills/slides/templates/corporate-grid.md +331 -0
- package/.local/skills/slides/templates/corporate-memphis-flat.md +938 -0
- package/.local/skills/slides/templates/cosmos-explorer.md +998 -0
- package/.local/skills/slides/templates/cpg-coffee.md +850 -0
- package/.local/skills/slides/templates/craft-coffee-roast.md +693 -0
- package/.local/skills/slides/templates/creative-agency.md +244 -0
- package/.local/skills/slides/templates/creative-director.md +875 -0
- package/.local/skills/slides/templates/culinary-brand.md +698 -0
- package/.local/skills/slides/templates/de-stijl-construct.md +320 -0
- package/.local/skills/slides/templates/desert-dunes-photo.md +483 -0
- package/.local/skills/slides/templates/desert-mirror.md +577 -0
- package/.local/skills/slides/templates/desert-modernism.md +439 -0
- package/.local/skills/slides/templates/developer-api-docs.md +654 -0
- package/.local/skills/slides/templates/editorial-magazine.md +694 -0
- package/.local/skills/slides/templates/engineering-blueprint.md +730 -0
- package/.local/skills/slides/templates/executive-mono.md +363 -0
- package/.local/skills/slides/templates/expedition-peak.md +298 -0
- package/.local/skills/slides/templates/fashion-campaign.md +681 -0
- package/.local/skills/slides/templates/fashion-editorial.md +497 -0
- package/.local/skills/slides/templates/figma-geometric.md +420 -0
- package/.local/skills/slides/templates/film-noir.md +857 -0
- package/.local/skills/slides/templates/fitness-athletics.md +663 -0
- package/.local/skills/slides/templates/flat-vector.md +912 -0
- package/.local/skills/slides/templates/fluid-luxe.md +665 -0
- package/.local/skills/slides/templates/furniture-brand.md +505 -0
- package/.local/skills/slides/templates/gallery-modern.md +436 -0
- package/.local/skills/slides/templates/gaming-esports.md +410 -0
- package/.local/skills/slides/templates/geodesic-future.md +368 -0
- package/.local/skills/slides/templates/glass-artisan.md +666 -0
- package/.local/skills/slides/templates/glassmorphism.md +320 -0
- package/.local/skills/slides/templates/greenhouse-botanical.md +662 -0
- package/.local/skills/slides/templates/healthcare-clarity.md +468 -0
- package/.local/skills/slides/templates/holographic-drop.md +663 -0
- package/.local/skills/slides/templates/hospitality-resort.md +608 -0
- package/.local/skills/slides/templates/hypercar-launch.md +557 -0
- package/.local/skills/slides/templates/infographic-title.md +306 -0
- package/.local/skills/slides/templates/ink-wash.md +244 -0
- package/.local/skills/slides/templates/investor-memo.md +509 -0
- package/.local/skills/slides/templates/isometric-data.md +703 -0
- package/.local/skills/slides/templates/ivory-boardroom.md +439 -0
- package/.local/skills/slides/templates/japanese-minimal.md +308 -0
- package/.local/skills/slides/templates/jazz-blue-note.md +478 -0
- package/.local/skills/slides/templates/kinetic-type.md +206 -0
- package/.local/skills/slides/templates/lagoon-luxury.md +320 -0
- package/.local/skills/slides/templates/lavender-pastoral.md +577 -0
- package/.local/skills/slides/templates/linear-precise.md +460 -0
- package/.local/skills/slides/templates/lineart-sketch.md +930 -0
- package/.local/skills/slides/templates/lost-temple.md +689 -0
- package/.local/skills/slides/templates/luxury-fashion.md +269 -0
- package/.local/skills/slides/templates/luxury-watch.md +678 -0
- package/.local/skills/slides/templates/marble-elegance.md +673 -0
- package/.local/skills/slides/templates/mediterranean-travel.md +811 -0
- package/.local/skills/slides/templates/memphis-design.md +426 -0
- package/.local/skills/slides/templates/midnight-jazz.md +260 -0
- package/.local/skills/slides/templates/minimalist-poster.md +538 -0
- package/.local/skills/slides/templates/molten-craft.md +743 -0
- package/.local/skills/slides/templates/moroccan-tile.md +738 -0
- package/.local/skills/slides/templates/motorsport.md +782 -0
- package/.local/skills/slides/templates/mountain-drift.md +311 -0
- package/.local/skills/slides/templates/music-label.md +641 -0
- package/.local/skills/slides/templates/neo-tokyo.md +637 -0
- package/.local/skills/slides/templates/neobrutalism.md +334 -0
- package/.local/skills/slides/templates/newspaper-broadsheet.md +687 -0
- package/.local/skills/slides/templates/noir-fragrance.md +672 -0
- package/.local/skills/slides/templates/non-profit-impact.md +320 -0
- package/.local/skills/slides/templates/ocean-breeze.md +398 -0
- package/.local/skills/slides/templates/origami-couture.md +636 -0
- package/.local/skills/slides/templates/origami-paper.md +308 -0
- package/.local/skills/slides/templates/pastel-playground.md +1114 -0
- package/.local/skills/slides/templates/perfume-noir.md +646 -0
- package/.local/skills/slides/templates/prairie-storm.md +625 -0
- package/.local/skills/slides/templates/private-equity-dark.md +506 -0
- package/.local/skills/slides/templates/renaissance-florals.md +225 -0
- package/.local/skills/slides/templates/retro-print.md +880 -0
- package/.local/skills/slides/templates/retro-vinyl-sleeve.md +229 -0
- package/.local/skills/slides/templates/riso-zine.md +1094 -0
- package/.local/skills/slides/templates/risograph.md +1151 -0
- package/.local/skills/slides/templates/saas-product-launch.md +972 -0
- package/.local/skills/slides/templates/scandinavian.md +372 -0
- package/.local/skills/slides/templates/skater-culture.md +583 -0
- package/.local/skills/slides/templates/slate-modern.md +469 -0
- package/.local/skills/slides/templates/sneaker-drop.md +1006 -0
- package/.local/skills/slides/templates/social-campaign.md +321 -0
- package/.local/skills/slides/templates/stained-glass.md +574 -0
- package/.local/skills/slides/templates/strategy-one-pager.md +508 -0
- package/.local/skills/slides/templates/street-drop.md +677 -0
- package/.local/skills/slides/templates/street-mural.md +588 -0
- package/.local/skills/slides/templates/studio-noir.md +466 -0
- package/.local/skills/slides/templates/sustainability-esg.md +686 -0
- package/.local/skills/slides/templates/swiss-archive.md +648 -0
- package/.local/skills/slides/templates/swiss-typographic.md +364 -0
- package/.local/skills/slides/templates/tea-ceremony.md +456 -0
- package/.local/skills/slides/templates/tech-earbuds.md +870 -0
- package/.local/skills/slides/templates/terracotta-studio.md +235 -0
- package/.local/skills/slides/templates/thesis-defense.md +390 -0
- package/.local/skills/slides/templates/travel-aerial.md +648 -0
- package/.local/skills/slides/templates/treasury-policy.md +475 -0
- package/.local/skills/slides/templates/tropical-lush.md +332 -0
- package/.local/skills/slides/templates/underwater-dream.md +627 -0
- package/.local/skills/slides/templates/urban-golden.md +342 -0
- package/.local/skills/slides/templates/vintage-apothecary.md +552 -0
- package/.local/skills/slides/templates/vintage-ticket-stub.md +637 -0
- package/.local/skills/slides/templates/vinyl-crate.md +550 -0
- package/.local/skills/slides/templates/vision-editorial.md +612 -0
- package/.local/skills/slides/templates/volcanic-edge.md +347 -0
- package/.local/skills/slides/templates/watercolor-city.md +827 -0
- package/.local/skills/slides/templates/wine-spirits.md +203 -0
- package/.local/skills/slides/templates/wireframe-prototype.md +718 -0
- package/.local/skills/slides/templates/workspace-design.md +782 -0
- package/.local/skills/slides/templates/workspace-modern.md +406 -0
- package/.local/skills/slides/templates/zen-meditation.md +284 -0
- package/.local/skills/slides/templates/zen-void.md +244 -0
- package/.local/skills/stripe/.fingerprint +1 -0
- package/.local/skills/stripe/SKILL.md +455 -0
- package/.local/skills/stripe/references/code-templates.md +588 -0
- package/.local/skills/threat_modeling/.fingerprint +1 -0
- package/.local/skills/threat_modeling/SKILL.md +240 -0
- package/.local/skills/validation/.fingerprint +1 -0
- package/.local/skills/validation/SKILL.md +237 -0
- package/.local/skills/video-js/.fingerprint +1 -0
- package/.local/skills/video-js/SKILL.md +793 -0
- package/.local/skills/video-js/references/audio.md +237 -0
- package/.local/skills/video-js/references/finalize_playback.md +16 -0
- package/.local/skills/video-js/references/first_build.md +87 -0
- package/.local/skills/video-js/references/scene_selectors.md +428 -0
- package/.local/skills/web-search/.fingerprint +1 -0
- package/.local/skills/web-search/SKILL.md +110 -0
- package/.local/skills/whop/.fingerprint +1 -0
- package/.local/skills/whop/SKILL.md +104 -0
- package/.local/skills/whop/references/code-templates.md +66 -0
- package/.local/skills/whop/references/whop-api.mjs +22 -0
- package/.local/skills/whop/references/whop-mcp.mjs +40 -0
- package/.local/skills/whop/references/whopClient.ts +54 -0
- package/.local/skills/workflows/.fingerprint +1 -0
- package/.local/skills/workflows/SKILL.md +245 -0
- package/.local/state/replit/agent/.agent_state_037313043e76b5c652f276153ea014a68570e145.bin +0 -0
- package/.local/state/replit/agent/.agent_state_0f5361c2a53ab324b2a941a797f6494891be084c.bin +0 -0
- package/.local/state/replit/agent/.agent_state_4272443827dc90eac8c5b1963a34ee86da70bb99.bin +0 -0
- package/.local/state/replit/agent/.agent_state_4f14655950cbd611b228b4f0e1f664b66a56af24.bin +0 -0
- package/.local/state/replit/agent/.agent_state_ce28955a30856aa3d095b3568c322c8ec098993f.bin +0 -0
- package/.local/state/replit/agent/.agent_state_ec5347d04ebfbf6cf850fe04e15590d423e96d1d.bin +0 -0
- package/.local/state/replit/agent/.agent_state_f68f8c104d815ccc387290f0fba2c87c818d29f1.bin +0 -0
- package/.local/state/replit/agent/.agent_state_f87c1803a179510408c57c7a380c26f5c2197a30.bin +0 -0
- package/.local/state/replit/agent/.agent_state_main.bin +0 -0
- package/.local/state/replit/agent/.latest.json +1 -0
- package/.local/state/replit/agent/repl_state.bin +0 -0
- package/.local/state/scribe/scribe.db +0 -0
- package/.local/state/scribe/scribe.db-shm +0 -0
- package/.local/state/scribe/scribe.db-wal +0 -0
- package/.local/state/workflow-logs/2tfQP52ibxJTy4lpZ7_JX/start_application.shell.exec.0 +27 -0
- package/.local/state/workflow-logs/6QjtmQThaHrR_QHf4v8HA/validation.external.managed.0 +31 -0
- package/.local/state/workflow-logs/6QjtmQThaHrR_QHf4v8HA/validation.json +1 -0
- package/.local/state/workflow-logs/85n-z_SHy4JSGaUeJIcxy/start_application.shell.exec.0 +18 -0
- package/.local/state/workflow-logs/GIL2Ql5124lrEqGrfRO4k/start_application.shell.exec.0 +222 -0
- package/.local/state/workflow-logs/LiH2MjG_9FwFummNHhDtO/validation.external.managed.0 +45 -0
- package/.local/state/workflow-logs/LiH2MjG_9FwFummNHhDtO/validation.json +1 -0
- package/.local/state/workflow-logs/OKp1t-fEO5U_zQi1SKOQ-/start_application.shell.exec.0 +10 -0
- package/.local/state/workflow-logs/Tpp7d6Hu6CO1NKGo_eAi7/validation.external.managed.0 +43 -0
- package/.local/state/workflow-logs/Tpp7d6Hu6CO1NKGo_eAi7/validation.json +1 -0
- package/.local/state/workflow-logs/UDYycRqPV-N4B7whZP-yX/start_application.shell.exec.0 +252 -0
- package/.local/state/workflow-logs/V8Anmvz-HuvAztflZ8yCo/start_application.shell.exec.0 +87 -0
- package/.local/state/workflow-logs/a5fMnjr9tCwoaFY93pYuN/start_application.shell.exec.0 +2519 -0
- package/.local/state/workflow-logs/ggFzYcdHfIlW0owP2pb0U/start_application.shell.exec.0 +28 -0
- package/.local/state/workflow-logs/hIHNKfUtPX3jZs8qXw_Vt/validation.external.managed.0 +41 -0
- package/.local/state/workflow-logs/hIHNKfUtPX3jZs8qXw_Vt/validation.json +1 -0
- package/.local/state/workflow-logs/nbLvtuGJXB0wPmnruB3BE/start_application.shell.exec.0 +199 -0
- package/.local/state/workflow-logs/uDhN6S0ypUEh0MphXaFGY/start_application.shell.exec.0 +73 -0
- package/.local/state/workflow-logs/xZqU5CdTivcY6KEDEcVmD/start_application.shell.exec.0 +17 -0
- package/.local/tasks/breadcrumb-component.md +89 -0
- package/.local/tasks/calendar-component.md +93 -0
- package/.local/tasks/invoicing-design-system-app.md +39 -0
- package/.local/tasks/task-1.md +42 -0
- package/.local/tasks/task-7.md +92 -0
- package/.local/tasks/task-8.md +96 -0
- package/.replit +34 -0
- package/.upm/store.json +1 -0
- package/README.md +121 -0
- package/app/dashboard/page.tsx +10 -0
- package/app/design-system/page.tsx +802 -0
- package/app/invoices/page.tsx +10 -0
- package/app/layout.tsx +28 -0
- package/app/login/page.tsx +5 -0
- package/app/page.tsx +93 -0
- package/app/signup/page.tsx +5 -0
- package/attached_assets/Colors_1779781016394.png +0 -0
- package/attached_assets/Navy_1779781016404.png +0 -0
- package/attached_assets/Orange_1779781016405.png +0 -0
- package/attached_assets/Screenshot_2026-05-26_at_1.14.29_PM_1779781472515.png +0 -0
- package/attached_assets/Screenshot_2026-05-26_at_11.28.20_AM_1779775171071.png +0 -0
- package/attached_assets/Screenshot_2026-05-26_at_2.04.42_PM_1779784485318.png +0 -0
- package/attached_assets/Typography_1779781016406.png +0 -0
- package/design-system/components/avatar.tsx +46 -0
- package/design-system/components/badge.tsx +34 -0
- package/design-system/components/breadcrumb.tsx +149 -0
- package/design-system/components/button.tsx +57 -0
- package/design-system/components/calendar.tsx +77 -0
- package/design-system/components/card.tsx +62 -0
- package/design-system/components/checkbox.tsx +27 -0
- package/design-system/components/date-picker.tsx +153 -0
- package/design-system/components/dialog.tsx +106 -0
- package/design-system/components/dropdown-menu.tsx +88 -0
- package/design-system/components/form-field.tsx +78 -0
- package/design-system/components/input.tsx +25 -0
- package/design-system/components/label.tsx +25 -0
- package/design-system/components/popover.tsx +30 -0
- package/design-system/components/radio-group.tsx +35 -0
- package/design-system/components/select.tsx +84 -0
- package/design-system/components/separator.tsx +24 -0
- package/design-system/components/switch.tsx +28 -0
- package/design-system/components/table.tsx +80 -0
- package/design-system/components/tabs.tsx +54 -0
- package/design-system/components/textarea.tsx +25 -0
- package/design-system/components/toast.tsx +118 -0
- package/design-system/components/toaster.tsx +38 -0
- package/design-system/components/tooltip.tsx +27 -0
- package/design-system/hooks/index.ts +2 -0
- package/design-system/hooks/use-media-query.ts +27 -0
- package/design-system/hooks/use-toast.ts +91 -0
- package/design-system/index.ts +36 -0
- package/design-system/lib/cn.ts +6 -0
- package/design-system/styles.css +142 -0
- package/design-system/tokens/tokens.css +149 -0
- package/design-system/tokens/tokens.ts +190 -0
- package/next.config.mjs +6 -0
- package/package.json +46 -0
- package/postcss.config.mjs +6 -0
- package/screens/_shared/app-shell.tsx +145 -0
- package/screens/auth/auth-screen.tsx +156 -0
- package/screens/dashboard/dashboard-screen.tsx +207 -0
- package/screens/index.ts +17 -0
- package/screens/invoices/invoices-screen.tsx +317 -0
- package/tailwind.config.ts +110 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
# Stripe Code Templates
|
|
2
|
+
|
|
3
|
+
## Code Files
|
|
4
|
+
|
|
5
|
+
Filename: seed-products.ts (in the scripts directory)
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { getUncachableStripeClient } from './stripeClient';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Script to create products and prices in Stripe
|
|
12
|
+
*
|
|
13
|
+
* This script is idempotent - it checks if products exist before creating them.
|
|
14
|
+
* You can run it multiple times safely.
|
|
15
|
+
*
|
|
16
|
+
* Modify this script to add the products and prices you need.
|
|
17
|
+
*
|
|
18
|
+
* Run with: npx tsx seed-products.ts
|
|
19
|
+
* Or after compiling: node seed-products.js
|
|
20
|
+
*/
|
|
21
|
+
async function createProducts() {
|
|
22
|
+
try {
|
|
23
|
+
const stripe = await getUncachableStripeClient();
|
|
24
|
+
|
|
25
|
+
console.log('Creating products and prices in Stripe...');
|
|
26
|
+
|
|
27
|
+
// Check if Pro Plan product already exists
|
|
28
|
+
const existingProducts = await stripe.products.search({
|
|
29
|
+
query: "name:'Pro Plan' AND active:'true'"
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (existingProducts.data.length > 0) {
|
|
33
|
+
console.log('Pro Plan product already exists. Skipping creation.');
|
|
34
|
+
console.log(`Existing product ID: ${existingProducts.data[0].id}`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Create a Pro Plan product
|
|
39
|
+
const proProduct = await stripe.products.create({
|
|
40
|
+
name: 'Pro Plan',
|
|
41
|
+
description: 'Professional subscription with advanced features',
|
|
42
|
+
});
|
|
43
|
+
console.log(`Created product: ${proProduct.name} (${proProduct.id})`);
|
|
44
|
+
|
|
45
|
+
// Create a monthly price for the Pro Plan
|
|
46
|
+
const proMonthlyPrice = await stripe.prices.create({
|
|
47
|
+
product: proProduct.id,
|
|
48
|
+
unit_amount: 2900, // $29.00
|
|
49
|
+
currency: 'usd',
|
|
50
|
+
recurring: {
|
|
51
|
+
interval: 'month',
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
console.log(`Created monthly price: $29.00/month (${proMonthlyPrice.id})`);
|
|
55
|
+
|
|
56
|
+
// Create a yearly price for the Pro Plan
|
|
57
|
+
const proYearlyPrice = await stripe.prices.create({
|
|
58
|
+
product: proProduct.id,
|
|
59
|
+
unit_amount: 29000, // $290.00 (save ~17%)
|
|
60
|
+
currency: 'usd',
|
|
61
|
+
recurring: {
|
|
62
|
+
interval: 'year',
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
console.log(`Created yearly price: $290.00/year (${proYearlyPrice.id})`);
|
|
66
|
+
|
|
67
|
+
console.log('✓ Products and prices created successfully!');
|
|
68
|
+
console.log('Webhooks will sync this data to your database automatically.');
|
|
69
|
+
|
|
70
|
+
} catch (error: any) {
|
|
71
|
+
console.error('Error creating products:', error.message);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Run the function
|
|
77
|
+
createProducts();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Filename: stripeClient.ts (in the API server directory; also copy to the scripts directory)
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import Stripe from 'stripe';
|
|
84
|
+
import { StripeSync } from 'stripe-replit-sync';
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Fetches Stripe credentials from the Replit connection API.
|
|
88
|
+
* Not cached -- tokens can rotate, so fetch fresh each time.
|
|
89
|
+
*/
|
|
90
|
+
async function getStripeCredentials(): Promise<{ secretKey: string; webhookSecret?: string }> {
|
|
91
|
+
const hostname = process.env.REPLIT_CONNECTORS_HOSTNAME;
|
|
92
|
+
const xReplitToken = process.env.REPL_IDENTITY
|
|
93
|
+
? "repl " + process.env.REPL_IDENTITY
|
|
94
|
+
: process.env.WEB_REPL_RENEWAL
|
|
95
|
+
? "depl " + process.env.WEB_REPL_RENEWAL
|
|
96
|
+
: null;
|
|
97
|
+
|
|
98
|
+
if (!hostname || !xReplitToken) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
'Missing Replit environment variables. ' +
|
|
101
|
+
'Ensure the Stripe integration is connected via the Integrations tab.'
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const resp = await fetch(
|
|
106
|
+
`https://${hostname}/api/v2/connection?include_secrets=true&connector_names=stripe`,
|
|
107
|
+
{
|
|
108
|
+
headers: { Accept: "application/json", X_REPLIT_TOKEN: xReplitToken },
|
|
109
|
+
signal: AbortSignal.timeout(10_000),
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
if (!resp.ok) {
|
|
114
|
+
throw new Error(`Failed to fetch Stripe credentials: ${resp.status} ${resp.statusText}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const data = await resp.json();
|
|
118
|
+
const settings = data.items?.[0]?.settings;
|
|
119
|
+
|
|
120
|
+
if (!settings?.secret_key) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
'Stripe integration not connected or missing secret key. ' +
|
|
123
|
+
'Connect Stripe via the Integrations tab first.'
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
secretKey: settings.secret_key,
|
|
129
|
+
webhookSecret: settings.webhook_secret,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Returns a fresh authenticated Stripe client.
|
|
135
|
+
* Not cached -- fetches credentials on every call so rotated keys are picked up.
|
|
136
|
+
*/
|
|
137
|
+
export async function getUncachableStripeClient(): Promise<Stripe> {
|
|
138
|
+
const { secretKey } = await getStripeCredentials();
|
|
139
|
+
return new Stripe(secretKey);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Returns a fresh StripeSync instance for webhook processing and data sync.
|
|
144
|
+
* Not cached -- fetches credentials on every call so rotated keys are picked up.
|
|
145
|
+
*/
|
|
146
|
+
export async function getStripeSync(): Promise<StripeSync> {
|
|
147
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
148
|
+
if (!databaseUrl) {
|
|
149
|
+
throw new Error('DATABASE_URL environment variable is required');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const { secretKey, webhookSecret } = await getStripeCredentials();
|
|
153
|
+
return new StripeSync({
|
|
154
|
+
poolConfig: { connectionString: databaseUrl },
|
|
155
|
+
stripeSecretKey: secretKey,
|
|
156
|
+
stripeWebhookSecret: webhookSecret ?? '',
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Filename: webhookHandlers.ts (in the API server directory)
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
import { getStripeSync } from './stripeClient';
|
|
165
|
+
|
|
166
|
+
export class WebhookHandlers {
|
|
167
|
+
static async processWebhook(payload: Buffer, signature: string): Promise<void> {
|
|
168
|
+
// Validate payload is a Buffer
|
|
169
|
+
if (!Buffer.isBuffer(payload)) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
'STRIPE WEBHOOK ERROR: Payload must be a Buffer. ' +
|
|
172
|
+
'Received type: ' + typeof payload + '. ' +
|
|
173
|
+
'This usually means express.json() parsed the body before reaching this handler. ' +
|
|
174
|
+
'FIX: Ensure webhook route is registered BEFORE app.use(express.json()).'
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const sync = await getStripeSync();
|
|
179
|
+
await sync.processWebhook(payload, signature);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Filename: stripeService.ts (in the API server directory)
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { storage } from './storage';
|
|
188
|
+
import { getUncachableStripeClient } from './stripeClient';
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* StripeService: Handles direct Stripe API operations
|
|
192
|
+
* Pattern: Use Stripe client for write operations, storage for read operations
|
|
193
|
+
*/
|
|
194
|
+
export class StripeService {
|
|
195
|
+
// Create customer in Stripe
|
|
196
|
+
async createCustomer(email: string, userId: string) {
|
|
197
|
+
const stripe = await getUncachableStripeClient();
|
|
198
|
+
return await stripe.customers.create({
|
|
199
|
+
email,
|
|
200
|
+
metadata: { userId },
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Create checkout session
|
|
205
|
+
async createCheckoutSession(customerId: string, priceId: string, successUrl: string, cancelUrl: string) {
|
|
206
|
+
const stripe = await getUncachableStripeClient();
|
|
207
|
+
return await stripe.checkout.sessions.create({
|
|
208
|
+
customer: customerId,
|
|
209
|
+
payment_method_types: ['card'],
|
|
210
|
+
line_items: [{ price: priceId, quantity: 1 }],
|
|
211
|
+
mode: 'subscription',
|
|
212
|
+
success_url: successUrl,
|
|
213
|
+
cancel_url: cancelUrl,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Create customer portal session
|
|
218
|
+
async createCustomerPortalSession(customerId: string, returnUrl: string) {
|
|
219
|
+
const stripe = await getUncachableStripeClient();
|
|
220
|
+
return await stripe.billingPortal.sessions.create({
|
|
221
|
+
customer: customerId,
|
|
222
|
+
return_url: returnUrl,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Read operations - delegate to storage (queries PostgreSQL)
|
|
227
|
+
async getProduct(productId: string) {
|
|
228
|
+
return await storage.getProduct(productId);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async getSubscription(subscriptionId: string) {
|
|
232
|
+
return await storage.getSubscription(subscriptionId);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export const stripeService = new StripeService();
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Filename: storage.ts (in the API server directory)
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
import { users } from '@shared/schema';
|
|
243
|
+
import { eq, sql } from 'drizzle-orm';
|
|
244
|
+
import { db } from './db';
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Storage: Query Stripe data from PostgreSQL
|
|
248
|
+
* Pattern: Simple SQL queries to stripe.* tables
|
|
249
|
+
*/
|
|
250
|
+
export class Storage {
|
|
251
|
+
// Query Stripe data from stripe.products table
|
|
252
|
+
async getProduct(productId: string) {
|
|
253
|
+
const result = await db.execute(
|
|
254
|
+
sql`SELECT * FROM stripe.products WHERE id = ${productId}`
|
|
255
|
+
);
|
|
256
|
+
return result.rows[0] || null;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async listProducts(active = true, limit = 20, offset = 0) {
|
|
260
|
+
const result = await db.execute(
|
|
261
|
+
sql`SELECT * FROM stripe.products WHERE active = ${active} LIMIT ${limit} OFFSET ${offset}`
|
|
262
|
+
);
|
|
263
|
+
return result.rows;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Get products with their prices (with proper pagination)
|
|
267
|
+
// This paginates on products first, then joins only active prices
|
|
268
|
+
async listProductsWithPrices(active = true, limit = 20, offset = 0) {
|
|
269
|
+
const result = await db.execute(
|
|
270
|
+
sql`
|
|
271
|
+
WITH paginated_products AS (
|
|
272
|
+
SELECT id, name, description, metadata, active
|
|
273
|
+
FROM stripe.products
|
|
274
|
+
WHERE active = ${active}
|
|
275
|
+
ORDER BY id
|
|
276
|
+
LIMIT ${limit} OFFSET ${offset}
|
|
277
|
+
)
|
|
278
|
+
SELECT
|
|
279
|
+
p.id as product_id,
|
|
280
|
+
p.name as product_name,
|
|
281
|
+
p.description as product_description,
|
|
282
|
+
p.active as product_active,
|
|
283
|
+
p.metadata as product_metadata,
|
|
284
|
+
pr.id as price_id,
|
|
285
|
+
pr.unit_amount,
|
|
286
|
+
pr.currency,
|
|
287
|
+
pr.recurring,
|
|
288
|
+
pr.active as price_active,
|
|
289
|
+
pr.metadata as price_metadata
|
|
290
|
+
FROM paginated_products p
|
|
291
|
+
LEFT JOIN stripe.prices pr ON pr.product = p.id AND pr.active = true
|
|
292
|
+
ORDER BY p.id, pr.unit_amount
|
|
293
|
+
`
|
|
294
|
+
);
|
|
295
|
+
return result.rows;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Query Stripe data from stripe.prices table
|
|
299
|
+
async getPrice(priceId: string) {
|
|
300
|
+
const result = await db.execute(
|
|
301
|
+
sql`SELECT * FROM stripe.prices WHERE id = ${priceId}`
|
|
302
|
+
);
|
|
303
|
+
return result.rows[0] || null;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async listPrices(active = true, limit = 20, offset = 0) {
|
|
307
|
+
const result = await db.execute(
|
|
308
|
+
sql`SELECT * FROM stripe.prices WHERE active = ${active} LIMIT ${limit} OFFSET ${offset}`
|
|
309
|
+
);
|
|
310
|
+
return result.rows;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Get prices for a specific product
|
|
314
|
+
// Note: productId should be the product's id from stripe.products table
|
|
315
|
+
async getPricesForProduct(productId: string) {
|
|
316
|
+
const result = await db.execute(
|
|
317
|
+
sql`SELECT * FROM stripe.prices WHERE product = ${productId} AND active = true`
|
|
318
|
+
);
|
|
319
|
+
return result.rows;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Query subscription
|
|
323
|
+
async getSubscription(subscriptionId: string) {
|
|
324
|
+
const result = await db.execute(
|
|
325
|
+
sql`SELECT * FROM stripe.subscriptions WHERE id = ${subscriptionId}`
|
|
326
|
+
);
|
|
327
|
+
return result.rows[0] || null;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// User operations
|
|
331
|
+
async getUser(id: string) {
|
|
332
|
+
const [user] = await db.select().from(users).where(eq(users.id, id));
|
|
333
|
+
return user;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
async updateUserStripeInfo(userId: string, stripeInfo: {
|
|
337
|
+
stripeCustomerId?: string;
|
|
338
|
+
stripeSubscriptionId?: string;
|
|
339
|
+
}) {
|
|
340
|
+
const [user] = await db.update(users).set(stripeInfo).where(eq(users.id, userId)).returning();
|
|
341
|
+
return user;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export const storage = new Storage();
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Filename: routes/index.ts (in the API server directory)
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
import { Router, type IRouter } from 'express';
|
|
352
|
+
import stripeRouter from './stripe';
|
|
353
|
+
|
|
354
|
+
const router: IRouter = Router();
|
|
355
|
+
|
|
356
|
+
router.use(stripeRouter);
|
|
357
|
+
|
|
358
|
+
export default router;
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Filename: routes/stripe.ts (in the API server directory)
|
|
362
|
+
|
|
363
|
+
```ts
|
|
364
|
+
import { Router, type IRouter } from 'express';
|
|
365
|
+
import { storage } from '../storage';
|
|
366
|
+
import { stripeService } from '../stripeService';
|
|
367
|
+
|
|
368
|
+
const router: IRouter = Router();
|
|
369
|
+
|
|
370
|
+
// Get user subscription
|
|
371
|
+
router.get('/subscription', async (req: any, res) => {
|
|
372
|
+
const user = await storage.getUser(req.user.id);
|
|
373
|
+
if (!user?.stripeSubscriptionId) {
|
|
374
|
+
return res.json({ subscription: null });
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const subscription = await storage.getSubscription(user.stripeSubscriptionId);
|
|
378
|
+
res.json({ subscription });
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
// Create checkout session
|
|
382
|
+
router.post('/checkout', async (req: any, res) => {
|
|
383
|
+
const user = await storage.getUser(req.user.id);
|
|
384
|
+
const { priceId } = req.body;
|
|
385
|
+
|
|
386
|
+
// Create or get customer
|
|
387
|
+
let customerId = user.stripeCustomerId;
|
|
388
|
+
if (!customerId) {
|
|
389
|
+
const customer = await stripeService.createCustomer(user.email, user.id);
|
|
390
|
+
await storage.updateUserStripeInfo(user.id, { stripeCustomerId: customer.id });
|
|
391
|
+
customerId = customer.id;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Create checkout session
|
|
395
|
+
const session = await stripeService.createCheckoutSession(
|
|
396
|
+
customerId,
|
|
397
|
+
priceId,
|
|
398
|
+
`${req.protocol}://${req.get('host')}/checkout/success`,
|
|
399
|
+
`${req.protocol}://${req.get('host')}/checkout/cancel`
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
res.json({ url: session.url });
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// List products
|
|
406
|
+
router.get('/products', async (_req, res) => {
|
|
407
|
+
const products = await storage.listProducts();
|
|
408
|
+
res.json({ data: products });
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// List products with prices (joined)
|
|
412
|
+
router.get('/products-with-prices', async (_req, res) => {
|
|
413
|
+
const rows = await storage.listProductsWithPrices();
|
|
414
|
+
|
|
415
|
+
// Group prices by product
|
|
416
|
+
const productsMap = new Map();
|
|
417
|
+
for (const row of rows) {
|
|
418
|
+
if (!productsMap.has(row.product_id)) {
|
|
419
|
+
productsMap.set(row.product_id, {
|
|
420
|
+
id: row.product_id,
|
|
421
|
+
name: row.product_name,
|
|
422
|
+
description: row.product_description,
|
|
423
|
+
active: row.product_active,
|
|
424
|
+
prices: []
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
if (row.price_id) {
|
|
428
|
+
productsMap.get(row.product_id).prices.push({
|
|
429
|
+
id: row.price_id,
|
|
430
|
+
unit_amount: row.unit_amount,
|
|
431
|
+
currency: row.currency,
|
|
432
|
+
recurring: row.recurring,
|
|
433
|
+
active: row.price_active,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
res.json({ data: Array.from(productsMap.values()) });
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
// List prices
|
|
442
|
+
router.get('/prices', async (_req, res) => {
|
|
443
|
+
const prices = await storage.listPrices();
|
|
444
|
+
res.json({ data: prices });
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
// Get prices for a specific product
|
|
448
|
+
router.get('/products/:productId/prices', async (req, res) => {
|
|
449
|
+
const { productId } = req.params;
|
|
450
|
+
|
|
451
|
+
// Validate product exists (productId should be the id from stripe.products)
|
|
452
|
+
const product = await storage.getProduct(productId);
|
|
453
|
+
if (!product) {
|
|
454
|
+
return res.status(404).json({ error: 'Product not found' });
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
const prices = await storage.getPricesForProduct(productId);
|
|
458
|
+
res.json({ data: prices });
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
export default router;
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
Filename: app.ts (in the API server directory)
|
|
465
|
+
|
|
466
|
+
```ts
|
|
467
|
+
import express, { type Express } from "express";
|
|
468
|
+
import cors from "cors";
|
|
469
|
+
import router from "./routes";
|
|
470
|
+
import { WebhookHandlers } from "./webhookHandlers";
|
|
471
|
+
|
|
472
|
+
const app: Express = express();
|
|
473
|
+
|
|
474
|
+
// Register Stripe webhook route BEFORE other middleware
|
|
475
|
+
// This is critical - webhook needs raw Buffer, not parsed JSON
|
|
476
|
+
app.post(
|
|
477
|
+
'/api/stripe/webhook',
|
|
478
|
+
express.raw({ type: 'application/json' }),
|
|
479
|
+
async (req, res) => {
|
|
480
|
+
const signature = req.headers['stripe-signature'];
|
|
481
|
+
|
|
482
|
+
if (!signature) {
|
|
483
|
+
return res.status(400).json({ error: 'Missing stripe-signature' });
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
try {
|
|
487
|
+
const sig = Array.isArray(signature) ? signature[0] : signature;
|
|
488
|
+
|
|
489
|
+
// Validate that req.body is a Buffer (not parsed JSON)
|
|
490
|
+
if (!Buffer.isBuffer(req.body)) {
|
|
491
|
+
const errorMsg = 'STRIPE WEBHOOK ERROR: req.body is not a Buffer. ' +
|
|
492
|
+
'This means express.json() ran before this webhook route. ' +
|
|
493
|
+
'FIX: Move this webhook route registration BEFORE app.use(express.json()) in your code.';
|
|
494
|
+
console.error(errorMsg);
|
|
495
|
+
return res.status(500).json({ error: 'Webhook processing error' });
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
await WebhookHandlers.processWebhook(req.body as Buffer, sig);
|
|
499
|
+
|
|
500
|
+
res.status(200).json({ received: true });
|
|
501
|
+
} catch (error: any) {
|
|
502
|
+
console.error('Webhook error:', error.message);
|
|
503
|
+
|
|
504
|
+
// Log helpful error message if it's the common "payload must be Buffer" error
|
|
505
|
+
if (error.message && error.message.includes('payload must be provided as a string or a Buffer')) {
|
|
506
|
+
const helpfulMsg = 'STRIPE WEBHOOK ERROR: Payload is not a Buffer. ' +
|
|
507
|
+
'This usually means express.json() parsed the body before the webhook handler. ' +
|
|
508
|
+
'FIX: Ensure the webhook route is registered BEFORE app.use(express.json()).';
|
|
509
|
+
console.error(helpfulMsg);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
res.status(400).json({ error: 'Webhook processing error' });
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
// Apply middleware after webhook route
|
|
518
|
+
app.use(cors());
|
|
519
|
+
app.use(express.json());
|
|
520
|
+
app.use(express.urlencoded({ extended: true }));
|
|
521
|
+
|
|
522
|
+
// Mount routes under /api prefix
|
|
523
|
+
app.use("/api", router);
|
|
524
|
+
|
|
525
|
+
export default app;
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
Filename: index.ts (in the API server directory)
|
|
529
|
+
|
|
530
|
+
```ts
|
|
531
|
+
import { runMigrations } from 'stripe-replit-sync';
|
|
532
|
+
import { getStripeSync } from "./stripeClient";
|
|
533
|
+
import app from "./app";
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Initialize Stripe schema and sync data on startup
|
|
537
|
+
*/
|
|
538
|
+
async function initStripe() {
|
|
539
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
540
|
+
|
|
541
|
+
if (!databaseUrl) {
|
|
542
|
+
throw new Error(
|
|
543
|
+
'DATABASE_URL environment variable is required for Stripe integration. ' +
|
|
544
|
+
'Please create a PostgreSQL database first.'
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
try {
|
|
549
|
+
console.log('Initializing Stripe schema...');
|
|
550
|
+
await runMigrations({
|
|
551
|
+
databaseUrl,
|
|
552
|
+
schema: 'stripe'
|
|
553
|
+
});
|
|
554
|
+
console.log('Stripe schema ready');
|
|
555
|
+
|
|
556
|
+
const stripeSync = await getStripeSync();
|
|
557
|
+
|
|
558
|
+
console.log('Setting up managed webhook...');
|
|
559
|
+
const webhookBaseUrl = `https://${process.env.REPLIT_DOMAINS?.split(',')[0]}`;
|
|
560
|
+
const webhookResult = await stripeSync.findOrCreateManagedWebhook(
|
|
561
|
+
`${webhookBaseUrl}/api/stripe/webhook`);
|
|
562
|
+
console.log('Webhook configured:', JSON.stringify(webhookResult?.webhook?.url || 'setup complete'));
|
|
563
|
+
|
|
564
|
+
console.log('Syncing Stripe data...');
|
|
565
|
+
stripeSync.syncBackfill()
|
|
566
|
+
.then(() => {
|
|
567
|
+
console.log('Stripe data synced');
|
|
568
|
+
})
|
|
569
|
+
.catch((err) => {
|
|
570
|
+
console.error('Error syncing Stripe data:', err);
|
|
571
|
+
});
|
|
572
|
+
} catch (error) {
|
|
573
|
+
console.error('Failed to initialize Stripe:', error);
|
|
574
|
+
throw error;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const port = Number(process.env.PORT);
|
|
579
|
+
if (!port) {
|
|
580
|
+
throw new Error('PORT environment variable is required');
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
await initStripe();
|
|
584
|
+
|
|
585
|
+
app.listen(port, () => {
|
|
586
|
+
console.log(`Server running on port ${port}`);
|
|
587
|
+
});
|
|
588
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4456810280b11256ea75832079831f77
|