chore: merge remote-tracking branch 'origin/main' into dev
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,17 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
const footerColumns: any[] = [
|
||||
type FooterLink = {
|
||||
label: string;
|
||||
href: string;
|
||||
};
|
||||
|
||||
type FooterColumn = {
|
||||
title: string;
|
||||
links: FooterLink[];
|
||||
};
|
||||
|
||||
const footerColumns: FooterColumn[] = [
|
||||
// {
|
||||
// title: "PRODUCT",
|
||||
// links: [
|
||||
@@ -32,149 +42,144 @@ const footerColumns: any[] = [
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<>
|
||||
<footer
|
||||
style={{
|
||||
width: "calc(100% + var(--page-pad) * 2)",
|
||||
marginLeft: "calc(var(--page-pad) * -1)",
|
||||
paddingLeft: "var(--page-pad)",
|
||||
paddingRight: "var(--page-pad)",
|
||||
}}
|
||||
className="mt-[50px] relative bg-[#000000] border-t border-[#292929] overflow-hidden text-[#FFFFFF99] grid"
|
||||
>
|
||||
<div className="col-start-1 row-start-1 flex flex-col z-10 w-full relative">
|
||||
<div className="relative w-full flex flex-col justify-between min-h-[400px]">
|
||||
<div className="absolute bottom-0 left-0 right-0 h-[300px] sm:h-[550px] lg:h-[400px] pointer-events-none opacity-70 bg-[url('/images/footer/footerbg.svg')] bg-cover sm:bg-contain bg-bottom bg-no-repeat z-0" />
|
||||
<footer
|
||||
style={{
|
||||
width: "calc(100% + var(--page-pad) * 2)",
|
||||
marginLeft: "calc(var(--page-pad) * -1)",
|
||||
paddingLeft: "var(--page-pad)",
|
||||
paddingRight: "var(--page-pad)",
|
||||
}}
|
||||
className="mt-[50px] relative bg-[#000000] border-t border-[#292929] overflow-hidden text-[#FFFFFF99] grid"
|
||||
>
|
||||
<div className="col-start-1 row-start-1 flex flex-col z-10 w-full relative">
|
||||
<div className="relative w-full flex flex-col justify-between min-h-[400px]">
|
||||
<div className="absolute bottom-0 left-0 right-0 h-[300px] sm:h-[550px] lg:h-[400px] pointer-events-none opacity-70 bg-[url('/images/footer/footerbg.svg')] bg-cover sm:bg-contain bg-bottom bg-no-repeat z-0" />
|
||||
|
||||
<div className="flex flex-col lg:flex-row justify-between pt-[32px] md:pt-24 pb-32 md:pb-16 pl-4.5 xl:pl-[90px] pr-4 sm:pr-8 lg:pr-12 gap-10 md:gap-16 lg:gap-8 relative z-10">
|
||||
{/* Left Side: Logo and Description */}
|
||||
<div className="flex flex-col max-w-sm">
|
||||
<Link href="/" className="mb-3 md:mb-6 inline-block">
|
||||
<Image
|
||||
src="/images/navbar/autumnlogo.svg"
|
||||
width={195}
|
||||
height={48}
|
||||
alt="Autumn"
|
||||
className="brightness-0 invert w-[130px] h-[32px] md:w-[195px] md:h-[48px]"
|
||||
/>
|
||||
</Link>
|
||||
<p className="text-[14px] md:text-[16px] leading-[18px] md:leading-[20px] tracking-[-2%] text-[#FFFFFF99] font-light">
|
||||
Autumn is drop-in billing for AI companies.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col lg:flex-row justify-between pt-[32px] md:pt-24 pb-32 md:pb-16 pl-4.5 xl:pl-[90px] pr-4 sm:pr-8 lg:pr-12 gap-10 md:gap-16 lg:gap-8 relative z-10">
|
||||
<div className="flex flex-col max-w-sm">
|
||||
<Link href="/" className="mb-3 md:mb-6 inline-block">
|
||||
<Image
|
||||
src="/images/navbar/autumnlogo.svg"
|
||||
width={195}
|
||||
height={48}
|
||||
alt="Autumn"
|
||||
className="brightness-0 invert w-[130px] h-[32px] md:w-[195px] md:h-[48px]"
|
||||
/>
|
||||
</Link>
|
||||
<p className="text-[14px] md:text-[16px] leading-[18px] md:leading-[20px] tracking-[-2%] text-[#FFFFFF99] font-light">
|
||||
Autumn is drop-in billing for AI companies.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Right Side: Columns */}
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 gap-12 sm:gap-16 lg:gap-24">
|
||||
{footerColumns.map((col, index) => (
|
||||
<div key={index} className="flex flex-col">
|
||||
<h3 className="flex items-center gap-2 text-white font-mono text-[14px] uppercase tracking-[-1%] mb-6">
|
||||
<div className="w-[8px] h-[8px] bg-[#FFFFFF99]"></div>
|
||||
{col.title}
|
||||
</h3>
|
||||
<ul className="flex flex-col gap-1">
|
||||
{col.links.map((link, i) => (
|
||||
<li key={i} className="group/strip">
|
||||
<Link
|
||||
href={link.href}
|
||||
target="_blank"
|
||||
className="group/strip flex items-center gap-3 text-[14px] font-mono uppercase tracking-[-1%] transition-colors duration-300"
|
||||
>
|
||||
<span className="w-1 h-1 bg-[#FFFFFF99] group-hover/strip:bg-white group-active/strip:bg-white transition-colors duration-300 shrink-0"></span>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 gap-12 sm:gap-16 lg:gap-24">
|
||||
{footerColumns.map((col) => (
|
||||
<div key={col.title} className="flex flex-col">
|
||||
<h3 className="flex items-center gap-2 text-white font-mono text-[14px] uppercase tracking-[-1%] mb-6">
|
||||
<div className="w-[8px] h-[8px] bg-[#FFFFFF99]"></div>
|
||||
{col.title}
|
||||
</h3>
|
||||
<ul className="flex flex-col gap-1">
|
||||
{col.links.map((link) => (
|
||||
<li key={link.href} className="group/strip">
|
||||
<Link
|
||||
href={link.href}
|
||||
target="_blank"
|
||||
className="group/strip flex items-center gap-3 text-[14px] font-mono uppercase tracking-[-1%] transition-colors duration-300"
|
||||
>
|
||||
<span className="w-1 h-1 bg-[#FFFFFF99] group-hover/strip:bg-white group-active/strip:bg-white transition-colors duration-300 shrink-0" />
|
||||
|
||||
<span className="relative">
|
||||
<span className="text-[#FFFFFF99]">
|
||||
<span className="relative">
|
||||
<span className="text-[#FFFFFF99]">
|
||||
{link.label}
|
||||
</span>
|
||||
<span
|
||||
className="absolute inset-y-0 left-0 w-0 group-hover/strip:w-full group-active/strip:w-full overflow-hidden transition-all duration-300 ease-in-out bg-white text-black font-normal pointer-events-none flex items-center"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<span className="whitespace-nowrap">
|
||||
{link.label}
|
||||
</span>
|
||||
<span
|
||||
className="absolute inset-y-0 left-0 w-0 group-hover/strip:w-full group-active/strip:w-full overflow-hidden transition-all duration-300 ease-in-out bg-white text-black font-normal pointer-events-none flex items-center"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<span className="whitespace-nowrap">
|
||||
{link.label}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="relative block z-10 bg-black/40 backdrop-blur-md border-y border-[#292929]"
|
||||
style={{
|
||||
width: "calc(100% + var(--page-pad) * 2)",
|
||||
marginLeft: "calc(var(--page-pad) * -1)",
|
||||
paddingLeft: "var(--page-pad)",
|
||||
paddingRight: "var(--page-pad)",
|
||||
}}
|
||||
>
|
||||
<div className="max-w-[1400px] mx-auto flex flex-col md:flex-row justify-between items-stretch h-auto md:h-14 font-mono text-[10px] sm:text-[11px] tracking-[0.2em]">
|
||||
{/* Social Left Box */}
|
||||
<div className="flex flex-row md:flex-row border-b md:border-b-0 border-[#292929] w-full md:w-auto">
|
||||
<div className="px-4 sm:px-8 py-4.5 md:py-0 border-r border-[#292929] tracking-[-2%] flex items-center justify-center md:justify-start text-[12px] md:text-[14px]">
|
||||
SOCIAL
|
||||
</div>
|
||||
<div className="px-6 sm:px-8 py-4 md:py-0 flex items-center justify-center md:justify-start gap-3 sm:gap-4 md:border-r border-[#292929]">
|
||||
<Link
|
||||
href="https://www.linkedin.com/company/useautumn"
|
||||
className="group/strip flex items-center text-[14px] tracking-[-2%] transition-colors duration-300"
|
||||
>
|
||||
<span className="relative">
|
||||
<span className="text-[#FFFFFF99] group-hover/strip:text-[#ffffff] text-[12px] md:text-[14px] transition-colors duration-300">
|
||||
LINKEDIN
|
||||
</span>
|
||||
<span
|
||||
className="absolute inset-y-0 left-0 w-0 group-hover/strip:w-full group-active/strip:w-full overflow-hidden transition-all duration-300 ease-in-out bg-white text-black font-normal pointer-events-none flex items-center"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<span className="whitespace-nowrap">LINKEDIN</span>
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
<div className="w-[5px] h-[5px] bg-[#FFFFFF]"></div>
|
||||
<Link
|
||||
href="https://x.com/autumnpricing"
|
||||
className="group/strip flex items-center text-[14px] tracking-[-2%] transition-colors duration-300"
|
||||
>
|
||||
<span className="relative">
|
||||
<span className="text-[#FFFFFF99] group-hover/strip:text-[#ffffff] transition-colors duration-300 text-[12px] md:text-[14px]">
|
||||
TWITTER
|
||||
</span>
|
||||
<span
|
||||
className="absolute inset-y-0 left-0 w-0 group-hover/strip:w-full group-active/strip:w-full overflow-hidden transition-all duration-300 ease-in-out bg-white text-black font-normal pointer-events-none flex items-center"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<span className="whitespace-nowrap">TWITTER</span>
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
<div
|
||||
className="relative block z-10 bg-black/40 backdrop-blur-md border-y border-[#292929]"
|
||||
style={{
|
||||
width: "calc(100% + var(--page-pad) * 2)",
|
||||
marginLeft: "calc(var(--page-pad) * -1)",
|
||||
paddingLeft: "var(--page-pad)",
|
||||
paddingRight: "var(--page-pad)",
|
||||
}}
|
||||
>
|
||||
<div className="max-w-[1400px] mx-auto flex flex-col md:flex-row justify-between items-stretch h-auto md:h-14 font-mono text-[10px] sm:text-[11px] tracking-[0.2em]">
|
||||
<div className="flex flex-row md:flex-row border-b md:border-b-0 border-[#292929] w-full md:w-auto">
|
||||
<div className="px-4 sm:px-8 py-4.5 md:py-0 border-r border-[#292929] tracking-[-2%] flex items-center justify-center md:justify-start text-[12px] md:text-[14px]">
|
||||
SOCIAL
|
||||
</div>
|
||||
<div className="px-6 sm:px-8 py-4 md:py-0 flex items-center justify-center md:justify-start gap-3 sm:gap-4 md:border-r border-[#292929]">
|
||||
<Link
|
||||
href="https://www.linkedin.com/company/useautumn"
|
||||
className="group/strip flex items-center text-[14px] tracking-[-2%] transition-colors duration-300"
|
||||
>
|
||||
<span className="relative">
|
||||
<span className="text-[#FFFFFF99] group-hover/strip:text-[#ffffff] text-[12px] md:text-[14px] transition-colors duration-300">
|
||||
LINKEDIN
|
||||
</span>
|
||||
<span
|
||||
className="absolute inset-y-0 left-0 w-0 group-hover/strip:w-full group-active/strip:w-full overflow-hidden transition-all duration-300 ease-in-out bg-white text-black font-normal pointer-events-none flex items-center"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<span className="whitespace-nowrap">LINKEDIN</span>
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
<div className="w-[5px] h-[5px] bg-[#FFFFFF]" />
|
||||
<Link
|
||||
href="https://x.com/autumnpricing"
|
||||
className="group/strip flex items-center text-[14px] tracking-[-2%] transition-colors duration-300"
|
||||
>
|
||||
<span className="relative">
|
||||
<span className="text-[#FFFFFF99] group-hover/strip:text-[#ffffff] transition-colors duration-300 text-[12px] md:text-[14px]">
|
||||
TWITTER
|
||||
</span>
|
||||
<span
|
||||
className="absolute inset-y-0 left-0 w-0 group-hover/strip:w-full group-active/strip:w-full overflow-hidden transition-all duration-300 ease-in-out bg-white text-black font-normal pointer-events-none flex items-center"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<span className="whitespace-nowrap">TWITTER</span>
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="px-4.5 py-4 md:py-0 flex items-center justify-start md:justify-end text-center md:text-right text-[#FFFFFF99] text-[12px] md:text-[14px] tracking-[-2%] border-b md:border-b-0 border-[#292929] w-full md:w-auto">
|
||||
Copyright © 2026 Autumn All rights reserved
|
||||
<div className="hidden lg:flex gap-3 ml-[15px] h-[54px]">
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
</div>
|
||||
<div className="px-4.5 py-4 md:py-0 flex items-center justify-start md:justify-end text-center md:text-right text-[#FFFFFF99] text-[12px] md:text-[14px] tracking-[-2%] border-b md:border-b-0 border-[#292929] w-full md:w-auto">
|
||||
Copyright © 2026 Autumn All rights reserved
|
||||
<div className="hidden lg:flex gap-3 ml-[15px] h-[54px]">
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
<div className="border-r border-[#292929]" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
55
apps/website/components/testimonials.tsx
Executable file → Normal file
55
apps/website/components/testimonials.tsx
Executable file → Normal file
@@ -1,11 +1,7 @@
|
||||
"use client";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
IconArrowLeft,
|
||||
IconArrowRight,
|
||||
IconQuotes,
|
||||
PixelatedPattern,
|
||||
} from "@/app/constant";
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { IconArrowLeft, IconArrowRight, IconQuotes } from "@/app/constant";
|
||||
|
||||
const testimonialsData = [
|
||||
{
|
||||
@@ -51,7 +47,7 @@ const Testimonials = () => {
|
||||
const [canScrollLeft, setCanScrollLeft] = useState(false);
|
||||
const [canScrollRight, setCanScrollRight] = useState(true);
|
||||
|
||||
const handleScroll = () => {
|
||||
const handleScroll = useCallback(() => {
|
||||
if (scrollRef.current) {
|
||||
const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current;
|
||||
setCanScrollLeft(scrollLeft > 0);
|
||||
@@ -63,7 +59,8 @@ const Testimonials = () => {
|
||||
progressRef.current.style.transform = `translateX(${progress}%)`;
|
||||
}
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (videoRef.current) {
|
||||
videoRef.current.playbackRate = 0.4;
|
||||
@@ -74,7 +71,7 @@ const Testimonials = () => {
|
||||
handleScroll();
|
||||
window.addEventListener("resize", handleScroll);
|
||||
return () => window.removeEventListener("resize", handleScroll);
|
||||
}, []);
|
||||
}, [handleScroll]);
|
||||
|
||||
const scrollByAmount = (amount: number) => {
|
||||
if (scrollRef.current) {
|
||||
@@ -97,6 +94,7 @@ const Testimonials = () => {
|
||||
onClick={() => scrollByAmount(-400)}
|
||||
disabled={!canScrollLeft}
|
||||
className="group p-1.5 bg-transparent cursor-pointer flex items-center justify-center transition-all duration-300 border border-[#292929]"
|
||||
type="button"
|
||||
aria-label="Previous testimonials"
|
||||
>
|
||||
<IconArrowLeft
|
||||
@@ -109,6 +107,7 @@ const Testimonials = () => {
|
||||
onClick={() => scrollByAmount(400)}
|
||||
disabled={!canScrollRight}
|
||||
className="group p-1.5 bg-transparent cursor-pointer flex items-center justify-center transition-all duration-300 border border-[#292929]"
|
||||
type="button"
|
||||
aria-label="Next testimonials"
|
||||
>
|
||||
<IconArrowRight
|
||||
@@ -119,7 +118,7 @@ const Testimonials = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-[#1A1A1A] w-full"></div>
|
||||
<div className="border-t border-[#1A1A1A] w-full" />
|
||||
|
||||
<div className="px-0 xl:pl-22.75">
|
||||
<div
|
||||
@@ -133,7 +132,6 @@ const Testimonials = () => {
|
||||
key={testimonial.id}
|
||||
className="group cursor-pointer shrink-0 w-[300px] sm:w-[300px] md:w-[360px] snap-start min-h-[360px] flex flex-col justify-between p-4 sm:p-10 border-l border-r border-b border-[#1A1A1A] transition-all duration-300 relative overflow-hidden"
|
||||
>
|
||||
{/* Hover Pixelated Pattern (Masked) */}
|
||||
<div className="absolute inset-x-0 bottom-0 h-[120%] pointer-events-none z-0 overflow-hidden">
|
||||
<div className="absolute inset-0 opacity-0 translate-y-6 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-500 ease-out pointer-events-none z-0 hidden md:block">
|
||||
<video
|
||||
@@ -147,7 +145,6 @@ const Testimonials = () => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* Purple Glow Gradient Overlay */}
|
||||
<div className="absolute inset-x-0 bottom-0 h-[70%] bg-[linear-gradient(to_bottom,rgba(10,10,10,0)_0%,rgba(135,82,250,0.15)_40%,rgba(135,82,250,0.45)_70%,rgba(135,82,250,0.85)_90%)] opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none z-0" />
|
||||
<div className="relative z-10 flex flex-col h-full justify-start">
|
||||
<IconQuotes className="w-8 h-8 text-[#4C4C4C] opacity-60 group-hover:text-[#9564FF] group-hover:opacity-100 transition-colors duration-500 mb-6" />
|
||||
@@ -162,7 +159,7 @@ const Testimonials = () => {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t border-[#1A1A1A] w-full"></div>
|
||||
<div className="border-t border-[#1A1A1A] w-full" />
|
||||
|
||||
<div className="flex md:hidden justify-end px-4 mt-6">
|
||||
<div className="flex items-center gap-4">
|
||||
@@ -170,6 +167,7 @@ const Testimonials = () => {
|
||||
onClick={() => scrollByAmount(-400)}
|
||||
disabled={!canScrollLeft}
|
||||
className="p-1.5 bg-transparent flex items-center justify-center border border-[#292929]"
|
||||
type="button"
|
||||
aria-label="Previous testimonials"
|
||||
>
|
||||
<IconArrowLeft
|
||||
@@ -182,6 +180,7 @@ const Testimonials = () => {
|
||||
onClick={() => scrollByAmount(400)}
|
||||
disabled={!canScrollRight}
|
||||
className="p-1.5 bg-transparent flex items-center justify-center border border-[#292929]"
|
||||
type="button"
|
||||
aria-label="Next testimonials"
|
||||
>
|
||||
<IconArrowRight
|
||||
@@ -196,25 +195,25 @@ const Testimonials = () => {
|
||||
<div
|
||||
ref={progressRef}
|
||||
className="absolute left-0 top-0 h-full bg-[#8752FA] w-[84px] rounded-full"
|
||||
style={{ transform: `translateX(0%)` }}
|
||||
></div>
|
||||
style={{ transform: "translateX(0%)" }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style jsx global>{`
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.arrow-corners {
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
transition: transform 0.25s ease;
|
||||
}
|
||||
.group:hover .arrow-corners {
|
||||
transform: scale(1.4);
|
||||
}
|
||||
`}</style>
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.arrow-corners {
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
transition: transform 0.25s ease;
|
||||
}
|
||||
.group:hover .arrow-corners {
|
||||
transform: scale(1.4);
|
||||
}
|
||||
`}</style>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -23,13 +23,16 @@
|
||||
"ngrok": "^5.0.0-beta.2",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"react-syntax-highlighter": "^16.1.1"
|
||||
"react-syntax-highlighter": "^16.1.1",
|
||||
"@types/react": "^19.2.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"eslint": "^10.2.0",
|
||||
"eslint-config-next": "16.2.1",
|
||||
"tailwindcss": "^4.2.2"
|
||||
"tailwindcss": "^4.2.2",
|
||||
"typescript": "^6.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +1,36 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"incremental": true,
|
||||
"typeRoots": [
|
||||
"../../node_modules/@types"
|
||||
],
|
||||
"types": [
|
||||
"node",
|
||||
"react",
|
||||
"react-dom"
|
||||
],
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"allowJs": true
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
".next/dev/types/**/*.ts",
|
||||
"**/*.mts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"incremental": true,
|
||||
"typeRoots": ["../../node_modules/@types"],
|
||||
"types": ["node", "react", "react-dom"],
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
},
|
||||
"allowJs": true
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
".next/dev/types/**/*.ts",
|
||||
"**/*.mts"
|
||||
],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
101
bun.lock
101
bun.lock
@@ -108,6 +108,7 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@gsap/react": "^2.1.2",
|
||||
"@types/react": "^19.2.14",
|
||||
"@vercel/analytics": "^2.0.1",
|
||||
"framer-motion": "^12.38.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
@@ -126,9 +127,11 @@
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"eslint": "^10.2.0",
|
||||
"eslint-config-next": "16.2.1",
|
||||
"tailwindcss": "^4.2.2",
|
||||
"typescript": "^6.0.2",
|
||||
},
|
||||
},
|
||||
"packages/atmn": {
|
||||
@@ -1231,11 +1234,11 @@
|
||||
|
||||
"@mermaid-js/parser": ["@mermaid-js/parser@1.1.0", "", { "dependencies": { "langium": "^4.0.0" } }, "sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw=="],
|
||||
|
||||
"@mintlify/cli": ["@mintlify/cli@4.0.1120", "", { "dependencies": { "@inquirer/prompts": "7.9.0", "@mintlify/common": "1.0.857", "@mintlify/link-rot": "3.0.1032", "@mintlify/prebuild": "1.0.999", "@mintlify/previewing": "4.0.1060", "@mintlify/validation": "0.1.668", "adm-zip": "0.5.16", "chalk": "5.2.0", "color": "4.2.3", "detect-port": "1.5.1", "front-matter": "4.0.2", "fs-extra": "11.2.0", "ink": "6.3.0", "inquirer": "12.3.0", "js-yaml": "4.1.0", "mdast-util-mdx-jsx": "3.2.0", "open": "^8.4.2", "openid-client": "^6.8.2", "posthog-node": "5.17.2", "react": "19.2.3", "semver": "7.7.2", "unist-util-visit": "5.0.0", "yargs": "17.7.1", "zod": "^4.3.6" }, "optionalDependencies": { "keytar": "^7.9.0" }, "bin": { "mint": "bin/index.js", "mintlify": "bin/index.js" } }, "sha512-hy0MgSypeZT4JtVo6Mczu6ZxaRAIfUOseL4otW+tGd2AA6cvod5WJUtM+5JGQu/bQCFov86YI30FffCv+9meUw=="],
|
||||
"@mintlify/cli": ["@mintlify/cli@4.0.1121", "", { "dependencies": { "@inquirer/prompts": "7.9.0", "@mintlify/common": "1.0.857", "@mintlify/link-rot": "3.0.1033", "@mintlify/prebuild": "1.0.999", "@mintlify/previewing": "4.0.1060", "@mintlify/validation": "0.1.668", "adm-zip": "0.5.16", "chalk": "5.2.0", "color": "4.2.3", "detect-port": "1.5.1", "front-matter": "4.0.2", "fs-extra": "11.2.0", "ink": "6.3.0", "inquirer": "12.3.0", "js-yaml": "4.1.0", "mdast-util-mdx-jsx": "3.2.0", "open": "^8.4.2", "openid-client": "^6.8.2", "posthog-node": "5.17.2", "react": "19.2.3", "semver": "7.7.2", "unist-util-visit": "5.0.0", "yargs": "17.7.1", "zod": "^4.3.6" }, "optionalDependencies": { "keytar": "^7.9.0" }, "bin": { "mint": "bin/index.js", "mintlify": "bin/index.js" } }, "sha512-erZIzK9M0A5OZBRX1iEgqHpqKHi5c++D43ew31gD4Pwp6SKOxie9ebtWrgLhBkhgkaVgvhCZqWsZDCaWN5heWQ=="],
|
||||
|
||||
"@mintlify/common": ["@mintlify/common@1.0.857", "", { "dependencies": { "@asyncapi/parser": "3.4.0", "@asyncapi/specs": "6.8.1", "@mintlify/mdx": "^3.0.4", "@mintlify/models": "0.0.291", "@mintlify/openapi-parser": "^0.0.8", "@mintlify/validation": "0.1.668", "@sindresorhus/slugify": "2.2.0", "@types/mdast": "4.0.4", "acorn": "8.11.2", "acorn-jsx": "5.3.2", "color-blend": "4.0.0", "estree-util-to-js": "2.0.0", "estree-walker": "3.0.3", "front-matter": "4.0.2", "hast-util-from-html": "2.0.3", "hast-util-to-html": "9.0.4", "hast-util-to-text": "4.0.2", "hex-rgb": "5.0.0", "ignore": "7.0.5", "js-yaml": "4.1.0", "lodash": "4.18.1", "mdast-util-from-markdown": "2.0.2", "mdast-util-gfm": "3.0.0", "mdast-util-mdx": "3.0.0", "mdast-util-mdx-jsx": "3.1.3", "micromark-extension-gfm": "3.0.0", "micromark-extension-mdx-jsx": "3.0.1", "micromark-extension-mdxjs": "3.0.0", "openapi-types": "12.1.3", "postcss": "8.5.6", "rehype-stringify": "10.0.1", "remark": "15.0.1", "remark-frontmatter": "5.0.0", "remark-gfm": "4.0.0", "remark-math": "6.0.0", "remark-mdx": "3.1.0", "remark-parse": "11.0.0", "remark-rehype": "11.1.1", "remark-stringify": "11.0.0", "sucrase": "^3.34.0", "tailwindcss": "^3.4.17", "unified": "11.0.5", "unist-builder": "4.0.0", "unist-util-map": "4.0.0", "unist-util-remove": "4.0.0", "unist-util-remove-position": "5.0.0", "unist-util-visit": "5.0.0", "unist-util-visit-parents": "6.0.1", "vfile": "6.0.3", "xss": "1.0.15" } }, "sha512-DBLf0HMgAtfksrmFDbW6EHVrYZHQniFUAXfk1/3LeNeOaegZo+wekO7KufZUGYDwwsZMe5OPr5pX5ldp41vAsg=="],
|
||||
|
||||
"@mintlify/link-rot": ["@mintlify/link-rot@3.0.1032", "", { "dependencies": { "@mintlify/common": "1.0.857", "@mintlify/prebuild": "1.0.999", "@mintlify/previewing": "4.0.1060", "@mintlify/scraping": "4.0.522", "@mintlify/validation": "0.1.668", "fs-extra": "11.1.0", "unist-util-visit": "4.1.2" } }, "sha512-JJLhHVs67zrHukNrptQ8bqv4RsXZKZpDQG6t5xjOwFSPdpY+3zo1y9k0Fep+vjQW8jgUI7Q3eEgvoR1gacC9Fg=="],
|
||||
"@mintlify/link-rot": ["@mintlify/link-rot@3.0.1033", "", { "dependencies": { "@mintlify/common": "1.0.857", "@mintlify/prebuild": "1.0.999", "@mintlify/previewing": "4.0.1060", "@mintlify/scraping": "4.0.522", "@mintlify/validation": "0.1.668", "fs-extra": "11.1.0", "unist-util-visit": "4.1.2" } }, "sha512-T+xAwZiOEpHY4YZorsoAz3sYzLJfjeBnk1Uw362O2djzI7MSocP67EEhFXi81l9I/sNeLDqnk0VPxorF/C82SA=="],
|
||||
|
||||
"@mintlify/mdx": ["@mintlify/mdx@3.0.4", "", { "dependencies": { "@shikijs/transformers": "^3.11.0", "@shikijs/twoslash": "^3.12.2", "arktype": "^2.1.26", "hast-util-to-string": "^3.0.1", "mdast-util-from-markdown": "^2.0.2", "mdast-util-gfm": "^3.1.0", "mdast-util-mdx-jsx": "^3.2.0", "mdast-util-to-hast": "^13.2.0", "next-mdx-remote-client": "^1.0.3", "rehype-katex": "^7.0.1", "remark-gfm": "^4.0.0", "remark-math": "^6.0.0", "remark-smartypants": "^3.0.2", "shiki": "^3.11.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "@radix-ui/react-popover": "^1.1.15", "react": "^18.3.1", "react-dom": "^18.3.1" } }, "sha512-tJhdpnM5ReJLNJ2fuDRIEr0zgVd6id7/oAIfs26V46QlygiLsc8qx4Rz3LWIX51rUXW/cfakjj0EATxIciIw+g=="],
|
||||
|
||||
@@ -1321,7 +1324,7 @@
|
||||
|
||||
"@onkernel/sdk": ["@onkernel/sdk@0.36.1", "", {}, "sha512-DbpPja/+sYiZxBKS4bM8HOpFYCV1DirrTflElbMtLDCPzqO1oFQLtLGfgfAg7T4wnmth3/QYtekJpnTjxh0VGg=="],
|
||||
|
||||
"@open-draft/deferred-promise": ["@open-draft/deferred-promise@2.2.0", "", {}, "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA=="],
|
||||
"@open-draft/deferred-promise": ["@open-draft/deferred-promise@3.0.0", "", {}, "sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA=="],
|
||||
|
||||
"@open-draft/logger": ["@open-draft/logger@0.3.0", "", { "dependencies": { "is-node-process": "^1.2.0", "outvariant": "^1.4.0" } }, "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ=="],
|
||||
|
||||
@@ -2237,6 +2240,8 @@
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@18.3.7", "", { "peerDependencies": { "@types/react": "^18.0.0" } }, "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ=="],
|
||||
|
||||
"@types/react-syntax-highlighter": ["@types/react-syntax-highlighter@15.5.13", "", { "dependencies": { "@types/react": "*" } }, "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA=="],
|
||||
|
||||
"@types/responselike": ["@types/responselike@1.0.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw=="],
|
||||
|
||||
"@types/retry": ["@types/retry@0.12.0", "", {}, "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="],
|
||||
@@ -2247,6 +2252,8 @@
|
||||
|
||||
"@types/serve-static": ["@types/serve-static@2.2.0", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*" } }, "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ=="],
|
||||
|
||||
"@types/set-cookie-parser": ["@types/set-cookie-parser@2.4.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw=="],
|
||||
|
||||
"@types/statuses": ["@types/statuses@2.0.6", "", {}, "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA=="],
|
||||
|
||||
"@types/superagent": ["@types/superagent@8.1.9", "", { "dependencies": { "@types/cookiejar": "^2.1.5", "@types/methods": "^1.1.4", "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ=="],
|
||||
@@ -3341,8 +3348,14 @@
|
||||
|
||||
"fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="],
|
||||
|
||||
"fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="],
|
||||
|
||||
"fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="],
|
||||
|
||||
"fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="],
|
||||
|
||||
"fast-wrap-ansi": ["fast-wrap-ansi@0.2.0", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w=="],
|
||||
|
||||
"fast-xml-parser": ["fast-xml-parser@5.3.4", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA=="],
|
||||
|
||||
"fastest-levenshtein": ["fastest-levenshtein@1.0.16", "", {}, "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="],
|
||||
@@ -3589,7 +3602,7 @@
|
||||
|
||||
"he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
|
||||
|
||||
"headers-polyfill": ["headers-polyfill@4.0.3", "", {}, "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ=="],
|
||||
"headers-polyfill": ["headers-polyfill@5.0.1", "", { "dependencies": { "@types/set-cookie-parser": "^2.4.10", "set-cookie-parser": "^3.0.1" } }, "sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA=="],
|
||||
|
||||
"help-me": ["help-me@5.0.0", "", {}, "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="],
|
||||
|
||||
@@ -4103,7 +4116,7 @@
|
||||
|
||||
"mdast-util-frontmatter": ["mdast-util-frontmatter@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "escape-string-regexp": "^5.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-extension-frontmatter": "^2.0.0" } }, "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA=="],
|
||||
|
||||
"mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="],
|
||||
"mdast-util-gfm": ["mdast-util-gfm@3.0.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw=="],
|
||||
|
||||
"mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-find-and-replace": "^3.0.0", "micromark-util-character": "^2.0.0" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="],
|
||||
|
||||
@@ -4261,7 +4274,7 @@
|
||||
|
||||
"minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
||||
|
||||
"mintlify": ["mintlify@4.2.517", "", { "dependencies": { "@mintlify/cli": "4.0.1120" }, "bin": { "mintlify": "index.js" } }, "sha512-dhYbBNe+KNGY9AN3Q0JbXybhgK+eZ7Mx8h1rDDe81xwMOh5RVFSP6TidOApEg3y+VOzeghK3LGXxORMbZRv1zw=="],
|
||||
"mintlify": ["mintlify@4.2.518", "", { "dependencies": { "@mintlify/cli": "4.0.1121" }, "bin": { "mintlify": "index.js" } }, "sha512-IF0VewkseLpBIN+zYBFT7axVexY4CBQVXylo2kd2UkJbpDB+bQBb5K+kgjXxPnW3iTBjL0BYNvV6MdxOSsmzQQ=="],
|
||||
|
||||
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
|
||||
|
||||
@@ -4297,7 +4310,7 @@
|
||||
|
||||
"msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="],
|
||||
|
||||
"msw": ["msw@2.13.3", "", { "dependencies": { "@inquirer/confirm": "^5.0.0", "@mswjs/interceptors": "^0.41.2", "@open-draft/deferred-promise": "^2.2.0", "@types/statuses": "^2.0.6", "cookie": "^1.0.2", "graphql": "^16.12.0", "headers-polyfill": "^4.0.2", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", "rettime": "^0.11.7", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.0", "type-fest": "^5.2.0", "until-async": "^3.0.2", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": ">= 4.8.x" }, "optionalPeers": ["typescript"], "bin": { "msw": "cli/index.js" } }, "sha512-/F49bxavkNGfreMlrKmTxZs6YorjfMbbDLd89Q3pWi+cXGtQQNXXaHt4MkXN7li91xnQJ24HWXqW9QDm5id33w=="],
|
||||
"msw": ["msw@2.13.4", "", { "dependencies": { "@inquirer/confirm": "^6.0.11", "@mswjs/interceptors": "^0.41.3", "@open-draft/deferred-promise": "^3.0.0", "@types/statuses": "^2.0.6", "cookie": "^1.1.1", "graphql": "^16.13.2", "headers-polyfill": "^5.0.1", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", "rettime": "^0.11.7", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.1", "type-fest": "^5.5.0", "until-async": "^3.0.2", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": ">= 4.8.x" }, "optionalPeers": ["typescript"], "bin": { "msw": "cli/index.js" } }, "sha512-fPlKBeFe+8rpcyR3umUmmHuNwu6gc6T3STvkgEa9WDX/HEgal9wDeflpCUAIRtmvaLZM2igfI5y1bZ9G5J26KA=="],
|
||||
|
||||
"mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="],
|
||||
|
||||
@@ -5621,12 +5634,16 @@
|
||||
|
||||
"@autumn/vite/typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
||||
|
||||
"@autumn/website/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"@autumn/website/eslint": ["eslint@10.2.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.4", "@eslint/config-helpers": "^0.5.4", "@eslint/core": "^1.2.0", "@eslint/plugin-kit": "^0.7.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA=="],
|
||||
|
||||
"@autumn/website/react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
||||
|
||||
"@autumn/website/react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
||||
|
||||
"@autumn/website/typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="],
|
||||
|
||||
"@aws-crypto/sha1-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
|
||||
|
||||
"@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
|
||||
@@ -5920,7 +5937,6 @@
|
||||
"@mintlify/common/js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
||||
|
||||
"@mintlify/common/mdast-util-gfm": ["mdast-util-gfm@3.0.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw=="],
|
||||
|
||||
"@mintlify/common/mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.1.3", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ=="],
|
||||
|
||||
"@mintlify/common/postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||
@@ -5931,11 +5947,13 @@
|
||||
|
||||
"@mintlify/common/tailwindcss": ["tailwindcss@3.4.19", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ=="],
|
||||
|
||||
"@mintlify/common/unist-util-visit": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="],
|
||||
"@mintlify/link-rot/fs-extra": ["fs-extra@11.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw=="],
|
||||
|
||||
"@mintlify/link-rot/unist-util-visit": ["unist-util-visit@4.1.2", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.1.1" } }, "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg=="],
|
||||
|
||||
"@mintlify/mdx/unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="],
|
||||
"@mintlify/mdx/mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="],
|
||||
|
||||
"@mintlify/models/axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="],
|
||||
|
||||
@@ -6017,6 +6035,8 @@
|
||||
|
||||
"@modelcontextprotocol/sdk/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
|
||||
|
||||
"@mswjs/interceptors/@open-draft/deferred-promise": ["@open-draft/deferred-promise@2.2.0", "", {}, "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA=="],
|
||||
|
||||
"@next/eslint-plugin-next/fast-glob": ["fast-glob@3.3.1", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" } }, "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg=="],
|
||||
|
||||
"@ngneat/falso/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
|
||||
@@ -6115,30 +6135,20 @@
|
||||
|
||||
"@opentelemetry/exporter-zipkin/@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.0.1", "", { "dependencies": { "@opentelemetry/core": "2.0.1", "@opentelemetry/resources": "2.0.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ=="],
|
||||
|
||||
"@opentelemetry/instrumentation-amqplib/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-amqplib/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-connect/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-connect/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-dataloader/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-express/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-express/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-fs/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-fs/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-generic-pool/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-graphql/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-hapi/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-hapi/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-http/@opentelemetry/core": ["@opentelemetry/core@2.5.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ=="],
|
||||
@@ -6151,24 +6161,18 @@
|
||||
|
||||
"@opentelemetry/instrumentation-knex/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-koa/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-koa/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-lru-memoizer/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-mongodb/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-mongoose/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-mongoose/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-mysql/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-mysql2/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-pg/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-pg/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-pg/@types/pg": ["@types/pg@8.15.6", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ=="],
|
||||
@@ -6177,8 +6181,6 @@
|
||||
|
||||
"@opentelemetry/instrumentation-tedious/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/instrumentation-undici/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@opentelemetry/instrumentation-undici/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@opentelemetry/otlp-grpc-exporter-base/@opentelemetry/core": ["@opentelemetry/core@2.0.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw=="],
|
||||
@@ -6219,8 +6221,6 @@
|
||||
|
||||
"@opentelemetry/sdk-trace-node/@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.0.1", "", { "dependencies": { "@opentelemetry/core": "2.0.1", "@opentelemetry/resources": "2.0.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ=="],
|
||||
|
||||
"@opentelemetry/sql-common/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@orpc/openapi/rou3": ["rou3@0.7.12", "", {}, "sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg=="],
|
||||
|
||||
"@orpc/server/cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
|
||||
@@ -6287,14 +6287,8 @@
|
||||
|
||||
"@sentry/node/@opentelemetry/context-async-hooks": ["@opentelemetry/context-async-hooks@2.6.1", "", { "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-XHzhwRNkBpeP8Fs/qjGrAf9r9PRv67wkJQ/7ZPaBQQ68DYlTBBx5MF9LvPx7mhuXcDessKK2b+DcxqwpgkcivQ=="],
|
||||
|
||||
"@sentry/node/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"@sentry/node/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.211.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.211.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q=="],
|
||||
|
||||
"@sentry/node/@opentelemetry/resources": ["@opentelemetry/resources@2.6.1", "", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA=="],
|
||||
|
||||
"@sentry/node/@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.6.1", "", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/resources": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw=="],
|
||||
|
||||
"@sentry/node/import-in-the-middle": ["import-in-the-middle@2.0.6", "", { "dependencies": { "acorn": "^8.15.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^2.2.0", "module-details-from-path": "^1.0.4" } }, "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw=="],
|
||||
|
||||
"@sentry/node-core/import-in-the-middle": ["import-in-the-middle@2.0.6", "", { "dependencies": { "acorn": "^8.15.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^2.2.0", "module-details-from-path": "^1.0.4" } }, "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw=="],
|
||||
@@ -6383,12 +6377,16 @@
|
||||
|
||||
"@types/pg/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
"@types/react-syntax-highlighter/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"@types/responselike/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
"@types/send/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
"@types/serve-static/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
"@types/set-cookie-parser/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
"@types/superagent/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
"@types/tedious/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
@@ -6732,8 +6730,8 @@
|
||||
"globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
|
||||
|
||||
"hast-util-raw/unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="],
|
||||
|
||||
"hast-util-to-mdast/hast-util-to-html": ["hast-util-to-html@9.0.4", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA=="],
|
||||
"headers-polyfill/set-cookie-parser": ["set-cookie-parser@3.1.0", "", {}, "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw=="],
|
||||
|
||||
"hosted-git-info/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
|
||||
|
||||
@@ -6827,6 +6825,8 @@
|
||||
|
||||
"monaco-editor/marked": ["marked@14.0.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ=="],
|
||||
|
||||
"msw/@inquirer/confirm": ["@inquirer/confirm@6.0.11", "", { "dependencies": { "@inquirer/core": "^11.1.8", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-pTpHjg0iEIRMYV/7oCZUMf27/383E6Wyhfc/MY+AVQGEoUobffIYWOK9YLP2XFRGz/9i6WlTQh1CkFVIo2Y7XA=="],
|
||||
|
||||
"msw/cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
|
||||
|
||||
"msw/path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="],
|
||||
@@ -6919,8 +6919,6 @@
|
||||
|
||||
"posthog-js/@opentelemetry/exporter-logs-otlp-http": ["@opentelemetry/exporter-logs-otlp-http@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-exporter-base": "0.208.0", "@opentelemetry/otlp-transformer": "0.208.0", "@opentelemetry/sdk-logs": "0.208.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-jOv40Bs9jy9bZVLo/i8FwUiuCvbjWDI+ZW13wimJm4LjnlwJxGgB+N/VWOZUTpM+ah/awXeQqKdNlpLf2EjvYg=="],
|
||||
|
||||
"posthog-js/@opentelemetry/resources": ["@opentelemetry/resources@2.6.1", "", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA=="],
|
||||
|
||||
"posthog-js/@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA=="],
|
||||
|
||||
"prebuild-install/tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
|
||||
@@ -7261,6 +7259,8 @@
|
||||
|
||||
"@autumn/server/ink/@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="],
|
||||
|
||||
"@autumn/server/ink/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"@autumn/server/ink/cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="],
|
||||
|
||||
"@autumn/server/ink/is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="],
|
||||
@@ -7485,6 +7485,8 @@
|
||||
|
||||
"@mintlify/cli/ink/@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="],
|
||||
|
||||
"@mintlify/cli/ink/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"@mintlify/cli/ink/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
||||
|
||||
"@mintlify/cli/ink/is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="],
|
||||
@@ -7653,6 +7655,8 @@
|
||||
|
||||
"@mintlify/previewing/ink/@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="],
|
||||
|
||||
"@mintlify/previewing/ink/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"@mintlify/previewing/ink/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
||||
|
||||
"@mintlify/previewing/ink/is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="],
|
||||
@@ -7682,7 +7686,6 @@
|
||||
"@mintlify/scraping/@mintlify/common/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||
|
||||
"@mintlify/scraping/@mintlify/common/mdast-util-gfm": ["mdast-util-gfm@3.0.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw=="],
|
||||
|
||||
"@mintlify/scraping/@mintlify/common/postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||
|
||||
"@mintlify/scraping/@mintlify/common/remark-mdx": ["remark-mdx@3.1.0", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA=="],
|
||||
@@ -7701,6 +7704,8 @@
|
||||
|
||||
"@mishieck/ink-titled-box/ink/@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="],
|
||||
|
||||
"@mishieck/ink-titled-box/ink/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"@mishieck/ink-titled-box/ink/cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="],
|
||||
|
||||
"@mishieck/ink-titled-box/ink/is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="],
|
||||
@@ -8005,6 +8010,8 @@
|
||||
|
||||
"@types/serve-static/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
|
||||
|
||||
"@types/set-cookie-parser/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
|
||||
|
||||
"@types/superagent/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
|
||||
|
||||
"@types/tedious/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
|
||||
@@ -8343,6 +8350,8 @@
|
||||
|
||||
"ink-scroll-list/ink/@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="],
|
||||
|
||||
"ink-scroll-list/ink/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"ink-scroll-list/ink/cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="],
|
||||
|
||||
"ink-scroll-list/ink/is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="],
|
||||
@@ -8415,6 +8424,10 @@
|
||||
|
||||
"mocha/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"msw/@inquirer/confirm/@inquirer/core": ["@inquirer/core@11.1.8", "", { "dependencies": { "@inquirer/ansi": "^2.0.5", "@inquirer/figures": "^2.0.5", "@inquirer/type": "^4.0.5", "cli-width": "^4.1.0", "fast-wrap-ansi": "^0.2.0", "mute-stream": "^3.0.0", "signal-exit": "^4.1.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-/u+yJk2pOKNDOh1ZgdUH2RQaRx6OOH4I0uwL95qPvTFTIL38YBsuSC4r1yXBB3Q6JvNqFFc202gk0Ew79rrcjA=="],
|
||||
|
||||
"msw/@inquirer/confirm/@inquirer/type": ["@inquirer/type@4.0.5", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q=="],
|
||||
|
||||
"msw/tough-cookie/tldts": ["tldts@7.0.28", "", { "dependencies": { "tldts-core": "^7.0.28" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw=="],
|
||||
|
||||
"next-mdx-remote-client/serialize-error/type-fest": ["type-fest@5.5.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g=="],
|
||||
@@ -8469,8 +8482,6 @@
|
||||
|
||||
"posthog-js/@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.208.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ=="],
|
||||
|
||||
"posthog-js/@opentelemetry/resources/@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="],
|
||||
|
||||
"posthog-js/@opentelemetry/sdk-logs/@opentelemetry/core": ["@opentelemetry/core@2.2.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw=="],
|
||||
|
||||
"posthog-js/@opentelemetry/sdk-logs/@opentelemetry/resources": ["@opentelemetry/resources@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A=="],
|
||||
@@ -9297,6 +9308,8 @@
|
||||
|
||||
"ink-confirm-input/ink-text-input/ink/@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="],
|
||||
|
||||
"ink-confirm-input/ink-text-input/ink/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"ink-confirm-input/ink-text-input/ink/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
||||
|
||||
"ink-confirm-input/ink-text-input/ink/cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="],
|
||||
@@ -9335,6 +9348,14 @@
|
||||
|
||||
"meow/read-pkg-up/read-pkg/normalize-package-data": ["normalize-package-data@3.0.3", "", { "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" } }, "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA=="],
|
||||
|
||||
"msw/@inquirer/confirm/@inquirer/core/@inquirer/ansi": ["@inquirer/ansi@2.0.5", "", {}, "sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw=="],
|
||||
|
||||
"msw/@inquirer/confirm/@inquirer/core/@inquirer/figures": ["@inquirer/figures@2.0.5", "", {}, "sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ=="],
|
||||
|
||||
"msw/@inquirer/confirm/@inquirer/core/mute-stream": ["mute-stream@3.0.0", "", {}, "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw=="],
|
||||
|
||||
"msw/@inquirer/confirm/@inquirer/core/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
||||
|
||||
"msw/tough-cookie/tldts/tldts-core": ["tldts-core@7.0.28", "", {}, "sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ=="],
|
||||
|
||||
"nodemon/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
|
||||
|
||||
@@ -34,7 +34,10 @@ import { executeWithHealthTracking } from "@/db/pgHealthMonitor.js";
|
||||
import type { RepoContext } from "@/db/repoContext.js";
|
||||
import type { AutumnContext } from "@/honoUtils/HonoEnv.js";
|
||||
import { withSpan } from "../analytics/tracer/spanUtils.js";
|
||||
import { getOrgCusProductLimit } from "../misc/edgeConfig/orgLimitsStore.js";
|
||||
import {
|
||||
getOrgCusProductLimit,
|
||||
getOrgEntitiesLimit,
|
||||
} from "../misc/edgeConfig/orgLimitsStore.js";
|
||||
import { resetCustomerEntitlements } from "./actions/resetCustomerEntitlements/resetCustomerEntitlements.js";
|
||||
import {
|
||||
ACTIVE_STATUSES,
|
||||
@@ -92,6 +95,10 @@ export class CusService {
|
||||
orgId,
|
||||
orgSlug: org.slug,
|
||||
});
|
||||
const entitiesLimit = getOrgEntitiesLimit({
|
||||
orgId,
|
||||
orgSlug: org.slug,
|
||||
});
|
||||
|
||||
const query = getFullCusQuery({
|
||||
idOrInternalId,
|
||||
@@ -105,6 +112,7 @@ export class CusService {
|
||||
withEvents,
|
||||
entityId,
|
||||
cusProductLimit,
|
||||
entitiesLimit,
|
||||
});
|
||||
|
||||
if (explain) {
|
||||
|
||||
@@ -98,7 +98,13 @@ const buildOptimizedCusProductsCTE = ({
|
||||
`;
|
||||
};
|
||||
|
||||
const buildEntitiesCTE = (withEntities: boolean) => {
|
||||
const buildEntitiesCTE = ({
|
||||
withEntities,
|
||||
entitiesLimit,
|
||||
}: {
|
||||
withEntities: boolean;
|
||||
entitiesLimit: number;
|
||||
}) => {
|
||||
if (!withEntities) {
|
||||
return sql``;
|
||||
}
|
||||
@@ -114,7 +120,7 @@ const buildEntitiesCTE = (withEntities: boolean) => {
|
||||
SELECT * FROM entities e
|
||||
WHERE e.internal_customer_id = (SELECT internal_id FROM customer_record)
|
||||
ORDER BY e.internal_id DESC
|
||||
LIMIT 1000
|
||||
LIMIT ${entitiesLimit}
|
||||
) e
|
||||
)
|
||||
`;
|
||||
@@ -284,6 +290,7 @@ export const getFullCusQuery = ({
|
||||
withEvents,
|
||||
entityId,
|
||||
cusProductLimit,
|
||||
entitiesLimit = 300,
|
||||
}: {
|
||||
idOrInternalId: string;
|
||||
orgId: string;
|
||||
@@ -296,6 +303,7 @@ export const getFullCusQuery = ({
|
||||
withEvents: boolean;
|
||||
entityId?: string;
|
||||
cusProductLimit: number;
|
||||
entitiesLimit?: number;
|
||||
}) => {
|
||||
const sqlChunks: SQL[] = [];
|
||||
|
||||
@@ -316,7 +324,7 @@ export const getFullCusQuery = ({
|
||||
// Step 2: Get entities
|
||||
if (withEntities) {
|
||||
sqlChunks.push(sql`, `);
|
||||
sqlChunks.push(buildEntitiesCTE(withEntities));
|
||||
sqlChunks.push(buildEntitiesCTE({ withEntities, entitiesLimit }));
|
||||
}
|
||||
|
||||
// Step 3: Get entity
|
||||
@@ -692,7 +700,7 @@ export const getPaginatedFullCusQuery = ({
|
||||
FROM entities e
|
||||
WHERE e.internal_customer_id = cr.internal_id
|
||||
ORDER BY e.internal_id DESC
|
||||
LIMIT 1000
|
||||
LIMIT 300
|
||||
) e ON true
|
||||
GROUP BY cr.internal_id
|
||||
)`
|
||||
|
||||
@@ -216,11 +216,6 @@ export class InvoiceService {
|
||||
currency: stripeInvoice.currency,
|
||||
});
|
||||
|
||||
const atmnAmountPaid = stripeToAtmnAmount({
|
||||
amount: stripeInvoice.amount_paid,
|
||||
currency: stripeInvoice.currency,
|
||||
});
|
||||
|
||||
const invoice: Invoice = {
|
||||
id: generateId("inv"),
|
||||
internal_customer_id: internalCustomerId,
|
||||
@@ -234,7 +229,6 @@ export class InvoiceService {
|
||||
|
||||
// Stripe stuff
|
||||
total: atmnTotal,
|
||||
amount_paid: atmnAmountPaid,
|
||||
refunded_amount: 0,
|
||||
currency: stripeInvoice.currency,
|
||||
discounts: getInvoiceDiscounts({
|
||||
@@ -329,7 +323,6 @@ export class InvoiceService {
|
||||
hosted_invoice_url: invoice.hosted_invoice_url,
|
||||
discounts: invoice.discounts,
|
||||
total: invoice.total,
|
||||
amount_paid: invoice.amount_paid,
|
||||
product_ids: invoice.product_ids?.length
|
||||
? sql`CASE
|
||||
WHEN ${invoices.product_ids} IS NULL OR cardinality(${invoices.product_ids}) = 0
|
||||
|
||||
@@ -29,10 +29,6 @@ export const updateInvoiceFromStripe = async ({
|
||||
amount: stripeInvoice.total,
|
||||
currency: stripeInvoice.currency,
|
||||
}),
|
||||
amount_paid: stripeToAtmnAmount({
|
||||
amount: stripeInvoice.amount_paid,
|
||||
currency: stripeInvoice.currency,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -50,11 +50,6 @@ export const initInvoiceFromStripe = async ({
|
||||
currency: stripeInvoice.currency,
|
||||
});
|
||||
|
||||
const atmnAmountPaid = stripeToAtmnAmount({
|
||||
amount: stripeInvoice.amount_paid,
|
||||
currency: stripeInvoice.currency,
|
||||
});
|
||||
|
||||
return {
|
||||
id: generateId("inv"),
|
||||
internal_customer_id: internalCustomerId,
|
||||
@@ -66,7 +61,6 @@ export const initInvoiceFromStripe = async ({
|
||||
status: stripeInvoice.status as string | undefined,
|
||||
internal_entity_id: internalEntityId || null,
|
||||
total: atmnTotal,
|
||||
amount_paid: atmnAmountPaid,
|
||||
currency: stripeInvoice.currency,
|
||||
discounts: getInvoiceDiscounts({ expandedInvoice: stripeInvoice }),
|
||||
items: autumnInvoiceItems,
|
||||
|
||||
@@ -6,6 +6,7 @@ export const OrgLimitsConfigSchema = z.object({
|
||||
z.string(),
|
||||
z.object({
|
||||
maxCusProducts: z.number().min(1).optional(),
|
||||
maxEntities: z.number().min(1).optional(),
|
||||
}),
|
||||
)
|
||||
.default({}),
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from "./orgLimitsSchemas.js";
|
||||
|
||||
export const DEFAULT_CUS_PRODUCT_LIMIT = 15;
|
||||
export const DEFAULT_ENTITIES_LIMIT = 300;
|
||||
|
||||
const store = createEdgeConfigStore<OrgLimitsConfig>({
|
||||
s3Key: ADMIN_ORG_LIMITS_CONFIG_KEY,
|
||||
@@ -28,11 +29,23 @@ export const getOrgCusProductLimit = ({
|
||||
}): number => {
|
||||
const orgs = store.get().orgs;
|
||||
const orgConfig =
|
||||
(orgId ? orgs[orgId] : undefined) ??
|
||||
(orgSlug ? orgs[orgSlug] : undefined);
|
||||
(orgId ? orgs[orgId] : undefined) ?? (orgSlug ? orgs[orgSlug] : undefined);
|
||||
return orgConfig?.maxCusProducts ?? DEFAULT_CUS_PRODUCT_LIMIT;
|
||||
};
|
||||
|
||||
export const getOrgEntitiesLimit = ({
|
||||
orgId,
|
||||
orgSlug,
|
||||
}: {
|
||||
orgId?: string;
|
||||
orgSlug?: string;
|
||||
}): number => {
|
||||
const orgs = store.get().orgs;
|
||||
const orgConfig =
|
||||
(orgId ? orgs[orgId] : undefined) ?? (orgSlug ? orgs[orgSlug] : undefined);
|
||||
return orgConfig?.maxEntities ?? DEFAULT_ENTITIES_LIMIT;
|
||||
};
|
||||
|
||||
export const getOrgLimitsConfigFromSource = async () => {
|
||||
return await store.readFromSource();
|
||||
};
|
||||
@@ -40,16 +53,22 @@ export const getOrgLimitsConfigFromSource = async () => {
|
||||
export const updateOrgLimitsInSource = async ({
|
||||
orgId,
|
||||
maxCusProducts,
|
||||
maxEntities,
|
||||
}: {
|
||||
orgId: string;
|
||||
maxCusProducts?: number;
|
||||
maxEntities?: number;
|
||||
}) => {
|
||||
const config = await store.readFromSource();
|
||||
|
||||
if (maxCusProducts === undefined) {
|
||||
if (maxCusProducts === undefined && maxEntities === undefined) {
|
||||
delete config.orgs[orgId];
|
||||
} else {
|
||||
config.orgs[orgId] = { maxCusProducts };
|
||||
config.orgs[orgId] = {
|
||||
...config.orgs[orgId],
|
||||
...(maxCusProducts !== undefined ? { maxCusProducts } : {}),
|
||||
...(maxEntities !== undefined ? { maxEntities } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
await store.writeToSource({ config });
|
||||
@@ -63,3 +82,15 @@ export const updateFullOrgLimitsConfig = async ({
|
||||
}) => {
|
||||
await store.writeToSource({ config });
|
||||
};
|
||||
|
||||
/**
|
||||
* Test-only helper: override the in-memory org limits config without touching S3.
|
||||
* Use inside tests to simulate admin-configured org limits deterministically.
|
||||
*/
|
||||
export const _setOrgLimitsConfigForTesting = ({
|
||||
config,
|
||||
}: {
|
||||
config: OrgLimitsConfig;
|
||||
}) => {
|
||||
store._setRuntimeConfigForTesting(config);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
import { afterAll, expect, test } from "bun:test";
|
||||
import { TestFeature } from "@tests/setup/v2Features.js";
|
||||
import { initScenario, s } from "@tests/utils/testInitUtils/initScenario.js";
|
||||
import chalk from "chalk";
|
||||
import { CusService } from "@/internal/customers/CusService.js";
|
||||
import type { OrgLimitsConfig } from "@/internal/misc/edgeConfig/orgLimitsSchemas.js";
|
||||
import {
|
||||
_setOrgLimitsConfigForTesting,
|
||||
DEFAULT_ENTITIES_LIMIT,
|
||||
getOrgEntitiesLimit,
|
||||
} from "@/internal/misc/edgeConfig/orgLimitsStore.js";
|
||||
|
||||
/**
|
||||
* These tests mutate the in-memory org limits store (a module-level singleton)
|
||||
* so they must run serially, not concurrently, to avoid leaking state into
|
||||
* unrelated tests.
|
||||
*
|
||||
* They call CusService.getFull directly (in-process) rather than going through
|
||||
* the HTTP server, because the running server has its own copy of the
|
||||
* orgLimitsStore that only refreshes from S3 every 30s. Calling in-process
|
||||
* exercises the same SQL path (getFullCusQuery -> buildEntitiesCTE) while
|
||||
* picking up the in-memory override immediately.
|
||||
*/
|
||||
|
||||
const resetOrgLimits = () => {
|
||||
_setOrgLimitsConfigForTesting({ config: { orgs: {} } });
|
||||
};
|
||||
|
||||
afterAll(() => {
|
||||
resetOrgLimits();
|
||||
});
|
||||
|
||||
test(`${chalk.yellowBright("maxEntities: caps entities returned by CusService.getFull to configured limit")}`, async () => {
|
||||
const customerId = "max-entities-cap";
|
||||
const entityCount = 5;
|
||||
const maxEntities = 3;
|
||||
|
||||
const { ctx, entities } = await initScenario({
|
||||
customerId,
|
||||
setup: [
|
||||
s.customer({}),
|
||||
s.entities({ count: entityCount, featureId: TestFeature.Users }),
|
||||
],
|
||||
actions: [],
|
||||
});
|
||||
|
||||
expect(entities.length).toBe(entityCount);
|
||||
|
||||
try {
|
||||
const config: OrgLimitsConfig = {
|
||||
orgs: { [ctx.org.id]: { maxEntities } },
|
||||
};
|
||||
_setOrgLimitsConfigForTesting({ config });
|
||||
|
||||
// Verify the accessor resolves to the override
|
||||
expect(getOrgEntitiesLimit({ orgId: ctx.org.id })).toBe(maxEntities);
|
||||
|
||||
const fullCus = await CusService.getFull({
|
||||
ctx,
|
||||
idOrInternalId: customerId,
|
||||
withEntities: true,
|
||||
});
|
||||
|
||||
expect(fullCus.entities).toBeDefined();
|
||||
expect(fullCus.entities.length).toBe(maxEntities);
|
||||
} finally {
|
||||
resetOrgLimits();
|
||||
}
|
||||
});
|
||||
|
||||
test(`${chalk.yellowBright("maxEntities: returns all entities when override is absent (falls back to default)")}`, async () => {
|
||||
const customerId = "max-entities-default";
|
||||
const entityCount = 4;
|
||||
|
||||
const { ctx, entities } = await initScenario({
|
||||
customerId,
|
||||
setup: [
|
||||
s.customer({}),
|
||||
s.entities({ count: entityCount, featureId: TestFeature.Users }),
|
||||
],
|
||||
actions: [],
|
||||
});
|
||||
|
||||
expect(entities.length).toBe(entityCount);
|
||||
|
||||
resetOrgLimits();
|
||||
|
||||
// No override for this org -> default (300) applies
|
||||
expect(getOrgEntitiesLimit({ orgId: ctx.org.id })).toBe(
|
||||
DEFAULT_ENTITIES_LIMIT,
|
||||
);
|
||||
|
||||
const fullCus = await CusService.getFull({
|
||||
ctx,
|
||||
idOrInternalId: customerId,
|
||||
withEntities: true,
|
||||
});
|
||||
|
||||
expect(fullCus.entities).toBeDefined();
|
||||
expect(fullCus.entities.length).toBe(entityCount);
|
||||
});
|
||||
|
||||
test(`${chalk.yellowBright("maxEntities: raising the limit exposes previously-hidden entities")}`, async () => {
|
||||
const customerId = "max-entities-raise";
|
||||
const entityCount = 4;
|
||||
|
||||
const { ctx, entities } = await initScenario({
|
||||
customerId,
|
||||
setup: [
|
||||
s.customer({}),
|
||||
s.entities({ count: entityCount, featureId: TestFeature.Users }),
|
||||
],
|
||||
actions: [],
|
||||
});
|
||||
|
||||
expect(entities.length).toBe(entityCount);
|
||||
|
||||
try {
|
||||
// Start with a tight cap
|
||||
_setOrgLimitsConfigForTesting({
|
||||
config: { orgs: { [ctx.org.id]: { maxEntities: 2 } } },
|
||||
});
|
||||
|
||||
const capped = await CusService.getFull({
|
||||
ctx,
|
||||
idOrInternalId: customerId,
|
||||
withEntities: true,
|
||||
});
|
||||
expect(capped.entities.length).toBe(2);
|
||||
|
||||
// Raise the cap above the entity count
|
||||
_setOrgLimitsConfigForTesting({
|
||||
config: { orgs: { [ctx.org.id]: { maxEntities: 50 } } },
|
||||
});
|
||||
|
||||
const uncapped = await CusService.getFull({
|
||||
ctx,
|
||||
idOrInternalId: customerId,
|
||||
withEntities: true,
|
||||
});
|
||||
expect(uncapped.entities.length).toBe(entityCount);
|
||||
} finally {
|
||||
resetOrgLimits();
|
||||
}
|
||||
});
|
||||
@@ -39,7 +39,6 @@ export const InvoiceSchema = z.object({
|
||||
|
||||
// Total amount of the invoice
|
||||
total: z.number(),
|
||||
amount_paid: z.number().nullish(),
|
||||
refunded_amount: z.number().default(0),
|
||||
currency: z.string(),
|
||||
receipt_url: z.string().nullish(),
|
||||
|
||||
@@ -28,7 +28,6 @@ export const invoices = pgTable(
|
||||
status: text("status").notNull().default("draft"),
|
||||
hosted_invoice_url: text("hosted_invoice_url"),
|
||||
total: numeric({ mode: "number" }).notNull().default(0),
|
||||
amount_paid: numeric({ mode: "number" }),
|
||||
refunded_amount: numeric({ mode: "number" }).notNull().default(0),
|
||||
currency: text("currency").notNull().default("usd"),
|
||||
discounts: jsonb("discounts").$type<InvoiceDiscount>().array().default([]),
|
||||
|
||||
@@ -8,9 +8,8 @@ import {
|
||||
import {
|
||||
ArrowCounterClockwiseIcon,
|
||||
ArrowSquareOutIcon,
|
||||
CalendarBlankIcon,
|
||||
CreditCardIcon,
|
||||
HashIcon,
|
||||
EyeIcon,
|
||||
EyeSlashIcon,
|
||||
} from "@phosphor-icons/react";
|
||||
import { format } from "date-fns";
|
||||
import { useMemo, useState } from "react";
|
||||
@@ -18,12 +17,10 @@ import { AdminHover } from "@/components/general/AdminHover";
|
||||
import { Badge } from "@/components/v2/badges/Badge";
|
||||
import { Button } from "@/components/v2/buttons/Button";
|
||||
import { MiniCopyButton } from "@/components/v2/buttons/CopyButton";
|
||||
import { InfoRow } from "@/components/v2/InfoRow";
|
||||
import { SheetHeader, SheetSection } from "@/components/v2/sheets/InlineSheet";
|
||||
import { useFeaturesQuery } from "@/hooks/queries/useFeaturesQuery";
|
||||
import { useOrgStripeQuery } from "@/hooks/queries/useOrgStripeQuery";
|
||||
import { useProductsQuery } from "@/hooks/queries/useProductsQuery";
|
||||
import { useSheetStore } from "@/hooks/stores/useSheetStore";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useEnv } from "@/utils/envUtils";
|
||||
import { getStripeInvoiceLink } from "@/utils/linkUtils";
|
||||
@@ -31,6 +28,11 @@ import { useCusQuery } from "@/views/customers/customer/hooks/useCusQuery";
|
||||
import { CustomerInvoiceStatus } from "../table/customer-invoices/CustomerInvoiceStatus";
|
||||
import { RefundInvoiceDialog } from "./RefundInvoiceDialog";
|
||||
|
||||
interface InvoiceDetailSheetProps {
|
||||
invoice: Invoice;
|
||||
lineItems: InvoiceLineItem[];
|
||||
}
|
||||
|
||||
type LineItemGroup = {
|
||||
groupKey: string;
|
||||
label: string;
|
||||
@@ -58,19 +60,29 @@ const resolveFeatureName = ({
|
||||
return feature?.name ?? featureId;
|
||||
};
|
||||
|
||||
export function InvoiceDetailSheet() {
|
||||
const sheetData = useSheetStore((s) => s.data);
|
||||
const invoice = sheetData?.invoice as Invoice | undefined;
|
||||
const lineItems = (sheetData?.lineItems as InvoiceLineItem[]) ?? [];
|
||||
|
||||
export function InvoiceDetailSheet({
|
||||
invoice,
|
||||
lineItems,
|
||||
}: InvoiceDetailSheetProps) {
|
||||
const { stripeAccount } = useOrgStripeQuery();
|
||||
const { features } = useFeaturesQuery();
|
||||
const { products } = useProductsQuery();
|
||||
const env = useEnv();
|
||||
const [showDescriptions, setShowDescriptions] = useState(false);
|
||||
const [refundDialogOpen, setRefundDialogOpen] = useState(false);
|
||||
const { customer } = useCusQuery();
|
||||
const isStripeCustomer = customer?.processor?.type === ProcessorType.Stripe;
|
||||
const isFullyRefunded =
|
||||
invoice.refunded_amount > 0 &&
|
||||
invoice.refunded_amount >= Math.abs(invoice.total);
|
||||
const canRefund =
|
||||
isStripeCustomer &&
|
||||
invoice.status === InvoiceStatus.Paid &&
|
||||
!isFullyRefunded;
|
||||
|
||||
|
||||
// Group line items: first by product_id, then within each product by
|
||||
// stripe_subscription_item_id (for tiered) or individually.
|
||||
// Sort: base price first, then alphabetically by label within each product.
|
||||
const productGroups = useMemo(() => {
|
||||
// Step 1: bucket line items by product_id
|
||||
const byProduct = new Map<string, InvoiceLineItem[]>();
|
||||
@@ -134,17 +146,6 @@ export function InvoiceDetailSheet() {
|
||||
return result;
|
||||
}, [lineItems, features, products]);
|
||||
|
||||
if (!invoice) return null;
|
||||
|
||||
const isStripeCustomer = customer?.processor?.type === ProcessorType.Stripe;
|
||||
const refundableAmount = Math.abs(invoice.amount_paid ?? invoice.total);
|
||||
const isFullyRefunded =
|
||||
invoice.refunded_amount > 0 && invoice.refunded_amount >= refundableAmount;
|
||||
const canRefund =
|
||||
isStripeCustomer &&
|
||||
invoice.status === InvoiceStatus.Paid &&
|
||||
!isFullyRefunded;
|
||||
|
||||
const formatAmount = (amount: number, currency: string) => {
|
||||
const absAmount = Math.abs(amount);
|
||||
return new Intl.NumberFormat("en-US", {
|
||||
@@ -188,14 +189,13 @@ export function InvoiceDetailSheet() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full overflow-y-auto">
|
||||
<div className="flex flex-col h-full">
|
||||
<SheetHeader
|
||||
title={
|
||||
<div className="flex items-center gap-2">
|
||||
<span>Invoice</span>
|
||||
<CustomerInvoiceStatus
|
||||
status={invoice.status ?? "paid"}
|
||||
amountPaid={invoice.amount_paid}
|
||||
total={invoice.total}
|
||||
refundedAmount={invoice.refunded_amount}
|
||||
/>
|
||||
@@ -204,105 +204,121 @@ export function InvoiceDetailSheet() {
|
||||
description={`${formatDate(invoice.created_at)} • ${formatSignedAmount(invoice.total, invoice.currency)}`}
|
||||
/>
|
||||
|
||||
{productGroups.map((productGroup) => (
|
||||
<SheetSection
|
||||
key={productGroup.productId ?? "unknown"}
|
||||
withSeparator={true}
|
||||
>
|
||||
<div className="mb-2">
|
||||
<span className="text-xs font-medium text-t3 truncate">
|
||||
{productGroup.productName}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto min-h-0">
|
||||
{/* Product groups with line items */}
|
||||
{productGroups.map((productGroup) => (
|
||||
<SheetSection
|
||||
key={productGroup.productId ?? "unknown"}
|
||||
withSeparator={true}
|
||||
>
|
||||
{/* Product header with description toggle */}
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-xs font-medium text-t3 truncate">
|
||||
{productGroup.productName}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowDescriptions((prev) => !prev)}
|
||||
className="text-t4 hover:text-t2 transition-colors p-0.5 rounded"
|
||||
title={
|
||||
showDescriptions
|
||||
? "Show computed display"
|
||||
: "Show descriptions"
|
||||
}
|
||||
>
|
||||
{showDescriptions ? (
|
||||
<EyeSlashIcon size={14} />
|
||||
) : (
|
||||
<EyeIcon size={14} />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
{productGroup.lineItemGroups.map((group) => (
|
||||
<LineItemGroupRow
|
||||
key={group.groupKey}
|
||||
group={group}
|
||||
formatAmount={formatAmount}
|
||||
formatPeriod={formatPeriod}
|
||||
currency={invoice.currency}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</SheetSection>
|
||||
))}
|
||||
{/* Line item groups within this product */}
|
||||
<div className="flex flex-col gap-2">
|
||||
{productGroup.lineItemGroups.map((group) => (
|
||||
<LineItemGroupRow
|
||||
key={group.groupKey}
|
||||
group={group}
|
||||
formatAmount={formatAmount}
|
||||
formatPeriod={formatPeriod}
|
||||
currency={invoice.currency}
|
||||
showDescriptions={showDescriptions}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</SheetSection>
|
||||
))}
|
||||
|
||||
<SheetSection withSeparator={true}>
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm font-medium text-foreground">Total</span>
|
||||
<span className="text-sm font-semibold text-foreground tabular-nums">
|
||||
{formatSignedAmount(invoice.total, invoice.currency)}
|
||||
</span>
|
||||
</div>
|
||||
{invoice.amount_paid != null && invoice.amount_paid !== invoice.total && (
|
||||
{/* Invoice Total */}
|
||||
<SheetSection withSeparator={true}>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-t2">Amount Paid</span>
|
||||
<span className="text-sm tabular-nums text-t2">
|
||||
{formatSignedAmount(invoice.amount_paid, invoice.currency)}
|
||||
<span className="text-sm font-medium text-foreground">Total</span>
|
||||
<span className="text-sm font-semibold text-foreground tabular-nums">
|
||||
{formatSignedAmount(invoice.total, invoice.currency)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{invoice.refunded_amount > 0 && (
|
||||
<>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-t3">Refunded</span>
|
||||
<span className="text-sm text-amber-500 tabular-nums">
|
||||
-{formatAmount(invoice.refunded_amount, invoice.currency)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between pt-1">
|
||||
<span className="text-sm text-t3">Net</span>
|
||||
<span className="text-sm font-semibold text-foreground tabular-nums">
|
||||
{formatSignedAmount(
|
||||
invoice.total - invoice.refunded_amount,
|
||||
invoice.currency,
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</SheetSection>
|
||||
{invoice.amount_paid != null &&
|
||||
invoice.amount_paid !== invoice.total && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-t2">Amount Paid</span>
|
||||
<span className="text-sm tabular-nums text-t2">
|
||||
{formatSignedAmount(invoice.amount_paid, invoice.currency)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{invoice.refunded_amount > 0 && (
|
||||
<>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-t3">Refunded</span>
|
||||
<span className="text-sm text-amber-500 tabular-nums">
|
||||
-{formatAmount(invoice.refunded_amount, invoice.currency)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between pt-1">
|
||||
<span className="text-sm text-t3">Net</span>
|
||||
<span className="text-sm font-semibold text-foreground tabular-nums">
|
||||
{formatSignedAmount(
|
||||
invoice.total - invoice.refunded_amount,
|
||||
invoice.currency,
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</SheetSection>
|
||||
|
||||
<SheetSection withSeparator={false}>
|
||||
<div className="space-y-3">
|
||||
<InfoRow
|
||||
icon={<HashIcon size={16} weight="duotone" />}
|
||||
label="Invoice ID"
|
||||
value={
|
||||
{/* Invoice Details - Compact */}
|
||||
<SheetSection withSeparator={false}>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-t3">Invoice ID</span>
|
||||
<MiniCopyButton
|
||||
text={invoice.id}
|
||||
innerClassName="text-sm text-t1 font-mono"
|
||||
innerClassName="text-xs text-t1 font-mono"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<InfoRow
|
||||
icon={<CreditCardIcon size={16} weight="duotone" />}
|
||||
label="Stripe ID"
|
||||
value={
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-t3">Stripe ID</span>
|
||||
<MiniCopyButton
|
||||
text={invoice.stripe_id}
|
||||
innerClassName="text-sm text-t1 font-mono"
|
||||
innerClassName="text-xs text-t1 font-mono"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<InfoRow
|
||||
icon={<CalendarBlankIcon size={16} weight="duotone" />}
|
||||
label="Created"
|
||||
value={
|
||||
<MiniCopyButton
|
||||
text={format(new Date(invoice.created_at), "MMM d, yyyy HH:mm")}
|
||||
innerClassName="text-sm text-t1"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</SheetSection>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-t3">Created</span>
|
||||
<span className="text-t1">
|
||||
{format(new Date(invoice.created_at), "MMM d, yyyy HH:mm")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</SheetSection>
|
||||
</div>
|
||||
|
||||
<div className="sticky bottom-0 p-4 flex gap-2 bg-card">
|
||||
{/* Footer */}
|
||||
<div className="p-4 flex gap-2 border-t border-border/40">
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="flex-1"
|
||||
@@ -338,11 +354,13 @@ function LineItemGroupRow({
|
||||
formatAmount,
|
||||
formatPeriod,
|
||||
currency,
|
||||
showDescriptions,
|
||||
}: {
|
||||
group: LineItemGroup;
|
||||
formatAmount: (amount: number, currency: string) => string;
|
||||
formatPeriod: (startMs: number | null, endMs: number | null) => string | null;
|
||||
currency: string;
|
||||
showDescriptions: boolean;
|
||||
}) {
|
||||
const isSingleItem = group.items.length === 1;
|
||||
const firstItem = group.items[0];
|
||||
@@ -378,19 +396,20 @@ function LineItemGroupRow({
|
||||
{/* Group header with label and total */}
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div className="flex flex-col min-w-0 flex-1 gap-0.5">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="text-sm text-t1">{group.label}</span>
|
||||
{totalQuantity > 0 && (
|
||||
<Badge
|
||||
variant="muted"
|
||||
className="text-[10px] px-1.5 py-0 text-t3"
|
||||
>
|
||||
Qty: {totalQuantity}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
{firstItem.description && (
|
||||
{showDescriptions ? (
|
||||
<span className="text-xs text-t3">{firstItem.description}</span>
|
||||
) : (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="text-sm text-t1">{group.label}</span>
|
||||
{totalQuantity > 0 && (
|
||||
<Badge
|
||||
variant="muted"
|
||||
className="text-[10px] px-1.5 py-0 text-t3"
|
||||
>
|
||||
Qty: {totalQuantity}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{period && <span className="text-xs text-t4">{period}</span>}
|
||||
</div>
|
||||
@@ -399,6 +418,7 @@ function LineItemGroupRow({
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Tier breakdown - each row has own hover */}
|
||||
<div className="mt-1 ml-3 flex flex-col gap-0.5">
|
||||
{group.items.map((item) => (
|
||||
<TierRow
|
||||
@@ -407,6 +427,7 @@ function LineItemGroupRow({
|
||||
hoverTexts={getLineItemHoverTexts(item)}
|
||||
formatAmount={formatAmount}
|
||||
currency={currency}
|
||||
showDescriptions={showDescriptions}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -423,25 +444,26 @@ function LineItemGroupRow({
|
||||
<div className="flex flex-col py-1">
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div className="flex flex-col min-w-0 flex-1 gap-0.5">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="text-sm text-t1">{group.label}</span>
|
||||
{(!group.isBasePrice && firstItem.total_quantity) ||
|
||||
(group.isBasePrice &&
|
||||
firstItem.stripe_quantity &&
|
||||
firstItem.stripe_quantity > 1) ? (
|
||||
<Badge
|
||||
variant="muted"
|
||||
className="text-[10px] px-1.5 py-0 text-t3"
|
||||
>
|
||||
Qty:{" "}
|
||||
{group.isBasePrice
|
||||
? firstItem.stripe_quantity
|
||||
: firstItem.total_quantity}
|
||||
</Badge>
|
||||
) : null}
|
||||
</div>
|
||||
{firstItem.description && (
|
||||
{showDescriptions ? (
|
||||
<span className="text-xs text-t3">{firstItem.description}</span>
|
||||
) : (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="text-sm text-t1">{group.label}</span>
|
||||
{(!group.isBasePrice && firstItem.total_quantity) ||
|
||||
(group.isBasePrice &&
|
||||
firstItem.stripe_quantity &&
|
||||
firstItem.stripe_quantity > 1) ? (
|
||||
<Badge
|
||||
variant="muted"
|
||||
className="text-[10px] px-1.5 py-0 text-t3"
|
||||
>
|
||||
Qty:{" "}
|
||||
{group.isBasePrice
|
||||
? firstItem.stripe_quantity
|
||||
: firstItem.total_quantity}
|
||||
</Badge>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
{period && <span className="text-xs text-t4">{period}</span>}
|
||||
</div>
|
||||
@@ -491,18 +513,23 @@ function TierRow({
|
||||
hoverTexts,
|
||||
formatAmount,
|
||||
currency,
|
||||
showDescriptions,
|
||||
}: {
|
||||
item: InvoiceLineItem;
|
||||
hoverTexts: { key: string; value: string }[];
|
||||
formatAmount: (amount: number, currency: string) => string;
|
||||
currency: string;
|
||||
showDescriptions: boolean;
|
||||
}) {
|
||||
const isRefund = item.direction === "refund";
|
||||
const quantityLabel = item.total_quantity ? `${item.total_quantity}` : "";
|
||||
|
||||
return (
|
||||
<AdminHover asChild texts={hoverTexts}>
|
||||
<div className="flex items-center justify-between text-xs text-t3">
|
||||
<span>{item.description}</span>
|
||||
<span>
|
||||
{showDescriptions ? item.description : `${quantityLabel} units`}
|
||||
</span>
|
||||
<span
|
||||
className={cn(
|
||||
"tabular-nums",
|
||||
|
||||
@@ -39,6 +39,9 @@ export function RefundInvoiceDialog({
|
||||
const buildQueryKey = useQueryKeyFactory();
|
||||
|
||||
const customerId = customer?.id || customer?.internal_id;
|
||||
const alreadyRefunded = invoice.refunded_amount ?? 0;
|
||||
const refundableAmount = Math.abs(invoice.amount_paid ?? invoice.total);
|
||||
const remainingRefundable = refundableAmount - alreadyRefunded;
|
||||
|
||||
const refundMutation = useMutation({
|
||||
mutationFn: async () => {
|
||||
@@ -70,10 +73,6 @@ export function RefundInvoiceDialog({
|
||||
},
|
||||
});
|
||||
|
||||
const alreadyRefunded = invoice.refunded_amount ?? 0;
|
||||
const refundableAmount = Math.abs(invoice.amount_paid ?? invoice.total);
|
||||
const remainingRefundable = refundableAmount - alreadyRefunded;
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (mode === "partial") {
|
||||
const parsed = Number.parseFloat(amount);
|
||||
@@ -148,7 +147,6 @@ export function RefundInvoiceDialog({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Refund summary */}
|
||||
<div className="flex flex-col gap-1 border-t border-border/40 pt-3">
|
||||
{alreadyRefunded > 0 && (
|
||||
<div className="flex justify-between text-xs text-t3">
|
||||
|
||||
@@ -24,17 +24,14 @@ const statusConfig = {
|
||||
};
|
||||
|
||||
const getRefundStatus = ({
|
||||
amountPaid,
|
||||
total,
|
||||
refundedAmount,
|
||||
}: {
|
||||
amountPaid: number;
|
||||
total: number;
|
||||
refundedAmount: number;
|
||||
}): { color: string; label: string } | null => {
|
||||
if (refundedAmount <= 0) return null;
|
||||
const refundableAmount = Math.abs(amountPaid ?? total);
|
||||
if (refundedAmount >= refundableAmount) {
|
||||
if (refundedAmount >= Math.abs(total)) {
|
||||
return {
|
||||
color: "bg-amber-500 dark:bg-amber-600",
|
||||
label: "Fully Refunded",
|
||||
@@ -48,12 +45,10 @@ const getRefundStatus = ({
|
||||
|
||||
export function CustomerInvoiceStatus({
|
||||
status,
|
||||
amountPaid,
|
||||
total,
|
||||
refundedAmount,
|
||||
}: {
|
||||
status: InvoiceStatus | null | undefined;
|
||||
amountPaid?: number | null;
|
||||
total?: number;
|
||||
refundedAmount?: number;
|
||||
}) {
|
||||
@@ -64,11 +59,7 @@ export function CustomerInvoiceStatus({
|
||||
status === InvoiceStatus.Paid &&
|
||||
total !== undefined &&
|
||||
refundedAmount !== undefined
|
||||
? getRefundStatus({
|
||||
amountPaid: amountPaid ?? total,
|
||||
total,
|
||||
refundedAmount,
|
||||
})
|
||||
? getRefundStatus({ total, refundedAmount })
|
||||
: null;
|
||||
|
||||
const config = refundStatus ?? statusConfig[status];
|
||||
|
||||
@@ -32,11 +32,10 @@ export const CustomerInvoicesColumns = [
|
||||
accessorKey: "total",
|
||||
cell: ({ row }: { row: Row<CustomerInvoice> }) => {
|
||||
const invoice = row.original;
|
||||
const displayTotal = invoice.amount_paid ?? invoice.total;
|
||||
const discountAmount = getTotalDiscountAmount(invoice);
|
||||
return (
|
||||
<div>
|
||||
{displayTotal.toFixed(2)} {invoice.currency.toUpperCase()}
|
||||
{invoice.total.toFixed(2)} {invoice.currency.toUpperCase()}
|
||||
{discountAmount > 0 && (
|
||||
<span className="text-t3"> (-{discountAmount.toFixed(2)})</span>
|
||||
)}
|
||||
@@ -52,7 +51,6 @@ export const CustomerInvoicesColumns = [
|
||||
return (
|
||||
<CustomerInvoiceStatus
|
||||
status={invoice.status}
|
||||
amountPaid={invoice.amount_paid}
|
||||
total={invoice.total}
|
||||
refundedAmount={invoice.refunded_amount}
|
||||
/>
|
||||
|
||||
@@ -36,7 +36,7 @@ export function CustomerInvoicesTable() {
|
||||
);
|
||||
|
||||
const { lineItemsByInvoiceId } = useInvoiceLineItemsQuery({
|
||||
customerId: customer?.id || customer?.internal_id,
|
||||
customerId: customer?.internal_id || customer?.id,
|
||||
invoiceIds,
|
||||
enabled: invoiceIds.length > 0,
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Invoice, InvoiceLineItem } from "@autumn/shared";
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
import { SheetContainer } from "@/components/v2/sheets/InlineSheet";
|
||||
import { SheetCloseButton } from "@/components/v2/sheets/SheetCloseButton";
|
||||
@@ -67,8 +68,12 @@ export function CustomerSheets() {
|
||||
return <BalanceDeleteSheet />;
|
||||
case "balance-create":
|
||||
return <BalanceCreateSheet />;
|
||||
case "invoice-detail":
|
||||
return <InvoiceDetailSheet />;
|
||||
case "invoice-detail": {
|
||||
const invoice = sheetData?.invoice as Invoice | undefined;
|
||||
const lineItems = (sheetData?.lineItems as InvoiceLineItem[]) ?? [];
|
||||
if (!invoice) return null;
|
||||
return <InvoiceDetailSheet invoice={invoice} lineItems={lineItems} />;
|
||||
}
|
||||
case "sync-stripe":
|
||||
return <SyncStripeSheet />;
|
||||
case "billing-auto-topup-add":
|
||||
|
||||
Reference in New Issue
Block a user