yaxa-svelte 1.0.0

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.
Files changed (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +163 -0
  3. package/dist/assets/favicon.svg +15 -0
  4. package/dist/components/elements/Avatar.svelte +106 -0
  5. package/dist/components/elements/Avatar.svelte.d.ts +40 -0
  6. package/dist/components/elements/AvatarGroup.svelte +18 -0
  7. package/dist/components/elements/AvatarGroup.svelte.d.ts +8 -0
  8. package/dist/components/elements/Badge.svelte +202 -0
  9. package/dist/components/elements/Badge.svelte.d.ts +75 -0
  10. package/dist/components/elements/Button.svelte +300 -0
  11. package/dist/components/elements/Button.svelte.d.ts +109 -0
  12. package/dist/components/elements/ButtonGroup.svelte +22 -0
  13. package/dist/components/elements/ButtonGroup.svelte.d.ts +9 -0
  14. package/dist/components/elements/Chip.svelte +117 -0
  15. package/dist/components/elements/Chip.svelte.d.ts +15 -0
  16. package/dist/components/elements/DataTable.svelte +222 -0
  17. package/dist/components/elements/DataTable.svelte.d.ts +43 -0
  18. package/dist/components/elements/Icon.svelte +87 -0
  19. package/dist/components/elements/Icon.svelte.d.ts +10 -0
  20. package/dist/components/elements/Kbd.svelte +37 -0
  21. package/dist/components/elements/Kbd.svelte.d.ts +32 -0
  22. package/dist/components/elements/Link.svelte +63 -0
  23. package/dist/components/elements/Link.svelte.d.ts +15 -0
  24. package/dist/components/elements/Logo.svelte +77 -0
  25. package/dist/components/elements/Logo.svelte.d.ts +9 -0
  26. package/dist/components/elements/Meter.svelte +87 -0
  27. package/dist/components/elements/Meter.svelte.d.ts +14 -0
  28. package/dist/components/elements/Progress.svelte +63 -0
  29. package/dist/components/elements/Progress.svelte.d.ts +49 -0
  30. package/dist/components/elements/Skeleton.svelte +12 -0
  31. package/dist/components/elements/Skeleton.svelte.d.ts +6 -0
  32. package/dist/components/elements/Spinner.svelte +39 -0
  33. package/dist/components/elements/Spinner.svelte.d.ts +7 -0
  34. package/dist/components/forms/Checkbox.svelte +77 -0
  35. package/dist/components/forms/Checkbox.svelte.d.ts +17 -0
  36. package/dist/components/forms/ColorPicker.svelte +142 -0
  37. package/dist/components/forms/ColorPicker.svelte.d.ts +10 -0
  38. package/dist/components/forms/Form.svelte +84 -0
  39. package/dist/components/forms/Form.svelte.d.ts +14 -0
  40. package/dist/components/forms/FormField.svelte +56 -0
  41. package/dist/components/forms/FormField.svelte.d.ts +14 -0
  42. package/dist/components/forms/Input.svelte +138 -0
  43. package/dist/components/forms/Input.svelte.d.ts +58 -0
  44. package/dist/components/forms/RadioGroup.svelte +74 -0
  45. package/dist/components/forms/RadioGroup.svelte.d.ts +17 -0
  46. package/dist/components/forms/Select.svelte +91 -0
  47. package/dist/components/forms/Select.svelte.d.ts +50 -0
  48. package/dist/components/forms/Slider.svelte +37 -0
  49. package/dist/components/forms/Slider.svelte.d.ts +12 -0
  50. package/dist/components/forms/Switch.svelte +81 -0
  51. package/dist/components/forms/Switch.svelte.d.ts +53 -0
  52. package/dist/components/forms/Textarea.svelte +73 -0
  53. package/dist/components/forms/Textarea.svelte.d.ts +64 -0
  54. package/dist/components/layout/Card.svelte +89 -0
  55. package/dist/components/layout/Card.svelte.d.ts +64 -0
  56. package/dist/components/layout/Container.svelte +36 -0
  57. package/dist/components/layout/Container.svelte.d.ts +37 -0
  58. package/dist/components/layout/Divider.svelte +45 -0
  59. package/dist/components/layout/Divider.svelte.d.ts +11 -0
  60. package/dist/components/layout/Footer.svelte +96 -0
  61. package/dist/components/layout/Footer.svelte.d.ts +10 -0
  62. package/dist/components/layout/Header.svelte +175 -0
  63. package/dist/components/layout/Header.svelte.d.ts +12 -0
  64. package/dist/components/layout/Section.svelte +62 -0
  65. package/dist/components/layout/Section.svelte.d.ts +14 -0
  66. package/dist/components/layout/YaxaApp.svelte +48 -0
  67. package/dist/components/layout/YaxaApp.svelte.d.ts +12 -0
  68. package/dist/components/navigation/Breadcrumb.svelte +58 -0
  69. package/dist/components/navigation/Breadcrumb.svelte.d.ts +13 -0
  70. package/dist/components/navigation/CommandPalette.svelte +201 -0
  71. package/dist/components/navigation/CommandPalette.svelte.d.ts +19 -0
  72. package/dist/components/navigation/DropdownMenu.svelte +75 -0
  73. package/dist/components/navigation/DropdownMenu.svelte.d.ts +20 -0
  74. package/dist/components/navigation/Pagination.svelte +106 -0
  75. package/dist/components/navigation/Pagination.svelte.d.ts +10 -0
  76. package/dist/components/navigation/Tabs.svelte +91 -0
  77. package/dist/components/navigation/Tabs.svelte.d.ts +18 -0
  78. package/dist/components/overlays/Accordion.svelte +54 -0
  79. package/dist/components/overlays/Accordion.svelte.d.ts +16 -0
  80. package/dist/components/overlays/Alert.svelte +110 -0
  81. package/dist/components/overlays/Alert.svelte.d.ts +37 -0
  82. package/dist/components/overlays/ContextMenu.svelte +67 -0
  83. package/dist/components/overlays/ContextMenu.svelte.d.ts +21 -0
  84. package/dist/components/overlays/Modal.svelte +99 -0
  85. package/dist/components/overlays/Modal.svelte.d.ts +40 -0
  86. package/dist/components/overlays/Popover.svelte +33 -0
  87. package/dist/components/overlays/Popover.svelte.d.ts +11 -0
  88. package/dist/components/overlays/Slideover.svelte +102 -0
  89. package/dist/components/overlays/Slideover.svelte.d.ts +37 -0
  90. package/dist/components/overlays/Tooltip.svelte +39 -0
  91. package/dist/components/overlays/Tooltip.svelte.d.ts +12 -0
  92. package/dist/components/saas/AuthCard.svelte +273 -0
  93. package/dist/components/saas/AuthCard.svelte.d.ts +16 -0
  94. package/dist/components/saas/PricingCard.svelte +166 -0
  95. package/dist/components/saas/PricingCard.svelte.d.ts +19 -0
  96. package/dist/components/saas/PricingTable.svelte +139 -0
  97. package/dist/components/saas/PricingTable.svelte.d.ts +11 -0
  98. package/dist/components/saas/SubscriptionCard.svelte +162 -0
  99. package/dist/components/saas/SubscriptionCard.svelte.d.ts +16 -0
  100. package/dist/components/saas/UserMenu.svelte +137 -0
  101. package/dist/components/saas/UserMenu.svelte.d.ts +19 -0
  102. package/dist/components/seo/Favicons.svelte +22 -0
  103. package/dist/components/seo/Favicons.svelte.d.ts +8 -0
  104. package/dist/components/seo/OgImage.svelte +61 -0
  105. package/dist/components/seo/OgImage.svelte.d.ts +12 -0
  106. package/dist/components/seo/Seo.svelte +170 -0
  107. package/dist/components/seo/Seo.svelte.d.ts +21 -0
  108. package/dist/composables/useAuth.svelte.d.ts +23 -0
  109. package/dist/composables/useAuth.svelte.js +157 -0
  110. package/dist/composables/useClipboard.svelte.d.ts +9 -0
  111. package/dist/composables/useClipboard.svelte.js +36 -0
  112. package/dist/composables/useColorMode.svelte.d.ts +8 -0
  113. package/dist/composables/useColorMode.svelte.js +20 -0
  114. package/dist/composables/useDebounce.svelte.d.ts +3 -0
  115. package/dist/composables/useDebounce.svelte.js +17 -0
  116. package/dist/composables/useMediaQuery.svelte.d.ts +3 -0
  117. package/dist/composables/useMediaQuery.svelte.js +17 -0
  118. package/dist/composables/useShortcuts.svelte.d.ts +10 -0
  119. package/dist/composables/useShortcuts.svelte.js +50 -0
  120. package/dist/composables/useToast.d.ts +19 -0
  121. package/dist/composables/useToast.js +34 -0
  122. package/dist/index.d.ts +101 -0
  123. package/dist/index.js +92 -0
  124. package/dist/server/auth/hook.d.ts +14 -0
  125. package/dist/server/auth/hook.js +36 -0
  126. package/dist/server/auth/index.d.ts +39 -0
  127. package/dist/server/auth/index.js +69 -0
  128. package/dist/server/db/index.d.ts +18 -0
  129. package/dist/server/db/index.js +43 -0
  130. package/dist/server/db/schema-pg.d.ts +977 -0
  131. package/dist/server/db/schema-pg.js +83 -0
  132. package/dist/server/db/schema-sqlite.d.ts +1045 -0
  133. package/dist/server/db/schema-sqlite.js +83 -0
  134. package/dist/server/db/types.d.ts +44 -0
  135. package/dist/server/db/types.js +1 -0
  136. package/dist/server/email/index.d.ts +27 -0
  137. package/dist/server/email/index.js +79 -0
  138. package/dist/server/polar/index.d.ts +29 -0
  139. package/dist/server/polar/index.js +49 -0
  140. package/dist/server/polar/webhook.d.ts +16 -0
  141. package/dist/server/polar/webhook.js +118 -0
  142. package/dist/site/config.d.ts +63 -0
  143. package/dist/site/config.js +48 -0
  144. package/dist/site/context.d.ts +11 -0
  145. package/dist/site/context.js +23 -0
  146. package/dist/site/hook.d.ts +15 -0
  147. package/dist/site/hook.js +38 -0
  148. package/dist/site/manifest.d.ts +6 -0
  149. package/dist/site/manifest.js +32 -0
  150. package/dist/site/og.d.ts +14 -0
  151. package/dist/site/og.js +116 -0
  152. package/dist/site/robots.d.ts +10 -0
  153. package/dist/site/robots.js +54 -0
  154. package/dist/site/schema.d.ts +67 -0
  155. package/dist/site/schema.js +67 -0
  156. package/dist/site/seo-helpers.d.ts +36 -0
  157. package/dist/site/seo-helpers.js +21 -0
  158. package/dist/site/sitemap-xsl.d.ts +6 -0
  159. package/dist/site/sitemap-xsl.js +164 -0
  160. package/dist/site/sitemap.d.ts +20 -0
  161. package/dist/site/sitemap.js +61 -0
  162. package/dist/styles/yaxa.css +84 -0
  163. package/dist/theme/theme.svelte.d.ts +74 -0
  164. package/dist/theme/theme.svelte.js +421 -0
  165. package/dist/utils/cn.d.ts +3 -0
  166. package/dist/utils/cn.js +3 -0
  167. package/dist/vite/index.d.ts +20 -0
  168. package/dist/vite/index.js +29 -0
  169. package/package.json +108 -0
@@ -0,0 +1,32 @@
1
+ import { DEFAULT_SITE_CONFIG } from './config';
2
+ export function createManifestHandler(optionsOrConfig) {
3
+ const config = !optionsOrConfig
4
+ ? DEFAULT_SITE_CONFIG
5
+ : 'name' in optionsOrConfig
6
+ ? optionsOrConfig
7
+ : optionsOrConfig.config || DEFAULT_SITE_CONFIG;
8
+ return async () => {
9
+ const manifest = {
10
+ name: config.title || config.name,
11
+ short_name: config.name,
12
+ description: config.description,
13
+ start_url: '/',
14
+ display: 'standalone',
15
+ background_color: config.theme?.neutralColor || '#121212',
16
+ theme_color: config.theme?.primaryColor || '#ff3e00',
17
+ icons: [
18
+ {
19
+ src: '/favicon.svg',
20
+ sizes: 'any',
21
+ type: 'image/svg+xml'
22
+ }
23
+ ]
24
+ };
25
+ return new Response(JSON.stringify(manifest, null, 2), {
26
+ headers: {
27
+ 'Content-Type': 'application/manifest+json; charset=utf-8',
28
+ 'Cache-Control': 'public, max-age=86400'
29
+ }
30
+ });
31
+ };
32
+ }
@@ -0,0 +1,14 @@
1
+ import type { RequestHandler } from '@sveltejs/kit';
2
+ import type { SiteConfig } from './config';
3
+ export interface OgImageOptions {
4
+ config?: SiteConfig;
5
+ }
6
+ export declare function generateOgSvg(params: {
7
+ title: string;
8
+ description?: string;
9
+ siteName?: string;
10
+ badge?: string;
11
+ theme?: 'dark' | 'light';
12
+ url?: string;
13
+ }): string;
14
+ export declare function createOgImageHandler(options?: OgImageOptions): RequestHandler;
@@ -0,0 +1,116 @@
1
+ export function generateOgSvg(params) {
2
+ const isDark = params.theme !== 'light';
3
+ const bgGradientStart = isDark ? '#121212' : '#fafafa';
4
+ const bgGradientEnd = isDark ? '#1c1917' : '#f5f5f4';
5
+ const cardBg = isDark ? 'rgba(24, 24, 27, 0.85)' : 'rgba(255, 255, 255, 0.9)';
6
+ const cardBorder = isDark ? 'rgba(63, 63, 70, 0.5)' : 'rgba(228, 228, 231, 0.9)';
7
+ const titleColor = isDark ? '#fafafa' : '#09090b';
8
+ const descColor = isDark ? '#a1a1aa' : '#52525b';
9
+ const svelteFlame1 = '#ff3e00';
10
+ const svelteFlame2 = '#ea580c';
11
+ const metaColor = isDark ? '#71717a' : '#71717a';
12
+ // Escape XML characters
13
+ const escapeXml = (unsafe) => unsafe
14
+ .replace(/&/g, '&')
15
+ .replace(/</g, '&lt;')
16
+ .replace(/>/g, '&gt;')
17
+ .replace(/"/g, '&quot;')
18
+ .replace(/'/g, '&apos;');
19
+ const safeTitle = escapeXml(params.title || 'Welcome');
20
+ const safeDesc = escapeXml(params.description || 'Fast, beautiful, accessible web applications.');
21
+ const safeSiteName = escapeXml(params.siteName || 'Yaxa');
22
+ const safeBadge = params.badge ? escapeXml(params.badge) : null;
23
+ const safeUrl = escapeXml(params.url ? params.url.replace(/^https?:\/\//, '') : 'yaxa.dev');
24
+ return `<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
25
+ <defs>
26
+ <linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
27
+ <stop offset="0%" stop-color="${bgGradientStart}"/>
28
+ <stop offset="100%" stop-color="${bgGradientEnd}"/>
29
+ </linearGradient>
30
+ <linearGradient id="brandGrad" x1="0%" y1="0%" x2="100%" y2="100%">
31
+ <stop offset="0%" stop-color="${svelteFlame1}"/>
32
+ <stop offset="100%" stop-color="${svelteFlame2}"/>
33
+ </linearGradient>
34
+ <linearGradient id="glowGrad" x1="0%" y1="0%" x2="100%" y2="100%">
35
+ <stop offset="0%" stop-color="${svelteFlame1}" stop-opacity="0.25"/>
36
+ <stop offset="100%" stop-color="${svelteFlame2}" stop-opacity="0.08"/>
37
+ </linearGradient>
38
+ <filter id="blurFilter" x="-20%" y="-20%" width="140%" height="140%">
39
+ <feGaussianBlur stdDeviation="80"/>
40
+ </filter>
41
+ </defs>
42
+
43
+ <!-- Background -->
44
+ <rect width="1200" height="630" fill="url(#bgGrad)"/>
45
+
46
+ <!-- Glowing Orbs -->
47
+ <circle cx="150" cy="120" r="280" fill="url(#glowGrad)" filter="url(#blurFilter)"/>
48
+ <circle cx="1050" cy="500" r="300" fill="url(#glowGrad)" filter="url(#blurFilter)"/>
49
+
50
+ <!-- Card Border and Container -->
51
+ <rect x="60" y="60" width="1080" height="510" rx="24" fill="${cardBg}" stroke="${cardBorder}" stroke-width="2"/>
52
+
53
+ <!-- Top Bar: Logo & Badge -->
54
+ <g transform="translate(120, 130)">
55
+ <!-- Yaxa Svelte-Style Dual-Tone X Ribbon Icon -->
56
+ <g transform="translate(0, -2) scale(0.44)">
57
+ <!-- Outer Flame Track -->
58
+ <path d="M24 24 L76 76" stroke="url(#brandGrad)" stroke-width="22" stroke-linecap="round"/>
59
+ <path d="M76 24 L56 44 M44 56 L24 76" stroke="url(#brandGrad)" stroke-width="22" stroke-linecap="round"/>
60
+ <!-- Inner White Core Track -->
61
+ <path d="M24 24 L76 76" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
62
+ <path d="M76 24 L58 42 M42 58 L24 76" stroke="#ffffff" stroke-width="8" stroke-linecap="round"/>
63
+ </g>
64
+
65
+ <!-- Site Name -->
66
+ <text x="54" y="27" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="24" font-weight="700" fill="${titleColor}">${safeSiteName}</text>
67
+
68
+ <!-- Badge -->
69
+ ${safeBadge
70
+ ? `
71
+ <rect x="760" y="2" width="${safeBadge.length * 10 + 36}" height="32" rx="16" fill="rgba(255, 62, 0, 0.15)" stroke="rgba(255, 62, 0, 0.4)" stroke-width="1"/>
72
+ <text x="${760 + (safeBadge.length * 10 + 36) / 2}" y="23" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="14" font-weight="600" fill="#ff6a00" text-anchor="middle">${safeBadge}</text>
73
+ `
74
+ : ''}
75
+ </g>
76
+
77
+ <!-- Middle: Title & Description -->
78
+ <g transform="translate(120, 250)">
79
+ <text x="0" y="40" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="52" font-weight="800" fill="${titleColor}" letter-spacing="-0.03em">${safeTitle}</text>
80
+ <text x="0" y="110" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="24" font-weight="400" fill="${descColor}" width="840">${safeDesc}</text>
81
+ </g>
82
+
83
+ <!-- Bottom: Domain and Decorative Accent Line -->
84
+ <g transform="translate(120, 480)">
85
+ <line x1="0" y1="0" x2="840" y2="0" stroke="${cardBorder}" stroke-width="1"/>
86
+ <circle cx="6" cy="30" r="4" fill="${svelteFlame1}"/>
87
+ <text x="20" y="35" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="18" font-weight="500" fill="${metaColor}">${safeUrl}</text>
88
+ </g>
89
+ </svg>`;
90
+ }
91
+ export function createOgImageHandler(options) {
92
+ return async ({ url }) => {
93
+ const title = url.searchParams.get('title') || options?.config?.title || 'Yaxa';
94
+ const description = url.searchParams.get('description') ||
95
+ options?.config?.description ||
96
+ 'Fast, beautiful, accessible UI components and SEO tools for SvelteKit.';
97
+ const badge = url.searchParams.get('badge') || undefined;
98
+ const theme = url.searchParams.get('theme') || 'dark';
99
+ const siteName = url.searchParams.get('site') || options?.config?.name || 'Yaxa';
100
+ const siteUrl = options?.config?.url || url.origin;
101
+ const svg = generateOgSvg({
102
+ title,
103
+ description,
104
+ siteName,
105
+ badge,
106
+ theme,
107
+ url: siteUrl
108
+ });
109
+ return new Response(svg, {
110
+ headers: {
111
+ 'Content-Type': 'image/svg+xml; charset=utf-8',
112
+ 'Cache-Control': 'public, max-age=86400, s-maxage=86400'
113
+ }
114
+ });
115
+ };
116
+ }
@@ -0,0 +1,10 @@
1
+ import type { RequestHandler } from '@sveltejs/kit';
2
+ import type { SiteConfig } from './config';
3
+ export interface RobotsOptions {
4
+ config: SiteConfig;
5
+ /**
6
+ * Override environment detection. If true, allows indexing. If false, disallows indexing.
7
+ */
8
+ isProduction?: boolean;
9
+ }
10
+ export declare function createRobotsHandler(optionsOrConfig: SiteConfig | RobotsOptions): RequestHandler;
@@ -0,0 +1,54 @@
1
+ export function createRobotsHandler(optionsOrConfig) {
2
+ const options = 'config' in optionsOrConfig ? optionsOrConfig : { config: optionsOrConfig };
3
+ const { config } = options;
4
+ return async ({ url }) => {
5
+ try {
6
+ const isProdEnv = typeof process !== 'undefined' && process.env?.NODE_ENV === 'production';
7
+ const isProd = options.isProduction ??
8
+ (isProdEnv &&
9
+ !url.hostname.includes('localhost') &&
10
+ !url.hostname.includes('vercel.app') &&
11
+ !url.hostname.includes('preview') &&
12
+ !url.hostname.includes('staging'));
13
+ const baseUrl = config?.url || url?.origin || 'https://yaxa.vercel.app';
14
+ let body;
15
+ if (!isProd && !options.isProduction) {
16
+ // Non-production or preview deployment: protect against indexing
17
+ body = `# Non-production environment: indexing disabled\nUser-agent: *\nDisallow: /\n`;
18
+ }
19
+ else if (config?.robots?.rules && config.robots.rules.length > 0) {
20
+ // Custom defined rules
21
+ body = config.robots.rules
22
+ .map((rule) => {
23
+ let ruleText = `User-agent: ${rule.userAgent}\n`;
24
+ if (rule.allow) {
25
+ ruleText += rule.allow.map((path) => `Allow: ${path}\n`).join('');
26
+ }
27
+ if (rule.disallow) {
28
+ ruleText += rule.disallow.map((path) => `Disallow: ${path}\n`).join('');
29
+ }
30
+ return ruleText;
31
+ })
32
+ .join('\n');
33
+ }
34
+ else {
35
+ // Default production allow
36
+ body = `User-agent: *\nAllow: /\n`;
37
+ }
38
+ // Always append sitemap reference
39
+ body += `\nSitemap: ${baseUrl}/sitemap.xml\n`;
40
+ return new Response(body, {
41
+ headers: {
42
+ 'Content-Type': 'text/plain; charset=utf-8',
43
+ 'Cache-Control': 'public, max-age=86400'
44
+ }
45
+ });
46
+ }
47
+ catch (err) {
48
+ console.error('robots.txt handler error:', err);
49
+ return new Response(`User-agent: *\nDisallow: /\n`, {
50
+ headers: { 'Content-Type': 'text/plain; charset=utf-8' }
51
+ });
52
+ }
53
+ };
54
+ }
@@ -0,0 +1,67 @@
1
+ import type { SiteConfig } from './config';
2
+ export type SchemaType = 'WebSite' | 'Organization' | 'WebPage' | 'Article' | 'Product' | 'BreadcrumbList' | 'FAQPage';
3
+ export interface BreadcrumbItem {
4
+ name: string;
5
+ url: string;
6
+ }
7
+ export interface ArticleSchemaData {
8
+ title: string;
9
+ description: string;
10
+ url: string;
11
+ datePublished: string;
12
+ dateModified?: string;
13
+ image?: string;
14
+ authorName?: string;
15
+ }
16
+ export declare function generateWebSiteSchema(config: SiteConfig): {
17
+ author?: {
18
+ '@type': string;
19
+ name: string;
20
+ url: string | undefined;
21
+ } | undefined;
22
+ '@context': string;
23
+ '@type': string;
24
+ name: string;
25
+ url: string;
26
+ description: string;
27
+ };
28
+ export declare function generateOrganizationSchema(config: SiteConfig): {
29
+ '@context': string;
30
+ '@type': string;
31
+ name: string;
32
+ url: string;
33
+ logo: string | undefined;
34
+ sameAs: (string | undefined)[];
35
+ };
36
+ export declare function generateArticleSchema(config: SiteConfig, article: ArticleSchemaData): {
37
+ '@context': string;
38
+ '@type': string;
39
+ headline: string;
40
+ description: string;
41
+ url: string;
42
+ datePublished: string;
43
+ dateModified: string;
44
+ image: string | undefined;
45
+ author: {
46
+ '@type': string;
47
+ name: string;
48
+ };
49
+ publisher: {
50
+ '@type': string;
51
+ name: string;
52
+ logo: {
53
+ '@type': string;
54
+ url: string;
55
+ } | undefined;
56
+ };
57
+ };
58
+ export declare function generateBreadcrumbSchema(config: SiteConfig, items: BreadcrumbItem[]): {
59
+ '@context': string;
60
+ '@type': string;
61
+ itemListElement: {
62
+ '@type': string;
63
+ position: number;
64
+ name: string;
65
+ item: string;
66
+ }[];
67
+ };
@@ -0,0 +1,67 @@
1
+ export function generateWebSiteSchema(config) {
2
+ return {
3
+ '@context': 'https://schema.org',
4
+ '@type': 'WebSite',
5
+ name: config.name,
6
+ url: config.url,
7
+ description: config.description,
8
+ ...(config.author
9
+ ? {
10
+ author: {
11
+ '@type': 'Person',
12
+ name: config.author.name,
13
+ url: config.author.url
14
+ }
15
+ }
16
+ : {})
17
+ };
18
+ }
19
+ export function generateOrganizationSchema(config) {
20
+ return {
21
+ '@context': 'https://schema.org',
22
+ '@type': 'Organization',
23
+ name: config.name,
24
+ url: config.url,
25
+ logo: config.logo ? `${config.url}${config.logo}` : undefined,
26
+ sameAs: [
27
+ config.socials?.github,
28
+ config.socials?.twitter,
29
+ config.socials?.discord,
30
+ config.socials?.bluesky,
31
+ config.socials?.youtube
32
+ ].filter(Boolean)
33
+ };
34
+ }
35
+ export function generateArticleSchema(config, article) {
36
+ return {
37
+ '@context': 'https://schema.org',
38
+ '@type': 'Article',
39
+ headline: article.title,
40
+ description: article.description,
41
+ url: article.url,
42
+ datePublished: article.datePublished,
43
+ dateModified: article.dateModified || article.datePublished,
44
+ image: article.image,
45
+ author: {
46
+ '@type': 'Person',
47
+ name: article.authorName || config.author?.name || config.name
48
+ },
49
+ publisher: {
50
+ '@type': 'Organization',
51
+ name: config.name,
52
+ logo: config.logo ? { '@type': 'ImageObject', url: `${config.url}${config.logo}` } : undefined
53
+ }
54
+ };
55
+ }
56
+ export function generateBreadcrumbSchema(config, items) {
57
+ return {
58
+ '@context': 'https://schema.org',
59
+ '@type': 'BreadcrumbList',
60
+ itemListElement: items.map((item, index) => ({
61
+ '@type': 'ListItem',
62
+ position: index + 1,
63
+ name: item.name,
64
+ item: item.url.startsWith('http') ? item.url : `${config.url}${item.url}`
65
+ }))
66
+ };
67
+ }
@@ -0,0 +1,36 @@
1
+ export interface PageSeoConfig {
2
+ title: string;
3
+ description?: string;
4
+ canonical?: string;
5
+ badge?: string;
6
+ ogImage?: string | {
7
+ title?: string;
8
+ description?: string;
9
+ badge?: string;
10
+ theme?: 'dark' | 'light';
11
+ };
12
+ twitterCard?: 'summary' | 'summary_large_image' | 'app' | 'player';
13
+ keywords?: string[];
14
+ noindex?: boolean;
15
+ nofollow?: boolean;
16
+ schema?: Record<string, unknown> | Record<string, unknown>[];
17
+ }
18
+ /**
19
+ * Type-safe helper for SvelteKit load() functions to define page-level SEO.
20
+ * When returned inside { seo: definePageSeo(...) }, YaxaApp automatically
21
+ * extracts and binds all meta tags, OpenGraph cards, Twitter cards, and Schema.org data.
22
+ *
23
+ * Example:
24
+ * ```ts
25
+ * export const load = () => {
26
+ * return {
27
+ * seo: definePageSeo({
28
+ * title: 'DataTable Component',
29
+ * description: 'Interactive sortable table for SvelteKit',
30
+ * badge: 'Components'
31
+ * })
32
+ * };
33
+ * };
34
+ * ```
35
+ */
36
+ export declare function definePageSeo(seo: PageSeoConfig): PageSeoConfig;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Type-safe helper for SvelteKit load() functions to define page-level SEO.
3
+ * When returned inside { seo: definePageSeo(...) }, YaxaApp automatically
4
+ * extracts and binds all meta tags, OpenGraph cards, Twitter cards, and Schema.org data.
5
+ *
6
+ * Example:
7
+ * ```ts
8
+ * export const load = () => {
9
+ * return {
10
+ * seo: definePageSeo({
11
+ * title: 'DataTable Component',
12
+ * description: 'Interactive sortable table for SvelteKit',
13
+ * badge: 'Components'
14
+ * })
15
+ * };
16
+ * };
17
+ * ```
18
+ */
19
+ export function definePageSeo(seo) {
20
+ return seo;
21
+ }
@@ -0,0 +1,6 @@
1
+ import type { RequestHandler } from '@sveltejs/kit';
2
+ import type { SiteConfig } from './config';
3
+ export declare function generateSitemapXsl(config?: SiteConfig): string;
4
+ export declare function createSitemapXslHandler(options?: {
5
+ config?: SiteConfig;
6
+ }): RequestHandler;
@@ -0,0 +1,164 @@
1
+ export function generateSitemapXsl(config) {
2
+ const siteName = config?.name || 'Yaxa';
3
+ const primaryColor = config?.theme?.primaryColor || '#ff3e00';
4
+ return `<?xml version="1.0" encoding="UTF-8"?>
5
+ <xsl:stylesheet version="2.0"
6
+ xmlns:html="http://www.w3.org/TR/REC-html40"
7
+ xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
8
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
9
+ <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
10
+ <xsl:template match="/">
11
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
12
+ <head>
13
+ <title>XML Sitemap · ${siteName}</title>
14
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
15
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
16
+ <style type="text/css">
17
+ :root {
18
+ --primary: ${primaryColor};
19
+ }
20
+ body {
21
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
22
+ background-color: #121212;
23
+ color: #e4e4e7;
24
+ margin: 0;
25
+ padding: 32px 16px;
26
+ }
27
+ .container {
28
+ max-width: 1024px;
29
+ margin: 0 auto;
30
+ background-color: #18181b;
31
+ border: 1px solid #27272a;
32
+ border-radius: 16px;
33
+ padding: 32px;
34
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5);
35
+ }
36
+ .header {
37
+ display: flex;
38
+ align-items: center;
39
+ justify-content: space-between;
40
+ border-bottom: 1px solid #27272a;
41
+ padding-bottom: 24px;
42
+ margin-bottom: 24px;
43
+ }
44
+ .logo-area {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: 12px;
48
+ }
49
+ .badge {
50
+ background-color: rgba(255, 62, 0, 0.15);
51
+ color: var(--primary);
52
+ border: 1px solid rgba(255, 62, 0, 0.3);
53
+ border-radius: 9999px;
54
+ padding: 4px 12px;
55
+ font-size: 12px;
56
+ font-weight: 600;
57
+ }
58
+ h1 {
59
+ font-size: 24px;
60
+ font-weight: 800;
61
+ margin: 0;
62
+ color: #ffffff;
63
+ }
64
+ p {
65
+ color: #a1a1aa;
66
+ font-size: 14px;
67
+ margin: 8px 0 0 0;
68
+ }
69
+ table {
70
+ width: 100%;
71
+ border-collapse: collapse;
72
+ font-size: 13px;
73
+ }
74
+ th {
75
+ background-color: #27272a;
76
+ color: #d4d4d8;
77
+ font-weight: 600;
78
+ text-align: left;
79
+ padding: 12px 16px;
80
+ border-bottom: 1px solid #3f3f46;
81
+ }
82
+ th:first-child { border-top-left-radius: 8px; }
83
+ th:last-child { border-top-right-radius: 8px; }
84
+ td {
85
+ padding: 12px 16px;
86
+ border-bottom: 1px solid #27272a;
87
+ }
88
+ tr:hover td {
89
+ background-color: #27272a;
90
+ }
91
+ a {
92
+ color: var(--primary);
93
+ text-decoration: none;
94
+ font-weight: 500;
95
+ }
96
+ a:hover {
97
+ text-decoration: underline;
98
+ }
99
+ .footer {
100
+ margin-top: 24px;
101
+ font-size: 12px;
102
+ color: #71717a;
103
+ text-align: center;
104
+ }
105
+ </style>
106
+ </head>
107
+ <body>
108
+ <div class="container">
109
+ <div class="header">
110
+ <div>
111
+ <div class="logo-area">
112
+ <h1>${siteName} Sitemap</h1>
113
+ <span class="badge"><xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> URLs</span>
114
+ </div>
115
+ <p>Generated dynamically by Yaxa for SvelteKit 2.7+ and search crawlers.</p>
116
+ </div>
117
+ </div>
118
+ <table>
119
+ <thead>
120
+ <tr>
121
+ <th style="width: 55%;">URL Location</th>
122
+ <th style="width: 15%;">Changefreq</th>
123
+ <th style="width: 15%;">Priority</th>
124
+ <th style="width: 15%;">Last Modified</th>
125
+ </tr>
126
+ </thead>
127
+ <tbody>
128
+ <xsl:for-each select="sitemap:urlset/sitemap:url">
129
+ <tr>
130
+ <td>
131
+ <a target="_blank">
132
+ <xsl:attribute name="href">
133
+ <xsl:value-of select="sitemap:loc"/>
134
+ </xsl:attribute>
135
+ <xsl:value-of select="sitemap:loc"/>
136
+ </a>
137
+ </td>
138
+ <td><xsl:value-of select="sitemap:changefreq"/></td>
139
+ <td><xsl:value-of select="sitemap:priority"/></td>
140
+ <td><xsl:value-of select="sitemap:lastmod"/></td>
141
+ </tr>
142
+ </xsl:for-each>
143
+ </tbody>
144
+ </table>
145
+ <div class="footer">
146
+ Powered by Yaxa · SvelteKit 2.7+ · Svelte 5
147
+ </div>
148
+ </div>
149
+ </body>
150
+ </html>
151
+ </xsl:template>
152
+ </xsl:stylesheet>`;
153
+ }
154
+ export function createSitemapXslHandler(options) {
155
+ return async () => {
156
+ const xsl = generateSitemapXsl(options?.config);
157
+ return new Response(xsl, {
158
+ headers: {
159
+ 'Content-Type': 'application/xml; charset=utf-8',
160
+ 'Cache-Control': 'public, max-age=86400, s-maxage=86400'
161
+ }
162
+ });
163
+ };
164
+ }
@@ -0,0 +1,20 @@
1
+ import type { RequestHandler } from '@sveltejs/kit';
2
+ import type { SiteConfig } from './config';
3
+ export interface SitemapRoute {
4
+ loc: string;
5
+ lastmod?: string;
6
+ changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
7
+ priority?: number;
8
+ }
9
+ export interface SitemapOptions {
10
+ config: SiteConfig;
11
+ /**
12
+ * Additional static or dynamic routes to include (e.g. /blog/[slug], /products/[id])
13
+ */
14
+ dynamicRoutes?: () => Promise<SitemapRoute[]> | SitemapRoute[];
15
+ /**
16
+ * Default routes to include if not providing dynamic list
17
+ */
18
+ staticRoutes?: string[];
19
+ }
20
+ export declare function createSitemapHandler(optionsOrConfig: SiteConfig | SitemapOptions): RequestHandler;