yaxa-svelte 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/components/layout/Footer.svelte +98 -5
- package/dist/components/legal/LegalDocument.svelte +341 -0
- package/dist/components/legal/LegalDocument.svelte.d.ts +21 -0
- package/dist/index.d.ts +4 -14
- package/dist/index.js +3 -9
- package/dist/server/auth/index.d.ts +2 -0
- package/dist/server/auth/index.js +1 -0
- package/dist/server/index.d.ts +20 -0
- package/dist/server/index.js +17 -0
- package/dist/server/polar/index.d.ts +2 -0
- package/dist/server/polar/index.js +1 -0
- package/dist/site/config.d.ts +29 -0
- package/dist/site/config.js +35 -0
- package/dist/site/schema.d.ts +11 -0
- package/dist/site/schema.js +23 -0
- package/package.json +51 -7
package/README.md
CHANGED
|
@@ -121,7 +121,8 @@ Handle **all 5 SEO endpoints** and **Better-Auth session parsing** in `src/hooks
|
|
|
121
121
|
```ts
|
|
122
122
|
// src/hooks.server.ts
|
|
123
123
|
import { sequence } from '@sveltejs/kit/hooks';
|
|
124
|
-
import { createYaxaHook
|
|
124
|
+
import { createYaxaHook } from 'yaxa-svelte/server';
|
|
125
|
+
import { createYaxaAuth, createYaxaAuthHook } from 'yaxa-svelte/auth';
|
|
125
126
|
import { siteConfig } from './site.config';
|
|
126
127
|
|
|
127
128
|
const yaxaHook = createYaxaHook(siteConfig);
|
|
@@ -143,7 +144,7 @@ Create a webhook endpoint in `src/routes/api/webhooks/polar/+server.ts`:
|
|
|
143
144
|
|
|
144
145
|
```ts
|
|
145
146
|
// src/routes/api/webhooks/polar/+server.ts
|
|
146
|
-
import { createPolarWebhookHandler } from 'yaxa-svelte';
|
|
147
|
+
import { createPolarWebhookHandler } from 'yaxa-svelte/polar';
|
|
147
148
|
|
|
148
149
|
export const POST = createPolarWebhookHandler();
|
|
149
150
|
```
|
|
@@ -16,21 +16,37 @@
|
|
|
16
16
|
|
|
17
17
|
let currentConfig = $derived(config || getSiteConfig());
|
|
18
18
|
let currentYear = new Date().getFullYear();
|
|
19
|
+
|
|
20
|
+
let company = $derived(currentConfig.company);
|
|
21
|
+
let legal = $derived(currentConfig.legal);
|
|
22
|
+
let legalLinks = $derived(legal?.links);
|
|
23
|
+
let entityName = $derived(company?.legalName || currentConfig.name);
|
|
24
|
+
|
|
25
|
+
let hasLegalLinks = $derived(
|
|
26
|
+
Boolean(
|
|
27
|
+
legalLinks?.privacy || legalLinks?.terms || legalLinks?.refunds || legalLinks?.impressum
|
|
28
|
+
)
|
|
29
|
+
);
|
|
19
30
|
</script>
|
|
20
31
|
|
|
21
32
|
<footer
|
|
22
33
|
class="border-t border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-950 {className}"
|
|
23
34
|
>
|
|
24
35
|
<Container size="lg" class="py-12 md:py-16">
|
|
25
|
-
<div class="grid grid-cols-1 gap-8 md:grid-cols-4">
|
|
36
|
+
<div class="grid grid-cols-1 gap-8 md:grid-cols-4 lg:grid-cols-5">
|
|
26
37
|
<!-- Brand Info -->
|
|
27
|
-
<div class="space-y-4 md:col-span-2">
|
|
38
|
+
<div class="space-y-4 md:col-span-2 lg:col-span-2">
|
|
28
39
|
<a href="/" class="inline-flex items-center gap-2.5 font-bold tracking-tight">
|
|
29
40
|
<Logo size="sm" showText text={currentConfig.name} />
|
|
30
41
|
</a>
|
|
31
42
|
<p class="max-w-sm text-base text-neutral-600 dark:text-neutral-400">
|
|
32
43
|
{currentConfig.description}
|
|
33
44
|
</p>
|
|
45
|
+
{#if legal?.morNotice}
|
|
46
|
+
<p class="text-xs text-neutral-500 dark:text-neutral-500">
|
|
47
|
+
{legal.morNotice}
|
|
48
|
+
</p>
|
|
49
|
+
{/if}
|
|
34
50
|
</div>
|
|
35
51
|
|
|
36
52
|
<!-- Quick Links -->
|
|
@@ -50,6 +66,57 @@
|
|
|
50
66
|
</ul>
|
|
51
67
|
</div>
|
|
52
68
|
|
|
69
|
+
<!-- Legal Links -->
|
|
70
|
+
{#if hasLegalLinks}
|
|
71
|
+
<div>
|
|
72
|
+
<h3 class="text-base font-semibold text-neutral-900 dark:text-white">
|
|
73
|
+
Legal & Compliance
|
|
74
|
+
</h3>
|
|
75
|
+
<ul class="mt-4 space-y-2.5 text-sm text-neutral-600 dark:text-neutral-400">
|
|
76
|
+
{#if legalLinks?.privacy}
|
|
77
|
+
<li>
|
|
78
|
+
<a
|
|
79
|
+
href={legalLinks.privacy}
|
|
80
|
+
class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
|
|
81
|
+
>
|
|
82
|
+
Privacy Policy
|
|
83
|
+
</a>
|
|
84
|
+
</li>
|
|
85
|
+
{/if}
|
|
86
|
+
{#if legalLinks?.terms}
|
|
87
|
+
<li>
|
|
88
|
+
<a
|
|
89
|
+
href={legalLinks.terms}
|
|
90
|
+
class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
|
|
91
|
+
>
|
|
92
|
+
Terms of Service
|
|
93
|
+
</a>
|
|
94
|
+
</li>
|
|
95
|
+
{/if}
|
|
96
|
+
{#if legalLinks?.refunds}
|
|
97
|
+
<li>
|
|
98
|
+
<a
|
|
99
|
+
href={legalLinks.refunds}
|
|
100
|
+
class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
|
|
101
|
+
>
|
|
102
|
+
Cancellation & Refunds
|
|
103
|
+
</a>
|
|
104
|
+
</li>
|
|
105
|
+
{/if}
|
|
106
|
+
{#if legalLinks?.impressum}
|
|
107
|
+
<li>
|
|
108
|
+
<a
|
|
109
|
+
href={legalLinks.impressum}
|
|
110
|
+
class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
|
|
111
|
+
>
|
|
112
|
+
Impressum
|
|
113
|
+
</a>
|
|
114
|
+
</li>
|
|
115
|
+
{/if}
|
|
116
|
+
</ul>
|
|
117
|
+
</div>
|
|
118
|
+
{/if}
|
|
119
|
+
|
|
53
120
|
<!-- Socials & Newsletter -->
|
|
54
121
|
<div>
|
|
55
122
|
<h3 class="text-base font-semibold text-neutral-900 dark:text-white">Community</h3>
|
|
@@ -86,11 +153,37 @@
|
|
|
86
153
|
</div>
|
|
87
154
|
</div>
|
|
88
155
|
|
|
156
|
+
<!-- Footer Bottom Identification Bar -->
|
|
89
157
|
<div
|
|
90
|
-
class="mt-12 flex flex-col items-center justify-between border-t border-neutral-200 pt-8 text-
|
|
158
|
+
class="mt-12 flex flex-col items-center justify-between gap-4 border-t border-neutral-200 pt-8 text-xs text-neutral-500 sm:flex-row dark:border-neutral-800 dark:text-neutral-400"
|
|
91
159
|
>
|
|
92
|
-
<
|
|
93
|
-
|
|
160
|
+
<div class="flex flex-wrap items-center justify-center gap-x-3 gap-y-1 sm:justify-start">
|
|
161
|
+
<span>© {currentYear} {entityName}.</span>
|
|
162
|
+
{#if company?.address}
|
|
163
|
+
<span>· {company.address}</span>
|
|
164
|
+
{/if}
|
|
165
|
+
{#if company?.vatNumber}
|
|
166
|
+
<span>· VAT: {company.vatNumber}</span>
|
|
167
|
+
{/if}
|
|
168
|
+
{#if company?.registrationCourt}
|
|
169
|
+
<span>· {company.registrationCourt}</span>
|
|
170
|
+
{/if}
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<div class="flex flex-wrap items-center justify-center gap-4">
|
|
174
|
+
{#if legalLinks?.privacy}
|
|
175
|
+
<a href={legalLinks.privacy} class="hover:underline">Privacy</a>
|
|
176
|
+
{/if}
|
|
177
|
+
{#if legalLinks?.terms}
|
|
178
|
+
<a href={legalLinks.terms} class="hover:underline">Terms</a>
|
|
179
|
+
{/if}
|
|
180
|
+
{#if legalLinks?.refunds}
|
|
181
|
+
<a href={legalLinks.refunds} class="hover:underline">Refunds</a>
|
|
182
|
+
{/if}
|
|
183
|
+
{#if legalLinks?.impressum}
|
|
184
|
+
<a href={legalLinks.impressum} class="hover:underline">Impressum</a>
|
|
185
|
+
{/if}
|
|
186
|
+
</div>
|
|
94
187
|
</div>
|
|
95
188
|
</Container>
|
|
96
189
|
</footer>
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { SiteConfig } from '../../site/config';
|
|
4
|
+
|
|
5
|
+
export type LegalDocumentType = 'privacy' | 'terms' | 'refunds' | 'impressum';
|
|
6
|
+
|
|
7
|
+
export interface LegalClause {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
content?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface LegalDocumentProps {
|
|
14
|
+
type: LegalDocumentType;
|
|
15
|
+
config?: SiteConfig;
|
|
16
|
+
lastUpdated?: string;
|
|
17
|
+
title?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
customClauses?: LegalClause[];
|
|
20
|
+
class?: string;
|
|
21
|
+
children?: Snippet;
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<script lang="ts">
|
|
26
|
+
import { getSiteConfig } from '../../site/context';
|
|
27
|
+
import Container from '../layout/Container.svelte';
|
|
28
|
+
import Badge from '../elements/Badge.svelte';
|
|
29
|
+
import Icon from '../elements/Icon.svelte';
|
|
30
|
+
|
|
31
|
+
let {
|
|
32
|
+
type,
|
|
33
|
+
config,
|
|
34
|
+
lastUpdated = 'September 2026',
|
|
35
|
+
title,
|
|
36
|
+
description,
|
|
37
|
+
customClauses = [],
|
|
38
|
+
class: className = '',
|
|
39
|
+
children
|
|
40
|
+
}: LegalDocumentProps = $props();
|
|
41
|
+
|
|
42
|
+
let currentConfig = $derived(config || getSiteConfig());
|
|
43
|
+
let company = $derived(currentConfig.company);
|
|
44
|
+
let legal = $derived(currentConfig.legal);
|
|
45
|
+
|
|
46
|
+
let entityName = $derived(company?.legalName || currentConfig.name);
|
|
47
|
+
let contactEmail = $derived(
|
|
48
|
+
company?.contactEmail ||
|
|
49
|
+
(currentConfig.url ? `support@${new URL(currentConfig.url).hostname}` : 'support@example.com')
|
|
50
|
+
);
|
|
51
|
+
let dpoEmail = $derived(legal?.dpoEmail || contactEmail);
|
|
52
|
+
let refundDays = $derived(legal?.refundDays ?? 14);
|
|
53
|
+
let processor = $derived(legal?.paymentProcessor ?? 'polar');
|
|
54
|
+
let isEthicalAds = $derived(legal?.adNetwork === 'ethicalads');
|
|
55
|
+
let isEu = $derived(legal?.jurisdiction?.toUpperCase() === 'EU');
|
|
56
|
+
|
|
57
|
+
let docTitle = $derived.by(() => {
|
|
58
|
+
if (title) return title;
|
|
59
|
+
switch (type) {
|
|
60
|
+
case 'privacy':
|
|
61
|
+
return 'Privacy Policy';
|
|
62
|
+
case 'terms':
|
|
63
|
+
return 'Terms of Service';
|
|
64
|
+
case 'refunds':
|
|
65
|
+
return 'Cancellation & Refund Policy';
|
|
66
|
+
case 'impressum':
|
|
67
|
+
return 'Impressum / Legal Notice';
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
let docDescription = $derived.by(() => {
|
|
72
|
+
if (description) return description;
|
|
73
|
+
switch (type) {
|
|
74
|
+
case 'privacy':
|
|
75
|
+
return `How ${entityName} handles, secures, and protects your personal data in full compliance with GDPR and global privacy standards.`;
|
|
76
|
+
case 'terms':
|
|
77
|
+
return `The terms and conditions governing your access to and use of ${currentConfig.name}.`;
|
|
78
|
+
case 'refunds':
|
|
79
|
+
return `Our transparent ${refundDays}-day refund policy, self-serve cancellation terms, and EU statutory withdrawal rights.`;
|
|
80
|
+
case 'impressum':
|
|
81
|
+
return `Provider identification and mandatory legal disclosure pursuant to EU E-Commerce regulations (§ 5 TMG / DDG).`;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Default sections by type
|
|
86
|
+
let defaultSections = $derived.by(() => {
|
|
87
|
+
if (type === 'privacy') {
|
|
88
|
+
return [
|
|
89
|
+
{
|
|
90
|
+
id: 'overview',
|
|
91
|
+
title: '1. Overview & Data Controller',
|
|
92
|
+
content: `This Privacy Policy outlines how **${entityName}** ("we", "us", or "our"), operating **${currentConfig.name}** at [${currentConfig.url}](${currentConfig.url}), collects, processes, and protects your personal data. We are dedicated to respecting your privacy and strictly upholding the European Union General Data Protection Regulation (GDPR), the UK GDPR, and applicable global data privacy regulations.`
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 'data-collected',
|
|
96
|
+
title: '2. Information We Collect',
|
|
97
|
+
content: `We collect minimal personal information essential for delivering our service:\n\n- **Account & Identity Data**: When registering via our authentication system, we store your name, email address, and avatar image.\n- **Authentication Logs**: Cryptographically secure session tokens, sign-in timestamps, and anonymized security identifiers to prevent unauthorized access.\n- **Communications**: Inquiries or support requests sent directly to **${contactEmail}**.`
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'payments',
|
|
101
|
+
title: '3. Payments & Merchant of Record',
|
|
102
|
+
content:
|
|
103
|
+
processor === 'polar'
|
|
104
|
+
? `All payments, recurring billing, and European Union VAT / sales tax calculations are handled by **Polar Payments Inc. ("Polar.sh")** acting as Merchant of Record.\n\nWe never receive, store, or process your credit card numbers or raw banking credentials on our local servers. Polar processes transaction data under strict PCI-DSS Level 1 compliance.`
|
|
105
|
+
: processor === 'lemonsqueezy'
|
|
106
|
+
? `Payments and VAT compliance are processed securely by **Lemon Squeezy, LLC** acting as Merchant of Record. We never collect or store your payment card details.`
|
|
107
|
+
: `Payment transactions are securely processed by our authorized payment gateway. We do not store sensitive payment card details on our infrastructure.`
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 'advertising',
|
|
111
|
+
title: '4. Privacy-First Advertising (Zero-Tracking)',
|
|
112
|
+
content: isEthicalAds
|
|
113
|
+
? `We proudly utilize **EthicalAds** to serve privacy-respecting developer advertisements.\n\n- **Zero Tracking Cookies**: EthicalAds does not set behavioral tracking cookies or device fingerprints.\n- **No Personal Data Profiling**: Ads are displayed strictly based on page context and high-level geolocation (country level), without tracking you across the web.\n- **No Cookie Banner Required**: Because EthicalAds processes no personal identifiers and stores no invasive cookies, your browsing experience remains free of consent interruptions.`
|
|
114
|
+
: `We do not sell your personal information or engage in invasive third-party cross-site advertising networks.`
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: 'cookies',
|
|
118
|
+
title: '5. Cookies & Local Storage',
|
|
119
|
+
content: `Our website minimizes local device storage. We utilize client-side \`localStorage\` solely to preserve essential functional user preferences (such as your chosen dark/light color mode and theme accent).\n\nWe do not use persistent advertising trackers or third-party behavioral profiling cookies.`
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: 'gdpr-rights',
|
|
123
|
+
title: '6. Your Rights Under GDPR / Data Protection Laws',
|
|
124
|
+
content: `Under the GDPR and equivalent data protection frameworks, you are entitled to the following rights:\n\n- **Right of Access**: Request a full copy of the personal data we hold about you.\n- **Right to Rectification**: Correct any inaccurate or incomplete personal information.\n- **Right to Erasure ("Right to be Forgotten")**: Request permanent deletion of your account and personal data.\n- **Right to Restriction & Object**: Restrict or object to specific processing of your information.\n- **Right to Data Portability**: Receive your data in a structured, machine-readable format.\n- **Right to Lodge a Complaint**: File a complaint with your competent national data protection supervisory authority.\n\nTo exercise any of these rights, contact us at [${dpoEmail}](mailto:${dpoEmail}).`
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: 'contact',
|
|
128
|
+
title: '7. Contact & Data Protection',
|
|
129
|
+
content: `If you have any questions or data requests regarding this Privacy Policy, please contact our Data Protection representative at **${dpoEmail}**.`
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (type === 'terms') {
|
|
135
|
+
return [
|
|
136
|
+
{
|
|
137
|
+
id: 'acceptance',
|
|
138
|
+
title: '1. Acceptance of Terms',
|
|
139
|
+
content: `By accessing or using **${currentConfig.name}** ([${currentConfig.url}](${currentConfig.url})), provided by **${entityName}**, you agree to be bound by these Terms of Service. If you do not agree to all terms, do not access or use the service.`
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: 'license',
|
|
143
|
+
title: '2. License & Acceptable Use',
|
|
144
|
+
content: `We grant you a non-exclusive, non-transferable, revocable license to use ${currentConfig.name} in accordance with your chosen subscription plan or open-source license.\n\nYou agree not to:\n- Reverse engineer, decompile, or exploit our proprietary services except as permitted by applicable law.\n- Use the service for unlawful activities, security vulnerabilities scanning, or spam distribution.\n- Interfere with or disrupt the stability of our servers and networks.`
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: 'subscriptions',
|
|
148
|
+
title: '3. Subscriptions, Invoicing & Taxes',
|
|
149
|
+
content:
|
|
150
|
+
processor === 'polar'
|
|
151
|
+
? `Subscriptions and paid tiers are billed in advance on a recurring monthly or annual basis. Invoicing, payment collection, and applicable VAT / sales taxes are managed by **Polar.sh** as Merchant of Record.\n\nYou can manage or cancel your subscription at any time directly through your account dashboard or billing portal.`
|
|
152
|
+
: `Paid subscription tiers are billed in advance on a recurring cycle. You may cancel your subscription at any time before your next billing cycle.`
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: 'liability',
|
|
156
|
+
title: '4. Limitation of Liability',
|
|
157
|
+
content: `To the maximum extent permitted by applicable law, **${entityName}** shall not be liable for any indirect, incidental, special, consequential, or punitive damages, including loss of profits, data, or business interruption.`
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: 'dispute-resolution',
|
|
161
|
+
title: '5. Governing Law & Dispute Resolution',
|
|
162
|
+
content:
|
|
163
|
+
(legal?.governingLaw
|
|
164
|
+
? `These terms are governed by the laws of **${legal.governingLaw}**.\n\n`
|
|
165
|
+
: '') +
|
|
166
|
+
(isEu
|
|
167
|
+
? `The European Commission provides an Online Dispute Resolution (ODR) platform accessible at [https://ec.europa.eu/consumers/odr](https://ec.europa.eu/consumers/odr). We aim to resolve any disagreement directly through friendly communication at [${contactEmail}](mailto:${contactEmail}).`
|
|
168
|
+
: `Any disputes arising from these Terms shall be resolved in accordance with standard arbitration and applicable local jurisdiction.`)
|
|
169
|
+
}
|
|
170
|
+
];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (type === 'refunds') {
|
|
174
|
+
return [
|
|
175
|
+
{
|
|
176
|
+
id: 'cancellation',
|
|
177
|
+
title: '1. Self-Serve Cancellation',
|
|
178
|
+
content: `You may cancel your active subscription at any time with immediate effect. Upon cancellation, your access will remain active through the end of your current paid billing period, and your payment method will not be charged again.`
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: 'refund-policy',
|
|
182
|
+
title: `2. ${refundDays}-Day Money-Back Guarantee`,
|
|
183
|
+
content: `We stand behind the quality of our software. If you are not completely satisfied with your purchase, we offer a **100% money-back guarantee within ${refundDays} days** of your initial purchase.\n\nTo request a refund within the ${refundDays}-day window, simply email [${contactEmail}](mailto:${contactEmail}) with your account email or transaction ID. We process refunds promptly without unnecessary hurdles.`
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: 'eu-withdrawal',
|
|
187
|
+
title: '3. EU Statutory Right of Withdrawal',
|
|
188
|
+
content: `If you are an EU consumer, you have the statutory right to withdraw from a purchase within 14 days without giving any reason.\n\nFor digital content or immediate SaaS access, if you explicitly consented to the immediate execution of the contract upon checkout, our generous ${refundDays}-day guarantee remains fully accessible to you regardless.`
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: 'disputes',
|
|
192
|
+
title: '4. Chargebacks & Friendly Resolution',
|
|
193
|
+
content: `If you experience any billing issue or unexpected charge, please reach out to us at [${contactEmail}](mailto:${contactEmail}) before initiating a bank dispute or chargeback. We will gladly investigate and resolve billing discrepancies swiftly.`
|
|
194
|
+
}
|
|
195
|
+
];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (type === 'impressum') {
|
|
199
|
+
return [
|
|
200
|
+
{
|
|
201
|
+
id: 'provider',
|
|
202
|
+
title: '1. Provider Identification / Angaben gemäß § 5 TMG / DDG',
|
|
203
|
+
content:
|
|
204
|
+
`**Entity / Legal Name:** ${company?.legalName || currentConfig.name}\n\n` +
|
|
205
|
+
(company?.address ? `**Geographical Address:**\n${company.address}\n\n` : '') +
|
|
206
|
+
(company?.country ? `**Country:** ${company.country}\n\n` : '') +
|
|
207
|
+
(company?.representative ? `**Represented By:** ${company.representative}\n\n` : '')
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: 'contact-info',
|
|
211
|
+
title: '2. Contact Information / Kontaktaufnahme',
|
|
212
|
+
content: `**Email:** [${contactEmail}](mailto:${contactEmail})\n\n**Website:** [${currentConfig.url}](${currentConfig.url})`
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
id: 'register',
|
|
216
|
+
title: '3. Commercial Register & Tax Information',
|
|
217
|
+
content:
|
|
218
|
+
(company?.registrationCourt || company?.registrationNumber
|
|
219
|
+
? `**Commercial Register:** ${company?.registrationCourt || 'Commercial Registry'}\n**Registration Number:** ${company?.registrationNumber || 'N/A'}\n\n`
|
|
220
|
+
: '') +
|
|
221
|
+
(company?.vatNumber
|
|
222
|
+
? `**VAT Identification Number (Umsatzsteuer-Identifikationsnummer gemäß § 27a UStG):**\n${company.vatNumber}\n\n`
|
|
223
|
+
: 'VAT Identification Number: Not applicable / Small business regulation.')
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
id: 'dispute-resolution',
|
|
227
|
+
title: '4. Consumer Dispute Resolution / Verbraucherstreitbeilegung',
|
|
228
|
+
content: `The European Commission provides a platform for online dispute resolution (ODR): [https://ec.europa.eu/consumers/odr](https://ec.europa.eu/consumers/odr).\n\nWe are neither obligated nor willing to participate in dispute resolution proceedings before a consumer arbitration board.`
|
|
229
|
+
}
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return [];
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
let allSections = $derived([...defaultSections, ...customClauses]);
|
|
237
|
+
</script>
|
|
238
|
+
|
|
239
|
+
<Container size="lg" class="py-12 md:py-20 {className}">
|
|
240
|
+
<!-- Header -->
|
|
241
|
+
<div class="mb-12 border-b border-neutral-200 pb-8 dark:border-neutral-800">
|
|
242
|
+
<div class="mb-4 flex flex-wrap items-center gap-3">
|
|
243
|
+
<Badge color="primary" variant="soft" size="sm">Legal & Compliance</Badge>
|
|
244
|
+
{#if isEu}
|
|
245
|
+
<Badge color="neutral" variant="outline" size="sm">EU / GDPR Compliant</Badge>
|
|
246
|
+
{/if}
|
|
247
|
+
{#if processor === 'polar'}
|
|
248
|
+
<Badge color="neutral" variant="outline" size="sm">Polar.sh MoR</Badge>
|
|
249
|
+
{/if}
|
|
250
|
+
{#if isEthicalAds}
|
|
251
|
+
<Badge color="success" variant="subtle" size="sm">Zero-Cookie Ad Disclosure</Badge>
|
|
252
|
+
{/if}
|
|
253
|
+
</div>
|
|
254
|
+
|
|
255
|
+
<h1
|
|
256
|
+
class="text-3xl font-extrabold tracking-tight text-neutral-900 sm:text-4xl lg:text-5xl dark:text-white"
|
|
257
|
+
>
|
|
258
|
+
{docTitle}
|
|
259
|
+
</h1>
|
|
260
|
+
|
|
261
|
+
<p class="mt-4 max-w-3xl text-lg text-neutral-600 dark:text-neutral-300">
|
|
262
|
+
{docDescription}
|
|
263
|
+
</p>
|
|
264
|
+
|
|
265
|
+
<div
|
|
266
|
+
class="mt-6 flex flex-wrap items-center gap-6 text-sm text-neutral-500 dark:text-neutral-400"
|
|
267
|
+
>
|
|
268
|
+
<span class="inline-flex items-center gap-1.5">
|
|
269
|
+
<Icon name="info" size="xs" />
|
|
270
|
+
Last Updated:
|
|
271
|
+
<strong class="font-medium text-neutral-700 dark:text-neutral-200">{lastUpdated}</strong>
|
|
272
|
+
</span>
|
|
273
|
+
<span>•</span>
|
|
274
|
+
<span
|
|
275
|
+
>Entity:
|
|
276
|
+
<strong class="font-medium text-neutral-700 dark:text-neutral-200">{entityName}</strong
|
|
277
|
+
></span
|
|
278
|
+
>
|
|
279
|
+
{#if contactEmail}
|
|
280
|
+
<span>•</span>
|
|
281
|
+
<a
|
|
282
|
+
href="mailto:{contactEmail}"
|
|
283
|
+
class="text-primary-600 hover:underline dark:text-primary-400"
|
|
284
|
+
>
|
|
285
|
+
{contactEmail}
|
|
286
|
+
</a>
|
|
287
|
+
{/if}
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
|
|
291
|
+
<!-- Main Grid: Sidebar Table of Contents + Document Content -->
|
|
292
|
+
<div class="grid grid-cols-1 gap-12 lg:grid-cols-4">
|
|
293
|
+
<!-- Table of Contents Sidebar -->
|
|
294
|
+
<aside class="hidden lg:col-span-1 lg:block">
|
|
295
|
+
<div
|
|
296
|
+
class="sticky top-24 space-y-4 rounded-xl border border-neutral-200 bg-neutral-50/50 p-5 dark:border-neutral-800 dark:bg-neutral-900/40"
|
|
297
|
+
>
|
|
298
|
+
<h3
|
|
299
|
+
class="text-xs font-semibold tracking-wider text-neutral-500 uppercase dark:text-neutral-400"
|
|
300
|
+
>
|
|
301
|
+
Table of Contents
|
|
302
|
+
</h3>
|
|
303
|
+
<nav class="space-y-2">
|
|
304
|
+
{#each allSections as sec}
|
|
305
|
+
<a
|
|
306
|
+
href="#{sec.id}"
|
|
307
|
+
class="block text-sm text-neutral-600 transition-colors hover:text-primary-600 dark:text-neutral-400 dark:hover:text-primary-400"
|
|
308
|
+
>
|
|
309
|
+
{sec.title}
|
|
310
|
+
</a>
|
|
311
|
+
{/each}
|
|
312
|
+
</nav>
|
|
313
|
+
</div>
|
|
314
|
+
</aside>
|
|
315
|
+
|
|
316
|
+
<!-- Content Column -->
|
|
317
|
+
<div class="space-y-12 lg:col-span-3">
|
|
318
|
+
{#each allSections as sec}
|
|
319
|
+
<section
|
|
320
|
+
id={sec.id}
|
|
321
|
+
class="scroll-mt-24 space-y-4 border-b border-neutral-100 pb-10 last:border-0 dark:border-neutral-900"
|
|
322
|
+
>
|
|
323
|
+
<h2 class="text-xl font-bold tracking-tight text-neutral-900 dark:text-white">
|
|
324
|
+
{sec.title}
|
|
325
|
+
</h2>
|
|
326
|
+
<div
|
|
327
|
+
class="prose max-w-none leading-relaxed whitespace-pre-line text-neutral-600 prose-neutral dark:text-neutral-300 dark:prose-invert"
|
|
328
|
+
>
|
|
329
|
+
{sec.content}
|
|
330
|
+
</div>
|
|
331
|
+
</section>
|
|
332
|
+
{/each}
|
|
333
|
+
|
|
334
|
+
{#if children}
|
|
335
|
+
<div class="mt-8">
|
|
336
|
+
{@render children()}
|
|
337
|
+
</div>
|
|
338
|
+
{/if}
|
|
339
|
+
</div>
|
|
340
|
+
</div>
|
|
341
|
+
</Container>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { SiteConfig } from '../../site/config';
|
|
3
|
+
export type LegalDocumentType = 'privacy' | 'terms' | 'refunds' | 'impressum';
|
|
4
|
+
export interface LegalClause {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
content?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface LegalDocumentProps {
|
|
10
|
+
type: LegalDocumentType;
|
|
11
|
+
config?: SiteConfig;
|
|
12
|
+
lastUpdated?: string;
|
|
13
|
+
title?: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
customClauses?: LegalClause[];
|
|
16
|
+
class?: string;
|
|
17
|
+
children?: Snippet;
|
|
18
|
+
}
|
|
19
|
+
declare const LegalDocument: import("svelte").Component<LegalDocumentProps, {}, "">;
|
|
20
|
+
type LegalDocument = ReturnType<typeof LegalDocument>;
|
|
21
|
+
export default LegalDocument;
|
package/dist/index.d.ts
CHANGED
|
@@ -73,8 +73,10 @@ export type { ThemeMode, AccentName, NeutralName, FontFamily, RadiusPreset, Base
|
|
|
73
73
|
export { default as Seo } from './components/seo/Seo.svelte';
|
|
74
74
|
export { default as Favicons } from './components/seo/Favicons.svelte';
|
|
75
75
|
export { default as OgImage } from './components/seo/OgImage.svelte';
|
|
76
|
-
export {
|
|
77
|
-
export type {
|
|
76
|
+
export { default as LegalDocument } from './components/legal/LegalDocument.svelte';
|
|
77
|
+
export type { LegalDocumentType, LegalClause, LegalDocumentProps } from './components/legal/LegalDocument.svelte';
|
|
78
|
+
export { defineSiteConfig, DEFAULT_SITE_CONFIG } from './site/config';
|
|
79
|
+
export type { SiteConfig, NavItem, AuthorConfig, CompanyConfig, LegalConfig, LegalLinksConfig } from './site/config';
|
|
78
80
|
export { setSiteConfig, getSiteConfig } from './site/context';
|
|
79
81
|
export { createYaxaHook } from './site/hook';
|
|
80
82
|
export type { YaxaHookOptions } from './site/hook';
|
|
@@ -99,17 +101,5 @@ export { default as PricingTable } from './components/saas/PricingTable.svelte';
|
|
|
99
101
|
export { default as SubscriptionCard } from './components/saas/SubscriptionCard.svelte';
|
|
100
102
|
export { useAuth } from './composables/useAuth.svelte';
|
|
101
103
|
export type { UseAuthOptions, SocialProvider } from './composables/useAuth.svelte';
|
|
102
|
-
export { getDb, schemaPg, schemaSqlite } from './server/db/index';
|
|
103
|
-
export type { DbConfig, DbDriver, SaasUser, SaasSubscription, SubscriptionStatus, PricingTier, PricingFeature } from './server/db/index';
|
|
104
|
-
export { createYaxaAuth } from './server/auth/index';
|
|
105
|
-
export type { YaxaAuthConfig, YaxaAuth } from './server/auth/index';
|
|
106
|
-
export { createYaxaAuthHook } from './server/auth/hook';
|
|
107
|
-
export type { YaxaAuthHookOptions } from './server/auth/hook';
|
|
108
|
-
export { getPolarClient, createPolarCheckout, createPolarCustomerPortalSession } from './server/polar/index';
|
|
109
|
-
export type { PolarConfig, CreateCheckoutOptions } from './server/polar/index';
|
|
110
|
-
export { createPolarWebhookHandler } from './server/polar/webhook';
|
|
111
|
-
export type { PolarWebhookOptions } from './server/polar/webhook';
|
|
112
|
-
export { getResendClient, sendMagicLinkEmail, sendWelcomeEmail } from './server/email/index';
|
|
113
|
-
export type { ResendEmailConfig, SendMagicLinkOptions, SendWelcomeEmailOptions } from './server/email/index';
|
|
114
104
|
export { cn, tv } from './utils/cn';
|
|
115
105
|
export type { VariantProps } from './utils/cn';
|
package/dist/index.js
CHANGED
|
@@ -63,7 +63,8 @@ export { theme, themeInitScript, ACCENT_PALETTES, NEUTRAL_PALETTES, FONT_PRESETS
|
|
|
63
63
|
export { default as Seo } from './components/seo/Seo.svelte';
|
|
64
64
|
export { default as Favicons } from './components/seo/Favicons.svelte';
|
|
65
65
|
export { default as OgImage } from './components/seo/OgImage.svelte';
|
|
66
|
-
export {
|
|
66
|
+
export { default as LegalDocument } from './components/legal/LegalDocument.svelte';
|
|
67
|
+
export { defineSiteConfig, DEFAULT_SITE_CONFIG } from './site/config';
|
|
67
68
|
export { setSiteConfig, getSiteConfig } from './site/context';
|
|
68
69
|
export { createYaxaHook } from './site/hook';
|
|
69
70
|
export { createRobotsHandler } from './site/robots';
|
|
@@ -74,19 +75,12 @@ export { createManifestHandler } from './site/manifest';
|
|
|
74
75
|
export { generateWebSiteSchema, generateOrganizationSchema, generateArticleSchema, generateBreadcrumbSchema } from './site/schema';
|
|
75
76
|
export { definePageSeo } from './site/seo-helpers';
|
|
76
77
|
export { yaxa } from './vite/index';
|
|
77
|
-
// SaaS Suite: Components
|
|
78
|
+
// SaaS Suite: UI Components & Composables
|
|
78
79
|
export { default as AuthCard } from './components/saas/AuthCard.svelte';
|
|
79
80
|
export { default as UserMenu } from './components/saas/UserMenu.svelte';
|
|
80
81
|
export { default as PricingCard } from './components/saas/PricingCard.svelte';
|
|
81
82
|
export { default as PricingTable } from './components/saas/PricingTable.svelte';
|
|
82
83
|
export { default as SubscriptionCard } from './components/saas/SubscriptionCard.svelte';
|
|
83
84
|
export { useAuth } from './composables/useAuth.svelte';
|
|
84
|
-
// SaaS Server & DB Modules
|
|
85
|
-
export { getDb, schemaPg, schemaSqlite } from './server/db/index';
|
|
86
|
-
export { createYaxaAuth } from './server/auth/index';
|
|
87
|
-
export { createYaxaAuthHook } from './server/auth/hook';
|
|
88
|
-
export { getPolarClient, createPolarCheckout, createPolarCustomerPortalSession } from './server/polar/index';
|
|
89
|
-
export { createPolarWebhookHandler } from './server/polar/webhook';
|
|
90
|
-
export { getResendClient, sendMagicLinkEmail, sendWelcomeEmail } from './server/email/index';
|
|
91
85
|
// Utilities
|
|
92
86
|
export { cn, tv } from './utils/cn';
|
|
@@ -37,3 +37,5 @@ export interface YaxaAuthConfig {
|
|
|
37
37
|
*/
|
|
38
38
|
export declare function createYaxaAuth(config?: YaxaAuthConfig): import("better-auth").Auth<BetterAuthOptions>;
|
|
39
39
|
export type YaxaAuth = ReturnType<typeof createYaxaAuth>;
|
|
40
|
+
export { createYaxaAuthHook } from './hook';
|
|
41
|
+
export type { YaxaAuthHookOptions } from './hook';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { createYaxaHook } from '../site/hook';
|
|
2
|
+
export type { YaxaHookOptions } from '../site/hook';
|
|
3
|
+
export { createRobotsHandler } from '../site/robots';
|
|
4
|
+
export type { RobotsOptions } from '../site/robots';
|
|
5
|
+
export { createSitemapHandler } from '../site/sitemap';
|
|
6
|
+
export type { SitemapRoute, SitemapOptions } from '../site/sitemap';
|
|
7
|
+
export { createSitemapXslHandler, generateSitemapXsl } from '../site/sitemap-xsl';
|
|
8
|
+
export { createOgImageHandler, generateOgSvg } from '../site/og';
|
|
9
|
+
export type { OgImageOptions } from '../site/og';
|
|
10
|
+
export { createManifestHandler } from '../site/manifest';
|
|
11
|
+
export { getDb, schemaPg, schemaSqlite } from './db/index';
|
|
12
|
+
export type { DbConfig, DbDriver, SaasUser, SaasSubscription, SubscriptionStatus, PricingTier, PricingFeature } from './db/index';
|
|
13
|
+
export { createYaxaAuth } from './auth/index';
|
|
14
|
+
export type { YaxaAuthConfig, YaxaAuth } from './auth/index';
|
|
15
|
+
export { createYaxaAuthHook } from './auth/hook';
|
|
16
|
+
export type { YaxaAuthHookOptions } from './auth/hook';
|
|
17
|
+
export { getPolarClient, createPolarCheckout, createPolarCustomerPortalSession, createPolarWebhookHandler } from './polar/index';
|
|
18
|
+
export type { PolarConfig, CreateCheckoutOptions, PolarWebhookOptions } from './polar/index';
|
|
19
|
+
export { getResendClient, sendMagicLinkEmail, sendWelcomeEmail } from './email/index';
|
|
20
|
+
export type { ResendEmailConfig, SendMagicLinkOptions, SendWelcomeEmailOptions } from './email/index';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Yaxa Server Suite - SvelteKit Server Hooks, Auth, Database, Payments & Email
|
|
2
|
+
// Server Hooks & SEO Endpoints
|
|
3
|
+
export { createYaxaHook } from '../site/hook';
|
|
4
|
+
export { createRobotsHandler } from '../site/robots';
|
|
5
|
+
export { createSitemapHandler } from '../site/sitemap';
|
|
6
|
+
export { createSitemapXslHandler, generateSitemapXsl } from '../site/sitemap-xsl';
|
|
7
|
+
export { createOgImageHandler, generateOgSvg } from '../site/og';
|
|
8
|
+
export { createManifestHandler } from '../site/manifest';
|
|
9
|
+
// Database & Drizzle ORM
|
|
10
|
+
export { getDb, schemaPg, schemaSqlite } from './db/index';
|
|
11
|
+
// Authentication (Better-Auth)
|
|
12
|
+
export { createYaxaAuth } from './auth/index';
|
|
13
|
+
export { createYaxaAuthHook } from './auth/hook';
|
|
14
|
+
// Polar.sh Payments & Webhooks
|
|
15
|
+
export { getPolarClient, createPolarCheckout, createPolarCustomerPortalSession, createPolarWebhookHandler } from './polar/index';
|
|
16
|
+
// Transactional Emails (Resend)
|
|
17
|
+
export { getResendClient, sendMagicLinkEmail, sendWelcomeEmail } from './email/index';
|
|
@@ -27,3 +27,5 @@ export declare function createPolarCheckout(options: CreateCheckoutOptions): Pro
|
|
|
27
27
|
export declare function createPolarCustomerPortalSession(customerId: string, polar?: Polar): Promise<{
|
|
28
28
|
url: string;
|
|
29
29
|
}>;
|
|
30
|
+
export { createPolarWebhookHandler } from './webhook';
|
|
31
|
+
export type { PolarWebhookOptions } from './webhook';
|
package/dist/site/config.d.ts
CHANGED
|
@@ -12,6 +12,33 @@ export interface NavItem {
|
|
|
12
12
|
external?: boolean;
|
|
13
13
|
badge?: string;
|
|
14
14
|
}
|
|
15
|
+
export interface CompanyConfig {
|
|
16
|
+
legalName: string;
|
|
17
|
+
address?: string;
|
|
18
|
+
country?: string;
|
|
19
|
+
contactEmail: string;
|
|
20
|
+
vatNumber?: string;
|
|
21
|
+
registrationNumber?: string;
|
|
22
|
+
registrationCourt?: string;
|
|
23
|
+
representative?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface LegalLinksConfig {
|
|
26
|
+
privacy?: string;
|
|
27
|
+
terms?: string;
|
|
28
|
+
refunds?: string;
|
|
29
|
+
impressum?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface LegalConfig {
|
|
32
|
+
jurisdiction?: string;
|
|
33
|
+
paymentProcessor?: 'polar' | 'stripe' | 'lemonsqueezy' | 'custom' | 'none';
|
|
34
|
+
adNetwork?: 'ethicalads' | 'custom' | 'none';
|
|
35
|
+
analytics?: 'none' | 'plausible' | 'fathom' | 'custom';
|
|
36
|
+
refundDays?: number;
|
|
37
|
+
governingLaw?: string;
|
|
38
|
+
dpoEmail?: string;
|
|
39
|
+
morNotice?: string;
|
|
40
|
+
links?: LegalLinksConfig;
|
|
41
|
+
}
|
|
15
42
|
export interface SiteConfig {
|
|
16
43
|
name: string;
|
|
17
44
|
title: string;
|
|
@@ -21,6 +48,8 @@ export interface SiteConfig {
|
|
|
21
48
|
defaultLocale?: string;
|
|
22
49
|
logo?: string;
|
|
23
50
|
author?: AuthorConfig;
|
|
51
|
+
company?: CompanyConfig;
|
|
52
|
+
legal?: LegalConfig;
|
|
24
53
|
theme?: {
|
|
25
54
|
primaryColor?: string;
|
|
26
55
|
neutralColor?: string;
|
package/dist/site/config.js
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
export function defineSiteConfig(config) {
|
|
2
|
+
const defaultMorNotice = config.legal?.paymentProcessor === 'polar'
|
|
3
|
+
? 'Payments securely processed by Polar.sh (Merchant of Record)'
|
|
4
|
+
: config.legal?.paymentProcessor === 'lemonsqueezy'
|
|
5
|
+
? 'Payments securely processed by Lemon Squeezy (Merchant of Record)'
|
|
6
|
+
: config.legal?.paymentProcessor === 'stripe'
|
|
7
|
+
? 'Payments securely processed by Stripe'
|
|
8
|
+
: undefined;
|
|
2
9
|
return {
|
|
3
10
|
defaultLocale: 'en',
|
|
4
11
|
theme: {
|
|
5
12
|
defaultMode: 'system',
|
|
6
13
|
...config.theme
|
|
7
14
|
},
|
|
15
|
+
legal: {
|
|
16
|
+
refundDays: 14,
|
|
17
|
+
paymentProcessor: 'polar',
|
|
18
|
+
morNotice: defaultMorNotice,
|
|
19
|
+
...config.legal,
|
|
20
|
+
links: {
|
|
21
|
+
privacy: '/privacy',
|
|
22
|
+
terms: '/terms',
|
|
23
|
+
refunds: '/refunds',
|
|
24
|
+
...config.legal?.links
|
|
25
|
+
}
|
|
26
|
+
},
|
|
8
27
|
seo: {
|
|
9
28
|
titleTemplate: '%s · ' + config.name,
|
|
10
29
|
defaultOgImage: '/api/og',
|
|
@@ -30,6 +49,22 @@ export const DEFAULT_SITE_CONFIG = defineSiteConfig({
|
|
|
30
49
|
description: 'A comprehensive Svelte 5 UI component and SEO library with Tailwind CSS v4.',
|
|
31
50
|
url: 'https://yaxa.vercel.app',
|
|
32
51
|
logo: '/favicon.svg',
|
|
52
|
+
company: {
|
|
53
|
+
legalName: 'Yaxa Open Source',
|
|
54
|
+
contactEmail: 'support@yaxa.vercel.app'
|
|
55
|
+
},
|
|
56
|
+
legal: {
|
|
57
|
+
jurisdiction: 'EU',
|
|
58
|
+
paymentProcessor: 'polar',
|
|
59
|
+
adNetwork: 'ethicalads',
|
|
60
|
+
refundDays: 14,
|
|
61
|
+
links: {
|
|
62
|
+
privacy: '/privacy',
|
|
63
|
+
terms: '/terms',
|
|
64
|
+
refunds: '/refunds',
|
|
65
|
+
impressum: '/impressum'
|
|
66
|
+
}
|
|
67
|
+
},
|
|
33
68
|
theme: {
|
|
34
69
|
primaryColor: '#ff3e00',
|
|
35
70
|
neutralColor: '#71717a',
|
package/dist/site/schema.d.ts
CHANGED
|
@@ -29,8 +29,19 @@ export declare function generateOrganizationSchema(config: SiteConfig): {
|
|
|
29
29
|
'@context': string;
|
|
30
30
|
'@type': string;
|
|
31
31
|
name: string;
|
|
32
|
+
legalName: string | undefined;
|
|
32
33
|
url: string;
|
|
33
34
|
logo: string | undefined;
|
|
35
|
+
email: string | undefined;
|
|
36
|
+
address: {
|
|
37
|
+
'@type': string;
|
|
38
|
+
streetAddress: string;
|
|
39
|
+
addressCountry: string | undefined;
|
|
40
|
+
} | undefined;
|
|
41
|
+
vatID: string | undefined;
|
|
42
|
+
taxID: string | undefined;
|
|
43
|
+
publishingPrinciples: string | undefined;
|
|
44
|
+
termsOfService: string | undefined;
|
|
34
45
|
sameAs: (string | undefined)[];
|
|
35
46
|
};
|
|
36
47
|
export declare function generateArticleSchema(config: SiteConfig, article: ArticleSchemaData): {
|
package/dist/site/schema.js
CHANGED
|
@@ -17,12 +17,35 @@ export function generateWebSiteSchema(config) {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
export function generateOrganizationSchema(config) {
|
|
20
|
+
const privacyUrl = config.legal?.links?.privacy
|
|
21
|
+
? config.legal.links.privacy.startsWith('http')
|
|
22
|
+
? config.legal.links.privacy
|
|
23
|
+
: `${config.url}${config.legal.links.privacy}`
|
|
24
|
+
: undefined;
|
|
25
|
+
const termsUrl = config.legal?.links?.terms
|
|
26
|
+
? config.legal.links.terms.startsWith('http')
|
|
27
|
+
? config.legal.links.terms
|
|
28
|
+
: `${config.url}${config.legal.links.terms}`
|
|
29
|
+
: undefined;
|
|
20
30
|
return {
|
|
21
31
|
'@context': 'https://schema.org',
|
|
22
32
|
'@type': 'Organization',
|
|
23
33
|
name: config.name,
|
|
34
|
+
legalName: config.company?.legalName || undefined,
|
|
24
35
|
url: config.url,
|
|
25
36
|
logo: config.logo ? `${config.url}${config.logo}` : undefined,
|
|
37
|
+
email: config.company?.contactEmail || undefined,
|
|
38
|
+
address: config.company?.address
|
|
39
|
+
? {
|
|
40
|
+
'@type': 'PostalAddress',
|
|
41
|
+
streetAddress: config.company.address,
|
|
42
|
+
addressCountry: config.company.country || undefined
|
|
43
|
+
}
|
|
44
|
+
: undefined,
|
|
45
|
+
vatID: config.company?.vatNumber || undefined,
|
|
46
|
+
taxID: config.company?.registrationNumber || undefined,
|
|
47
|
+
publishingPrinciples: privacyUrl,
|
|
48
|
+
termsOfService: termsUrl,
|
|
26
49
|
sameAs: [
|
|
27
50
|
config.socials?.github,
|
|
28
51
|
config.socials?.twitter,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yaxa-svelte",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "The Intuitive Svelte UI Library — Nuxt UI v4 equivalent for SvelteKit 2.7+ & Svelte 5 with automated SEO, dynamic OpenGraph cards, sitemaps, robots.txt, and Tailwind CSS v4.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://yaxa.vercel.app",
|
|
@@ -41,6 +41,26 @@
|
|
|
41
41
|
"svelte": "./dist/index.js",
|
|
42
42
|
"default": "./dist/index.js"
|
|
43
43
|
},
|
|
44
|
+
"./server": {
|
|
45
|
+
"types": "./dist/server/index.d.ts",
|
|
46
|
+
"default": "./dist/server/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./auth": {
|
|
49
|
+
"types": "./dist/server/auth/index.d.ts",
|
|
50
|
+
"default": "./dist/server/auth/index.js"
|
|
51
|
+
},
|
|
52
|
+
"./db": {
|
|
53
|
+
"types": "./dist/server/db/index.d.ts",
|
|
54
|
+
"default": "./dist/server/db/index.js"
|
|
55
|
+
},
|
|
56
|
+
"./polar": {
|
|
57
|
+
"types": "./dist/server/polar/index.d.ts",
|
|
58
|
+
"default": "./dist/server/polar/index.js"
|
|
59
|
+
},
|
|
60
|
+
"./email": {
|
|
61
|
+
"types": "./dist/server/email/index.d.ts",
|
|
62
|
+
"default": "./dist/server/email/index.js"
|
|
63
|
+
},
|
|
44
64
|
"./vite": {
|
|
45
65
|
"types": "./dist/vite/index.d.ts",
|
|
46
66
|
"default": "./dist/vite/index.js"
|
|
@@ -50,7 +70,10 @@
|
|
|
50
70
|
"devDependencies": {
|
|
51
71
|
"@eslint/js": "^10.0.1",
|
|
52
72
|
"@iconify/json": "^2.2.525",
|
|
73
|
+
"@libsql/client": "^0.18.0",
|
|
53
74
|
"@lucide/svelte": "^1.45.0",
|
|
75
|
+
"@neondatabase/serverless": "^1.1.0",
|
|
76
|
+
"@polar-sh/sdk": "^0.49.0",
|
|
54
77
|
"@sveltejs/adapter-vercel": "^6.3.3",
|
|
55
78
|
"@sveltejs/kit": "^2.63.0",
|
|
56
79
|
"@sveltejs/package": "^2.5.8",
|
|
@@ -58,7 +81,9 @@
|
|
|
58
81
|
"@tailwindcss/typography": "^0.5.19",
|
|
59
82
|
"@tailwindcss/vite": "^4.3.0",
|
|
60
83
|
"@types/node": "^26.4.1",
|
|
84
|
+
"better-auth": "^1.7.3",
|
|
61
85
|
"drizzle-kit": "^0.31.10",
|
|
86
|
+
"drizzle-orm": "^0.45.2",
|
|
62
87
|
"eslint": "^10.4.1",
|
|
63
88
|
"eslint-config-prettier": "^10.1.8",
|
|
64
89
|
"eslint-plugin-svelte": "^3.19.0",
|
|
@@ -66,6 +91,7 @@
|
|
|
66
91
|
"prettier": "^3.8.3",
|
|
67
92
|
"prettier-plugin-svelte": "^4.1.0",
|
|
68
93
|
"prettier-plugin-tailwindcss": "^0.8.0",
|
|
94
|
+
"resend": "^6.27.0",
|
|
69
95
|
"super-sitemap": "^2.0.6",
|
|
70
96
|
"svelte": "^5.56.1",
|
|
71
97
|
"svelte-check": "^4.6.0",
|
|
@@ -77,15 +103,9 @@
|
|
|
77
103
|
"vite": "^8.0.16"
|
|
78
104
|
},
|
|
79
105
|
"dependencies": {
|
|
80
|
-
"@libsql/client": "^0.18.0",
|
|
81
|
-
"@neondatabase/serverless": "^1.1.0",
|
|
82
|
-
"@polar-sh/sdk": "^0.49.0",
|
|
83
|
-
"better-auth": "^1.7.3",
|
|
84
106
|
"bits-ui": "^2.19.0",
|
|
85
|
-
"drizzle-orm": "^0.45.2",
|
|
86
107
|
"formsnap": "^2.0.1",
|
|
87
108
|
"mode-watcher": "^1.1.0",
|
|
88
|
-
"resend": "^6.27.0",
|
|
89
109
|
"runed": "^0.37.1",
|
|
90
110
|
"svelte-sonner": "^1.2.1",
|
|
91
111
|
"sveltekit-superforms": "^2.30.2",
|
|
@@ -93,13 +113,37 @@
|
|
|
93
113
|
"zod": "^4.5.4"
|
|
94
114
|
},
|
|
95
115
|
"peerDependencies": {
|
|
116
|
+
"@libsql/client": ">=0.18.0",
|
|
96
117
|
"@lucide/svelte": "^1.0.0",
|
|
118
|
+
"@neondatabase/serverless": ">=1.1.0",
|
|
119
|
+
"@polar-sh/sdk": ">=0.49.0",
|
|
97
120
|
"@sveltejs/kit": "^2.0.0",
|
|
121
|
+
"better-auth": ">=1.7.0",
|
|
122
|
+
"drizzle-orm": ">=0.45.0",
|
|
123
|
+
"resend": ">=6.27.0",
|
|
98
124
|
"svelte": "^5.0.0"
|
|
99
125
|
},
|
|
100
126
|
"peerDependenciesMeta": {
|
|
127
|
+
"@libsql/client": {
|
|
128
|
+
"optional": true
|
|
129
|
+
},
|
|
101
130
|
"@lucide/svelte": {
|
|
102
131
|
"optional": true
|
|
132
|
+
},
|
|
133
|
+
"@neondatabase/serverless": {
|
|
134
|
+
"optional": true
|
|
135
|
+
},
|
|
136
|
+
"@polar-sh/sdk": {
|
|
137
|
+
"optional": true
|
|
138
|
+
},
|
|
139
|
+
"better-auth": {
|
|
140
|
+
"optional": true
|
|
141
|
+
},
|
|
142
|
+
"drizzle-orm": {
|
|
143
|
+
"optional": true
|
|
144
|
+
},
|
|
145
|
+
"resend": {
|
|
146
|
+
"optional": true
|
|
103
147
|
}
|
|
104
148
|
},
|
|
105
149
|
"scripts": {
|