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.
Files changed (33) hide show
  1. package/README.md +41 -29
  2. package/dist/components/content/Callout.svelte +182 -0
  3. package/dist/components/content/Callout.svelte.d.ts +39 -0
  4. package/dist/components/content/CodeGroup.svelte +238 -0
  5. package/dist/components/content/CodeGroup.svelte.d.ts +41 -0
  6. package/dist/components/content/Steps.svelte +146 -0
  7. package/dist/components/content/Steps.svelte.d.ts +39 -0
  8. package/dist/components/content/content.test.d.ts +1 -0
  9. package/dist/components/content/content.test.js +115 -0
  10. package/dist/components/content/index.d.ts +6 -0
  11. package/dist/components/content/index.js +3 -0
  12. package/dist/components/saas/auth-cards.test.js +9 -1
  13. package/dist/index.d.ts +2 -12
  14. package/dist/index.js +2 -7
  15. package/dist/root-purity.test.d.ts +1 -0
  16. package/dist/root-purity.test.js +102 -0
  17. package/dist/server/endpoint/index.js +89 -14
  18. package/dist/server/endpoint/types.d.ts +21 -0
  19. package/dist/server/index.d.ts +2 -0
  20. package/dist/server/index.js +2 -0
  21. package/dist/server/observability/index.d.ts +4 -0
  22. package/dist/server/observability/index.js +4 -0
  23. package/dist/server/observability/logger.d.ts +14 -0
  24. package/dist/server/observability/logger.js +117 -0
  25. package/dist/server/observability/observability.test.d.ts +1 -0
  26. package/dist/server/observability/observability.test.js +159 -0
  27. package/dist/server/observability/timing.d.ts +6 -0
  28. package/dist/server/observability/timing.js +65 -0
  29. package/dist/server/observability/trace.d.ts +19 -0
  30. package/dist/server/observability/trace.js +66 -0
  31. package/dist/server/observability/types.d.ts +51 -0
  32. package/dist/server/observability/types.js +1 -0
  33. 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';
@@ -0,0 +1,3 @@
1
+ export { default as Callout, calloutVariants } from './Callout.svelte';
2
+ export { default as CodeGroup, codeGroupVariants } from './CodeGroup.svelte';
3
+ export { default as Steps, stepsVariants } 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
+ });