fix build

This commit is contained in:
KMKoushik
2025-05-02 21:58:38 +10:00
parent d6e0126f7b
commit 2de7147cdf
7 changed files with 56 additions and 44 deletions

View File

@@ -22,11 +22,8 @@ import { isLocalhost } from "~/utils/client";
const FormSchema = z.object({ const FormSchema = z.object({
region: z.string(), region: z.string(),
unsendUrl: z.string().url(), unsendUrl: z.string().url(),
sendRate: z.preprocess((val) => Number(val), z.number()), sendRate: z.coerce.number(),
transactionalQuota: z.preprocess( transactionalQuota: z.coerce.number().min(0).max(100),
(val) => Number(val),
z.number().min(0).max(100)
),
}); });
type SesSettingsProps = { type SesSettingsProps = {

View File

@@ -1,7 +1,7 @@
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
export function useInterval(callback: () => void, delay: number | null) { export function useInterval(callback: () => void, delay: number | null) {
const savedCallback = useRef<() => void>(); const savedCallback = useRef<(() => void) | null>(null);
// Remember the latest callback. // Remember the latest callback.
useEffect(() => { useEffect(() => {

View File

@@ -125,13 +125,21 @@ export async function syncStripeData(customerId: string) {
return; return;
} }
if (!subscription.items.data[0]) {
return;
}
await db.subscription.upsert({ await db.subscription.upsert({
where: { id: subscription.id }, where: { id: subscription.id },
update: { update: {
status: subscription.status, status: subscription.status,
priceId: subscription.items.data[0]?.price?.id || "", priceId: subscription.items.data[0]?.price?.id || "",
currentPeriodEnd: new Date(subscription.current_period_end * 1000), currentPeriodEnd: new Date(
currentPeriodStart: new Date(subscription.current_period_start * 1000), subscription.items.data[0]?.current_period_end * 1000
),
currentPeriodStart: new Date(
subscription.items.data[0]?.current_period_start * 1000
),
cancelAtPeriodEnd: subscription.cancel_at cancelAtPeriodEnd: subscription.cancel_at
? new Date(subscription.cancel_at * 1000) ? new Date(subscription.cancel_at * 1000)
: null, : null,
@@ -142,8 +150,12 @@ export async function syncStripeData(customerId: string) {
id: subscription.id, id: subscription.id,
status: subscription.status, status: subscription.status,
priceId: subscription.items.data[0]?.price?.id || "", priceId: subscription.items.data[0]?.price?.id || "",
currentPeriodEnd: new Date(subscription.current_period_end * 1000), currentPeriodEnd: new Date(
currentPeriodStart: new Date(subscription.current_period_start * 1000), subscription.items.data[0]?.current_period_end * 1000
),
currentPeriodStart: new Date(
subscription.items.data[0]?.current_period_start * 1000
),
cancelAtPeriodEnd: subscription.cancel_at cancelAtPeriodEnd: subscription.cancel_at
? new Date(subscription.cancel_at * 1000) ? new Date(subscription.cancel_at * 1000)
: null, : null,

View File

@@ -6,7 +6,7 @@ const METER_EVENT_NAME = "unsend_usage";
export async function sendUsageToStripe(customerId: string, usage: number) { export async function sendUsageToStripe(customerId: string, usage: number) {
const stripe = new Stripe(env.STRIPE_SECRET_KEY!, { const stripe = new Stripe(env.STRIPE_SECRET_KEY!, {
apiVersion: "2025-01-27.acacia", apiVersion: "2025-03-31.basil",
}); });
const meterEvent = await stripe.billing.meterEvents.create({ const meterEvent = await stripe.billing.meterEvents.create({

View File

@@ -44,7 +44,7 @@ export type SlashCommandItem = {
title: string; title: string;
description: string; description: string;
searchTerms: string[]; searchTerms: string[];
icon: JSX.Element; icon: ReactNode;
command: (options: CommandProps) => void; command: (options: CommandProps) => void;
}; };

View File

@@ -5,7 +5,7 @@ import { MenuProps } from "../types";
import { LinkPreviewPanel } from "../components/panels/LinkPreviewPanel"; import { LinkPreviewPanel } from "../components/panels/LinkPreviewPanel";
import { LinkEditorPanel } from "../components/panels/LinkEditorPanel"; import { LinkEditorPanel } from "../components/panels/LinkEditorPanel";
export const LinkMenu = ({ editor, appendTo }: MenuProps): JSX.Element => { export const LinkMenu = ({ editor, appendTo }: MenuProps): React.ReactNode => {
const [showEdit, setShowEdit] = useState(false); const [showEdit, setShowEdit] = useState(false);
const shouldShow = useCallback(() => { const shouldShow = useCallback(() => {

View File

@@ -10,7 +10,7 @@ import {
Link, Link,
Heading, Heading,
Hr, Hr,
Button, Butan as Button,
Img, Img,
Preview, Preview,
Row, Row,
@@ -271,17 +271,17 @@ export class EmailRenderer {
} }
// `renderMark` will call the method of the corresponding mark type // `renderMark` will call the method of the corresponding mark type
private renderMark(node: JSONContent): JSX.Element { private renderMark(node: JSONContent): React.ReactNode {
// It will wrap the text with the corresponding mark type // It will wrap the text with the corresponding mark type
const text = node.text || <>&nbsp;</>; const text = node.text || <>&nbsp;</>;
const marks = node.marks || []; const marks = node.marks || [];
return marks.reduce( return marks.reduce<React.ReactNode>(
(acc, mark) => { (acc, mark) => {
const type = mark.type; const type = mark.type;
if (type in this) { if (type in this) {
// @ts-expect-error - `this` is not assignable to type 'never' // @ts-expect-error - `this` is not assignable to type 'never'
return this[type]?.(mark, acc) as JSX.Element; return this[type]?.(mark, acc) as React.ReactNode;
} }
throw new Error(`Mark type "${type}" is not supported.`); throw new Error(`Mark type "${type}" is not supported.`);
@@ -293,7 +293,7 @@ export class EmailRenderer {
private getMappedContent( private getMappedContent(
node: JSONContent, node: JSONContent,
options?: NodeOptions options?: NodeOptions
): JSX.Element[] { ): React.ReactNode[] {
return node.content return node.content
?.map((childNode) => { ?.map((childNode) => {
const component = this.renderNode(childNode, options); const component = this.renderNode(childNode, options);
@@ -303,18 +303,18 @@ export class EmailRenderer {
return <Fragment key={generateKey()}>{component}</Fragment>; return <Fragment key={generateKey()}>{component}</Fragment>;
}) })
.filter((n) => n !== null) as JSX.Element[]; .filter((n) => n !== null) as React.ReactNode[];
} }
private renderNode( private renderNode(
node: JSONContent, node: JSONContent,
options: NodeOptions = {} options: NodeOptions = {}
): JSX.Element | null { ): React.ReactNode | null {
const type = node.type || ""; const type = node.type || "";
if (type in this) { if (type in this) {
// @ts-expect-error - `this` is not assignable to type 'never' // @ts-expect-error - `this` is not assignable to type 'never'
return this[type]?.(node, options) as JSX.Element; return this[type]?.(node, options) as React.ReactNode;
} }
throw new Error(`Node type "${type}" is not supported.`); throw new Error(`Node type "${type}" is not supported.`);
@@ -323,7 +323,7 @@ export class EmailRenderer {
private unsubscribeFooter( private unsubscribeFooter(
node: JSONContent, node: JSONContent,
options?: NodeOptions options?: NodeOptions
): JSX.Element { ): React.ReactNode {
return ( return (
<Container <Container
style={{ style={{
@@ -338,7 +338,7 @@ export class EmailRenderer {
); );
} }
private paragraph(node: JSONContent, options?: NodeOptions): JSX.Element { private paragraph(node: JSONContent, options?: NodeOptions): React.ReactNode {
const { attrs } = node; const { attrs } = node;
const alignment = attrs?.textAlign || "left"; const alignment = attrs?.textAlign || "left";
@@ -362,7 +362,7 @@ export class EmailRenderer {
); );
} }
private text(node: JSONContent, _?: NodeOptions): JSX.Element { private text(node: JSONContent, _?: NodeOptions): React.ReactNode {
const text = node.text || "&nbsp"; const text = node.text || "&nbsp";
if (node.marks) { if (node.marks) {
return this.renderMark(node); return this.renderMark(node);
@@ -371,30 +371,30 @@ export class EmailRenderer {
return <>{text}</>; return <>{text}</>;
} }
private bold(_: MarkType, text: JSX.Element): JSX.Element { private bold(_: MarkType, text: React.ReactNode): React.ReactNode {
return <strong>{text}</strong>; return <strong>{text}</strong>;
} }
private italic(_: MarkType, text: JSX.Element): JSX.Element { private italic(_: MarkType, text: React.ReactNode): React.ReactNode {
return <em>{text}</em>; return <em>{text}</em>;
} }
private underline(_: MarkType, text: JSX.Element): JSX.Element { private underline(_: MarkType, text: React.ReactNode): React.ReactNode {
return <u>{text}</u>; return <u>{text}</u>;
} }
private strike(_: MarkType, text: JSX.Element): JSX.Element { private strike(_: MarkType, text: React.ReactNode): React.ReactNode {
return <s style={{ textDecoration: "line-through" }}>{text}</s>; return <s style={{ textDecoration: "line-through" }}>{text}</s>;
} }
private textStyle(mark: MarkType, text: JSX.Element): JSX.Element { private textStyle(mark: MarkType, text: React.ReactNode): React.ReactNode {
const { attrs } = mark; const { attrs } = mark;
const { fontSize, fontWeight, color } = attrs || {}; const { fontSize, fontWeight, color } = attrs || {};
return <span style={{ fontSize, fontWeight, color }}>{text}</span>; return <span style={{ fontSize, fontWeight, color }}>{text}</span>;
} }
private link(mark: MarkType, text: JSX.Element): JSX.Element { private link(mark: MarkType, text: React.ReactNode): React.ReactNode {
const { attrs } = mark; const { attrs } = mark;
let href = attrs?.href || "#"; let href = attrs?.href || "#";
const target = attrs?.target || "_blank"; const target = attrs?.target || "_blank";
@@ -425,7 +425,7 @@ export class EmailRenderer {
); );
} }
private heading(node: JSONContent, options?: NodeOptions): JSX.Element { private heading(node: JSONContent, options?: NodeOptions): React.ReactNode {
const { attrs } = node; const { attrs } = node;
const { next, prev } = options || {}; const { next, prev } = options || {};
@@ -456,7 +456,7 @@ export class EmailRenderer {
); );
} }
private variable(node: JSONContent, _?: NodeOptions): JSX.Element { private variable(node: JSONContent, _?: NodeOptions): React.ReactNode {
const { id: variable, fallback } = node.attrs || {}; const { id: variable, fallback } = node.attrs || {};
let formattedVariable = this.variableFormatter({ let formattedVariable = this.variableFormatter({
@@ -474,7 +474,7 @@ export class EmailRenderer {
return <>{formattedVariable}</>; return <>{formattedVariable}</>;
} }
private horizontalRule(_: JSONContent, __?: NodeOptions): JSX.Element { private horizontalRule(_: JSONContent, __?: NodeOptions): React.ReactNode {
return ( return (
<Hr <Hr
style={{ style={{
@@ -486,7 +486,7 @@ export class EmailRenderer {
); );
} }
private orderedList(node: JSONContent, _?: NodeOptions): JSX.Element { private orderedList(node: JSONContent, _?: NodeOptions): React.ReactNode {
return ( return (
<Container style={{ maxWidth: "100%" }}> <Container style={{ maxWidth: "100%" }}>
<ol <ol
@@ -503,7 +503,7 @@ export class EmailRenderer {
); );
} }
private bulletList(node: JSONContent, _?: NodeOptions): JSX.Element { private bulletList(node: JSONContent, _?: NodeOptions): React.ReactNode {
return ( return (
<Container <Container
style={{ style={{
@@ -524,7 +524,7 @@ export class EmailRenderer {
); );
} }
private listItem(node: JSONContent, options?: NodeOptions): JSX.Element { private listItem(node: JSONContent, options?: NodeOptions): React.ReactNode {
return ( return (
<Container <Container
style={{ style={{
@@ -544,7 +544,7 @@ export class EmailRenderer {
); );
} }
private button(node: JSONContent, options?: NodeOptions): JSX.Element { private button(node: JSONContent, options?: NodeOptions): React.ReactNode {
const { attrs } = node; const { attrs } = node;
const { const {
text, text,
@@ -592,7 +592,7 @@ export class EmailRenderer {
); );
} }
private spacer(node: JSONContent, _?: NodeOptions): JSX.Element { private spacer(node: JSONContent, _?: NodeOptions): React.ReactNode {
const { attrs } = node; const { attrs } = node;
const { height = "auto" } = attrs || {}; const { height = "auto" } = attrs || {};
@@ -605,11 +605,11 @@ export class EmailRenderer {
); );
} }
private hardBreak(_: JSONContent, __?: NodeOptions): JSX.Element { private hardBreak(_: JSONContent, __?: NodeOptions): React.ReactNode {
return <br />; return <br />;
} }
private logo(node: JSONContent, options?: NodeOptions): JSX.Element { private logo(node: JSONContent, options?: NodeOptions): React.ReactNode {
const { attrs } = node; const { attrs } = node;
const { const {
src, src,
@@ -645,7 +645,7 @@ export class EmailRenderer {
); );
} }
private image(node: JSONContent, options?: NodeOptions): JSX.Element { private image(node: JSONContent, options?: NodeOptions): React.ReactNode {
const { attrs } = node; const { attrs } = node;
const { const {
src, src,
@@ -711,7 +711,10 @@ export class EmailRenderer {
); );
} }
private blockquote(node: JSONContent, options?: NodeOptions): JSX.Element { private blockquote(
node: JSONContent,
options?: NodeOptions
): React.ReactNode {
const { next, prev } = options || {}; const { next, prev } = options || {};
const isNextSpacer = next?.type === "spacer"; const isNextSpacer = next?.type === "spacer";
const isPrevSpacer = prev?.type === "spacer"; const isPrevSpacer = prev?.type === "spacer";
@@ -734,7 +737,7 @@ export class EmailRenderer {
); );
} }
private code(_: MarkType, text: JSX.Element): JSX.Element { private code(_: MarkType, text: React.ReactNode): React.ReactNode {
return ( return (
<code <code
style={{ style={{
@@ -752,7 +755,7 @@ export class EmailRenderer {
); );
} }
private codeBlock(node: JSONContent, options?: NodeOptions): JSX.Element { private codeBlock(node: JSONContent, options?: NodeOptions): React.ReactNode {
const { attrs } = node; const { attrs } = node;
const language = attrs?.language; const language = attrs?.language;