You've already forked AstralRinth
forked from didirus/AstralRinth
feat: introduce vue-email for templating with tailwind (#4358)
* feat: start on vue-email set up * feat: email rendering and base template * refactor: body slot only * feat: templates * fix: lint * fix: build process * fix: default import issue * feat: continue making emails * feat: update address * feat: new templates * feat: email temp page viewer * fix: lint * fix: reset password heading * fix: lint * fix: qa issues
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
|
||||
import { match as matchLocale } from '@formatjs/intl-localematcher'
|
||||
import serverSidedVue from '@vitejs/plugin-vue'
|
||||
import { consola } from 'consola'
|
||||
import { promises as fs } from 'fs'
|
||||
import { globIterate } from 'glob'
|
||||
@@ -111,6 +112,17 @@ export default defineNuxtConfig({
|
||||
],
|
||||
},
|
||||
hooks: {
|
||||
async 'nitro:config'(nitroConfig) {
|
||||
const emailTemplates = Object.keys(
|
||||
await import('./src/emails/index.ts').then((m) => m.default),
|
||||
)
|
||||
|
||||
nitroConfig.prerender = nitroConfig.prerender || {}
|
||||
nitroConfig.prerender.routes = nitroConfig.prerender.routes || []
|
||||
for (const template of emailTemplates) {
|
||||
nitroConfig.prerender.routes.push(`/email/${template}`)
|
||||
}
|
||||
},
|
||||
async 'build:before'() {
|
||||
// 30 minutes
|
||||
const TTL = 30 * 60 * 1000
|
||||
@@ -435,6 +447,10 @@ export default defineNuxtConfig({
|
||||
},
|
||||
nitro: {
|
||||
moduleSideEffects: ['@vintl/compact-number/locale-data'],
|
||||
rollupConfig: {
|
||||
// @ts-expect-error it's not infinite.
|
||||
plugins: [serverSidedVue()],
|
||||
},
|
||||
},
|
||||
devtools: {
|
||||
enabled: true,
|
||||
@@ -453,6 +469,13 @@ export default defineNuxtConfig({
|
||||
'Critical-CH': 'Sec-CH-Prefers-Color-Scheme',
|
||||
},
|
||||
},
|
||||
'/email/**': {
|
||||
prerender: true,
|
||||
headers: {
|
||||
'Content-Type': 'text/html',
|
||||
'Cache-Control': 'public, max-age=3600',
|
||||
},
|
||||
},
|
||||
},
|
||||
compatibilityDate: '2024-07-03',
|
||||
telemetry: false,
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
"@pinia/nuxt": "^0.5.1",
|
||||
"@types/three": "^0.172.0",
|
||||
"@vintl/vintl": "^4.4.1",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vue-email/components": "^0.0.21",
|
||||
"@vue-email/render": "^0.0.9",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"ace-builds": "^1.36.2",
|
||||
"ansi-to-html": "^0.7.2",
|
||||
|
||||
34
apps/frontend/src/emails/index.ts
Normal file
34
apps/frontend/src/emails/index.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import type { Component } from 'vue'
|
||||
|
||||
export default {
|
||||
// Account
|
||||
'auth-method-added': () => import('./templates/account/AuthenticationMethodAdded.vue'),
|
||||
'auth-method-removed': () => import('./templates/account/AuthenticationMethodRemoved.vue'),
|
||||
'email-changed': () => import('./templates/account/EmailChanged.vue'),
|
||||
'password-changed': () => import('./templates/account/PasswordChanged.vue'),
|
||||
'password-removed': () => import('./templates/account/PasswordRemoved.vue'),
|
||||
'payment-failed': () => import('./templates/account/PaymentFailed.vue'),
|
||||
'reset-password': () => import('./templates/account/ResetPassword.vue'),
|
||||
'two-factor-added': () => import('./templates/account/TwoFactorAdded.vue'),
|
||||
'two-factor-removed': () => import('./templates/account/TwoFactorRemoved.vue'),
|
||||
'verify-email': () => import('./templates/account/VerifyEmail.vue'),
|
||||
'login-new-device': () => import('./templates/account/LoginNewDevice.vue'),
|
||||
'payout-available': () => import('./templates/account/PayoutAvailable.vue'),
|
||||
'personal-access-token-created': () => import('./templates/account/PATCreated.vue'),
|
||||
|
||||
// Moderation
|
||||
'report-submitted': () => import('./templates/moderation/ReportSubmitted.vue'),
|
||||
'report-status-updated': () => import('./templates/moderation/ReportStatusUpdated.vue'),
|
||||
'moderation-thread-message-received': () =>
|
||||
import('./templates/moderation/ModerationThreadMessageReceived.vue'),
|
||||
|
||||
// Project
|
||||
'project-status-updated-neutral': () =>
|
||||
import('./templates/project/ProjectStatusUpdatedNeutral.vue'),
|
||||
'project-status-approved': () => import('./templates/project/ProjectStatusApproved.vue'),
|
||||
'project-invited': () => import('./templates/project/ProjectInvited.vue'),
|
||||
'project-transferred': () => import('./templates/project/ProjectTransferred.vue'),
|
||||
|
||||
// Organization
|
||||
'organization-invited': () => import('./templates/organization/OrganizationInvited.vue'),
|
||||
} as Record<string, () => Promise<{ default: Component }>>
|
||||
239
apps/frontend/src/emails/shared/StyledEmail.vue
Normal file
239
apps/frontend/src/emails/shared/StyledEmail.vue
Normal file
@@ -0,0 +1,239 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
Body,
|
||||
Column,
|
||||
Container,
|
||||
Head,
|
||||
Html,
|
||||
Img,
|
||||
Link as VLink,
|
||||
Row,
|
||||
Section,
|
||||
Style,
|
||||
Tailwind,
|
||||
Text,
|
||||
} from '@vue-email/components'
|
||||
|
||||
defineProps<{
|
||||
title?: string
|
||||
manualLinks?: { link: string; label?: string }[]
|
||||
}>()
|
||||
|
||||
interface SocialLink {
|
||||
href: string
|
||||
alt: string
|
||||
src: string
|
||||
}
|
||||
|
||||
const socialLinks = Object.freeze<readonly SocialLink[]>([
|
||||
{
|
||||
href: 'https://discord.modrinth.com',
|
||||
alt: 'Discord',
|
||||
src: 'https://cdn-raw.modrinth.com/email/discord.png',
|
||||
},
|
||||
{
|
||||
href: 'https://bsky.app/profile/modrinth.com',
|
||||
alt: 'Bluesky',
|
||||
src: 'https://cdn-raw.modrinth.com/email/bluesky.png',
|
||||
},
|
||||
{
|
||||
href: 'https://floss.social/@modrinth',
|
||||
alt: 'Mastodon',
|
||||
src: 'https://cdn-raw.modrinth.com/email/mastodon.png',
|
||||
},
|
||||
{
|
||||
href: 'https://x.com/modrinth',
|
||||
alt: 'X (Twitter)',
|
||||
src: 'https://cdn-raw.modrinth.com/email/x.png',
|
||||
},
|
||||
{
|
||||
href: 'https://www.instagram.com/modrinth/',
|
||||
alt: 'Instagram',
|
||||
src: 'https://cdn-raw.modrinth.com/email/instagram.png',
|
||||
},
|
||||
{
|
||||
href: 'https://www.youtube.com/@modrinth',
|
||||
alt: 'YouTube',
|
||||
src: 'https://cdn-raw.modrinth.com/email/youtube.png',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/modrinth',
|
||||
alt: 'GitHub',
|
||||
src: 'https://cdn-raw.modrinth.com/email/github.png',
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Html lang="en">
|
||||
<Head>
|
||||
<title>{{ title }}</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Inter:700,400"
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
/>
|
||||
<Style>
|
||||
/* Outlook.com centering + line-height fixes */ .ExternalClass { width:100%; }
|
||||
.ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td {
|
||||
line-height:100%; } table { border-collapse:separate; } a, a:link, a:visited {
|
||||
text-decoration:none; color:#1f68c0; } a:hover { text-decoration:underline; }
|
||||
h1,h2,h3,h4,h5,h6 { color:#000 !important; margin:0; mso-line-height-rule:exactly; }
|
||||
</Style>
|
||||
</Head>
|
||||
|
||||
<Body>
|
||||
<Tailwind
|
||||
:config="{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
bg: { DEFAULT: '#ebebeb', raised: '#ffffff', super: '#e9e9e9' },
|
||||
divider: { DEFAULT: '#babfc5', dark: '#c8cdd3' },
|
||||
base: '#2c2e31',
|
||||
secondary: '#484d54',
|
||||
contrast: '#1a202c',
|
||||
accentContrast: '#ffffff',
|
||||
red: '#cb2245',
|
||||
orange: '#e08325',
|
||||
green: '#00af5c',
|
||||
blue: '#1f68c0',
|
||||
purple: '#8e32f3',
|
||||
gray: '#595b61',
|
||||
brand: {
|
||||
DEFAULT: '#00af5c',
|
||||
highlight: 'rgba(0, 175, 92, 0.25)',
|
||||
shadow: 'rgba(0, 175, 92, 0.7)',
|
||||
},
|
||||
highlight: {
|
||||
red: 'rgba(203, 34, 69, 0.25)',
|
||||
orange: 'rgba(224, 131, 37, 0.25)',
|
||||
green: 'rgba(0, 175, 92, 0.25)',
|
||||
blue: 'rgba(31, 104, 192, 0.25)',
|
||||
purple: 'rgba(142, 50, 243, 0.25)',
|
||||
gray: 'rgba(89, 91, 97, 0.25)',
|
||||
},
|
||||
tint: {
|
||||
red: 'rgba(203, 34, 69, 0.1)',
|
||||
orange: 'rgba(224, 131, 37, 0.1)',
|
||||
green: 'rgba(0, 175, 92, 0.1)',
|
||||
blue: 'rgba(31, 104, 192, 0.1)',
|
||||
purple: 'rgba(142, 50, 243, 0.1)',
|
||||
},
|
||||
link: { DEFAULT: '#1f68c0', hover: '#1f68c0', active: '#1f68c0' },
|
||||
muted: '#777777',
|
||||
footerText: '#4d4d4d',
|
||||
},
|
||||
fontSize: {
|
||||
base: ['16px', { lineHeight: '24px' }],
|
||||
'2xl': ['28px', { lineHeight: '32px' }],
|
||||
xs: ['13px', { lineHeight: '16px' }],
|
||||
'2xs': ['11px', { lineHeight: '16px' }],
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'Arial', 'sans-serif'],
|
||||
},
|
||||
},
|
||||
},
|
||||
}"
|
||||
>
|
||||
<Section class="m-0 pb-0 pl-0 pr-0 pt-0 font-sans">
|
||||
<Section class="bg-bg pb-4 pl-4 pr-4 pt-4">
|
||||
<Container class="max-w-[600px]">
|
||||
<Row>
|
||||
<Column>
|
||||
<Img
|
||||
src="https://cdn.modrinth.com/email/f740e2decee8764a4629bff677a284f9.png"
|
||||
width="29"
|
||||
alt=""
|
||||
class="block h-auto"
|
||||
/>
|
||||
</Column>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
|
||||
<Section class="bg-white pb-8 pl-8 pr-8 pt-8">
|
||||
<Container class="max-w-[600px]">
|
||||
<slot />
|
||||
</Container>
|
||||
</Section>
|
||||
|
||||
<Section class="mb-4 bg-bg pb-4 pl-4 pr-4 pt-4">
|
||||
<Container class="max-w-[600px]">
|
||||
<Row>
|
||||
<Column class="align-middle">
|
||||
<VLink href="https://modrinth.com" aria-label="Modrinth">
|
||||
<Img
|
||||
src="https://cdn.modrinth.com/email/bd3357dfae4b1d266250372db3a0988f.png"
|
||||
width="175"
|
||||
alt="modrinth logo"
|
||||
class="block h-auto"
|
||||
/>
|
||||
</VLink>
|
||||
|
||||
<Row class="text-right align-middle">
|
||||
<Section class="m-0 inline-block pb-0 pl-0 pr-0 pt-0">
|
||||
<template v-for="(item, index) in socialLinks" :key="item.href">
|
||||
<VLink
|
||||
:href="item.href"
|
||||
:class="['inline-block', index !== socialLinks.length - 1 ? 'mr-4' : '']"
|
||||
>
|
||||
<Img width="20" height="20" :alt="item.alt" :src="item.src" />
|
||||
</VLink>
|
||||
</template>
|
||||
</Section>
|
||||
</Row>
|
||||
|
||||
<Text class="mb-0 mt-2 text-xs" :style="{ color: '#4d4d4d' }"> Rinth, Inc. </Text>
|
||||
<Section class="m-0 pb-0 pl-0 pr-0 pt-0">
|
||||
<Text class="m-0 text-xs text-secondary">800 N King St</Text>
|
||||
<Text class="m-0 text-xs text-secondary">Suite 304 #3133</Text>
|
||||
<Text class="m-0 text-xs text-secondary">Wilmington, DE 19801</Text>
|
||||
</Section>
|
||||
</Column>
|
||||
</Row>
|
||||
</Container>
|
||||
</Section>
|
||||
|
||||
<!-- <Text
|
||||
class="text-footerText text-2xs mb-4 mt-0 pb-0 pl-4 pr-4 pt-0 text-center font-sans"
|
||||
>
|
||||
This email was sent to you as a registered user of Modrinth. You can customize the
|
||||
emails you recieve in your
|
||||
<VLink href="https://modrinth.com/settings/notifications" class="text-green underline"
|
||||
>notification settings</VLink
|
||||
>. Some emails are required to keep your account secure and cannot be disabled.
|
||||
</Text> -->
|
||||
|
||||
<hr />
|
||||
|
||||
<Section
|
||||
v-if="manualLinks && manualLinks.length"
|
||||
class="text-footerText text-2xs mb-4 mt-4 pb-0 pl-4 pr-4 pt-0 font-sans"
|
||||
>
|
||||
<small class="text-muted text-2xs"
|
||||
>If you're having trouble with the links above, copy and paste these URLs into your
|
||||
web browser:</small
|
||||
>
|
||||
<Text class="text-2xs text-muted mt-0">
|
||||
<span v-for="(item, index) in manualLinks" :key="index" class="block break-words">
|
||||
<span v-if="item.label">
|
||||
<b>{{ item.label }}:</b><br />
|
||||
</span>
|
||||
{{ item.link }}
|
||||
</span>
|
||||
<!-- <span class="block break-words">
|
||||
<span> <b>Notification settings:</b><br /> </span>
|
||||
https://modrinth.com/settings/notifications
|
||||
</span> -->
|
||||
</Text>
|
||||
</Section>
|
||||
</Section>
|
||||
</Tailwind>
|
||||
</Body>
|
||||
</Html>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="New sign-in method added"
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> New sign-in method added </Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
Your {authprovider.name} account has been connected and you can now use it to sign in to your
|
||||
Modrinth account.
|
||||
</Text>
|
||||
<Text class="text-muted text-base">
|
||||
If you did not make this change, please contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Sign-in method removed"
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> Sign-in method removed</Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
Your <b>{authprovider.name}</b> account has been disconnected and you can no longer use it to
|
||||
sign in to your Modrinth account.
|
||||
</Text>
|
||||
<Text class="text-muted text-base">
|
||||
If you did not make this change, please contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
26
apps/frontend/src/emails/templates/account/EmailChanged.vue
Normal file
26
apps/frontend/src/emails/templates/account/EmailChanged.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Your email has been changed"
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> Your email has been changed </Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
At your request, we've successfully updated your Modrinth account's email to
|
||||
{emailchanged.new_email}.
|
||||
</Text>
|
||||
<Text class="text-muted text-base">
|
||||
If you did not make this change, please contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
import { Column, Heading, Img, Link as VLink, Row, Section, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Sign in from new device"
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> Sign in from new device </Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
We noticed that your account was just signed into from a new device or location. If this was
|
||||
you, you can safely ignore this email.
|
||||
</Text>
|
||||
|
||||
<Section class="bg-bg-super rounded-lg border border-divider pb-4 pl-4 pr-4 pt-4">
|
||||
<Row>
|
||||
<Column class="w-full">
|
||||
<Row class="mb-2 mt-0">
|
||||
<Column class="w-8">
|
||||
<Img
|
||||
width="20"
|
||||
height="20"
|
||||
alt="Time icon"
|
||||
src="https://cdn-raw.modrinth.com/email/earth.png"
|
||||
/>
|
||||
</Column>
|
||||
<Column>
|
||||
<Text class="m-0 text-sm font-semibold text-secondary">Approximate location</Text>
|
||||
<Text class="m-0 text-base">{newdevice.location}</Text>
|
||||
</Column>
|
||||
</Row>
|
||||
|
||||
<Row class="mb-2">
|
||||
<Column class="w-8">
|
||||
<Img
|
||||
width="20"
|
||||
height="20"
|
||||
alt="Time icon"
|
||||
src="https://cdn-raw.modrinth.com/email/monitor-smartphone.png"
|
||||
/>
|
||||
</Column>
|
||||
<Column>
|
||||
<Text class="m-0 text-sm font-semibold text-secondary">IP Address</Text>
|
||||
<Text class="m-0 font-mono text-base">{newdevice.ip}</Text>
|
||||
</Column>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Column class="w-8">
|
||||
<Img
|
||||
width="20"
|
||||
height="20"
|
||||
alt="Time icon"
|
||||
src="https://cdn-raw.modrinth.com/email/clock.png"
|
||||
/>
|
||||
</Column>
|
||||
<Column>
|
||||
<Text class="m-0 text-sm font-semibold text-secondary">Time</Text>
|
||||
<Text class="m-0 text-base">{time.now}</Text>
|
||||
</Column>
|
||||
</Row>
|
||||
</Column>
|
||||
</Row>
|
||||
</Section>
|
||||
|
||||
<Text class="text-muted text-base">
|
||||
If this wasn't you, please update your password and review your account security settings. If
|
||||
you cannot do this, contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
27
apps/frontend/src/emails/templates/account/PATCreated.vue
Normal file
27
apps/frontend/src/emails/templates/account/PATCreated.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="A new personal access token has been created"
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold">
|
||||
A new personal access token has been created
|
||||
</Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
A new personal access token, <b>{newpat.token_name}</b>, has been added to your account.
|
||||
</Text>
|
||||
<Text class="text-muted text-base">
|
||||
If you did not create this token, please contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Your password has been changed"
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> Your password has been changed </Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base"> Your password has been changed on your account. </Text>
|
||||
<Text class="text-muted text-base">
|
||||
If you did not make this change, please contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Your password has been removed"
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> Your password has been removed </Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
At your request, your password has been removed from your account. You must now use a linked
|
||||
authentication provider (such as your {passremoved.provider} account) to log into your
|
||||
Modrinth account.</Text
|
||||
>
|
||||
<Text class="text-muted text-base">
|
||||
If you did not make this change, please contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
33
apps/frontend/src/emails/templates/account/PaymentFailed.vue
Normal file
33
apps/frontend/src/emails/templates/account/PaymentFailed.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Payment failed for {paymentfailed.service}"
|
||||
:manual-links="[{ link: '{billing.url}', label: 'Billing settings' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold">
|
||||
Payment failed for {paymentfailed.service}
|
||||
</Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
Our attempt to collect payment for {paymentfailed.amount} from the payment card on file was
|
||||
unsuccessful. Please update your billing settings to avoid suspension of your service.
|
||||
</Text>
|
||||
<Button
|
||||
href="{billing.url}"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
Update billing settings
|
||||
</Button>
|
||||
|
||||
<VLink href="{billing.url}">
|
||||
<Text class="text-muted mt-2 break-words text-xs font-bold">{billing.url}</Text>
|
||||
</VLink>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Link as VLink, Section, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Revenue available to withdraw!"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/dashboard/revenue', label: 'Revenue dashboard' },
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold">Revenue available to withdraw!</Heading>
|
||||
|
||||
<Text class="text-base">Hi {user.name},</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
The ${payout.amount} earned during {payout.period} has been processed and is now available to
|
||||
withdraw from your account.
|
||||
</Text>
|
||||
|
||||
<Section class="mb-4 mt-4">
|
||||
<Button
|
||||
href="https://modrinth.com/dashboard/revenue"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
View revenue dashboard
|
||||
</Button>
|
||||
</Section>
|
||||
|
||||
<Text class="text-base">
|
||||
If you have any questions about the creator rewards program, please contact support through
|
||||
the
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline">Support Portal</VLink>
|
||||
or by replying to this email.
|
||||
</Text>
|
||||
|
||||
<Text class="text-base">Thank you for being a creator on Modrinth!</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
32
apps/frontend/src/emails/templates/account/ResetPassword.vue
Normal file
32
apps/frontend/src/emails/templates/account/ResetPassword.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Reset your password"
|
||||
:manual-links="[{ link: '{resetpassword.url}', label: 'Password reset link' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> Reset your password </Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
Please visit the link below to reset your password. If you did not request for your password
|
||||
to be reset, you can safely ignore this email.
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
href="{resetpassword.url}"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
Reset password
|
||||
</Button>
|
||||
|
||||
<VLink href="{resetpassword.url}">
|
||||
<Text class="text-muted mt-2 break-words text-xs font-bold">{resetpassword.url}</Text>
|
||||
</VLink>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Two-factor authentication enabled"
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> Two-factor authentication enabled </Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
You've secured your account with two-factor authentication. Now, when signing in, you will
|
||||
need to submit the code generated by your authenticator app.
|
||||
</Text>
|
||||
<Text class="text-muted text-base">
|
||||
If you did not make this change, please contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="You've disabled two-factor authentication security on your account."
|
||||
:manual-links="[{ link: 'https://support.modrinth.com', label: 'Support Portal' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold">
|
||||
You've disabled two-factor authentication security on your account.
|
||||
</Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
At your request, we've removed two-factor authentication from your Modrinth account.
|
||||
</Text>
|
||||
<Text class="text-muted text-base">
|
||||
If you did not make this change, please contact us immediately by replying to this email or
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline"
|
||||
>through our Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
32
apps/frontend/src/emails/templates/account/VerifyEmail.vue
Normal file
32
apps/frontend/src/emails/templates/account/VerifyEmail.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Verify your Modrinth email"
|
||||
:manual-links="[{ link: '{verifyemail.url}', label: 'Verification link' }]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"> Verify your email </Heading>
|
||||
|
||||
<Text class="text-muted text-base">Hi {user.name},</Text>
|
||||
<Text class="text-muted text-base">
|
||||
Please visit the link below to verify your email. If the button does not work, you can copy
|
||||
the link and paste it into your browser. This link expires in 24 hours.
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
href="{verifyemail.url}"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
Verify email
|
||||
</Button>
|
||||
|
||||
<VLink href="{verifyemail.url}">
|
||||
<Text class="text-muted mt-2 break-words text-xs font-bold">{verifyemail.url}</Text>
|
||||
</VLink>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Img, Link as VLink, Section, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="New moderation message"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/legal/rules', label: 'Community Guidelines' },
|
||||
{
|
||||
link: 'https://modrinth.com/project/{project.id}/moderation',
|
||||
label: 'Your project\'s moderation thread',
|
||||
},
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Section class="mb-4 mt-2">
|
||||
<Img
|
||||
src="{project.icon_url}"
|
||||
alt="project icon"
|
||||
width="64"
|
||||
height="64"
|
||||
class="block h-auto"
|
||||
/>
|
||||
</Section>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"
|
||||
>New message from moderators on {project.name}</Heading
|
||||
>
|
||||
|
||||
<Text class="text-base">Hi {user.name},</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
Modrinth's moderation team has left a message on your project,
|
||||
<VLink
|
||||
href="https://modrinth.com/project/{project.id}/moderation"
|
||||
class="text-green underline"
|
||||
>{project.name}</VLink
|
||||
>.
|
||||
</Text>
|
||||
|
||||
<Section class="bg-bg-super mb-4 mt-4 rounded-lg border border-divider pb-4 pl-4 pr-4 pt-4">
|
||||
<Text class="m-0 text-base">
|
||||
Please
|
||||
<VLink
|
||||
href="https://modrinth.com/project/{project.id}/moderation"
|
||||
class="text-green underline"
|
||||
>sign in to view the message</VLink
|
||||
>
|
||||
and reply if requested. It's important to address feedback from the moderation team
|
||||
promptly.
|
||||
</Text>
|
||||
</Section>
|
||||
|
||||
<Text class="text-base">Thank you for publishing on Modrinth!</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Report of '{report.title}' has been updated"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/legal/rules', label: 'Community Guidelines' },
|
||||
{
|
||||
link: 'https://modrinth.com/dashboard/report/{report.id}',
|
||||
label: 'View report in dashboard',
|
||||
},
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"
|
||||
>Report of '{report.title}' has been updated</Heading
|
||||
>
|
||||
|
||||
<Text class="text-base">Hi {user.name},</Text>
|
||||
|
||||
<Text class="text-base"
|
||||
>Your report of {report.title} from {report.date} has been updated by our moderation
|
||||
team.</Text
|
||||
>
|
||||
|
||||
<Text class="text-base">
|
||||
You can
|
||||
<VLink href="https://modrinth.com/dashboard/report/{report.id}" class="text-green underline"
|
||||
>view the full report thread</VLink
|
||||
>
|
||||
to see the update. If you have more information to add, please reply in the report thread for
|
||||
our moderators to review.
|
||||
</Text>
|
||||
|
||||
<Text class="text-base"
|
||||
>Thank you for helping keep Modrinth safe and welcoming for everyone.</Text
|
||||
>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import { Heading, Link as VLink, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Report of {report.title} has been submitted"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/legal/rules', label: 'Community Guidelines' },
|
||||
{
|
||||
link: 'https://modrinth.com/dashboard/report/{newreport.id}',
|
||||
label: 'View report in dashboard',
|
||||
},
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"
|
||||
>Report of {report.title} has been submitted</Heading
|
||||
>
|
||||
|
||||
<Text class="text-base">Hi {user.name},</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
We've received your report of {report.title} and our moderation team will review it shortly.
|
||||
</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
Our team takes all reports seriously and will investigate according to our
|
||||
<VLink href="https://modrinth.com/legal/rules" class="text-green underline"
|
||||
>Content Rules</VLink
|
||||
>, <VLink href="https://modrinth.com/legal/terms">Terms of Service</VLink> and
|
||||
<VLink href="https://modrinth.com/legal/copyright">Copyright Policy</VLink>. You'll receive an
|
||||
email update once we've completed our review.
|
||||
</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
If you have any additional information about this report, you can
|
||||
<VLink
|
||||
href="https://modrinth.com/dashboard/report/{newreport.id}"
|
||||
class="text-green underline"
|
||||
>view it here</VLink
|
||||
>.
|
||||
</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
Thank you for helping keep Modrinth safe and welcoming for everyone.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,75 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Img, Link as VLink, Section, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="You've been invited to an organization"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/organization/{organization.id}', label: 'Organization page' },
|
||||
{ link: 'https://modrinth.com/dashboard/notifications', label: 'Notification dashboard' },
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Section class="mb-4 mt-2">
|
||||
<Img
|
||||
src="{organization.icon_url}"
|
||||
alt="organization icon"
|
||||
width="64"
|
||||
height="64"
|
||||
class="block h-auto rounded-lg"
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"
|
||||
>You've been invited to an organization</Heading
|
||||
>
|
||||
|
||||
<Text class="text-base">Hi {user.name},</Text>
|
||||
|
||||
<Text class="text-base"
|
||||
>Modrinth user
|
||||
<b
|
||||
><VLink href="https://modrinth.com/user/{inviter.name}" class="text-green underline">
|
||||
{inviter.name}
|
||||
</VLink></b
|
||||
>
|
||||
has invited you to join the organization
|
||||
<b
|
||||
><VLink
|
||||
href="https://modrinth.com/organization/{organization.id}"
|
||||
class="text-green underline"
|
||||
>
|
||||
{organization.name}
|
||||
</VLink></b
|
||||
>
|
||||
on Modrinth.
|
||||
</Text>
|
||||
|
||||
<Section class="bg-bg-super mb-4 mt-4 rounded-lg border border-divider pb-4 pl-4 pr-4 pt-4">
|
||||
<Text class="m-0 text-base">
|
||||
As an organization member you may gain access to manage projects, teams, members, settings,
|
||||
and other resources depending on the permissions assigned to you.
|
||||
</Text>
|
||||
</Section>
|
||||
|
||||
<Button
|
||||
href="https://modrinth.com/dashboard/notifications"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
Review invitation
|
||||
</Button>
|
||||
|
||||
<Text class="text-base">
|
||||
If you were not expecting this invitation you should reject it. If you believe this was sent
|
||||
in error or is abusive, please contact support
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline">
|
||||
through the Support Portal</VLink
|
||||
>
|
||||
or by replying to this email.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,70 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Img, Link as VLink, Section, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="You've been invited to a project"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/project/{project.id}', label: 'Project page' },
|
||||
{ link: 'https://modrinth.com/dashboard/notifications', label: 'Notification dashboard' },
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Section class="mb-4 mt-2">
|
||||
<Img
|
||||
src="{project.icon_url}"
|
||||
alt="project icon"
|
||||
width="64"
|
||||
height="64"
|
||||
class="block h-auto rounded-lg"
|
||||
/>
|
||||
</Section>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold">You've been invited to a project</Heading>
|
||||
|
||||
<Text class="text-base">Hi {user.name},</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
Modrinth user
|
||||
<b
|
||||
><VLink href="https://modrinth.com/user/{inviter.name}" class="text-green underline">
|
||||
{inviter.name}
|
||||
</VLink></b
|
||||
>
|
||||
has invited you to join the project
|
||||
<b>
|
||||
<VLink href="https://modrinth.com/project/{project.id}" class="text-green underline">
|
||||
{project.name}
|
||||
</VLink>
|
||||
</b>
|
||||
on Modrinth.
|
||||
</Text>
|
||||
|
||||
<Section class="bg-bg-super mb-4 mt-4 rounded-lg border border-divider pb-4 pl-4 pr-4 pt-4">
|
||||
<Text class="m-0 text-base">
|
||||
As a project member you may be able to manage versions, edit project details, configure
|
||||
settings, and collaborate with other maintainers depending on the permissions assigned to
|
||||
you.
|
||||
</Text>
|
||||
</Section>
|
||||
|
||||
<Button
|
||||
href="https://modrinth.com/dashboard/notifications"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
Review invitation
|
||||
</Button>
|
||||
|
||||
<Text class="text-base">
|
||||
If you were not expecting this invitation you should reject the invitation. If you believe
|
||||
this was sent in error or is abusive, please contact support
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline">
|
||||
through the Support Portal</VLink
|
||||
>
|
||||
or by replying to this email.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,56 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Img, Link as VLink, Section, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Your project, {project.name}, has been approved 🎉"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/project/{project.id}', label: 'Project page' },
|
||||
{ link: 'https://modrinth.com/legal/rules', label: 'Community Guidelines' },
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Section class="mb-4 mt-2">
|
||||
<Img
|
||||
src="{project.icon_url}"
|
||||
alt="project icon"
|
||||
width="64"
|
||||
height="64"
|
||||
class="block h-auto rounded-lg"
|
||||
/>
|
||||
</Section>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"
|
||||
>Your project, {project.name}, has been approved 🎉</Heading
|
||||
>
|
||||
|
||||
<Text class="text-base">Congratulations {user.name},</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
Your project
|
||||
<VLink href="https://modrinth.com/project/{project.id}" class="text-green underline"
|
||||
>{project.name}</VLink
|
||||
>
|
||||
has been <b>approved</b> by the moderation team!
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
href="https://modrinth.com/project/{project.id}"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
View project
|
||||
</Button>
|
||||
|
||||
<Text class="text-base">
|
||||
If you have questions or believe something isn't correct, you can reply to this email or reach
|
||||
out via the
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline">Support Portal</VLink
|
||||
>.
|
||||
</Text>
|
||||
|
||||
<Text class="text-base">Thank you for sharing your work with the Modrinth community!</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Img, Link as VLink, Section, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Your project, {project.name}, status has been updated"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/legal/rules', label: 'Community Guidelines' },
|
||||
{
|
||||
link: 'https://modrinth.com/project/{project.id}/moderation',
|
||||
label: 'Your project\'s moderation thread',
|
||||
},
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Section class="mb-4 mt-2">
|
||||
<Img
|
||||
src="{project.icon_url}"
|
||||
alt="project icon"
|
||||
width="64"
|
||||
height="64"
|
||||
class="block h-auto rounded-lg"
|
||||
/>
|
||||
</Section>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold"
|
||||
>Your project, {project.name}, status has been updated</Heading
|
||||
>
|
||||
|
||||
<Text class="text-base">Hi {user.name},</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
Your project's status has been changed from <b>{project.oldstatus}</b> to
|
||||
<b>{project.newstatus}</b> by the moderation team. Please review any messages left in the
|
||||
<VLink
|
||||
href="https://modrinth.com/project/{project.id}/moderation"
|
||||
class="text-green underline"
|
||||
>moderation thread</VLink
|
||||
>
|
||||
which might be relevant to why the status was changed.
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
href="https://modrinth.com/project/{project.id}"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
View project
|
||||
</Button>
|
||||
|
||||
<Text class="text-base">
|
||||
If you believe this status was applied in error, you can reply in the moderation thread or
|
||||
contact support through our
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline">Support Portal</VLink>
|
||||
or by replying to this email.
|
||||
</Text>
|
||||
|
||||
<Text class="text-base">Thank you for publishing on Modrinth!</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
@@ -0,0 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Heading, Img, Link as VLink, Section, Text } from '@vue-email/components'
|
||||
|
||||
import StyledEmail from '@/emails/shared/StyledEmail.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StyledEmail
|
||||
title="Project ownership transferred"
|
||||
:manual-links="[
|
||||
{ link: 'https://modrinth.com/project/{project.id}', label: 'Project page' },
|
||||
{ link: 'https://modrinth.com/dashboard/notifications', label: 'Notification dashboard' },
|
||||
{ link: 'https://support.modrinth.com', label: 'Support Portal' },
|
||||
]"
|
||||
>
|
||||
<Section class="mb-4 mt-2">
|
||||
<Img
|
||||
src="{project.icon_url}"
|
||||
alt="project icon"
|
||||
width="64"
|
||||
height="64"
|
||||
class="block h-auto rounded-lg"
|
||||
/>
|
||||
</Section>
|
||||
<Heading as="h1" class="mb-2 text-2xl font-bold">Project ownership transferred</Heading>
|
||||
|
||||
<Text class="text-base">Hi {user.name},</Text>
|
||||
|
||||
<Text class="text-base">
|
||||
The ownership of
|
||||
<b>
|
||||
<VLink href="https://modrinth.com/project/{project.id}" class="text-green underline">
|
||||
{project.name}
|
||||
</VLink>
|
||||
</b>
|
||||
has been successfully transferred to the Modrinth {new_owner.type_capitalized}
|
||||
<b
|
||||
><VLink
|
||||
href="https://modrinth.com/{new_owner.type}/{new_owner.name}"
|
||||
class="text-green underline"
|
||||
>{new_owner.name}</VLink
|
||||
></b
|
||||
>.
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
href="https://modrinth.com/project/{project.id}"
|
||||
target="_blank"
|
||||
class="text-accentContrast inline-block rounded-[12px] bg-brand pb-3 pl-4 pr-4 pt-3 text-[14px] font-bold"
|
||||
>
|
||||
View project
|
||||
</Button>
|
||||
|
||||
<Text class="text-base">
|
||||
If you did not initiate this transfer, please contact support immediately through the
|
||||
<VLink href="https://support.modrinth.com" class="text-green underline">Support Portal</VLink>
|
||||
or by replying to this email.
|
||||
</Text>
|
||||
</StyledEmail>
|
||||
</template>
|
||||
129
apps/frontend/src/pages/admin/emails.vue
Normal file
129
apps/frontend/src/pages/admin/emails.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<script setup lang="ts">
|
||||
import { CopyIcon, LibraryIcon, PlayIcon, SearchIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, Card } from '@modrinth/ui'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
|
||||
import emails from '@/emails'
|
||||
|
||||
const allTemplates = Object.keys(emails).sort()
|
||||
const query = ref('')
|
||||
const filtered = computed(() =>
|
||||
allTemplates.filter((t) => t.toLowerCase().includes(query.value.toLowerCase().trim())),
|
||||
)
|
||||
|
||||
function openAll() {
|
||||
let offset = 0
|
||||
for (const id of filtered.value) {
|
||||
openPreview(id, offset)
|
||||
offset++
|
||||
}
|
||||
}
|
||||
|
||||
function copy(id: string) {
|
||||
navigator.clipboard?.writeText(`/email/${id}`).catch(() => {})
|
||||
}
|
||||
|
||||
function openPreview(id: string, offset = 0) {
|
||||
const width = 600
|
||||
const height = 850
|
||||
const left = window.screenX + (window.outerWidth - width) / 2 + ((offset * 28) % 320)
|
||||
const top = window.screenY + (window.outerHeight - height) / 2 + ((offset * 28) % 320)
|
||||
window.open(
|
||||
`/email/${id}`,
|
||||
`email-${id}`,
|
||||
`popup=yes,width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no`,
|
||||
)
|
||||
}
|
||||
|
||||
const counts = computed(() => ({
|
||||
total: allTemplates.length,
|
||||
shown: filtered.value.length,
|
||||
}))
|
||||
|
||||
onMounted(() => {
|
||||
document.getElementById('email-search')?.focus()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="normal-page no-sidebar">
|
||||
<h1 class="mb-4 text-3xl font-extrabold text-heading">Email templates</h1>
|
||||
<div class="normal-page__content">
|
||||
<Card class="mb-6 flex flex-col gap-4">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<div class="relative">
|
||||
<SearchIcon
|
||||
class="pointer-events-none absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-secondary"
|
||||
/>
|
||||
<input
|
||||
id="email-search"
|
||||
v-model="query"
|
||||
type="text"
|
||||
placeholder="Search templates..."
|
||||
class="w-72 rounded-lg border border-divider bg-bg px-7 py-2 text-sm text-primary placeholder-secondary focus:border-green focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ButtonStyled color="brand">
|
||||
<button :disabled="filtered.length === 0" @click="openAll">
|
||||
<LibraryIcon class="h-4 w-4" aria-hidden="true" />
|
||||
Open all ({{ counts.shown }})
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
|
||||
<span class="text-sm text-secondary">
|
||||
Showing <span class="font-medium text-contrast">{{ counts.shown }}</span> of
|
||||
<span class="font-medium text-contrast">{{ counts.total }}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="filtered.length === 0"
|
||||
class="rounded-lg border border-dashed border-divider px-6 py-10 text-center text-sm text-secondary"
|
||||
>
|
||||
No templates match your search.
|
||||
</div>
|
||||
|
||||
<ul v-else class="grid gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||
<li
|
||||
v-for="id in filtered"
|
||||
:key="id"
|
||||
class="hover:border-green/70 group flex flex-col justify-between rounded-lg border border-divider bg-button-bg p-4 shadow-sm transition hover:shadow"
|
||||
>
|
||||
<div class="mb-3">
|
||||
<div class="font-mono text-sm font-semibold tracking-tight text-contrast">
|
||||
{{ id }}
|
||||
</div>
|
||||
<div class="mt-1 truncate text-xs text-secondary">/email/{{ id }}</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-auto flex gap-2">
|
||||
<ButtonStyled color="brand" class="flex-1">
|
||||
<button class="w-full justify-center" @click="openPreview(id)">
|
||||
<PlayIcon class="h-4 w-4" aria-hidden="true" />
|
||||
Preview
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
|
||||
<ButtonStyled>
|
||||
<button class="justify-center" title="Copy preview URL" @click="copy(id)">
|
||||
<CopyIcon class="h-4 w-4" aria-hidden="true" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</Card>
|
||||
|
||||
<p class="mt-2 text-xs text-secondary">
|
||||
All templates come from
|
||||
<code class="rounded bg-code-bg px-1 py-0.5 text-[11px] text-code-text"
|
||||
>src/emails/index.ts</code
|
||||
>. Popouts render via
|
||||
<code class="rounded bg-code-bg px-1 py-0.5 text-[11px] text-code-text"
|
||||
>/email/[template]</code
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,2 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow:
|
||||
Disallow: /email/
|
||||
|
||||
28
apps/frontend/src/server/routes/email/[template].ts
Normal file
28
apps/frontend/src/server/routes/email/[template].ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { render } from '@vue-email/render'
|
||||
import type { Component } from 'vue'
|
||||
|
||||
import emails from '~/emails'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const template = event.context.params?.template as string
|
||||
try {
|
||||
const component = (await emails[template]()).default as Component | undefined
|
||||
|
||||
if (!component) {
|
||||
throw createError({
|
||||
statusCode: 404,
|
||||
message: 'Email template not found',
|
||||
})
|
||||
}
|
||||
|
||||
const html = await render(component, {})
|
||||
|
||||
return html
|
||||
} catch (error) {
|
||||
console.error(`Error rendering email template ${template}:`, error)
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
message: 'Failed to render email template',
|
||||
})
|
||||
}
|
||||
})
|
||||
370
pnpm-lock.yaml
generated
370
pnpm-lock.yaml
generated
@@ -242,6 +242,15 @@ importers:
|
||||
'@vintl/vintl':
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1(typescript@5.5.4)(vue@3.5.13(typescript@5.5.4))
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.0.4
|
||||
version: 5.2.1(vite@5.4.11(@types/node@20.14.11)(sass@1.77.6)(terser@5.43.1))(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/components':
|
||||
specifier: ^0.0.21
|
||||
version: 0.0.21(typescript@5.5.4)(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/render':
|
||||
specifier: ^0.0.9
|
||||
version: 0.0.9(typescript@5.5.4)
|
||||
'@vueuse/core':
|
||||
specifier: ^11.1.0
|
||||
version: 11.1.0(vue@3.5.13(typescript@5.5.4))
|
||||
@@ -2039,6 +2048,9 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^3.3.4
|
||||
|
||||
'@one-ini/wasm@0.1.1':
|
||||
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
|
||||
|
||||
'@oslojs/encoding@1.1.0':
|
||||
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
|
||||
|
||||
@@ -2472,6 +2484,9 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@selderee/plugin-htmlparser2@0.11.0':
|
||||
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
|
||||
|
||||
'@sentry-internal/browser-utils@8.27.0':
|
||||
resolution: {integrity: sha512-YTIwQ1GM1NTRXgN4DvpFSQ2x4pjlqQ0FQAyHW5x2ZYv4z7VmqG4Xkid1P/srQUipECk6nxkebfD4WR19nLsvnQ==}
|
||||
engines: {node: '>=14.18'}
|
||||
@@ -3046,6 +3061,116 @@ packages:
|
||||
'@vscode/l10n@0.0.18':
|
||||
resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==}
|
||||
|
||||
'@vue-email/body@0.0.3':
|
||||
resolution: {integrity: sha512-JxZb1upJTnt6tLKszqHfrCWTpioWuG7eZXneUmCBr0YVt6gI781dSAgUQASTBprENnO+M2sNsarszoo7jGZNOQ==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/button@0.0.3':
|
||||
resolution: {integrity: sha512-Su1iKBpfzF03SqLhxxIGDm2ZgpnXh+yD8kvLQ9+V0COepXOSdVQD5Ovif14uKGweafXSMkyQSi5lqmnVIace3A==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/code-block@0.0.3':
|
||||
resolution: {integrity: sha512-NuOAY3dhWCwnywQ9lguLWqh+2BDKr1UM7AkV/ejDJwfX/GLZnlN9EEJRYOVhFnGwXOcJnS27NmvjZHaRweZfWA==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/code-inline@0.0.3':
|
||||
resolution: {integrity: sha512-FN9WPQBwWWumpPIAN/++oly9/hpUfioVokb7nfM/U0hEOS3mGsVjYPZNiX/oGOAHrAF83qOqgIFcd9ipVMtefg==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/column@0.0.3':
|
||||
resolution: {integrity: sha512-L1tYu3ZqoqcSNa5GK8wEKQKuvUBlsWeSA3RqKlkLrc+dR+uitcyCcbYsoE/N2tgvzZ1poykE/S6VIcrqH/zL9A==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/components@0.0.21':
|
||||
resolution: {integrity: sha512-xtL9vdWgBpq2B4OqbOvW9s9+5fF8bZamNHCBNYkFMzGg7Ne+SWk/vZI0LhCeMqWUkodnCvCoW/i7IYGjw5veHw==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
peerDependencies:
|
||||
vue: ^3.4.29
|
||||
|
||||
'@vue-email/container@0.0.3':
|
||||
resolution: {integrity: sha512-L+9VZ3RbCgyPaV54QCQsOAe9lAvq549JULEmH3QRDgHsIaFE3Yaddc1zMJKdbwH7ugiaRPRFrM2paR57IS6sWw==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/font@0.0.3':
|
||||
resolution: {integrity: sha512-X9vwUTKjPeFuh06BkYbFVM3rdZggLo7hJ3SHgJ09qBF7e0J7zZx5KLjkeYzKTWfHlM1fx9XtNdpQ35UKyIpwUg==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/head@0.0.3':
|
||||
resolution: {integrity: sha512-RobskTPhRQ18aHFcwOe1eorGDd3BCotXJy2YfZF9VRHvw1MtV5M/AQ0eqUUgnNuNrxFGobZtxZJMu4+EE2ToUQ==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/heading@0.0.3':
|
||||
resolution: {integrity: sha512-cUxlLDuRHEdLn+CZWehsUuJjWNnDVC1LAK1iKtZl++J9xGE1l4lrxaBFdhIZctH2yoZZLGm8OHvUJiYrke9YIg==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/hr@0.0.3':
|
||||
resolution: {integrity: sha512-DNSi4CrsgRJRstTIB8ILcCqg0rWIIMKZ1fmSVgHoEBfgiV9I4m/6wKv2Rzg1AxkYldy5w1YhwVx0NfBTCHlL7A==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/html@0.0.3':
|
||||
resolution: {integrity: sha512-kjUBwwWcgNoJ6jEmZW7gkdSXZzy6rcJ0jV4507TZlF6PRsu4FaCpeI6WHnDexdXIfCeAIwZqeAQOJHASHJd2mw==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/img@0.0.3':
|
||||
resolution: {integrity: sha512-lFDavbzdbOXo2VK8Fq/YPFB/2ZolOaToC/oFR9fQlw2hA9n1TTiEZZK5D7en62FSD9gPG1P7eQ81tOt6/Tc6+A==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/link@0.0.3':
|
||||
resolution: {integrity: sha512-AvX5wxXACrxqyLaooIDQBsz/8Q6FDSVGDg0Lo1opUZKEW80s68zI+FUhI3kuByVEogzIhfdpq9rc1yGmkUUh8A==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/markdown@0.0.7':
|
||||
resolution: {integrity: sha512-AxMpxo0A20lFiED7l1nJy6Y+fDYHknYW6u1HZ7F2QbDUihtinwAWU9pBFDX9SSHg9Ihkf3KeitvGf4YHiYlXRA==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/preview@0.0.3':
|
||||
resolution: {integrity: sha512-e9qLDsP5+f5KZQhiVGjI/d/x5NfLfYusjI9C4bewwXM6bYJo1i5WRRzX6SM7sygKEk0ZbKqnzPqbnSWtABuzDw==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/render@0.0.9':
|
||||
resolution: {integrity: sha512-FShvnLSoys3y+30uIO4ZuBSsXKGaj/VOB+CfNxhgxLmFsLbwKwUZQgJVAmXviuuSC5xpWQCOEPQ8P7oEEYa0WA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@vue-email/row@0.0.3':
|
||||
resolution: {integrity: sha512-/wnkRMFJl5WTehD3/ryn7taJs42Vk7K1xUH37Q5R5T8tu1lBnAhwWcDvUeqaH/7+N4weELEBjQdKa9F6fqYlcA==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/section@0.0.3':
|
||||
resolution: {integrity: sha512-DPvDBmf3jPZGw8ZoIgs/lS3yt8H0BXMLniR0aTa6FhBPWJsXXaaQHDPY6h7jfeCgppgAoDRLZqiMnZXfqSTUWw==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/style@0.0.3':
|
||||
resolution: {integrity: sha512-1t1I1EFJ77N4AC0qb1WYUfSOsFXTUUR2gxnbg88dsXHiaMiBlyokqy50wnn4/FrubUqbOFmseCz+4nSZzGg5bA==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-email/tailwind@0.2.0':
|
||||
resolution: {integrity: sha512-/DNEMhvEuZa9OptICLelwh4Rh4Lh54GtoTkQgCAV0/4qvAgbAmjUMr0f7GsincdxoPrFwpTofaKAxMFm6ZO0xA==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.29
|
||||
|
||||
'@vue-email/text@0.0.3':
|
||||
resolution: {integrity: sha512-xn6MYicnXyFeV72nNTDZylOL7ut60clYUR2bqMDKkW6+XD6qWp6LGAx4b8sE0kADgu7MTq23zbU9kA/cebhk8w==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.27
|
||||
|
||||
'@vue-macros/common@1.15.0':
|
||||
resolution: {integrity: sha512-yg5VqW7+HRfJGimdKvFYzx8zorHUYo0hzPwuraoC1DWa7HHazbTMoVsHDvk3JHa1SGfSL87fRnzmlvgjEHhszA==}
|
||||
engines: {node: '>=16.14.0'}
|
||||
@@ -3226,6 +3351,10 @@ packages:
|
||||
abbrev@1.1.1:
|
||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||
|
||||
abbrev@2.0.0:
|
||||
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
|
||||
abort-controller@3.0.0:
|
||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||
engines: {node: '>=6.5'}
|
||||
@@ -3733,6 +3862,9 @@ packages:
|
||||
confbox@0.2.2:
|
||||
resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==}
|
||||
|
||||
config-chain@1.1.13:
|
||||
resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
|
||||
|
||||
consola@3.2.3:
|
||||
resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
|
||||
engines: {node: ^14.18.0 || >=16.10.0}
|
||||
@@ -4097,6 +4229,11 @@ packages:
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
editorconfig@1.0.4:
|
||||
resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
ee-first@1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
|
||||
@@ -4897,12 +5034,19 @@ packages:
|
||||
resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
html-to-text@9.0.5:
|
||||
resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
html-void-elements@3.0.0:
|
||||
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
|
||||
|
||||
html-whitespace-sensitive-tag-names@3.0.0:
|
||||
resolution: {integrity: sha512-KlClZ3/Qy5UgvpvVvDomGhnQhNWH5INE8GwvSIQ9CWt1K0zbbXrl7eN5bWaafOZgtmO3jMPwUqmrmEwinhPq1w==}
|
||||
|
||||
htmlparser2@8.0.2:
|
||||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||
|
||||
http-cache-semantics@4.1.1:
|
||||
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
|
||||
|
||||
@@ -5174,6 +5318,15 @@ packages:
|
||||
resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==}
|
||||
hasBin: true
|
||||
|
||||
js-beautify@1.15.4:
|
||||
resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
js-cookie@3.0.5:
|
||||
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
js-levenshtein@1.1.6:
|
||||
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -5287,6 +5440,9 @@ packages:
|
||||
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
|
||||
engines: {node: '>= 0.6.3'}
|
||||
|
||||
leac@0.6.0:
|
||||
resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==}
|
||||
|
||||
leven@3.1.0:
|
||||
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -5413,6 +5569,11 @@ packages:
|
||||
markdown-table@3.0.3:
|
||||
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
||||
|
||||
marked@7.0.4:
|
||||
resolution: {integrity: sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ==}
|
||||
engines: {node: '>= 16'}
|
||||
hasBin: true
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -5663,6 +5824,10 @@ packages:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minimatch@9.0.1:
|
||||
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
@@ -5813,6 +5978,11 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
nopt@7.2.1:
|
||||
resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
hasBin: true
|
||||
|
||||
normalize-package-data@2.5.0:
|
||||
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
|
||||
|
||||
@@ -6026,6 +6196,9 @@ packages:
|
||||
parse5@7.1.2:
|
||||
resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
|
||||
|
||||
parseley@0.12.1:
|
||||
resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==}
|
||||
|
||||
parseurl@1.3.3:
|
||||
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@@ -6073,6 +6246,9 @@ packages:
|
||||
pathe@2.0.3:
|
||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||
|
||||
peberminta@0.9.0:
|
||||
resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==}
|
||||
|
||||
perfect-debounce@1.0.0:
|
||||
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
||||
|
||||
@@ -6484,6 +6660,9 @@ packages:
|
||||
property-information@7.0.0:
|
||||
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
|
||||
|
||||
proto-list@1.2.4:
|
||||
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
|
||||
|
||||
protocols@2.0.1:
|
||||
resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==}
|
||||
|
||||
@@ -6799,6 +6978,9 @@ packages:
|
||||
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
selderee@0.11.0:
|
||||
resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==}
|
||||
|
||||
semver@5.7.2:
|
||||
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
|
||||
hasBin: true
|
||||
@@ -9834,6 +10016,8 @@ snapshots:
|
||||
- vti
|
||||
- vue-tsc
|
||||
|
||||
'@one-ini/wasm@0.1.1': {}
|
||||
|
||||
'@oslojs/encoding@1.1.0': {}
|
||||
|
||||
'@pagefind/darwin-arm64@1.3.0':
|
||||
@@ -10189,6 +10373,11 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc@4.34.9':
|
||||
optional: true
|
||||
|
||||
'@selderee/plugin-htmlparser2@0.11.0':
|
||||
dependencies:
|
||||
domhandler: 5.0.3
|
||||
selderee: 0.11.0
|
||||
|
||||
'@sentry-internal/browser-utils@8.27.0':
|
||||
dependencies:
|
||||
'@sentry/core': 8.27.0
|
||||
@@ -10973,6 +11162,123 @@ snapshots:
|
||||
|
||||
'@vscode/l10n@0.0.18': {}
|
||||
|
||||
'@vue-email/body@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/button@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/code-block@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
shiki: 1.29.2
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/code-inline@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/column@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/components@0.0.21(typescript@5.5.4)(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
'@vue-email/body': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/button': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/code-block': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/code-inline': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/column': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/container': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/font': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/head': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/heading': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/hr': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/html': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/img': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/link': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/markdown': 0.0.7(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/preview': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/render': 0.0.9(typescript@5.5.4)
|
||||
'@vue-email/row': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/section': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/style': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/tailwind': 0.2.0(vue@3.5.13(typescript@5.5.4))
|
||||
'@vue-email/text': 0.0.3(vue@3.5.13(typescript@5.5.4))
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@vue-email/container@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/font@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/head@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/heading@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/hr@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/html@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/img@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/link@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/markdown@0.0.7(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
marked: 7.0.4
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/preview@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/render@0.0.9(typescript@5.5.4)':
|
||||
dependencies:
|
||||
html-to-text: 9.0.5
|
||||
js-beautify: 1.15.4
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@vue-email/row@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/section@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/style@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/tailwind@0.2.0(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-email/text@0.0.3(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.5.4)
|
||||
|
||||
'@vue-macros/common@1.15.0(rollup@4.28.1)(vue@3.5.13(typescript@5.5.4))':
|
||||
dependencies:
|
||||
'@babel/types': 7.26.3
|
||||
@@ -11289,6 +11595,8 @@ snapshots:
|
||||
|
||||
abbrev@1.1.1: {}
|
||||
|
||||
abbrev@2.0.0: {}
|
||||
|
||||
abort-controller@3.0.0:
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
@@ -11890,6 +12198,11 @@ snapshots:
|
||||
confbox@0.2.2:
|
||||
optional: true
|
||||
|
||||
config-chain@1.1.13:
|
||||
dependencies:
|
||||
ini: 1.3.8
|
||||
proto-list: 1.2.4
|
||||
|
||||
consola@3.2.3: {}
|
||||
|
||||
consola@3.4.2: {}
|
||||
@@ -12185,6 +12498,13 @@ snapshots:
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
editorconfig@1.0.4:
|
||||
dependencies:
|
||||
'@one-ini/wasm': 0.1.1
|
||||
commander: 10.0.1
|
||||
minimatch: 9.0.1
|
||||
semver: 7.7.2
|
||||
|
||||
ee-first@1.1.1: {}
|
||||
|
||||
electron-to-chromium@1.5.182:
|
||||
@@ -13391,10 +13711,25 @@ snapshots:
|
||||
|
||||
html-tags@3.3.1: {}
|
||||
|
||||
html-to-text@9.0.5:
|
||||
dependencies:
|
||||
'@selderee/plugin-htmlparser2': 0.11.0
|
||||
deepmerge: 4.3.1
|
||||
dom-serializer: 2.0.0
|
||||
htmlparser2: 8.0.2
|
||||
selderee: 0.11.0
|
||||
|
||||
html-void-elements@3.0.0: {}
|
||||
|
||||
html-whitespace-sensitive-tag-names@3.0.0: {}
|
||||
|
||||
htmlparser2@8.0.2:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.1.0
|
||||
entities: 4.5.0
|
||||
|
||||
http-cache-semantics@4.1.1: {}
|
||||
|
||||
http-errors@2.0.0:
|
||||
@@ -13633,6 +13968,16 @@ snapshots:
|
||||
jiti@2.5.1:
|
||||
optional: true
|
||||
|
||||
js-beautify@1.15.4:
|
||||
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: {}
|
||||
|
||||
js-levenshtein@1.1.6: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
@@ -13727,6 +14072,8 @@ snapshots:
|
||||
dependencies:
|
||||
readable-stream: 2.3.8(patch_hash=h52dazg37p4h3yox67pw36akse)
|
||||
|
||||
leac@0.6.0: {}
|
||||
|
||||
leven@3.1.0: {}
|
||||
|
||||
levn@0.4.1:
|
||||
@@ -13877,6 +14224,8 @@ snapshots:
|
||||
|
||||
markdown-table@3.0.3: {}
|
||||
|
||||
marked@7.0.4: {}
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
mdast-util-definitions@6.0.0:
|
||||
@@ -14406,6 +14755,10 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimatch@9.0.1:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
@@ -14608,6 +14961,10 @@ snapshots:
|
||||
dependencies:
|
||||
abbrev: 1.1.1
|
||||
|
||||
nopt@7.2.1:
|
||||
dependencies:
|
||||
abbrev: 2.0.0
|
||||
|
||||
normalize-package-data@2.5.0:
|
||||
dependencies:
|
||||
hosted-git-info: 2.8.9
|
||||
@@ -14968,6 +15325,11 @@ snapshots:
|
||||
dependencies:
|
||||
entities: 4.5.0
|
||||
|
||||
parseley@0.12.1:
|
||||
dependencies:
|
||||
leac: 0.6.0
|
||||
peberminta: 0.9.0
|
||||
|
||||
parseurl@1.3.3: {}
|
||||
|
||||
pascal-case@3.1.2:
|
||||
@@ -15001,6 +15363,8 @@ snapshots:
|
||||
pathe@2.0.3:
|
||||
optional: true
|
||||
|
||||
peberminta@0.9.0: {}
|
||||
|
||||
perfect-debounce@1.0.0: {}
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
@@ -15325,6 +15689,8 @@ snapshots:
|
||||
|
||||
property-information@7.0.0: {}
|
||||
|
||||
proto-list@1.2.4: {}
|
||||
|
||||
protocols@2.0.1: {}
|
||||
|
||||
pump@3.0.2:
|
||||
@@ -15794,6 +16160,10 @@ snapshots:
|
||||
extend-shallow: 2.0.1
|
||||
kind-of: 6.0.3
|
||||
|
||||
selderee@0.11.0:
|
||||
dependencies:
|
||||
parseley: 0.12.1
|
||||
|
||||
semver@5.7.2: {}
|
||||
|
||||
semver@6.3.1: {}
|
||||
|
||||
Reference in New Issue
Block a user