yaxa-svelte 2.0.4 → 2.2.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 (65) hide show
  1. package/README.md +38 -3
  2. package/dist/components/blocks/FAQ.svelte.d.ts +1 -1
  3. package/dist/components/blocks/FeatureGrid.svelte.d.ts +1 -1
  4. package/dist/components/blocks/Testimonials.svelte.d.ts +1 -1
  5. package/dist/components/elements/Avatar.svelte.d.ts +7 -25
  6. package/dist/components/elements/Badge.svelte.d.ts +15 -57
  7. package/dist/components/elements/Button.svelte.d.ts +19 -77
  8. package/dist/components/elements/Carousel.svelte.d.ts +2 -54
  9. package/dist/components/elements/CodeBlock.svelte +237 -8
  10. package/dist/components/elements/CodeBlock.test.js +227 -0
  11. package/dist/components/elements/CodeDiff.svelte +14 -0
  12. package/dist/components/elements/CodeDiff.test.js +16 -0
  13. package/dist/components/elements/EmptyState.svelte.d.ts +6 -26
  14. package/dist/components/elements/Icon.svelte.d.ts +6 -22
  15. package/dist/components/elements/Kbd.svelte.d.ts +5 -19
  16. package/dist/components/elements/Progress.svelte.d.ts +9 -35
  17. package/dist/components/elements/Skeleton.svelte.d.ts +8 -32
  18. package/dist/components/elements/Terminal.svelte.d.ts +1 -1
  19. package/dist/components/elements/Timeline.svelte.d.ts +4 -16
  20. package/dist/components/elements/Tree.svelte.d.ts +3 -13
  21. package/dist/components/elements/VirtualList.svelte.d.ts +3 -13
  22. package/dist/components/forms/Combobox.svelte.d.ts +7 -29
  23. package/dist/components/forms/Input.svelte.d.ts +9 -35
  24. package/dist/components/forms/MultiSelect.svelte.d.ts +7 -29
  25. package/dist/components/forms/NumberInput.svelte.d.ts +7 -29
  26. package/dist/components/forms/Select.svelte.d.ts +7 -29
  27. package/dist/components/forms/Switch.svelte.d.ts +8 -32
  28. package/dist/components/forms/Textarea.svelte.d.ts +11 -45
  29. package/dist/components/layout/Card.svelte.d.ts +10 -42
  30. package/dist/components/layout/Container.svelte.d.ts +7 -25
  31. package/dist/components/layout/DashboardShell.svelte.d.ts +1 -31
  32. package/dist/components/layout/ResizablePanels.svelte.d.ts +1 -35
  33. package/dist/components/navigation/CommandPalette.dom.test.d.ts +1 -0
  34. package/dist/components/navigation/CommandPalette.dom.test.js +76 -0
  35. package/dist/components/navigation/Stepper.svelte.d.ts +3 -13
  36. package/dist/components/overlays/Alert.svelte.d.ts +5 -19
  37. package/dist/components/overlays/Drawer.svelte.d.ts +3 -13
  38. package/dist/components/overlays/Modal.svelte.d.ts +6 -22
  39. package/dist/components/overlays/NotificationCenter.svelte.d.ts +1 -1
  40. package/dist/components/overlays/Slideover.svelte.d.ts +5 -19
  41. package/dist/components/overlays/Toast.svelte.d.ts +12 -44
  42. package/dist/components/saas/OrgSwitcher.svelte.d.ts +1 -1
  43. package/dist/components/saas/PasskeyUI.svelte.d.ts +1 -1
  44. package/dist/server/endpoint/endpoint.test.d.ts +1 -0
  45. package/dist/server/endpoint/endpoint.test.js +364 -0
  46. package/dist/server/endpoint/guards.d.ts +52 -0
  47. package/dist/server/endpoint/guards.js +137 -0
  48. package/dist/server/endpoint/index.d.ts +14 -0
  49. package/dist/server/endpoint/index.js +238 -0
  50. package/dist/server/endpoint/problem.d.ts +26 -0
  51. package/dist/server/endpoint/problem.js +62 -0
  52. package/dist/server/endpoint/types.d.ts +144 -0
  53. package/dist/server/endpoint/types.js +1 -0
  54. package/dist/server/endpoint/validate.d.ts +21 -0
  55. package/dist/server/endpoint/validate.js +128 -0
  56. package/dist/server/index.d.ts +2 -0
  57. package/dist/server/index.js +2 -0
  58. package/dist/server/polar/index.d.ts +2 -1
  59. package/dist/server/polar/index.js +9 -8
  60. package/dist/server/polar/webhook.js +14 -11
  61. package/dist/server/polar/webhook.test.js +81 -0
  62. package/dist/testing/index.d.ts +2 -0
  63. package/dist/testing/index.js +12 -1
  64. package/dist/utils/cn.d.ts +2 -2
  65. package/package.json +11 -13
