yaxa-svelte 2.8.0 → 2.9.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.
- package/README.md +41 -29
- package/dist/components/content/Callout.svelte +182 -0
- package/dist/components/content/Callout.svelte.d.ts +39 -0
- package/dist/components/content/CodeGroup.svelte +238 -0
- package/dist/components/content/CodeGroup.svelte.d.ts +41 -0
- package/dist/components/content/Steps.svelte +146 -0
- package/dist/components/content/Steps.svelte.d.ts +39 -0
- package/dist/components/content/content.test.d.ts +1 -0
- package/dist/components/content/content.test.js +115 -0
- package/dist/components/content/index.d.ts +6 -0
- package/dist/components/content/index.js +3 -0
- package/dist/components/saas/auth-cards.test.js +9 -1
- package/dist/index.d.ts +2 -12
- package/dist/index.js +2 -7
- package/dist/root-purity.test.d.ts +1 -0
- package/dist/root-purity.test.js +102 -0
- package/dist/server/endpoint/index.js +89 -14
- package/dist/server/endpoint/types.d.ts +21 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +2 -0
- package/dist/server/observability/index.d.ts +4 -0
- package/dist/server/observability/index.js +4 -0
- package/dist/server/observability/logger.d.ts +14 -0
- package/dist/server/observability/logger.js +117 -0
- package/dist/server/observability/observability.test.d.ts +1 -0
- package/dist/server/observability/observability.test.js +159 -0
- package/dist/server/observability/timing.d.ts +6 -0
- package/dist/server/observability/timing.js +65 -0
- package/dist/server/observability/trace.d.ts +19 -0
- package/dist/server/observability/trace.js +66 -0
- package/dist/server/observability/types.d.ts +51 -0
- package/dist/server/observability/types.js +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { tv, cn, type VariantProps } from '../../utils/cn.js';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { IconSource } from '../elements/Icon.svelte';
|
|
5
|
+
|
|
6
|
+
export const stepsVariants = tv({
|
|
7
|
+
base: 'not-prose relative my-6 flex flex-col',
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
sm: 'gap-5',
|
|
11
|
+
md: 'gap-7',
|
|
12
|
+
lg: 'gap-9'
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
size: 'md'
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export interface StepGuideItem {
|
|
21
|
+
title: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
code?: string;
|
|
24
|
+
language?: string;
|
|
25
|
+
filename?: string;
|
|
26
|
+
badge?: string;
|
|
27
|
+
icon?: IconSource;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface StepsSlots {
|
|
31
|
+
root?: string;
|
|
32
|
+
item?: string;
|
|
33
|
+
indicator?: string;
|
|
34
|
+
line?: string;
|
|
35
|
+
content?: string;
|
|
36
|
+
title?: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
code?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type StepsProps = VariantProps<typeof stepsVariants> & {
|
|
42
|
+
items?: StepGuideItem[];
|
|
43
|
+
level?: 'h2' | 'h3' | 'h4';
|
|
44
|
+
class?: string;
|
|
45
|
+
ui?: StepsSlots;
|
|
46
|
+
children?: Snippet;
|
|
47
|
+
};
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<script lang="ts">
|
|
51
|
+
import CodeBlock from '../elements/CodeBlock.svelte';
|
|
52
|
+
import Badge from '../elements/Badge.svelte';
|
|
53
|
+
import Icon from '../elements/Icon.svelte';
|
|
54
|
+
|
|
55
|
+
let {
|
|
56
|
+
items = [],
|
|
57
|
+
level = 'h3',
|
|
58
|
+
size = 'md',
|
|
59
|
+
class: className = '',
|
|
60
|
+
ui,
|
|
61
|
+
children
|
|
62
|
+
}: StepsProps = $props();
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<div data-slot="root" role="list" class={cn(stepsVariants({ size, class: className }), ui?.root)}>
|
|
66
|
+
{#if items.length > 0}
|
|
67
|
+
{#each items as item, index (item.title + '-' + index)}
|
|
68
|
+
{@const isLast = index === items.length - 1}
|
|
69
|
+
<div data-slot="item" role="listitem" class={cn('relative flex gap-4', ui?.item)}>
|
|
70
|
+
<!-- Vertical Connector Line -->
|
|
71
|
+
{#if !isLast}
|
|
72
|
+
<div
|
|
73
|
+
data-slot="line"
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
class={cn(
|
|
76
|
+
'absolute top-8 -bottom-7 left-3.5 w-px bg-neutral-200 dark:bg-neutral-800',
|
|
77
|
+
ui?.line
|
|
78
|
+
)}
|
|
79
|
+
></div>
|
|
80
|
+
{/if}
|
|
81
|
+
|
|
82
|
+
<!-- Number / Icon Indicator -->
|
|
83
|
+
<div
|
|
84
|
+
data-slot="indicator"
|
|
85
|
+
class={cn(
|
|
86
|
+
'relative z-10 flex h-7 w-7 shrink-0 items-center justify-center rounded-full border border-neutral-200 bg-neutral-100 text-xs font-bold text-neutral-800 shadow-2xs dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-200',
|
|
87
|
+
ui?.indicator
|
|
88
|
+
)}
|
|
89
|
+
>
|
|
90
|
+
{#if item.icon}
|
|
91
|
+
<Icon name={item.icon} size="xs" />
|
|
92
|
+
{:else}
|
|
93
|
+
<span>{index + 1}</span>
|
|
94
|
+
{/if}
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<!-- Step Content -->
|
|
98
|
+
<div data-slot="content" class={cn('min-w-0 flex-1 space-y-2 pt-0.5', ui?.content)}>
|
|
99
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
100
|
+
<svelte:element
|
|
101
|
+
this={level}
|
|
102
|
+
data-slot="title"
|
|
103
|
+
class={cn(
|
|
104
|
+
'font-semibold tracking-tight text-neutral-900 dark:text-neutral-100',
|
|
105
|
+
size === 'sm' ? 'text-sm' : size === 'lg' ? 'text-lg' : 'text-base',
|
|
106
|
+
ui?.title
|
|
107
|
+
)}
|
|
108
|
+
>
|
|
109
|
+
{item.title}
|
|
110
|
+
</svelte:element>
|
|
111
|
+
|
|
112
|
+
{#if item.badge}
|
|
113
|
+
<Badge size="sm" variant="subtle" color="primary">{item.badge}</Badge>
|
|
114
|
+
{/if}
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
{#if item.description}
|
|
118
|
+
<p
|
|
119
|
+
data-slot="description"
|
|
120
|
+
class={cn(
|
|
121
|
+
'text-sm leading-relaxed text-neutral-600 dark:text-neutral-400',
|
|
122
|
+
ui?.description
|
|
123
|
+
)}
|
|
124
|
+
>
|
|
125
|
+
{item.description}
|
|
126
|
+
</p>
|
|
127
|
+
{/if}
|
|
128
|
+
|
|
129
|
+
{#if item.code}
|
|
130
|
+
<div data-slot="code" class={cn('pt-1', ui?.code)}>
|
|
131
|
+
<CodeBlock
|
|
132
|
+
code={item.code}
|
|
133
|
+
language={item.language ?? 'bash'}
|
|
134
|
+
filename={item.filename}
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
{/if}
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
{/each}
|
|
141
|
+
{:else if children}
|
|
142
|
+
<div class="relative border-l border-neutral-200 pl-6 dark:border-neutral-800">
|
|
143
|
+
{@render children()}
|
|
144
|
+
</div>
|
|
145
|
+
{/if}
|
|
146
|
+
</div>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type VariantProps } from '../../utils/cn.js';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { IconSource } from '../elements/Icon.svelte';
|
|
4
|
+
export declare const stepsVariants: import("tailwind-variants").TVReturnType<{
|
|
5
|
+
size: {
|
|
6
|
+
sm: string;
|
|
7
|
+
md: string;
|
|
8
|
+
lg: string;
|
|
9
|
+
};
|
|
10
|
+
}, undefined, "not-prose relative my-6 flex flex-col", undefined, undefined, undefined>;
|
|
11
|
+
export interface StepGuideItem {
|
|
12
|
+
title: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
code?: string;
|
|
15
|
+
language?: string;
|
|
16
|
+
filename?: string;
|
|
17
|
+
badge?: string;
|
|
18
|
+
icon?: IconSource;
|
|
19
|
+
}
|
|
20
|
+
export interface StepsSlots {
|
|
21
|
+
root?: string;
|
|
22
|
+
item?: string;
|
|
23
|
+
indicator?: string;
|
|
24
|
+
line?: string;
|
|
25
|
+
content?: string;
|
|
26
|
+
title?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
code?: string;
|
|
29
|
+
}
|
|
30
|
+
export type StepsProps = VariantProps<typeof stepsVariants> & {
|
|
31
|
+
items?: StepGuideItem[];
|
|
32
|
+
level?: 'h2' | 'h3' | 'h4';
|
|
33
|
+
class?: string;
|
|
34
|
+
ui?: StepsSlots;
|
|
35
|
+
children?: Snippet;
|
|
36
|
+
};
|
|
37
|
+
declare const Steps: import("svelte").Component<StepsProps, {}, "">;
|
|
38
|
+
type Steps = ReturnType<typeof Steps>;
|
|
39
|
+
export default Steps;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { flushSync } from 'svelte';
|
|
3
|
+
import { renderComponent } from '../../testing/index.js';
|
|
4
|
+
import Callout, { calloutVariants } from './Callout.svelte';
|
|
5
|
+
import CodeGroup, { codeGroupVariants } from './CodeGroup.svelte';
|
|
6
|
+
import Steps, { stepsVariants } from './Steps.svelte';
|
|
7
|
+
describe('Docs & Content Primitives (Callout, CodeGroup, Steps)', () => {
|
|
8
|
+
describe('Callout', () => {
|
|
9
|
+
it('generates semantic variant classes for note, tip, warning, and danger', () => {
|
|
10
|
+
expect(calloutVariants({ type: 'note' })).toContain('border-l-sky-500');
|
|
11
|
+
expect(calloutVariants({ type: 'tip' })).toContain('border-l-emerald-500');
|
|
12
|
+
expect(calloutVariants({ type: 'important' })).toContain('border-l-violet-500');
|
|
13
|
+
expect(calloutVariants({ type: 'warning' })).toContain('border-l-amber-500');
|
|
14
|
+
expect(calloutVariants({ type: 'danger' })).toContain('border-l-rose-500');
|
|
15
|
+
});
|
|
16
|
+
it('renders title, description, and dismisses when closable is clicked', () => {
|
|
17
|
+
let closed = false;
|
|
18
|
+
const { target, cleanup } = renderComponent(Callout, {
|
|
19
|
+
type: 'tip',
|
|
20
|
+
title: 'Performance Tip',
|
|
21
|
+
description: 'Use Svelte 5 runes for fine-grained reactivity.',
|
|
22
|
+
closable: true,
|
|
23
|
+
onclose: () => {
|
|
24
|
+
closed = true;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
expect(target.textContent).toContain('Performance Tip');
|
|
28
|
+
expect(target.textContent).toContain('Use Svelte 5 runes for fine-grained reactivity.');
|
|
29
|
+
const closeBtn = target.querySelector('[data-slot="close"]');
|
|
30
|
+
expect(closeBtn).not.toBeNull();
|
|
31
|
+
closeBtn?.click();
|
|
32
|
+
flushSync();
|
|
33
|
+
expect(closed).toBe(true);
|
|
34
|
+
expect(target.querySelector('[data-slot="root"]')).toBeNull();
|
|
35
|
+
cleanup();
|
|
36
|
+
});
|
|
37
|
+
it('renders as an anchor element when href is provided', () => {
|
|
38
|
+
const { target, cleanup } = renderComponent(Callout, {
|
|
39
|
+
type: 'important',
|
|
40
|
+
title: 'Read the Migration Guide',
|
|
41
|
+
href: '/docs/migration'
|
|
42
|
+
});
|
|
43
|
+
const root = target.querySelector('[data-slot="root"]');
|
|
44
|
+
expect(root?.tagName.toLowerCase()).toBe('a');
|
|
45
|
+
expect(root?.getAttribute('href')).toBe('/docs/migration');
|
|
46
|
+
cleanup();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('CodeGroup', () => {
|
|
50
|
+
it('generates variant classes for dark and adaptive theme modes', () => {
|
|
51
|
+
expect(codeGroupVariants({ themeMode: 'dark' })).toContain('bg-neutral-950');
|
|
52
|
+
expect(codeGroupVariants({ themeMode: 'adaptive' })).toContain('dark:bg-neutral-950');
|
|
53
|
+
});
|
|
54
|
+
it('renders tabs, displays active code, and synchronizes across instances via syncKey', () => {
|
|
55
|
+
const items = [
|
|
56
|
+
{ label: 'pnpm', code: 'pnpm add yaxa-svelte' },
|
|
57
|
+
{ label: 'npm', code: 'npm install yaxa-svelte' },
|
|
58
|
+
{ label: 'bun', code: 'bun add yaxa-svelte' }
|
|
59
|
+
];
|
|
60
|
+
const first = renderComponent(CodeGroup, {
|
|
61
|
+
items,
|
|
62
|
+
syncKey: 'test-pm-sync'
|
|
63
|
+
});
|
|
64
|
+
const second = renderComponent(CodeGroup, {
|
|
65
|
+
items,
|
|
66
|
+
syncKey: 'test-pm-sync'
|
|
67
|
+
});
|
|
68
|
+
expect(first.target.textContent).toContain('pnpm add yaxa-svelte');
|
|
69
|
+
expect(second.target.textContent).toContain('pnpm add yaxa-svelte');
|
|
70
|
+
// Click 'bun' tab on first CodeGroup
|
|
71
|
+
const tabs = first.target.querySelectorAll('[role="tab"]');
|
|
72
|
+
expect(tabs).toHaveLength(3);
|
|
73
|
+
tabs[2].click();
|
|
74
|
+
flushSync();
|
|
75
|
+
// Both first and second CodeGroup instances should now show 'bun add yaxa-svelte'
|
|
76
|
+
expect(first.target.textContent).toContain('bun add yaxa-svelte');
|
|
77
|
+
expect(second.target.textContent).toContain('bun add yaxa-svelte');
|
|
78
|
+
first.cleanup();
|
|
79
|
+
second.cleanup();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('Steps', () => {
|
|
83
|
+
it('generates size variant classes', () => {
|
|
84
|
+
expect(stepsVariants({ size: 'sm' })).toContain('gap-5');
|
|
85
|
+
expect(stepsVariants({ size: 'md' })).toContain('gap-7');
|
|
86
|
+
expect(stepsVariants({ size: 'lg' })).toContain('gap-9');
|
|
87
|
+
});
|
|
88
|
+
it('renders numbered step guide items with badges, descriptions, and code blocks', () => {
|
|
89
|
+
const items = [
|
|
90
|
+
{
|
|
91
|
+
title: 'Install Package',
|
|
92
|
+
badge: 'Required',
|
|
93
|
+
description: 'Add Yaxa to your SvelteKit project.',
|
|
94
|
+
code: 'pnpm add yaxa-svelte'
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
title: 'Configure Styles',
|
|
98
|
+
description: 'Import the Tailwind v4 stylesheet.',
|
|
99
|
+
code: "@import 'yaxa-svelte/yaxa.css';",
|
|
100
|
+
language: 'css'
|
|
101
|
+
}
|
|
102
|
+
];
|
|
103
|
+
const { target, cleanup } = renderComponent(Steps, {
|
|
104
|
+
items
|
|
105
|
+
});
|
|
106
|
+
const stepItems = target.querySelectorAll('[data-slot="item"]');
|
|
107
|
+
expect(stepItems).toHaveLength(2);
|
|
108
|
+
expect(target.textContent).toContain('Install Package');
|
|
109
|
+
expect(target.textContent).toContain('Required');
|
|
110
|
+
expect(target.textContent).toContain('Configure Styles');
|
|
111
|
+
expect(target.textContent).toContain('pnpm add yaxa-svelte');
|
|
112
|
+
cleanup();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as Callout, calloutVariants } from './Callout.svelte';
|
|
2
|
+
export type { CalloutProps, CalloutSlots, CalloutType } from './Callout.svelte';
|
|
3
|
+
export { default as CodeGroup, codeGroupVariants } from './CodeGroup.svelte';
|
|
4
|
+
export type { CodeGroupProps, CodeGroupSlots, CodeGroupItem } from './CodeGroup.svelte';
|
|
5
|
+
export { default as Steps, stepsVariants } from './Steps.svelte';
|
|
6
|
+
export type { StepsProps, StepsSlots, StepGuideItem } from './Steps.svelte';
|
|
@@ -3,13 +3,21 @@ import AuthCard from './AuthCard.svelte';
|
|
|
3
3
|
import SignInCard from './SignInCard.svelte';
|
|
4
4
|
import SignUpCard from './SignUpCard.svelte';
|
|
5
5
|
import ResetPasswordCard from './ResetPasswordCard.svelte';
|
|
6
|
+
import { AuthCard as SubpathAuthCard, SignInCard as SubpathSignInCard, SignUpCard as SubpathSignUpCard, ResetPasswordCard as SubpathResetPasswordCard, PasskeyUI, TwoFactorModal, useAuth } from '../../auth/index.js';
|
|
6
7
|
import { renderComponent } from '../../testing/index.js';
|
|
7
8
|
describe('Turnkey Auth Suite Components', () => {
|
|
8
|
-
it('exports all auth card component definitions', () => {
|
|
9
|
+
it('exports all auth card component definitions from yaxa-svelte/auth', () => {
|
|
9
10
|
expect(AuthCard).toBeDefined();
|
|
10
11
|
expect(SignInCard).toBeDefined();
|
|
11
12
|
expect(SignUpCard).toBeDefined();
|
|
12
13
|
expect(ResetPasswordCard).toBeDefined();
|
|
14
|
+
expect(SubpathAuthCard).toBeDefined();
|
|
15
|
+
expect(SubpathSignInCard).toBeDefined();
|
|
16
|
+
expect(SubpathSignUpCard).toBeDefined();
|
|
17
|
+
expect(SubpathResetPasswordCard).toBeDefined();
|
|
18
|
+
expect(PasskeyUI).toBeDefined();
|
|
19
|
+
expect(TwoFactorModal).toBeDefined();
|
|
20
|
+
expect(typeof useAuth).toBe('function');
|
|
13
21
|
});
|
|
14
22
|
it('renders SignInCard with sign-in fields and action buttons', () => {
|
|
15
23
|
const { cleanup, target } = renderComponent(SignInCard, {
|
package/dist/index.d.ts
CHANGED
|
@@ -202,18 +202,6 @@ export type { OrgSwitcherProps, OrgItem } from './components/saas/OrgSwitcher.sv
|
|
|
202
202
|
export { default as PricingCard } from './components/saas/PricingCard.svelte';
|
|
203
203
|
export { default as PricingTable } from './components/saas/PricingTable.svelte';
|
|
204
204
|
export { default as SubscriptionCard } from './components/saas/SubscriptionCard.svelte';
|
|
205
|
-
export { default as AuthCard } from './components/saas/AuthCard.svelte';
|
|
206
|
-
export type { AuthCardProps, AuthCardMode } from './components/saas/AuthCard.svelte';
|
|
207
|
-
export { default as SignInCard } from './components/saas/SignInCard.svelte';
|
|
208
|
-
export type { SignInCardProps } from './components/saas/SignInCard.svelte';
|
|
209
|
-
export { default as SignUpCard } from './components/saas/SignUpCard.svelte';
|
|
210
|
-
export type { SignUpCardProps } from './components/saas/SignUpCard.svelte';
|
|
211
|
-
export { default as ResetPasswordCard } from './components/saas/ResetPasswordCard.svelte';
|
|
212
|
-
export type { ResetPasswordCardProps } from './components/saas/ResetPasswordCard.svelte';
|
|
213
|
-
export { default as PasskeyUI } from './components/saas/PasskeyUI.svelte';
|
|
214
|
-
export { default as TwoFactorModal } from './components/saas/TwoFactorModal.svelte';
|
|
215
|
-
export { useAuth } from './composables/useAuth.svelte';
|
|
216
|
-
export type { SocialProvider } from './composables/useAuth.svelte';
|
|
217
205
|
export { useGate } from './composables/useGate.svelte';
|
|
218
206
|
export type { UseGateOptions } from './composables/useGate.svelte';
|
|
219
207
|
export { useUpload } from './composables/useUpload.svelte';
|
|
@@ -224,6 +212,8 @@ export { default as FAQ, faqVariants } from './components/blocks/FAQ.svelte';
|
|
|
224
212
|
export type { FAQProps, FAQItem } from './components/blocks/FAQ.svelte';
|
|
225
213
|
export { default as FeatureGrid, featureGridVariants } from './components/blocks/FeatureGrid.svelte';
|
|
226
214
|
export type { FeatureGridProps, FeatureItem } from './components/blocks/FeatureGrid.svelte';
|
|
215
|
+
export { Callout, calloutVariants, CodeGroup, codeGroupVariants, Steps, stepsVariants } from './components/content/index';
|
|
216
|
+
export type { CalloutProps, CalloutSlots, CalloutType, CodeGroupProps, CodeGroupSlots, CodeGroupItem, StepsProps, StepsSlots, StepGuideItem } from './components/content/index';
|
|
227
217
|
export { createMockSiteConfig, createMockUser, createTestWrapperProps } from './testing';
|
|
228
218
|
export type { YaxaTestOptions } from './testing';
|
|
229
219
|
export { createApiClient, interpolatePath, serializeQueryParams, createQuery, createMutation, QueryClient, getQueryClient, setQueryClient, hashQueryKey } from './client';
|
package/dist/index.js
CHANGED
|
@@ -134,19 +134,14 @@ export { default as OrgSwitcher, orgSwitcherVariants } from './components/saas/O
|
|
|
134
134
|
export { default as PricingCard } from './components/saas/PricingCard.svelte';
|
|
135
135
|
export { default as PricingTable } from './components/saas/PricingTable.svelte';
|
|
136
136
|
export { default as SubscriptionCard } from './components/saas/SubscriptionCard.svelte';
|
|
137
|
-
export { default as AuthCard } from './components/saas/AuthCard.svelte';
|
|
138
|
-
export { default as SignInCard } from './components/saas/SignInCard.svelte';
|
|
139
|
-
export { default as SignUpCard } from './components/saas/SignUpCard.svelte';
|
|
140
|
-
export { default as ResetPasswordCard } from './components/saas/ResetPasswordCard.svelte';
|
|
141
|
-
export { default as PasskeyUI } from './components/saas/PasskeyUI.svelte';
|
|
142
|
-
export { default as TwoFactorModal } from './components/saas/TwoFactorModal.svelte';
|
|
143
|
-
export { useAuth } from './composables/useAuth.svelte';
|
|
144
137
|
export { useGate } from './composables/useGate.svelte';
|
|
145
138
|
export { useUpload } from './composables/useUpload.svelte';
|
|
146
139
|
// Pre-Built SaaS Blocks
|
|
147
140
|
export { default as Testimonials, testimonialsVariants } from './components/blocks/Testimonials.svelte';
|
|
148
141
|
export { default as FAQ, faqVariants } from './components/blocks/FAQ.svelte';
|
|
149
142
|
export { default as FeatureGrid, featureGridVariants } from './components/blocks/FeatureGrid.svelte';
|
|
143
|
+
// Docs & Content Primitives (Prose Callouts, Synced CodeGroups & Step Guides)
|
|
144
|
+
export { Callout, calloutVariants, CodeGroup, codeGroupVariants, Steps, stepsVariants } from './components/content/index';
|
|
150
145
|
// Testing Utilities
|
|
151
146
|
export { createMockSiteConfig, createMockUser, createTestWrapperProps } from './testing';
|
|
152
147
|
// Type-Safe Client RPC & Runes Query Engine
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import * as rootExports from './index';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
describe('Root Entry Point Purity (yaxa-svelte)', () => {
|
|
6
|
+
const FORBIDDEN_EXPORTS = [
|
|
7
|
+
// Better-Auth client cards & composables (strictly yaxa-svelte/auth)
|
|
8
|
+
'useAuth',
|
|
9
|
+
'AuthCard',
|
|
10
|
+
'SignInCard',
|
|
11
|
+
'SignUpCard',
|
|
12
|
+
'ResetPasswordCard',
|
|
13
|
+
'PasskeyUI',
|
|
14
|
+
'TwoFactorModal',
|
|
15
|
+
'createYaxaAuth',
|
|
16
|
+
// Database & ORM (strictly yaxa-svelte/db)
|
|
17
|
+
'getDb',
|
|
18
|
+
'schemaPg',
|
|
19
|
+
'schemaSqlite',
|
|
20
|
+
// Server endpoints & pipeline (strictly yaxa-svelte/server)
|
|
21
|
+
'yaxaEndpoint',
|
|
22
|
+
'requireAuth',
|
|
23
|
+
'requireRole',
|
|
24
|
+
'createAiStreamHandler',
|
|
25
|
+
'createApiDocsHandler',
|
|
26
|
+
'yaxaSSE',
|
|
27
|
+
'broadcast',
|
|
28
|
+
'enqueueJob',
|
|
29
|
+
'defineWorker',
|
|
30
|
+
'createJobRunner',
|
|
31
|
+
'createRequestLogger',
|
|
32
|
+
'createServerTiming',
|
|
33
|
+
'resolveTraceContext',
|
|
34
|
+
// Admin (strictly yaxa-svelte/admin)
|
|
35
|
+
'createYaxaAdminHook',
|
|
36
|
+
'createDrizzleAdmin',
|
|
37
|
+
'AdminDashboard',
|
|
38
|
+
// Polar billing (strictly yaxa-svelte/polar)
|
|
39
|
+
'createPolarCheckout',
|
|
40
|
+
'createPolarWebhookHandler',
|
|
41
|
+
// Resend emails (strictly yaxa-svelte/email)
|
|
42
|
+
'sendMagicLinkEmail',
|
|
43
|
+
'sendWelcomeEmail',
|
|
44
|
+
// Storage uploads (strictly yaxa-svelte/storage)
|
|
45
|
+
'createPresignedUploadUrl'
|
|
46
|
+
];
|
|
47
|
+
it('must NOT export any Better-Auth, database, or server backend primitives', () => {
|
|
48
|
+
for (const name of FORBIDDEN_EXPORTS) {
|
|
49
|
+
expect(rootExports[name], `Accidental re-export of '${name}' in root 'yaxa-svelte'! Must be in appropriate subpath ('yaxa-svelte/auth', 'yaxa-svelte/server', etc.)`).toBeUndefined();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
it('src/lib/index.ts source must not reference restricted subpaths or heavy backend peer dependencies', () => {
|
|
53
|
+
const indexPath = path.resolve('src/lib/index.ts');
|
|
54
|
+
const source = fs.readFileSync(indexPath, 'utf-8');
|
|
55
|
+
const FORBIDDEN_SUBPATHS = [
|
|
56
|
+
'./auth',
|
|
57
|
+
'./server',
|
|
58
|
+
'./db',
|
|
59
|
+
'./polar',
|
|
60
|
+
'./email',
|
|
61
|
+
'./storage',
|
|
62
|
+
'./admin',
|
|
63
|
+
'better-auth',
|
|
64
|
+
'drizzle-orm',
|
|
65
|
+
'@polar-sh/sdk',
|
|
66
|
+
'resend',
|
|
67
|
+
'@aws-sdk'
|
|
68
|
+
];
|
|
69
|
+
for (const forbidden of FORBIDDEN_SUBPATHS) {
|
|
70
|
+
expect(source.includes(forbidden), `src/lib/index.ts contains forbidden reference: '${forbidden}'`).toBe(false);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
it('src/lib/index.ts must not re-export auth card components', () => {
|
|
74
|
+
const indexPath = path.resolve('src/lib/index.ts');
|
|
75
|
+
const source = fs.readFileSync(indexPath, 'utf-8');
|
|
76
|
+
const FORBIDDEN_AUTH_CARDS = [
|
|
77
|
+
'AuthCard',
|
|
78
|
+
'SignInCard',
|
|
79
|
+
'SignUpCard',
|
|
80
|
+
'ResetPasswordCard',
|
|
81
|
+
'PasskeyUI',
|
|
82
|
+
'TwoFactorModal',
|
|
83
|
+
'useAuth'
|
|
84
|
+
];
|
|
85
|
+
for (const card of FORBIDDEN_AUTH_CARDS) {
|
|
86
|
+
const regex = new RegExp(`\\b${card}\\b`);
|
|
87
|
+
expect(regex.test(source), `src/lib/index.ts contains forbidden auth component: '${card}'`).toBe(false);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
it('root entry point successfully evaluates without throwing runtime errors', () => {
|
|
91
|
+
expect(rootExports).toBeDefined();
|
|
92
|
+
expect(typeof rootExports.Button).toBe('function');
|
|
93
|
+
expect(typeof rootExports.Modal).toBe('function');
|
|
94
|
+
expect(typeof rootExports.Gate).toBe('function');
|
|
95
|
+
expect(typeof rootExports.UserMenu).toBe('function');
|
|
96
|
+
expect(typeof rootExports.useGate).toBe('function');
|
|
97
|
+
expect(typeof rootExports.useYaxa).toBe('function');
|
|
98
|
+
expect(typeof rootExports.Callout).toBe('function');
|
|
99
|
+
expect(typeof rootExports.CodeGroup).toBe('function');
|
|
100
|
+
expect(typeof rootExports.Steps).toBe('function');
|
|
101
|
+
});
|
|
102
|
+
});
|