Compare commits
8 Commits
feature/se
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5362ff7599 | |||
| 21b3c3ba83 | |||
| 44b9793c60 | |||
| 35020f2499 | |||
| 20b09849bc | |||
| dc3850ac4d | |||
| e73262b3b3 | |||
| 7299a266f1 |
@@ -1,6 +1,6 @@
|
|||||||
ADMIN_EMAIL=""
|
ADMIN_EMAIL=""
|
||||||
CRON_SECRET=""
|
CRON_SECRET=""
|
||||||
HOME_URL=""
|
NEXT_PUBLIC_HOME_URL=""
|
||||||
OVHCLOUD_API_KEY=""
|
OVHCLOUD_API_KEY=""
|
||||||
MAINTENANCE_MODE="0"
|
MAINTENANCE_MODE="0"
|
||||||
NEWS_LIMIT="50"
|
NEWS_LIMIT="50"
|
||||||
@@ -8,7 +8,8 @@ NEWS_TO_USE="10"
|
|||||||
NEXT_PUBLIC_BRAND_COUNTRY=""
|
NEXT_PUBLIC_BRAND_COUNTRY=""
|
||||||
NEXT_PUBLIC_BRAND_EMAIL=""
|
NEXT_PUBLIC_BRAND_EMAIL=""
|
||||||
NEXT_PUBLIC_BRAND_NAME=""
|
NEXT_PUBLIC_BRAND_NAME=""
|
||||||
|
NEXT_PUBLIC_BRAND_OWNER_NAME=""
|
||||||
DATABASE_URL=""
|
DATABASE_URL=""
|
||||||
RESEND_FROM=""
|
SWEEGO_API_KEY=""
|
||||||
RESEND_KEY=""
|
SWEEGO_FROM=""
|
||||||
SECRET_HASH=""
|
SECRET_HASH=""
|
||||||
|
|||||||
@@ -36,6 +36,6 @@ jobs:
|
|||||||
ssh debian@51.210.247.57 << 'EOF'
|
ssh debian@51.210.247.57 << 'EOF'
|
||||||
cd /home/debian/newsletter-hackernews
|
cd /home/debian/newsletter-hackernews
|
||||||
git pull origin main
|
git pull origin main
|
||||||
cd /home/debian/gitea
|
cd /home/debian/infrastructure
|
||||||
docker compose up -d --build newsletter
|
docker compose up -d --build newsletter
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@@ -11,10 +11,14 @@ COPY . .
|
|||||||
ARG NEXT_PUBLIC_BRAND_NAME
|
ARG NEXT_PUBLIC_BRAND_NAME
|
||||||
ARG NEXT_PUBLIC_BRAND_EMAIL
|
ARG NEXT_PUBLIC_BRAND_EMAIL
|
||||||
ARG NEXT_PUBLIC_BRAND_COUNTRY
|
ARG NEXT_PUBLIC_BRAND_COUNTRY
|
||||||
|
ARG NEXT_PUBLIC_HOME_URL
|
||||||
|
ARG NEXT_PUBLIC_BRAND_OWNER_NAME
|
||||||
|
|
||||||
ENV NEXT_PUBLIC_BRAND_NAME=$NEXT_PUBLIC_BRAND_NAME
|
ENV NEXT_PUBLIC_BRAND_NAME=$NEXT_PUBLIC_BRAND_NAME
|
||||||
ENV NEXT_PUBLIC_BRAND_EMAIL=$NEXT_PUBLIC_BRAND_EMAIL
|
ENV NEXT_PUBLIC_BRAND_EMAIL=$NEXT_PUBLIC_BRAND_EMAIL
|
||||||
ENV NEXT_PUBLIC_BRAND_COUNTRY=$NEXT_PUBLIC_BRAND_COUNTRY
|
ENV NEXT_PUBLIC_BRAND_COUNTRY=$NEXT_PUBLIC_BRAND_COUNTRY
|
||||||
|
ENV NEXT_PUBLIC_HOME_URL=$NEXT_PUBLIC_HOME_URL
|
||||||
|
ENV NEXT_PUBLIC_BRAND_OWNER_NAME=$NEXT_PUBLIC_BRAND_OWNER_NAME
|
||||||
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ export const dynamic = 'force-dynamic'; // defaults to force-static
|
|||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
if (!process.env.RESEND_KEY) {
|
if (!process.env.SWEEGO_API_KEY) {
|
||||||
throw new Error('Resend variables not set');
|
throw new Error('SWEEGO_API_KEY is not set');
|
||||||
}
|
}
|
||||||
const body = await request.json();
|
const body = await request.json();
|
||||||
const validation = ConfirmationSchema.safeParse(body);
|
const validation = ConfirmationSchema.safeParse(body);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { NewsletterTemplate } from '@components/email/Newsletter';
|
import { NewsletterTemplate } from '@components/email/Newsletter';
|
||||||
import prisma from '@prisma/prisma';
|
import prisma from '@prisma/prisma';
|
||||||
import { formatApiResponse } from '@utils/formatApiResponse';
|
import { formatApiResponse } from '@utils/formatApiResponse';
|
||||||
import { sender } from '@utils/resendClient';
|
import { sender } from '@utils/sweego';
|
||||||
import {
|
import {
|
||||||
INTERNAL_SERVER_ERROR,
|
INTERNAL_SERVER_ERROR,
|
||||||
STATUS_INTERNAL_SERVER_ERROR,
|
STATUS_INTERNAL_SERVER_ERROR,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ConfirmationTemplate } from '@components/email/Confirmation';
|
import { ConfirmationTemplate } from '@components/email/Confirmation';
|
||||||
import prisma from '@prisma/prisma';
|
import prisma from '@prisma/prisma';
|
||||||
import { formatApiResponse } from '@utils/formatApiResponse';
|
import { formatApiResponse } from '@utils/formatApiResponse';
|
||||||
import { sender } from '@utils/resendClient';
|
import { sender } from '@utils/sweego';
|
||||||
import {
|
import {
|
||||||
BAD_REQUEST,
|
BAD_REQUEST,
|
||||||
INTERNAL_SERVER_ERROR,
|
INTERNAL_SERVER_ERROR,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UnsubscribeTemplate } from '@components/email/Unsubscribe';
|
import { UnsubscribeTemplate } from '@components/email/Unsubscribe';
|
||||||
import prisma from '@prisma/prisma';
|
import prisma from '@prisma/prisma';
|
||||||
import { formatApiResponse } from '@utils/formatApiResponse';
|
import { formatApiResponse } from '@utils/formatApiResponse';
|
||||||
import { sender } from '@utils/resendClient';
|
import { sender } from '@utils/sweego';
|
||||||
import {
|
import {
|
||||||
BAD_REQUEST,
|
BAD_REQUEST,
|
||||||
INTERNAL_SERVER_ERROR,
|
INTERNAL_SERVER_ERROR,
|
||||||
@@ -30,13 +30,10 @@ export async function POST(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user && !user.deleted) {
|
if (user) {
|
||||||
await prisma.user.update({
|
await prisma.user.delete({
|
||||||
where: {
|
where: {
|
||||||
email
|
email
|
||||||
},
|
|
||||||
data: {
|
|
||||||
deleted: true
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const Confirmation = () => {
|
|||||||
'@type': 'WebSite',
|
'@type': 'WebSite',
|
||||||
name: 'Hackernews Newsletter',
|
name: 'Hackernews Newsletter',
|
||||||
title: 'Subscription Confirmation',
|
title: 'Subscription Confirmation',
|
||||||
url: `${process.env.HOME_URL}/confirmation`
|
url: `${process.env.NEXT_PUBLIC_HOME_URL}/confirmation`
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Tiles } from '@components/tiles/Tiles';
|
import { Tiles } from '@components/tiles/Tiles';
|
||||||
import { cn } from '@utils/cn';
|
import { cn } from '@utils/cn';
|
||||||
import { Analytics } from '@vercel/analytics/react';
|
|
||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
import { Inter as FontSans } from 'next/font/google';
|
import { Inter as FontSans } from 'next/font/google';
|
||||||
|
import Script from 'next/script';
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
@@ -34,8 +34,12 @@ export default function RootLayout({
|
|||||||
<Tiles>
|
<Tiles>
|
||||||
<div className='z-10'>{children}</div>
|
<div className='z-10'>{children}</div>
|
||||||
</Tiles>
|
</Tiles>
|
||||||
<Analytics />
|
|
||||||
</body>
|
</body>
|
||||||
|
<Script
|
||||||
|
defer
|
||||||
|
src='https://analytics.frompixels.com/script.js'
|
||||||
|
data-website-id='588e7b7d-e9cd-4b96-94bf-8269c499b0a2'
|
||||||
|
/>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const Home = () => {
|
|||||||
'@type': 'WebSite',
|
'@type': 'WebSite',
|
||||||
name: 'Hackernews Newsletter',
|
name: 'Hackernews Newsletter',
|
||||||
title: 'Home',
|
title: 'Home',
|
||||||
url: process.env.HOME_URL
|
url: process.env.NEXT_PUBLIC_HOME_URL
|
||||||
};
|
};
|
||||||
|
|
||||||
const form = useForm<SubscribeFormType>({
|
const form = useForm<SubscribeFormType>({
|
||||||
|
|||||||
@@ -2,458 +2,113 @@
|
|||||||
|
|
||||||
import { CustomCard } from '@components/CustomCard';
|
import { CustomCard } from '@components/CustomCard';
|
||||||
import { SchemaOrg } from '@components/SchemaOrg';
|
import { SchemaOrg } from '@components/SchemaOrg';
|
||||||
import { useState, useEffect } from 'react';
|
|
||||||
|
|
||||||
const useObfuscatedEmail = () => {
|
|
||||||
const [email, setEmail] = useState<string | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setEmail(process.env.NEXT_PUBLIC_BRAND_EMAIL || null);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return email;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Privacy = () => {
|
const Privacy = () => {
|
||||||
const email = useObfuscatedEmail();
|
|
||||||
|
|
||||||
const schema = {
|
const schema = {
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@type': 'WebSite',
|
'@type': 'WebSite',
|
||||||
name: 'Hackernews Newsletter',
|
name: 'Hackernews Newsletter',
|
||||||
title: 'Privacy Policy',
|
title: 'Privacy Policy',
|
||||||
url: `${process.env.HOME_URL}/privacy`
|
url: `${process.env.NEXT_PUBLIC_HOME_URL}/privacy`
|
||||||
};
|
};
|
||||||
|
|
||||||
const body = (
|
const body = (
|
||||||
<div className='privacy-content my-2 max-h-[50vh] space-y-1 overflow-auto'>
|
<div className='privacy-content my-2 max-h-[50vh] space-y-1 overflow-auto'>
|
||||||
|
<h2>Who We Are</h2>
|
||||||
<p className='leading-relaxed'>
|
<p className='leading-relaxed'>
|
||||||
This Privacy Policy describes Our policies and procedures on the
|
Data controller: {process.env.NEXT_PUBLIC_BRAND_OWNER_NAME}, an
|
||||||
collection, use and disclosure of Your information when You use the
|
individual based in {process.env.NEXT_PUBLIC_BRAND_COUNTRY}.
|
||||||
Service and tells You about Your privacy rights and how the law protects
|
|
||||||
You.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
We use Your Personal data to provide and improve the Service. By using
|
Contact:{' '}
|
||||||
the Service, You agree to the collection and use of information in
|
|
||||||
accordance with this Privacy Policy.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Interpretation and Definitions</h2>
|
|
||||||
<h3>Interpretation</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
The words of which the initial letter is capitalized have meanings
|
|
||||||
defined under the following conditions. The following definitions shall
|
|
||||||
have the same meaning regardless of whether they appear in singular or
|
|
||||||
in plural.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Definitions</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
For the purposes of this Privacy Policy:
|
|
||||||
</p>
|
|
||||||
<ul className='list-disc space-y-4 pl-6'>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Account</strong> means a unique account created for You to
|
|
||||||
access our Service or parts of our Service.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Affiliate</strong> means an entity that controls, is
|
|
||||||
controlled by or is under common control with a party, where
|
|
||||||
"control" means ownership of 50% or more of the shares,
|
|
||||||
equity interest or other securities entitled to vote for election of
|
|
||||||
directors or other managing authority.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Application</strong> refers to{' '}
|
|
||||||
{process.env.NEXT_PUBLIC_BRAND_NAME}, the software program provided
|
|
||||||
by the Company.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Company</strong> (referred to as either "the
|
|
||||||
Company", "We", "Us" or "Our" in
|
|
||||||
this Agreement) refers to {process.env.NEXT_PUBLIC_BRAND_NAME}.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Country</strong> refers to:{' '}
|
|
||||||
{process.env.NEXT_PUBLIC_BRAND_COUNTRY}
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Device</strong> means any device that can access the Service
|
|
||||||
such as a computer, a cellphone or a digital tablet.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Personal Data</strong> is any information that relates to an
|
|
||||||
identified or identifiable individual.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Service</strong> refers to the Application.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Service Provider</strong> means any natural or legal person
|
|
||||||
who processes the data on behalf of the Company. It refers to
|
|
||||||
third-party companies or individuals employed by the Company to
|
|
||||||
facilitate the Service, to provide the Service on behalf of the
|
|
||||||
Company, to perform services related to the Service or to assist the
|
|
||||||
Company in analyzing how the Service is used.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>Usage Data</strong> refers to data collected automatically,
|
|
||||||
either generated by the use of the Service or from the Service
|
|
||||||
infrastructure itself (for example, the duration of a page visit).
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>You</strong> means the individual accessing or using the
|
|
||||||
Service, or the company, or other legal entity on behalf of which
|
|
||||||
such individual is accessing or using the Service, as applicable.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Data Collection and Usage</h2>
|
|
||||||
<h3>Types of Data Collected</h3>
|
|
||||||
|
|
||||||
<h4>Personal Data</h4>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
While using Our Service, We may ask You to provide Us with certain
|
|
||||||
personally identifiable information that can be used to contact or
|
|
||||||
identify You. Personally identifiable information may include, but is
|
|
||||||
not limited to:
|
|
||||||
</p>
|
|
||||||
<ul className='list-disc space-y-4 pl-6'>
|
|
||||||
<li>
|
|
||||||
<p>Email address</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>Usage Data</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h4>Usage Data</h4>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
Usage Data is collected automatically when using the Service.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Usage Data may include information such as Your Device's Internet
|
|
||||||
Protocol address (e.g. IP address), browser type, browser version, the
|
|
||||||
pages of our Service that You visit, the time and date of Your visit,
|
|
||||||
the time spent on those pages, unique device identifiers and other
|
|
||||||
diagnostic data.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
When You access the Service by or through a mobile device, We may
|
|
||||||
collect certain information automatically, including, but not limited
|
|
||||||
to, the type of mobile device You use, Your mobile device unique ID, the
|
|
||||||
IP address of Your mobile device, Your mobile operating system, the type
|
|
||||||
of mobile Internet browser You use, unique device identifiers and other
|
|
||||||
diagnostic data.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We may also collect information that Your browser sends whenever You
|
|
||||||
visit our Service or when You access the Service by or through a mobile
|
|
||||||
device.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Use of Your Personal Data</h2>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
The Company may use Personal Data for the following purposes:
|
|
||||||
</p>
|
|
||||||
<ul className='list-disc space-y-4 pl-6'>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>To provide and maintain our Service</strong>, including to
|
|
||||||
monitor the usage of our Service.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>To manage Your Account:</strong> to manage Your registration
|
|
||||||
as a user of the Service. The Personal Data You provide can give You
|
|
||||||
access to different functionalities of the Service that are
|
|
||||||
available to You as a registered user.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>For the performance of a contract:</strong> the development,
|
|
||||||
compliance and undertaking of the purchase contract for the
|
|
||||||
products, items or services You have purchased or of any other
|
|
||||||
contract with Us through the Service.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>To contact You:</strong> To contact You by email, telephone
|
|
||||||
calls, SMS, or other equivalent forms of electronic communication,
|
|
||||||
such as a mobile application's push notifications regarding
|
|
||||||
updates or informative communications related to the
|
|
||||||
functionalities, products or contracted services, including the
|
|
||||||
security updates, when necessary or reasonable for their
|
|
||||||
implementation.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>To provide You</strong> with news, special offers and
|
|
||||||
general information about other goods, services and events which we
|
|
||||||
offer that are similar to those that you have already purchased or
|
|
||||||
enquired about unless You have opted not to receive such
|
|
||||||
information.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>To manage Your requests:</strong> To attend and manage Your
|
|
||||||
requests to Us.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>For business transfers:</strong> We may use Your information
|
|
||||||
to evaluate or conduct a merger, divestiture, restructuring,
|
|
||||||
reorganization, dissolution, or other sale or transfer of some or
|
|
||||||
all of Our assets, whether as a going concern or as part of
|
|
||||||
bankruptcy, liquidation, or similar proceeding, in which Personal
|
|
||||||
Data held by Us about our Service users is among the assets
|
|
||||||
transferred.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<strong>For other purposes</strong>: We may use Your information for
|
|
||||||
other purposes, such as data analysis, identifying usage trends,
|
|
||||||
determining the effectiveness of our promotional campaigns and to
|
|
||||||
evaluate and improve our Service, products, services, marketing and
|
|
||||||
your experience.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>We may share Your personal information in the following situations:</p>
|
|
||||||
<ul className='list-disc space-y-4 pl-6'>
|
|
||||||
<li>
|
|
||||||
<strong>With Service Providers:</strong> We may share Your personal
|
|
||||||
information with Service Providers to monitor and analyze the use of
|
|
||||||
our Service, to contact You.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<strong>For business transfers:</strong> We may share or transfer Your
|
|
||||||
personal information in connection with, or during negotiations of,
|
|
||||||
any merger, sale of Company assets, financing, or acquisition of all
|
|
||||||
or a portion of Our business to another company.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<strong>With Affiliates:</strong> We may share Your information with
|
|
||||||
Our affiliates, in which case we will require those affiliates to
|
|
||||||
honor this Privacy Policy. Affiliates include Our parent company and
|
|
||||||
any other subsidiaries, joint venture partners or other companies that
|
|
||||||
We control or that are under common control with Us.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<strong>With business partners:</strong> We may share Your information
|
|
||||||
with Our business partners to offer You certain products, services or
|
|
||||||
promotions.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<strong>With other users:</strong> when You share personal information
|
|
||||||
or otherwise interact in the public areas with other users, such
|
|
||||||
information may be viewed by all users and may be publicly distributed
|
|
||||||
outside.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<strong>With Your consent</strong>: We may disclose Your personal
|
|
||||||
information for any other purpose with Your consent.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Data Handling and Security</h2>
|
|
||||||
|
|
||||||
<h3>Retention of Your Personal Data</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
The Company will retain Your Personal Data only for as long as is
|
|
||||||
necessary for the purposes set out in this Privacy Policy. We will
|
|
||||||
retain and use Your Personal Data to the extent necessary to comply with
|
|
||||||
our legal obligations (for example, if we are required to retain your
|
|
||||||
data to comply with applicable laws), resolve disputes, and enforce our
|
|
||||||
legal agreements and policies.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The Company will also retain Usage Data for internal analysis purposes.
|
|
||||||
Usage Data is generally retained for a shorter period of time, except
|
|
||||||
when this data is used to strengthen the security or to improve the
|
|
||||||
functionality of Our Service, or We are legally obligated to retain this
|
|
||||||
data for longer time periods.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Transfer of Your Personal Data</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
Your information, including Personal Data, is processed at the
|
|
||||||
Company's operating offices and in any other places where the
|
|
||||||
parties involved in the processing are located. It means that this
|
|
||||||
information may be transferred to — and maintained on — computers
|
|
||||||
located outside of Your state, province, country or other governmental
|
|
||||||
jurisdiction where the data protection laws may differ than those from
|
|
||||||
Your jurisdiction.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Security of Your Personal Data</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
Your consent to this Privacy Policy followed by Your submission of such
|
|
||||||
information represents Your agreement to that transfer.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The Company will take all steps reasonably necessary to ensure that Your
|
|
||||||
data is treated securely and in accordance with this Privacy Policy and
|
|
||||||
no transfer of Your Personal Data will take place to an organization or
|
|
||||||
a country unless there are adequate controls in place including the
|
|
||||||
security of Your data and other personal information.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h4 className='text-lg font-medium text-gray-800'>
|
|
||||||
Delete Your Personal Data
|
|
||||||
</h4>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
You have the right to delete or request that We assist in deleting the
|
|
||||||
Personal Data that We have collected about You.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Our Service may give You the ability to delete certain information about
|
|
||||||
You from within the Service.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You may update, amend, or delete Your information at any time by signing
|
|
||||||
in to Your Account, if you have one, and visiting the account settings
|
|
||||||
section that allows you to manage Your personal information. You may
|
|
||||||
also contact Us to request access to, correct, or delete any personal
|
|
||||||
information that You have provided to Us.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Please note, however, that We may need to retain certain information
|
|
||||||
when we have a legal obligation or lawful basis to do so.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Legal Disclosures</h2>
|
|
||||||
|
|
||||||
<h3>Business Transactions</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
If the Company is involved in a merger, acquisition or asset sale, Your
|
|
||||||
Personal Data may be transferred. We will provide notice before Your
|
|
||||||
Personal Data is transferred and becomes subject to a different Privacy
|
|
||||||
Policy.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Law Enforcement</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
Under certain circumstances, the Company may be required to disclose
|
|
||||||
Your Personal Data if required to do so by law or in response to valid
|
|
||||||
requests by public authorities (e.g. a court or a government agency).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Other Legal Requirements</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
The Company may disclose Your Personal Data in the good faith belief
|
|
||||||
that such action is necessary to:
|
|
||||||
</p>
|
|
||||||
<ul className='list-disc space-y-4 pl-6'>
|
|
||||||
<li>Comply with a legal obligation</li>
|
|
||||||
<li>Protect and defend the rights or property of the Company</li>
|
|
||||||
<li>
|
|
||||||
Prevent or investigate possible wrongdoing in connection with the
|
|
||||||
Service
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Protect the personal safety of Users of the Service or the public
|
|
||||||
</li>
|
|
||||||
<li>Protect against legal liability</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Additional Information</h2>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
The security of Your Personal Data is important to Us, but remember that
|
|
||||||
no method of transmission over the Internet, or method of electronic
|
|
||||||
storage is 100% secure. While We strive to use commercially acceptable
|
|
||||||
means to protect Your Personal Data, We cannot guarantee its absolute
|
|
||||||
security.
|
|
||||||
</p>
|
|
||||||
<h3>Children's Privacy</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
Our Service does not address anyone under the age of 13. We do not
|
|
||||||
knowingly collect personally identifiable information from anyone under
|
|
||||||
the age of 13. If You are a parent or guardian and You are aware that
|
|
||||||
Your child has provided Us with Personal Data, please contact Us. If We
|
|
||||||
become aware that We have collected Personal Data from anyone under the
|
|
||||||
age of 13 without verification of parental consent, We take steps to
|
|
||||||
remove that information from Our servers.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If We need to rely on consent as a legal basis for processing Your
|
|
||||||
information and Your country requires consent from a parent, We may
|
|
||||||
require Your parent's consent before We collect and use that
|
|
||||||
information.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Links to Other Websites</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
Our Service may contain links to other websites that are not operated by
|
|
||||||
Us. If You click on a third party link, You will be directed to that
|
|
||||||
third party's site. We strongly advise You to review the Privacy
|
|
||||||
Policy of every site You visit.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We have no control over and assume no responsibility for the content,
|
|
||||||
privacy policies or practices of any third party sites or services.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Changes to this Privacy Policy</h3>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
We may update Our Privacy Policy from time to time. We will notify You
|
|
||||||
of any changes by posting the new Privacy Policy on this page.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We will let You know via email and/or a prominent notice on Our Service,
|
|
||||||
prior to the change becoming effective and update the "Last
|
|
||||||
updated" date at the top of this Privacy Policy.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You are advised to review this Privacy Policy periodically for any
|
|
||||||
changes. Changes to this Privacy Policy are effective when they are
|
|
||||||
posted on this page.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Contact Information</h2>
|
|
||||||
<p className='leading-relaxed'>
|
|
||||||
If you have any questions about this Privacy Policy, You can contact us
|
|
||||||
by writing to{' '}
|
|
||||||
{email ? (
|
|
||||||
<a
|
<a
|
||||||
href={`mailto:${email}`}
|
href={`mailto:${process.env.NEXT_PUBLIC_BRAND_EMAIL}`}
|
||||||
className='text-purple-600 hover:text-purple-700'
|
className='text-purple-600 hover:text-purple-700'
|
||||||
>
|
>
|
||||||
{email}
|
{process.env.NEXT_PUBLIC_BRAND_EMAIL}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>What We Collect</h2>
|
||||||
|
<p className='leading-relaxed'>
|
||||||
|
Your email address (required to send the newsletter).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Why We Collect It</h2>
|
||||||
|
<p className='leading-relaxed'>
|
||||||
|
To deliver the daily {process.env.NEXT_PUBLIC_BRAND_NAME}{' '}
|
||||||
|
newsletter—a digest of top Hacker News stories with AI-generated
|
||||||
|
commentary.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
We do not sell products, track your activity beyond essential delivery,
|
||||||
|
or share your data for marketing.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Legal Basis</h2>
|
||||||
|
<p className='leading-relaxed'>
|
||||||
|
Your explicit consent via double opt-in signup (you receive a
|
||||||
|
confirmation email with an activation link).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Third Parties</h2>
|
||||||
|
<ul className='list-disc space-y-4 pl-6'>
|
||||||
|
<li>
|
||||||
|
<strong>Email delivery:</strong> Resend (US). GDPR-compliant email
|
||||||
|
infrastructure.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Hosting & analytics:</strong> Vercel (US). Analytics are
|
||||||
|
anonymized and aggregated—no personal data beyond your email is
|
||||||
|
collected.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Content source:</strong> Public Hacker News API (Y Combinator,
|
||||||
|
US).
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Your Rights</h2>
|
||||||
|
<ul className='list-disc space-y-4 pl-6'>
|
||||||
|
<li>Unsubscribe anytime via the link in every email</li>
|
||||||
|
<li>
|
||||||
|
Request deletion of your email by contacting{' '}
|
||||||
|
<a
|
||||||
|
href={`mailto:${process.env.NEXT_PUBLIC_BRAND_EMAIL}`}
|
||||||
|
className='text-purple-600 hover:text-purple-700'
|
||||||
|
>
|
||||||
|
{process.env.NEXT_PUBLIC_BRAND_EMAIL}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Upon unsubscribe or deletion request, your email is permanently
|
||||||
|
deleted from our database
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Data Retention</h2>
|
||||||
|
<p className='leading-relaxed'>
|
||||||
|
We retain your email address only until you unsubscribe.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>International Transfers</h2>
|
||||||
|
<p className='leading-relaxed'>
|
||||||
|
We rely on EU-approved safeguards including Standard Contractual Clauses
|
||||||
|
to ensure adequate protection when using US-based services.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Changes</h2>
|
||||||
|
<p className='leading-relaxed'>
|
||||||
|
We may update this policy occasionally. The latest version will always
|
||||||
|
be available at{' '}
|
||||||
|
<a
|
||||||
|
href={`${process.env.NEXT_PUBLIC_HOME_URL}/privacy`}
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
className='text-purple-600 hover:text-purple-700'
|
||||||
|
>
|
||||||
|
{process.env.NEXT_PUBLIC_HOME_URL}/privacy
|
||||||
</a>
|
</a>
|
||||||
) : (
|
|
||||||
<span className='text-gray-400'>loading...</span>
|
|
||||||
)}
|
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -465,7 +120,7 @@ const Privacy = () => {
|
|||||||
<CustomCard
|
<CustomCard
|
||||||
className='max-90vh max-90vw'
|
className='max-90vh max-90vw'
|
||||||
title='Privacy Policy'
|
title='Privacy Policy'
|
||||||
description='Last updated: November 23, 2024'
|
description='Last updated: January 28, 2026'
|
||||||
content={body}
|
content={body}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ export default function robots(): MetadataRoute.Robots {
|
|||||||
userAgent: '*',
|
userAgent: '*',
|
||||||
disallow: ''
|
disallow: ''
|
||||||
},
|
},
|
||||||
sitemap: `${process.env.HOME_URL!}/sitemap.xml`
|
sitemap: `${process.env.NEXT_PUBLIC_HOME_URL!}/sitemap.xml`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,19 +3,19 @@ import { MetadataRoute } from 'next';
|
|||||||
export default function sitemap(): MetadataRoute.Sitemap {
|
export default function sitemap(): MetadataRoute.Sitemap {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
url: process.env.HOME_URL!,
|
url: process.env.NEXT_PUBLIC_HOME_URL!,
|
||||||
lastModified: new Date(),
|
lastModified: new Date(),
|
||||||
changeFrequency: 'yearly',
|
changeFrequency: 'yearly',
|
||||||
priority: 1
|
priority: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: `${process.env.HOME_URL!}/privacy`,
|
url: `${process.env.NEXT_PUBLIC_HOME_URL!}/privacy`,
|
||||||
lastModified: new Date(),
|
lastModified: new Date(),
|
||||||
changeFrequency: 'yearly',
|
changeFrequency: 'yearly',
|
||||||
priority: 0.5
|
priority: 0.5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: `${process.env.HOME_URL!}/unsubscribe`,
|
url: `${process.env.NEXT_PUBLIC_HOME_URL!}/unsubscribe`,
|
||||||
lastModified: new Date(),
|
lastModified: new Date(),
|
||||||
changeFrequency: 'yearly',
|
changeFrequency: 'yearly',
|
||||||
priority: 0.2
|
priority: 0.2
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const Unsubscribe = () => {
|
|||||||
'@type': 'WebSite',
|
'@type': 'WebSite',
|
||||||
name: 'Hackernews Newsletter',
|
name: 'Hackernews Newsletter',
|
||||||
title: 'Unsubscribe',
|
title: 'Unsubscribe',
|
||||||
url: `${process.env.HOME_URL}/unsubscribe`
|
url: `${process.env.NEXT_PUBLIC_HOME_URL}/unsubscribe`
|
||||||
};
|
};
|
||||||
|
|
||||||
const form = useForm<UnsubscribeFormType>({
|
const form = useForm<UnsubscribeFormType>({
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const ConfirmationTemplate = (code: string) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href={`${process.env.HOME_URL}/confirmation?code=${code}`}
|
href={`${process.env.NEXT_PUBLIC_HOME_URL}/confirmation?code=${code}`}
|
||||||
style={{
|
style={{
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
padding: '12px 24px',
|
padding: '12px 24px',
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const UnsubscribeTemplate = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href={`${process.env.HOME_URL}/`}
|
href={`${process.env.NEXT_PUBLIC_HOME_URL}/`}
|
||||||
style={{
|
style={{
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
padding: '12px 24px',
|
padding: '12px 24px',
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
const iconStyle = {
|
import {
|
||||||
display: 'inline-block',
|
User,
|
||||||
verticalAlign: 'middle'
|
Building2,
|
||||||
};
|
Mail,
|
||||||
|
LogOut,
|
||||||
const Icon = ({ name, size = 16 }: { name: string; size?: number }) => (
|
LayoutGrid,
|
||||||
<img
|
Shield,
|
||||||
src={`${process.env.HOME_URL}/email-icons/${name}.png`}
|
Home
|
||||||
width={size}
|
} from 'lucide-react';
|
||||||
height={size}
|
|
||||||
alt=""
|
|
||||||
style={iconStyle}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
export const Footer = () => {
|
export const Footer = () => {
|
||||||
return (
|
return (
|
||||||
@@ -49,7 +44,7 @@ export const Footer = () => {
|
|||||||
letterSpacing: '0.05em'
|
letterSpacing: '0.05em'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="user" size={16} />
|
<User size={16} color='#386FA4' />
|
||||||
Contact Us
|
Contact Us
|
||||||
</h4>
|
</h4>
|
||||||
<p
|
<p
|
||||||
@@ -62,7 +57,7 @@ export const Footer = () => {
|
|||||||
color: '#4A5568'
|
color: '#4A5568'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="building-2" size={14} />
|
<Building2 size={14} color='#386FA4' />
|
||||||
{process.env.NEXT_PUBLIC_BRAND_NAME}
|
{process.env.NEXT_PUBLIC_BRAND_NAME}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
@@ -75,7 +70,7 @@ export const Footer = () => {
|
|||||||
color: '#4A5568'
|
color: '#4A5568'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="mail" size={14} />
|
<Mail size={14} color='#386FA4' />
|
||||||
<a
|
<a
|
||||||
href={`mailto:${process.env.NEXT_PUBLIC_BRAND_EMAIL}`}
|
href={`mailto:${process.env.NEXT_PUBLIC_BRAND_EMAIL}`}
|
||||||
style={{ color: '#386FA4', textDecoration: 'none' }}
|
style={{ color: '#386FA4', textDecoration: 'none' }}
|
||||||
@@ -93,11 +88,11 @@ export const Footer = () => {
|
|||||||
color: '#4A5568'
|
color: '#4A5568'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="log-out" size={14} />
|
<LogOut size={14} color='#386FA4' />
|
||||||
<span>
|
<span>
|
||||||
Click{' '}
|
Click{' '}
|
||||||
<a
|
<a
|
||||||
href={`${process.env.HOME_URL}/unsubscribe`}
|
href={`${process.env.NEXT_PUBLIC_HOME_URL}/unsubscribe`}
|
||||||
style={{ color: '#386FA4', textDecoration: 'none' }}
|
style={{ color: '#386FA4', textDecoration: 'none' }}
|
||||||
>
|
>
|
||||||
here
|
here
|
||||||
@@ -129,7 +124,7 @@ export const Footer = () => {
|
|||||||
letterSpacing: '0.05em'
|
letterSpacing: '0.05em'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="layout-grid" size={16} />
|
<LayoutGrid size={16} color='#386FA4' />
|
||||||
Quick Links
|
Quick Links
|
||||||
</h4>
|
</h4>
|
||||||
<p
|
<p
|
||||||
@@ -142,9 +137,9 @@ export const Footer = () => {
|
|||||||
color: '#4A5568'
|
color: '#4A5568'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="shield" size={14} />
|
<Shield size={14} color='#386FA4' />
|
||||||
<a
|
<a
|
||||||
href={`${process.env.HOME_URL}/privacy`}
|
href={`${process.env.NEXT_PUBLIC_HOME_URL}/privacy`}
|
||||||
style={{ color: '#386FA4', textDecoration: 'none' }}
|
style={{ color: '#386FA4', textDecoration: 'none' }}
|
||||||
>
|
>
|
||||||
Privacy Policy
|
Privacy Policy
|
||||||
@@ -160,9 +155,9 @@ export const Footer = () => {
|
|||||||
color: '#4A5568'
|
color: '#4A5568'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="house" size={14} />
|
<Home size={14} color='#386FA4' />
|
||||||
<a
|
<a
|
||||||
href={process.env.HOME_URL}
|
href={process.env.NEXT_PUBLIC_HOME_URL}
|
||||||
style={{ color: '#386FA4', textDecoration: 'none' }}
|
style={{ color: '#386FA4', textDecoration: 'none' }}
|
||||||
>
|
>
|
||||||
Visit Website
|
Visit Website
|
||||||
|
|||||||
421
package-lock.json
generated
@@ -13,7 +13,6 @@
|
|||||||
"@prisma/client": "^5.6.0",
|
"@prisma/client": "^5.6.0",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
"@vercel/analytics": "^1.1.1",
|
|
||||||
"axios": "^1.12.0",
|
"axios": "^1.12.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
@@ -25,7 +24,6 @@
|
|||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hook-form": "^7.48.2",
|
"react-hook-form": "^7.48.2",
|
||||||
"resend": "^3.1.0",
|
|
||||||
"tailwind-merge": "^2.1.0",
|
"tailwind-merge": "^2.1.0",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
@@ -1546,12 +1544,6 @@
|
|||||||
"node": ">=12.4.0"
|
"node": ">=12.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@one-ini/wasm": {
|
|
||||||
"version": "0.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
|
|
||||||
"integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@pkgjs/parseargs": {
|
"node_modules/@pkgjs/parseargs": {
|
||||||
"version": "0.11.0",
|
"version": "0.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||||
@@ -1715,24 +1707,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-email/render": {
|
|
||||||
"version": "0.0.16",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-email/render/-/render-0.0.16.tgz",
|
|
||||||
"integrity": "sha512-wDaMy27xAq1cJHtSFptp0DTKPuV2GYhloqia95ub/DH9Dea1aWYsbdM918MOc/b/HvVS3w1z8DWzfAk13bGStQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"html-to-text": "9.0.5",
|
|
||||||
"js-beautify": "^1.14.11",
|
|
||||||
"react-promise-suspense": "0.3.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@rtsao/scc": {
|
"node_modules/@rtsao/scc": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||||
@@ -1747,19 +1721,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@selderee/plugin-htmlparser2": {
|
|
||||||
"version": "0.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz",
|
|
||||||
"integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"domhandler": "^5.0.3",
|
|
||||||
"selderee": "^0.11.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://ko-fi.com/killymxi"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@swc/helpers": {
|
"node_modules/@swc/helpers": {
|
||||||
"version": "0.5.15",
|
"version": "0.5.15",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
|
||||||
@@ -2343,53 +2304,6 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@vercel/analytics": {
|
|
||||||
"version": "1.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.5.0.tgz",
|
|
||||||
"integrity": "sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g==",
|
|
||||||
"license": "MPL-2.0",
|
|
||||||
"peerDependencies": {
|
|
||||||
"@remix-run/react": "^2",
|
|
||||||
"@sveltejs/kit": "^1 || ^2",
|
|
||||||
"next": ">= 13",
|
|
||||||
"react": "^18 || ^19 || ^19.0.0-rc",
|
|
||||||
"svelte": ">= 4",
|
|
||||||
"vue": "^3",
|
|
||||||
"vue-router": "^4"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@remix-run/react": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@sveltejs/kit": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"next": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"react": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"svelte": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"vue": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"vue-router": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/abbrev": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/abort-controller": {
|
"node_modules/abort-controller": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
@@ -3325,16 +3239,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/config-chain": {
|
|
||||||
"version": "1.1.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
|
|
||||||
"integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"ini": "^1.3.4",
|
|
||||||
"proto-list": "~1.2.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/conventional-changelog-angular": {
|
"node_modules/conventional-changelog-angular": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
|
||||||
@@ -3642,15 +3546,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/deepmerge": {
|
|
||||||
"version": "4.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
|
||||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/define-data-property": {
|
"node_modules/define-data-property": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||||
@@ -3744,59 +3639,6 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dom-serializer": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"domelementtype": "^2.3.0",
|
|
||||||
"domhandler": "^5.0.2",
|
|
||||||
"entities": "^4.2.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dom-serializer/node_modules/entities": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.12"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/domelementtype": {
|
|
||||||
"version": "2.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
|
||||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/fb55"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "BSD-2-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/domhandler": {
|
|
||||||
"version": "5.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
|
||||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"domelementtype": "^2.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 4"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dompurify": {
|
"node_modules/dompurify": {
|
||||||
"version": "3.2.7",
|
"version": "3.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz",
|
||||||
@@ -3806,20 +3648,6 @@
|
|||||||
"@types/trusted-types": "^2.0.7"
|
"@types/trusted-types": "^2.0.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/domutils": {
|
|
||||||
"version": "3.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
|
|
||||||
"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"dom-serializer": "^2.0.0",
|
|
||||||
"domelementtype": "^2.3.0",
|
|
||||||
"domhandler": "^5.0.3"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dot-prop": {
|
"node_modules/dot-prop": {
|
||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
|
||||||
@@ -3859,48 +3687,6 @@
|
|||||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/editorconfig": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@one-ini/wasm": "0.1.1",
|
|
||||||
"commander": "^10.0.0",
|
|
||||||
"minimatch": "9.0.1",
|
|
||||||
"semver": "^7.5.3"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"editorconfig": "bin/editorconfig"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/editorconfig/node_modules/commander": {
|
|
||||||
"version": "10.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
|
|
||||||
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/editorconfig/node_modules/minimatch": {
|
|
||||||
"version": "9.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
|
|
||||||
"integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16 || 14 >=14.17"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.234",
|
"version": "1.5.234",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz",
|
||||||
@@ -5597,53 +5383,6 @@
|
|||||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/html-to-text": {
|
|
||||||
"version": "9.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz",
|
|
||||||
"integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@selderee/plugin-htmlparser2": "^0.11.0",
|
|
||||||
"deepmerge": "^4.3.1",
|
|
||||||
"dom-serializer": "^2.0.0",
|
|
||||||
"htmlparser2": "^8.0.2",
|
|
||||||
"selderee": "^0.11.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/htmlparser2": {
|
|
||||||
"version": "8.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
|
||||||
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
|
|
||||||
"funding": [
|
|
||||||
"https://github.com/fb55/htmlparser2?sponsor=1",
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/fb55"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"domelementtype": "^2.3.0",
|
|
||||||
"domhandler": "^5.0.3",
|
|
||||||
"domutils": "^3.0.1",
|
|
||||||
"entities": "^4.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/htmlparser2/node_modules/entities": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.12"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/http-proxy-agent": {
|
"node_modules/http-proxy-agent": {
|
||||||
"version": "7.0.2",
|
"version": "7.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
||||||
@@ -5797,6 +5536,7 @@
|
|||||||
"version": "1.3.8",
|
"version": "1.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/internal-slot": {
|
"node_modules/internal-slot": {
|
||||||
@@ -6403,71 +6143,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/js-beautify": {
|
|
||||||
"version": "1.15.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
|
|
||||||
"integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"config-chain": "^1.1.13",
|
|
||||||
"editorconfig": "^1.0.4",
|
|
||||||
"glob": "^10.4.2",
|
|
||||||
"js-cookie": "^3.0.5",
|
|
||||||
"nopt": "^7.2.1"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"css-beautify": "js/bin/css-beautify.js",
|
|
||||||
"html-beautify": "js/bin/html-beautify.js",
|
|
||||||
"js-beautify": "js/bin/js-beautify.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-beautify/node_modules/glob": {
|
|
||||||
"version": "10.4.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
|
||||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"foreground-child": "^3.1.0",
|
|
||||||
"jackspeak": "^3.1.2",
|
|
||||||
"minimatch": "^9.0.4",
|
|
||||||
"minipass": "^7.1.2",
|
|
||||||
"package-json-from-dist": "^1.0.0",
|
|
||||||
"path-scurry": "^1.11.1"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"glob": "dist/esm/bin.mjs"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-beautify/node_modules/minimatch": {
|
|
||||||
"version": "9.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
|
||||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16 || 14 >=14.17"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-cookie": {
|
|
||||||
"version": "3.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
|
|
||||||
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
@@ -6650,15 +6325,6 @@
|
|||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/leac": {
|
|
||||||
"version": "0.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
|
|
||||||
"integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://ko-fi.com/killymxi"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/levn": {
|
"node_modules/levn": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||||
@@ -7509,21 +7175,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/nopt": {
|
|
||||||
"version": "7.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
|
|
||||||
"integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"abbrev": "^2.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"nopt": "bin/nopt.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/normalize-package-data": {
|
"node_modules/normalize-package-data": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
|
||||||
@@ -7911,19 +7562,6 @@
|
|||||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/parseley": {
|
|
||||||
"version": "0.12.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz",
|
|
||||||
"integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"leac": "^0.6.0",
|
|
||||||
"peberminta": "^0.9.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://ko-fi.com/killymxi"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
@@ -8004,15 +7642,6 @@
|
|||||||
"through": "~2.3"
|
"through": "~2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/peberminta": {
|
|
||||||
"version": "0.9.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz",
|
|
||||||
"integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://ko-fi.com/killymxi"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
@@ -8388,12 +8017,6 @@
|
|||||||
"react-is": "^16.13.1"
|
"react-is": "^16.13.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/proto-list": {
|
|
||||||
"version": "1.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
|
|
||||||
"integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/proxy-from-env": {
|
"node_modules/proxy-from-env": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
@@ -8487,21 +8110,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/react-promise-suspense": {
|
|
||||||
"version": "0.3.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-promise-suspense/-/react-promise-suspense-0.3.4.tgz",
|
|
||||||
"integrity": "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"fast-deep-equal": "^2.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-promise-suspense/node_modules/fast-deep-equal": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
@@ -8765,18 +8373,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/resend": {
|
|
||||||
"version": "3.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/resend/-/resend-3.5.0.tgz",
|
|
||||||
"integrity": "sha512-bKu4LhXSecP6krvhfDzyDESApYdNfjirD5kykkT1xO0Cj9TKSiGh5Void4pGTs3Am+inSnp4dg0B5XzdwHBJOQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@react-email/render": "0.0.16"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.10",
|
"version": "1.22.10",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||||
@@ -9042,22 +8638,11 @@
|
|||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/selderee": {
|
|
||||||
"version": "0.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz",
|
|
||||||
"integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"parseley": "^0.12.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://ko-fi.com/killymxi"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.6.0",
|
"version": "7.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
@@ -9073,6 +8658,7 @@
|
|||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yallist": "^4.0.0"
|
"yallist": "^4.0.0"
|
||||||
@@ -10761,6 +10347,7 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/yaml": {
|
"node_modules/yaml": {
|
||||||
|
|||||||
@@ -26,19 +26,17 @@
|
|||||||
"@prisma/client": "^5.6.0",
|
"@prisma/client": "^5.6.0",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
"@vercel/analytics": "^1.1.1",
|
|
||||||
"openai": "^4.77.0",
|
|
||||||
"axios": "^1.12.0",
|
"axios": "^1.12.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"isomorphic-dompurify": "^2.15.0",
|
"isomorphic-dompurify": "^2.15.0",
|
||||||
"lucide-react": "^0.460.0",
|
"lucide-react": "^0.460.0",
|
||||||
"next": "^15.5.9",
|
"next": "^15.5.9",
|
||||||
|
"openai": "^4.77.0",
|
||||||
"postcss-nesting": "^12.0.2",
|
"postcss-nesting": "^12.0.2",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hook-form": "^7.48.2",
|
"react-hook-form": "^7.48.2",
|
||||||
"resend": "^3.1.0",
|
|
||||||
"tailwind-merge": "^2.1.0",
|
"tailwind-merge": "^2.1.0",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 397 B |
|
Before Width: | Height: | Size: 416 B |
|
Before Width: | Height: | Size: 305 B |
|
Before Width: | Height: | Size: 328 B |
|
Before Width: | Height: | Size: 414 B |
|
Before Width: | Height: | Size: 480 B |
|
Before Width: | Height: | Size: 394 B |
@@ -1,65 +0,0 @@
|
|||||||
import { Resend } from 'resend';
|
|
||||||
|
|
||||||
interface EmailTemplate {
|
|
||||||
subject: string;
|
|
||||||
template: JSX.Element;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function sender(
|
|
||||||
recipients: string[],
|
|
||||||
{ subject, template }: EmailTemplate
|
|
||||||
) {
|
|
||||||
if (!process.env.RESEND_KEY) {
|
|
||||||
throw new Error('RESEND_KEY is not set');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipients.length === 0) {
|
|
||||||
console.info(`${subject} email skipped for having zero recipients`);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const resend = new Resend(process.env.RESEND_KEY);
|
|
||||||
|
|
||||||
try {
|
|
||||||
let response;
|
|
||||||
|
|
||||||
if (recipients.length == 1) {
|
|
||||||
response = await resend.emails.send({
|
|
||||||
from: process.env.RESEND_FROM!,
|
|
||||||
to: recipients[0],
|
|
||||||
subject,
|
|
||||||
react: template,
|
|
||||||
headers: {
|
|
||||||
'List-Unsubscribe': `<${process.env.HOME_URL}/unsubscribe>`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
response = await resend.batch.send(
|
|
||||||
recipients.map(recipient => {
|
|
||||||
return {
|
|
||||||
from: process.env.RESEND_FROM!,
|
|
||||||
to: recipient,
|
|
||||||
subject,
|
|
||||||
react: template,
|
|
||||||
headers: {
|
|
||||||
'List-Unsubscribe': `<${process.env.HOME_URL}/unsubscribe>`
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { error } = response;
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
console.error(error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.info(`${subject} email sent to ${recipients.length} recipients`);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
90
utils/sweego.ts
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
interface EmailTemplate {
|
||||||
|
subject: string;
|
||||||
|
template: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SWEEGO_API_URL = 'https://api.sweego.io/send';
|
||||||
|
|
||||||
|
const renderTemplate = async (template: JSX.Element): Promise<string> => {
|
||||||
|
const { renderToStaticMarkup } = await import('react-dom/server');
|
||||||
|
const html = renderToStaticMarkup(template);
|
||||||
|
return `<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
</head>
|
||||||
|
<body style="margin: 0; padding: 0; background-color: #f4f4f5;">
|
||||||
|
${html}
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function sender(
|
||||||
|
recipients: string[],
|
||||||
|
{ subject, template }: EmailTemplate
|
||||||
|
): Promise<boolean> {
|
||||||
|
if (!process.env.SWEEGO_API_KEY) {
|
||||||
|
throw new Error('SWEEGO_API_KEY is not set');
|
||||||
|
}
|
||||||
|
if (!process.env.SWEEGO_FROM) {
|
||||||
|
throw new Error('SWEEGO_FROM is not set');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recipients.length === 0) {
|
||||||
|
console.info(`${subject} email skipped for having zero recipients`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const htmlContent = await renderTemplate(template);
|
||||||
|
const fromName = process.env.NEXT_PUBLIC_BRAND_NAME || 'Newsletter';
|
||||||
|
|
||||||
|
let successCount = 0;
|
||||||
|
let failCount = 0;
|
||||||
|
|
||||||
|
for (const recipient of recipients) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(SWEEGO_API_URL, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Api-Key': process.env.SWEEGO_API_KEY
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
channel: 'email',
|
||||||
|
provider: 'sweego',
|
||||||
|
recipients: [{ email: recipient }],
|
||||||
|
from: {
|
||||||
|
name: fromName,
|
||||||
|
email: process.env.SWEEGO_FROM
|
||||||
|
},
|
||||||
|
subject,
|
||||||
|
'message-html': htmlContent,
|
||||||
|
headers: {
|
||||||
|
'List-Unsubscribe': `<mailto:${process.env.NEXT_PUBLIC_BRAND_EMAIL}>`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const error = await response.text();
|
||||||
|
console.error(
|
||||||
|
`Failed to send to ${recipient}: ${response.status} ${error}`
|
||||||
|
);
|
||||||
|
failCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
successCount++;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to send to ${recipient}:`, error);
|
||||||
|
failCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info(
|
||||||
|
`${subject} email: ${successCount} sent, ${failCount} failed out of ${recipients.length} recipients`
|
||||||
|
);
|
||||||
|
|
||||||
|
return successCount > 0;
|
||||||
|
}
|
||||||
220
yarn.lock
@@ -599,11 +599,6 @@
|
|||||||
resolved "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz"
|
resolved "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz"
|
||||||
integrity sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==
|
integrity sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==
|
||||||
|
|
||||||
"@one-ini/wasm@0.1.1":
|
|
||||||
version "0.1.1"
|
|
||||||
resolved "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz"
|
|
||||||
integrity sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==
|
|
||||||
|
|
||||||
"@pkgjs/parseargs@^0.11.0":
|
"@pkgjs/parseargs@^0.11.0":
|
||||||
version "0.11.0"
|
version "0.11.0"
|
||||||
resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz"
|
resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz"
|
||||||
@@ -681,15 +676,6 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@radix-ui/react-compose-refs" "1.1.2"
|
"@radix-ui/react-compose-refs" "1.1.2"
|
||||||
|
|
||||||
"@react-email/render@0.0.16":
|
|
||||||
version "0.0.16"
|
|
||||||
resolved "https://registry.npmjs.org/@react-email/render/-/render-0.0.16.tgz"
|
|
||||||
integrity sha512-wDaMy27xAq1cJHtSFptp0DTKPuV2GYhloqia95ub/DH9Dea1aWYsbdM918MOc/b/HvVS3w1z8DWzfAk13bGStQ==
|
|
||||||
dependencies:
|
|
||||||
html-to-text "9.0.5"
|
|
||||||
js-beautify "^1.14.11"
|
|
||||||
react-promise-suspense "0.3.4"
|
|
||||||
|
|
||||||
"@rtsao/scc@^1.1.0":
|
"@rtsao/scc@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz"
|
resolved "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz"
|
||||||
@@ -700,14 +686,6 @@
|
|||||||
resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.13.0.tgz"
|
resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.13.0.tgz"
|
||||||
integrity sha512-2ih5qGw5SZJ+2fLZxP6Lr6Na2NTIgPRL/7Kmyuw0uIyBQnuhQ8fi8fzUTd38eIQmqp+GYLC00cI6WgtqHxBwmw==
|
integrity sha512-2ih5qGw5SZJ+2fLZxP6Lr6Na2NTIgPRL/7Kmyuw0uIyBQnuhQ8fi8fzUTd38eIQmqp+GYLC00cI6WgtqHxBwmw==
|
||||||
|
|
||||||
"@selderee/plugin-htmlparser2@^0.11.0":
|
|
||||||
version "0.11.0"
|
|
||||||
resolved "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz"
|
|
||||||
integrity sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==
|
|
||||||
dependencies:
|
|
||||||
domhandler "^5.0.3"
|
|
||||||
selderee "^0.11.0"
|
|
||||||
|
|
||||||
"@swc/helpers@0.5.15":
|
"@swc/helpers@0.5.15":
|
||||||
version "0.5.15"
|
version "0.5.15"
|
||||||
resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz"
|
resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz"
|
||||||
@@ -980,16 +958,6 @@
|
|||||||
resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz"
|
resolved "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz"
|
||||||
integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==
|
integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==
|
||||||
|
|
||||||
"@vercel/analytics@^1.1.1":
|
|
||||||
version "1.5.0"
|
|
||||||
resolved "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.5.0.tgz"
|
|
||||||
integrity sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g==
|
|
||||||
|
|
||||||
abbrev@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz"
|
|
||||||
integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==
|
|
||||||
|
|
||||||
abort-controller@^3.0.0:
|
abort-controller@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz"
|
||||||
@@ -1489,11 +1457,6 @@ combined-stream@^1.0.8:
|
|||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
commander@^10.0.0:
|
|
||||||
version "10.0.1"
|
|
||||||
resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz"
|
|
||||||
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
|
|
||||||
|
|
||||||
commander@^13.1.0:
|
commander@^13.1.0:
|
||||||
version "13.1.0"
|
version "13.1.0"
|
||||||
resolved "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz"
|
resolved "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz"
|
||||||
@@ -1522,14 +1485,6 @@ concat-map@0.0.1:
|
|||||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||||
|
|
||||||
config-chain@^1.1.13:
|
|
||||||
version "1.1.13"
|
|
||||||
resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz"
|
|
||||||
integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
|
|
||||||
dependencies:
|
|
||||||
ini "^1.3.4"
|
|
||||||
proto-list "~1.2.1"
|
|
||||||
|
|
||||||
conventional-changelog-angular@^7.0.0:
|
conventional-changelog-angular@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz"
|
resolved "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz"
|
||||||
@@ -1694,11 +1649,6 @@ deep-is@^0.1.3:
|
|||||||
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
|
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
|
||||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||||
|
|
||||||
deepmerge@^4.3.1:
|
|
||||||
version "4.3.1"
|
|
||||||
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
|
|
||||||
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
|
|
||||||
|
|
||||||
define-data-property@^1.0.1, define-data-property@^1.1.4:
|
define-data-property@^1.0.1, define-data-property@^1.1.4:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz"
|
resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz"
|
||||||
@@ -1758,27 +1708,6 @@ doctrine@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
|
|
||||||
dom-serializer@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz"
|
|
||||||
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
|
|
||||||
dependencies:
|
|
||||||
domelementtype "^2.3.0"
|
|
||||||
domhandler "^5.0.2"
|
|
||||||
entities "^4.2.0"
|
|
||||||
|
|
||||||
domelementtype@^2.3.0:
|
|
||||||
version "2.3.0"
|
|
||||||
resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz"
|
|
||||||
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
|
||||||
|
|
||||||
domhandler@^5.0.2, domhandler@^5.0.3:
|
|
||||||
version "5.0.3"
|
|
||||||
resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz"
|
|
||||||
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
|
|
||||||
dependencies:
|
|
||||||
domelementtype "^2.3.0"
|
|
||||||
|
|
||||||
dompurify@^3.2.7:
|
dompurify@^3.2.7:
|
||||||
version "3.2.7"
|
version "3.2.7"
|
||||||
resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz"
|
resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz"
|
||||||
@@ -1786,15 +1715,6 @@ dompurify@^3.2.7:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@types/trusted-types" "^2.0.7"
|
"@types/trusted-types" "^2.0.7"
|
||||||
|
|
||||||
domutils@^3.0.1:
|
|
||||||
version "3.2.2"
|
|
||||||
resolved "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz"
|
|
||||||
integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==
|
|
||||||
dependencies:
|
|
||||||
dom-serializer "^2.0.0"
|
|
||||||
domelementtype "^2.3.0"
|
|
||||||
domhandler "^5.0.3"
|
|
||||||
|
|
||||||
dot-prop@^5.1.0:
|
dot-prop@^5.1.0:
|
||||||
version "5.3.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz"
|
resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz"
|
||||||
@@ -1821,16 +1741,6 @@ eastasianwidth@^0.2.0:
|
|||||||
resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz"
|
resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz"
|
||||||
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
|
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
|
||||||
|
|
||||||
editorconfig@^1.0.4:
|
|
||||||
version "1.0.4"
|
|
||||||
resolved "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz"
|
|
||||||
integrity sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==
|
|
||||||
dependencies:
|
|
||||||
"@one-ini/wasm" "0.1.1"
|
|
||||||
commander "^10.0.0"
|
|
||||||
minimatch "9.0.1"
|
|
||||||
semver "^7.5.3"
|
|
||||||
|
|
||||||
electron-to-chromium@^1.5.227:
|
electron-to-chromium@^1.5.227:
|
||||||
version "1.5.234"
|
version "1.5.234"
|
||||||
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz"
|
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz"
|
||||||
@@ -1851,16 +1761,6 @@ emoji-regex@^9.2.2:
|
|||||||
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz"
|
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz"
|
||||||
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
|
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
|
||||||
|
|
||||||
entities@^4.2.0:
|
|
||||||
version "4.5.0"
|
|
||||||
resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
|
|
||||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
|
||||||
|
|
||||||
entities@^4.4.0:
|
|
||||||
version "4.5.0"
|
|
||||||
resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
|
|
||||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
|
||||||
|
|
||||||
entities@^6.0.0:
|
entities@^6.0.0:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz"
|
resolved "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz"
|
||||||
@@ -2280,11 +2180,6 @@ execa@^8.0.1:
|
|||||||
signal-exit "^4.1.0"
|
signal-exit "^4.1.0"
|
||||||
strip-final-newline "^3.0.0"
|
strip-final-newline "^3.0.0"
|
||||||
|
|
||||||
fast-deep-equal@^2.0.1:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz"
|
|
||||||
integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==
|
|
||||||
|
|
||||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||||
version "3.1.3"
|
version "3.1.3"
|
||||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||||
@@ -2567,18 +2462,6 @@ glob@^10.3.10:
|
|||||||
package-json-from-dist "^1.0.0"
|
package-json-from-dist "^1.0.0"
|
||||||
path-scurry "^1.11.1"
|
path-scurry "^1.11.1"
|
||||||
|
|
||||||
glob@^10.4.2:
|
|
||||||
version "10.4.5"
|
|
||||||
resolved "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz"
|
|
||||||
integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
|
|
||||||
dependencies:
|
|
||||||
foreground-child "^3.1.0"
|
|
||||||
jackspeak "^3.1.2"
|
|
||||||
minimatch "^9.0.4"
|
|
||||||
minipass "^7.1.2"
|
|
||||||
package-json-from-dist "^1.0.0"
|
|
||||||
path-scurry "^1.11.1"
|
|
||||||
|
|
||||||
glob@^7.1.3, glob@7.1.7:
|
glob@^7.1.3, glob@7.1.7:
|
||||||
version "7.1.7"
|
version "7.1.7"
|
||||||
resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz"
|
resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz"
|
||||||
@@ -2714,27 +2597,6 @@ html-escaper@^2.0.2:
|
|||||||
resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz"
|
resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz"
|
||||||
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
|
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
|
||||||
|
|
||||||
html-to-text@9.0.5:
|
|
||||||
version "9.0.5"
|
|
||||||
resolved "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz"
|
|
||||||
integrity sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==
|
|
||||||
dependencies:
|
|
||||||
"@selderee/plugin-htmlparser2" "^0.11.0"
|
|
||||||
deepmerge "^4.3.1"
|
|
||||||
dom-serializer "^2.0.0"
|
|
||||||
htmlparser2 "^8.0.2"
|
|
||||||
selderee "^0.11.0"
|
|
||||||
|
|
||||||
htmlparser2@^8.0.2:
|
|
||||||
version "8.0.2"
|
|
||||||
resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz"
|
|
||||||
integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==
|
|
||||||
dependencies:
|
|
||||||
domelementtype "^2.3.0"
|
|
||||||
domhandler "^5.0.3"
|
|
||||||
domutils "^3.0.1"
|
|
||||||
entities "^4.4.0"
|
|
||||||
|
|
||||||
http-proxy-agent@^7.0.2:
|
http-proxy-agent@^7.0.2:
|
||||||
version "7.0.2"
|
version "7.0.2"
|
||||||
resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz"
|
resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz"
|
||||||
@@ -3140,22 +3002,6 @@ jju@^1.4.0:
|
|||||||
resolved "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz"
|
resolved "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz"
|
||||||
integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==
|
integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==
|
||||||
|
|
||||||
js-beautify@^1.14.11:
|
|
||||||
version "1.15.4"
|
|
||||||
resolved "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz"
|
|
||||||
integrity sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==
|
|
||||||
dependencies:
|
|
||||||
config-chain "^1.1.13"
|
|
||||||
editorconfig "^1.0.4"
|
|
||||||
glob "^10.4.2"
|
|
||||||
js-cookie "^3.0.5"
|
|
||||||
nopt "^7.2.1"
|
|
||||||
|
|
||||||
js-cookie@^3.0.5:
|
|
||||||
version "3.0.5"
|
|
||||||
resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz"
|
|
||||||
integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==
|
|
||||||
|
|
||||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
|
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
|
||||||
@@ -3273,11 +3119,6 @@ language-tags@^1.0.9:
|
|||||||
dependencies:
|
dependencies:
|
||||||
language-subtag-registry "^0.3.20"
|
language-subtag-registry "^0.3.20"
|
||||||
|
|
||||||
leac@^0.6.0:
|
|
||||||
version "0.6.0"
|
|
||||||
resolved "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz"
|
|
||||||
integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==
|
|
||||||
|
|
||||||
levn@^0.4.1:
|
levn@^0.4.1:
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
|
resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
|
||||||
@@ -3558,13 +3399,6 @@ minimatch@^9.0.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^2.0.1"
|
brace-expansion "^2.0.1"
|
||||||
|
|
||||||
minimatch@9.0.1:
|
|
||||||
version "9.0.1"
|
|
||||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz"
|
|
||||||
integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==
|
|
||||||
dependencies:
|
|
||||||
brace-expansion "^2.0.1"
|
|
||||||
|
|
||||||
minimatch@9.0.3:
|
minimatch@9.0.3:
|
||||||
version "9.0.3"
|
version "9.0.3"
|
||||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz"
|
resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz"
|
||||||
@@ -3625,7 +3459,7 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
|
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
|
||||||
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
||||||
|
|
||||||
next@^15.5.9, "next@>= 13":
|
next@^15.5.9:
|
||||||
version "15.5.9"
|
version "15.5.9"
|
||||||
resolved "https://registry.npmjs.org/next/-/next-15.5.9.tgz"
|
resolved "https://registry.npmjs.org/next/-/next-15.5.9.tgz"
|
||||||
integrity sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==
|
integrity sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==
|
||||||
@@ -3663,13 +3497,6 @@ node-releases@^2.0.21:
|
|||||||
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.23.tgz"
|
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.23.tgz"
|
||||||
integrity sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==
|
integrity sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==
|
||||||
|
|
||||||
nopt@^7.2.1:
|
|
||||||
version "7.2.1"
|
|
||||||
resolved "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz"
|
|
||||||
integrity sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==
|
|
||||||
dependencies:
|
|
||||||
abbrev "^2.0.0"
|
|
||||||
|
|
||||||
normalize-package-data@^2.5.0:
|
normalize-package-data@^2.5.0:
|
||||||
version "2.5.0"
|
version "2.5.0"
|
||||||
resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz"
|
resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz"
|
||||||
@@ -3914,14 +3741,6 @@ parse5@^7.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
entities "^6.0.0"
|
entities "^6.0.0"
|
||||||
|
|
||||||
parseley@^0.12.0:
|
|
||||||
version "0.12.1"
|
|
||||||
resolved "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz"
|
|
||||||
integrity sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==
|
|
||||||
dependencies:
|
|
||||||
leac "^0.6.0"
|
|
||||||
peberminta "^0.9.0"
|
|
||||||
|
|
||||||
path-exists@^4.0.0:
|
path-exists@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
|
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
|
||||||
@@ -3967,11 +3786,6 @@ pause-stream@^0.0.11:
|
|||||||
dependencies:
|
dependencies:
|
||||||
through "~2.3"
|
through "~2.3"
|
||||||
|
|
||||||
peberminta@^0.9.0:
|
|
||||||
version "0.9.0"
|
|
||||||
resolved "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz"
|
|
||||||
integrity sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==
|
|
||||||
|
|
||||||
picocolors@^1.0.0, picocolors@^1.1.1:
|
picocolors@^1.0.0, picocolors@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
|
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
|
||||||
@@ -4110,11 +3924,6 @@ prop-types@^15.8.1:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
react-is "^16.13.1"
|
react-is "^16.13.1"
|
||||||
|
|
||||||
proto-list@~1.2.1:
|
|
||||||
version "1.2.4"
|
|
||||||
resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz"
|
|
||||||
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
|
|
||||||
|
|
||||||
proxy-from-env@^1.1.0:
|
proxy-from-env@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
|
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
|
||||||
@@ -4135,7 +3944,7 @@ quick-lru@^4.0.1:
|
|||||||
resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz"
|
resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz"
|
||||||
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
|
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
|
||||||
|
|
||||||
"react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", react-dom@^18, react-dom@^18.2.0, "react-dom@^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0":
|
"react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", react-dom@^18, "react-dom@^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0":
|
||||||
version "18.3.1"
|
version "18.3.1"
|
||||||
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
|
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
|
||||||
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
|
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
|
||||||
@@ -4153,14 +3962,7 @@ react-is@^16.13.1:
|
|||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
react-promise-suspense@0.3.4:
|
"react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17 || ^18 || ^19", react@^18, "react@^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", react@^18.3.1, "react@>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0":
|
||||||
version "0.3.4"
|
|
||||||
resolved "https://registry.npmjs.org/react-promise-suspense/-/react-promise-suspense-0.3.4.tgz"
|
|
||||||
integrity sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==
|
|
||||||
dependencies:
|
|
||||||
fast-deep-equal "^2.0.1"
|
|
||||||
|
|
||||||
"react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17 || ^18 || ^19", react@^18, "react@^18 || ^19 || ^19.0.0-rc", react@^18.2.0, "react@^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", react@^18.3.1, "react@>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0":
|
|
||||||
version "18.3.1"
|
version "18.3.1"
|
||||||
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
|
||||||
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
|
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
|
||||||
@@ -4258,13 +4060,6 @@ require-from-string@^2.0.2:
|
|||||||
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
||||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||||
|
|
||||||
resend@^3.1.0:
|
|
||||||
version "3.5.0"
|
|
||||||
resolved "https://registry.npmjs.org/resend/-/resend-3.5.0.tgz"
|
|
||||||
integrity sha512-bKu4LhXSecP6krvhfDzyDESApYdNfjirD5kykkT1xO0Cj9TKSiGh5Void4pGTs3Am+inSnp4dg0B5XzdwHBJOQ==
|
|
||||||
dependencies:
|
|
||||||
"@react-email/render" "0.0.16"
|
|
||||||
|
|
||||||
resolve-from@^4.0.0:
|
resolve-from@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
|
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
|
||||||
@@ -4394,19 +4189,12 @@ scheduler@^0.23.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
|
|
||||||
selderee@^0.11.0:
|
|
||||||
version "0.11.0"
|
|
||||||
resolved "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz"
|
|
||||||
integrity sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==
|
|
||||||
dependencies:
|
|
||||||
parseley "^0.12.0"
|
|
||||||
|
|
||||||
semver@^6.3.1:
|
semver@^6.3.1:
|
||||||
version "6.3.1"
|
version "6.3.1"
|
||||||
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
|
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
|
||||||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||||
|
|
||||||
semver@^7.0.0, semver@^7.3.4, semver@^7.5.3, semver@^7.5.4, semver@7.6.0:
|
semver@^7.0.0, semver@^7.3.4, semver@^7.5.4, semver@7.6.0:
|
||||||
version "7.6.0"
|
version "7.6.0"
|
||||||
resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz"
|
resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz"
|
||||||
integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==
|
integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==
|
||||||
|
|||||||