@@ -1,4 +1,4 @@
1
- import { Polar } from '@polar-sh/sdk';
1
+ import { createPolar } from '@polar-sh/sdk/2026-10';
2
2
  /**
3
3
  * Creates and initializes a Polar SDK client instance.
4
4
  */
@@ -6,13 +6,14 @@ export function getPolarClient(config = {}) {
6
6
  const accessToken = config.accessToken ||
7
7
  (typeof process !== 'undefined' ? process.env.POLAR_ACCESS_TOKEN : undefined) ||
8
8
  '';
9
- const server = config.server ||
9
+ const environment = config.environment ||
10
+ config.server ||
10
11
  (typeof process !== 'undefined' && process.env.POLAR_ENVIRONMENT === 'production'
11
12
  ? 'production'
12
13
  : 'sandbox');
13
- return new Polar({
14
+ return createPolar({
14
15
  accessToken,
15
- server
16
+ environment
16
17
  });
17
18
  }
18
19
  /**
@@ -26,8 +27,8 @@ export async function createPolarCheckout(options) {
26
27
  : 'http://localhost:5173/dashboard?checkout=success');
27
28
  const result = await polar.checkouts.create({
28
29
  products: [options.productId],
29
- customerEmail: options.customerEmail,
30
- successUrl,
30
+ customer_email: options.customerEmail,
31
+ success_url: successUrl,
31
32
  metadata: options.metadata
32
33
  });
33
34
  return {
@@ -41,10 +42,10 @@ export async function createPolarCheckout(options) {
41
42
  export async function createPolarCustomerPortalSession(customerId, polar) {
42
43
  const client = polar || getPolarClient();
43
44
  const session = await client.customerSessions.create({
44
- customerId
45
+ customer_id: customerId
45
46
  });
46
47
  return {
47
- url: session.customerPortalUrl || ''
48
+ url: session.customer_portal_url || session.customerPortalUrl || ''
48
49
  };
49
50
  }
50
51
  export { createPolarWebhookHandler } from './webhook';
@@ -1,4 +1,4 @@
1
- import { validateEvent } from '@polar-sh/sdk/webhooks';
1
+ import { webhooks } from '@polar-sh/sdk/2026-10';
2
2
  import { eq } from 'drizzle-orm';
3
3
  import { getDb, schemaPg, schemaSqlite } from '../db';
4
4
  /**
@@ -36,7 +36,7 @@ export function createPolarWebhookHandler(options = {}) {
36
36
  if (headersObj['polar-signature'] && !headersObj['webhook-signature']) {
37
37
  headersObj['webhook-signature'] = headersObj['polar-signature'];
38
38
  }
39
- payload = validateEvent(rawBody, headersObj, secret);
39
+ payload = await webhooks.validateEvent(rawBody, headersObj, secret);
40
40
  }
41
41
  catch {
42
42
  return new Response('Invalid or missing webhook signature', { status: 401 });
@@ -57,20 +57,22 @@ export function createPolarWebhookHandler(options = {}) {
57
57
  const subTable = isPg ? schemaPg.subscription : schemaSqlite.subscription;
58
58
  switch (eventType) {
59
59
  case 'subscription.created': {
60
- if (data && data.id && data.userId) {
60
+ const userId = data?.userId || data?.user_id || data?.customer_id;
61
+ if (data && data.id && userId) {
62
+ const periodEnd = data.currentPeriodEnd || data.current_period_end;
61
63
  await db
62
64
  .insert(subTable)
63
65
  .values({
64
66
  id: data.id,
65
- userId: data.userId,
67
+ userId,
66
68
  polarId: data.id,
67
69
  status: data.status || 'active',
68
- priceId: data.priceId || null,
69
- productId: data.productId || null,
70
+ priceId: data.priceId || data.price_id || null,
71
+ productId: data.productId || data.product_id || null,
70
72
  tier: data.product?.name?.toLowerCase() || 'pro',
71
- interval: data.recurringInterval || 'month',
72
- currentPeriodEnd: data.currentPeriodEnd ? new Date(data.currentPeriodEnd) : null,
73
- cancelAtPeriodEnd: data.cancelAtPeriodEnd || false,
73
+ interval: data.recurringInterval || data.recurring_interval || 'month',
74
+ currentPeriodEnd: periodEnd ? new Date(periodEnd) : null,
75
+ cancelAtPeriodEnd: data.cancelAtPeriodEnd ?? data.cancel_at_period_end ?? false,
74
76
  createdAt: new Date(),
75
77
  updatedAt: new Date()
76
78
  })
@@ -88,12 +90,13 @@ export function createPolarWebhookHandler(options = {}) {
88
90
  }
89
91
  case 'subscription.updated': {
90
92
  if (data && data.id) {
93
+ const periodEnd = data.currentPeriodEnd || data.current_period_end;
91
94
  await db
92
95
  .update(subTable)
93
96
  .set({
94
97
  status: data.status,
95
- currentPeriodEnd: data.currentPeriodEnd ? new Date(data.currentPeriodEnd) : null,
96
- cancelAtPeriodEnd: data.cancelAtPeriodEnd || false,
98
+ currentPeriodEnd: periodEnd ? new Date(periodEnd) : null,
99
+ cancelAtPeriodEnd: data.cancelAtPeriodEnd ?? data.cancel_at_period_end ?? false,
97
100
  updatedAt: new Date()
98
101
  })
99
102
  .where(eq(subTable.polarId, data.id));
@@ -1,5 +1,8 @@
1
1
  import { describe, it, expect, vi } from 'vitest';
2
+ import crypto from 'node:crypto';
2
3
  import { createPolarWebhookHandler } from './webhook';
4
+ import { getPolarClient, createPolarCheckout, createPolarCustomerPortalSession } from './index';
5
+ import { createMockPolarClient } from '../../testing/index';
3
6
  describe('createPolarWebhookHandler', () => {
4
7
  it('rejects non-POST requests with 405 Method Not Allowed', async () => {
5
8
  const handler = createPolarWebhookHandler();
@@ -50,6 +53,54 @@ describe('createPolarWebhookHandler', () => {
50
53
  expect(resForged.status).toBe(401);
51
54
  expect(await resForged.text()).toBe('Invalid or missing webhook signature');
52
55
  });
56
+ it('authenticates valid Standard Webhook signature and processes payload', async () => {
57
+ const rawKey = '01234567890123456789012345678901';
58
+ const base64Key = Buffer.from(rawKey).toString('base64');
59
+ const webhookSecret = `whsec_${base64Key}`;
60
+ const onSubscriptionCreated = vi.fn();
61
+ const mockDb = {
62
+ insert: vi.fn().mockReturnValue({
63
+ values: vi.fn().mockReturnValue({
64
+ onConflictDoUpdate: vi.fn().mockResolvedValue({})
65
+ })
66
+ })
67
+ };
68
+ const handler = createPolarWebhookHandler({
69
+ webhookSecret,
70
+ db: mockDb,
71
+ onSubscriptionCreated
72
+ });
73
+ const body = JSON.stringify({
74
+ type: 'subscription.created',
75
+ data: {
76
+ id: 'sub_test_polar_123',
77
+ user_id: 'usr_abc',
78
+ status: 'active'
79
+ }
80
+ });
81
+ const msgId = 'msg_valid_test_456';
82
+ const timestamp = Math.floor(Date.now() / 1000);
83
+ const signedPayload = `${msgId}.${timestamp}.${body}`;
84
+ const sig = crypto
85
+ .createHmac('sha256', Buffer.from(base64Key, 'base64'))
86
+ .update(signedPayload)
87
+ .digest('base64');
88
+ const response = await handler({
89
+ request: new Request('https://example.com/api/webhooks/polar', {
90
+ method: 'POST',
91
+ headers: {
92
+ 'webhook-id': msgId,
93
+ 'webhook-timestamp': `${timestamp}`,
94
+ 'webhook-signature': `v1,${sig}`
95
+ },
96
+ body
97
+ })
98
+ });
99
+ expect(response.status).toBe(200);
100
+ const json = await response.json();
101
+ expect(json).toEqual({ received: true });
102
+ expect(onSubscriptionCreated).toHaveBeenCalledOnce();
103
+ });
53
104
  it('invokes onOrderCreated callback and responds with received: true', async () => {
54
105
  const onOrderCreated = vi.fn();
55
106
  const handler = createPolarWebhookHandler({
@@ -88,3 +139,33 @@ describe('createPolarWebhookHandler', () => {
88
139
  expect(text).not.toContain('postgres://');
89
140
  });
90
141
  });
142
+ describe('Polar Server SDK Utilities', () => {
143
+ it('initializes Polar client instance via getPolarClient with sandbox / production config', () => {
144
+ const clientSandbox = getPolarClient({ accessToken: 'test_token', environment: 'sandbox' });
145
+ expect(clientSandbox).toBeDefined();
146
+ expect(clientSandbox.checkouts).toBeDefined();
147
+ expect(clientSandbox.customerSessions).toBeDefined();
148
+ const clientLegacyServer = getPolarClient({ accessToken: 'test_token', server: 'production' });
149
+ expect(clientLegacyServer).toBeDefined();
150
+ });
151
+ it('creates Polar checkout session with snake_case parameters', async () => {
152
+ const mockPolar = createMockPolarClient();
153
+ const result = await createPolarCheckout({
154
+ productId: 'prod_pro_tier_123',
155
+ customerEmail: 'dev@test.org',
156
+ metadata: { tenantId: 'tenant_789' },
157
+ polar: mockPolar
158
+ });
159
+ expect(result.id).toContain('chk_mock_');
160
+ expect(result.url).toContain('https://polar.sh/checkout/');
161
+ expect(mockPolar.createdCheckouts).toHaveLength(1);
162
+ expect(mockPolar.createdCheckouts[0].products).toEqual(['prod_pro_tier_123']);
163
+ expect(mockPolar.createdCheckouts[0].customer_email).toBe('dev@test.org');
164
+ expect(mockPolar.createdCheckouts[0].metadata).toEqual({ tenantId: 'tenant_789' });
165
+ });
166
+ it('generates Polar customer portal billing session link', async () => {
167
+ const mockPolar = createMockPolarClient();
168
+ const result = await createPolarCustomerPortalSession('cust_user_456', mockPolar);
169
+ expect(result.url).toBe('https://polar.sh/portal/mock_cust_user_456');
170
+ });
171
+ });
@@ -123,6 +123,7 @@ export declare function createMockResend(): {
123
123
  export declare function createMockPolarClient(): {
124
124
  createdCheckouts: any[];
125
125
  checkouts: {
126
+ create: (params: any) => Promise<any>;
126
127
  custom: {
127
128
  create: (params: any) => Promise<any>;
128
129
  };
@@ -131,6 +132,7 @@ export declare function createMockPolarClient(): {
131
132
  create: (params: any) => Promise<{
132
133
  id: string;
133
134
  customerPortalUrl: string;
135
+ customer_portal_url: string;
134
136
  }>;
135
137
  };
136
138
  };
@@ -191,6 +191,15 @@ export function createMockPolarClient() {
191
191
  return {
192
192
  createdCheckouts,
193
193
  checkouts: {
194
+ create: async (params) => {
195
+ const checkout = {
196
+ id: `chk_mock_${Date.now()}`,
197
+ url: `https://polar.sh/checkout/mock_${Date.now()}`,
198
+ ...params
199
+ };
200
+ createdCheckouts.push(checkout);
201
+ return checkout;
202
+ },
194
203
  custom: {
195
204
  create: async (params) => {
196
205
  const checkout = {
@@ -205,9 +214,11 @@ export function createMockPolarClient() {
205
214
  },
206
215
  customerSessions: {
207
216
  create: async (params) => {
217
+ const customerId = params.customer_id || params.customerId || 'cust_123';
208
218
  return {
209
219
  id: `cs_mock_${Date.now()}`,
210
- customerPortalUrl: `https://polar.sh/portal/mock_${params.customerId || 'cust_123'}`
220
+ customerPortalUrl: `https://polar.sh/portal/mock_${customerId}`,
221
+ customer_portal_url: `https://polar.sh/portal/mock_${customerId}`
211
222
  };
212
223
  }
213
224
  }
@@ -1,3 +1,3 @@
1
- export declare const cn: <T extends import("tailwind-variants").CnOptions>(...classnames: T) => import("tailwind-variants").CnReturn;
2
- export declare const tv: import("tailwind-variants").TV;
1
+ export declare const cn: import("tailwind-variants").CnFunction;
2
+ export declare const tv: import("tailwind-variants").TV<import("tailwind-variants").TVConfig>;
3
3
  export type { VariantProps } from 'tailwind-variants';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yaxa-svelte",
3
- "version": "2.0.4",
3
+ "version": "2.2.0",
4
4
  "description": "The Intuitive Svelte UI Library — Nuxt UI v4 equivalent for SvelteKit 2 & 3 & 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",
@@ -86,14 +86,13 @@
86
86
  "./theme.css": "./dist/styles/theme.css"
87
87
  },
88
88
  "devDependencies": {
89
- "@aws-sdk/client-s3": "^3.1146.0",
90
- "@aws-sdk/s3-request-presigner": "^3.1146.0",
89
+ "@aws-sdk/client-s3": "^3.1156.0",
90
+ "@aws-sdk/s3-request-presigner": "^3.1156.0",
91
91
  "@eslint/js": "^10.0.1",
92
92
  "@libsql/client": "^0.18.0",
93
- "@lucide/svelte": "^1.51.0",
93
+ "@lucide/svelte": "^1.61.0",
94
94
  "@neondatabase/serverless": "^1.2.0",
95
- "@playwright/test": "^1.63.0",
96
- "@polar-sh/sdk": "^0.49.0",
95
+ "@polar-sh/sdk": "^1.0.2",
97
96
  "@sveltejs/adapter-vercel": "^7.0.0",
98
97
  "@sveltejs/kit": "^3.0.0",
99
98
  "@sveltejs/package": "^3.0.0",
@@ -105,7 +104,7 @@
105
104
  "better-auth": "^1.7.7",
106
105
  "drizzle-kit": "^0.31.11",
107
106
  "drizzle-orm": "^0.45.3",
108
- "eslint": "^10.12.0",
107
+ "eslint": "^10.13.0",
109
108
  "eslint-config-prettier": "^10.1.8",
110
109
  "eslint-plugin-svelte": "^3.19.0",
111
110
  "globals": "^17.13.0",
@@ -113,21 +112,21 @@
113
112
  "prettier": "^3.9.9",
114
113
  "prettier-plugin-svelte": "^4.1.0",
115
114
  "prettier-plugin-tailwindcss": "^0.8.0",
116
- "resend": "^6.32.0",
115
+ "resend": "^6.34.1",
117
116
  "super-sitemap": "^2.0.6",
118
117
  "svelte": "^5.57.1",
119
118
  "svelte-check": "^4.7.5",
120
119
  "svelte-meta-tags": "^5.0.2",
121
120
  "tailwindcss": "^4.3.0",
122
121
  "typescript": "^6.0.3",
123
- "typescript-eslint": "^8.71.0",
122
+ "typescript-eslint": "^8.72.1",
124
123
  "vite": "^8.3.2",
125
124
  "vitest": "^5.0.3",
126
125
  "zod": "^4.6.5"
127
126
  },
128
127
  "dependencies": {
129
- "bits-ui": "^2.19.5",
130
- "tailwind-variants": "^3.3.1"
128
+ "bits-ui": "^2.20.2",
129
+ "tailwind-variants": "^4.0.1"
131
130
  },
132
131
  "peerDependencies": {
133
132
  "@aws-sdk/client-s3": ">=3.0.0",
@@ -135,7 +134,7 @@
135
134
  "@libsql/client": ">=0.18.0",
136
135
  "@lucide/svelte": "^1.0.0",
137
136
  "@neondatabase/serverless": ">=1.1.0",
138
- "@polar-sh/sdk": ">=0.49.0",
137
+ "@polar-sh/sdk": ">=1.0.0",
139
138
  "@sveltejs/kit": "^2.0.0 || ^3.0.0",
140
139
  "better-auth": ">=1.7.0",
141
140
  "drizzle-orm": ">=0.45.0",
@@ -188,7 +187,6 @@
188
187
  "lint": "prettier --check . && eslint .",
189
188
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
190
189
  "test": "vitest run",
191
- "test:e2e": "playwright test",
192
190
  "precommit": "pnpm lint && pnpm check && pnpm test && pnpm build",
193
191
  "prerelease": "pnpm precommit && pnpm package",
194
192
  "db:generate": "drizzle-kit generate",