@neondatabase/neon-js 0.1.0-beta.9 → 0.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@neondatabase/neon-js.svg)](https://www.npmjs.com/package/@neondatabase/neon-js)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@neondatabase/neon-js.svg)](https://www.npmjs.com/package/@neondatabase/neon-js)
5
5
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue.svg)](https://www.typescriptlang.org/)
6
- [![License](https://img.shields.io/npm/l/@neondatabase/neon-js.svg)](https://github.com/neondatabase-labs/neon-js/blob/main/LICENSE)
6
+ [![License](https://img.shields.io/npm/l/@neondatabase/neon-js.svg)](https://github.com/neondatabase/neon-js/blob/main/LICENSE)
7
7
 
8
8
  The official TypeScript SDK for Neon, combining authentication and database querying in a familiar interface.
9
9
 
@@ -15,6 +15,7 @@ The official TypeScript SDK for Neon, combining authentication and database quer
15
15
 
16
16
  - **Integrated Authentication** - Works out of the box with optional adapters (Supabase-compatible, React hooks)
17
17
  - **PostgreSQL Querying** - Full PostgREST client with type-safe queries
18
+ - **Anonymous Access** - Optional RLS-based data access for unauthenticated users
18
19
  - **High Performance** - Session caching, request deduplication
19
20
  - **Automatic Token Management** - Seamless token injection for database queries
20
21
  - **TypeScript First** - Fully typed with strict type checking
@@ -34,16 +35,64 @@ npm install @neondatabase/neon-js
34
35
  bun add @neondatabase/neon-js
35
36
  ```
36
37
 
38
+ ## Prerequisites
39
+
40
+ Before using neon-js, you'll need:
41
+
42
+ ### 1. A Neon Account and Project
43
+
44
+ - Sign up at [neon.tech](https://neon.tech)
45
+ - Create a new project in the Neon Console
46
+
47
+ ### 2. Enable the Data API (for database queries)
48
+
49
+ - Go to your project settings in Neon Console
50
+ - Enable the Data API feature
51
+ - Copy your Data API URL
52
+
53
+ **Data API URL format:**
54
+ ```
55
+ https://ep-xxx.apirest.c-2.us-east-2.aws.neon.build/dbname/rest/v1
56
+ ```
57
+
58
+ ### 3. Enable Neon Auth (for authentication)
59
+
60
+ - Go to your project settings in Neon Console
61
+ - Enable Neon Auth
62
+ - Copy your Auth URL
63
+
64
+ **Auth URL format:**
65
+ ```
66
+ https://ep-xxx.neonauth.c-2.us-east-2.aws.neon.build/dbname/auth
67
+ ```
68
+
69
+ ### 4. Configure Environment Variables
70
+
71
+ Create a `.env` or `.env.local` file:
72
+
73
+ ```bash
74
+ # Next.js
75
+ NEON_AUTH_BASE_URL=https://ep-xxx.neonauth.c-2.us-east-2.aws.neon.build/dbname/auth
76
+ NEXT_PUBLIC_NEON_AUTH_URL=https://ep-xxx.neonauth.c-2.us-east-2.aws.neon.build/dbname/auth
77
+ NEON_DATA_API_URL=https://ep-xxx.apirest.c-2.us-east-2.aws.neon.build/dbname/rest/v1
78
+
79
+ # Vite/React
80
+ VITE_NEON_AUTH_URL=https://ep-xxx.neonauth.c-2.us-east-2.aws.neon.build/dbname/auth
81
+ VITE_NEON_DATA_API_URL=https://ep-xxx.apirest.c-2.us-east-2.aws.neon.build/dbname/rest/v1
82
+ ```
83
+
37
84
  ## Quick Start
38
85
 
39
86
  ```typescript
40
87
  import { createClient } from '@neondatabase/neon-js';
41
88
 
42
- // Database type generated via: npx neon-js gen-types --db-url "..."
89
+ // Database type generated via: npx @neondatabase/neon-js gen-types --db-url "..."
43
90
  // See "TypeScript" section below for details
44
91
  const client = createClient<Database>({
45
92
  auth: {
46
93
  url: import.meta.env.VITE_NEON_AUTH_URL,
94
+ // Optional: allow unauthenticated users to query data via RLS
95
+ // allowAnonymous: true,
47
96
  },
48
97
  dataApi: {
49
98
  url: import.meta.env.VITE_NEON_DATA_API_URL,
@@ -74,7 +123,7 @@ Use this adapter if you're migrating from Supabase or prefer the Supabase API st
74
123
  ```typescript
75
124
  import { createClient, SupabaseAuthAdapter } from '@neondatabase/neon-js';
76
125
 
77
- // Database type generated via: npx neon-js gen-types --db-url "..."
126
+ // Database type generated via: npx @neondatabase/neon-js gen-types --db-url "..."
78
127
  // See "TypeScript" section below for details
79
128
  const client = createClient<Database>({
80
129
  auth: {
@@ -103,7 +152,7 @@ Use this adapter in React applications to get access to hooks like `useSession`:
103
152
  import { createClient } from '@neondatabase/neon-js';
104
153
  import { BetterAuthReactAdapter } from '@neondatabase/neon-js/auth/react/adapters';
105
154
 
106
- // Database type generated via: npx neon-js gen-types --db-url "..."
155
+ // Database type generated via: npx @neondatabase/neon-js gen-types --db-url "..."
107
156
  // See "TypeScript" section below for details
108
157
  const client = createClient<Database>({
109
158
  auth: {
@@ -126,6 +175,27 @@ function MyComponent() {
126
175
  }
127
176
  ```
128
177
 
178
+ ### Anonymous Access
179
+
180
+ Enable `allowAnonymous` to let unauthenticated users query data. This uses an anonymous token for RLS-based access control:
181
+
182
+ ```typescript
183
+ import { createClient } from '@neondatabase/neon-js';
184
+
185
+ const client = createClient<Database>({
186
+ auth: {
187
+ url: import.meta.env.VITE_NEON_AUTH_URL,
188
+ allowAnonymous: true, // Enable anonymous data access
189
+ },
190
+ dataApi: {
191
+ url: import.meta.env.VITE_NEON_DATA_API_URL,
192
+ },
193
+ });
194
+
195
+ // Works without signing in - uses anonymous token for RLS
196
+ const { data: publicItems } = await client.from('public_items').select();
197
+ ```
198
+
129
199
  ## Authentication
130
200
 
131
201
  ### Sign Up
@@ -293,6 +363,7 @@ const client = createClient({
293
363
  // Auth configuration
294
364
  auth: {
295
365
  url: 'https://your-auth-server.neon.tech/auth',
366
+ allowAnonymous: true, // Optional: enable anonymous data access
296
367
  },
297
368
 
298
369
  // Data API configuration
@@ -335,30 +406,72 @@ const client = createClient({
335
406
  });
336
407
  ```
337
408
 
338
- ## UI Component Styles
409
+ ## UI Components
339
410
 
340
- Styles for Neon Auth UI components are available from this package:
411
+ Pre-built login forms and auth pages are included. No extra installation needed.
341
412
 
342
- | Export | Use Case |
343
- |--------|----------|
344
- | `@neondatabase/neon-js/ui/css` | Pre-built styles (~47KB) |
345
- | `@neondatabase/neon-js/ui/tailwind` | Tailwind-ready CSS |
413
+ ### 1. Import CSS
346
414
 
347
- ```css
348
- /* Without Tailwind */
349
- @import '@neondatabase/neon-js/ui/css';
415
+ **Without Tailwind CSS:**
416
+ ```typescript
417
+ import '@neondatabase/neon-js/ui/css';
418
+ ```
350
419
 
351
- /* With Tailwind CSS v4 */
420
+ **With Tailwind CSS v4:**
421
+ ```css
352
422
  @import 'tailwindcss';
353
423
  @import '@neondatabase/neon-js/ui/tailwind';
354
424
  ```
355
425
 
426
+ ### 2. Setup Provider
427
+
428
+ ```typescript
429
+ "use client"
430
+
431
+ import { NeonAuthUIProvider } from "@neondatabase/neon-js/auth/react/ui"
432
+ import "@neondatabase/neon-js/ui/css"
433
+
434
+ export function Providers({ children }) {
435
+ return (
436
+ <NeonAuthUIProvider authClient={client.auth} redirectTo="/dashboard">
437
+ {children}
438
+ </NeonAuthUIProvider>
439
+ )
440
+ }
441
+ ```
442
+
443
+ ### 3. Use Components
444
+
445
+ **Option A: Full Auth Pages (Recommended)**
446
+
447
+ Use `AuthView` to render complete auth flows based on the URL path:
448
+
449
+ ```typescript
450
+ import { AuthView } from "@neondatabase/neon-js/auth/react/ui"
451
+
452
+ // Renders sign-in, sign-up, forgot-password, etc. based on path
453
+ <AuthView path="sign-in" />
454
+ ```
455
+
456
+ **Option B: Individual Components**
457
+
458
+ ```typescript
459
+ import { SignInForm, UserButton } from "@neondatabase/neon-js/auth/react/ui"
460
+
461
+ <SignInForm />
462
+ <UserButton />
463
+ ```
464
+
465
+ Available components: `SignInForm`, `SignUpForm`, `UserButton`, `AuthView`, `AccountView`, `OrganizationView`
466
+
467
+ For full documentation and theming, see [`@neondatabase/auth-ui`](../auth-ui).
468
+
356
469
  ## TypeScript
357
470
 
358
471
  Generate TypeScript types from your database schema:
359
472
 
360
473
  ```bash
361
- npx neon-js gen-types --db-url "postgresql://user:pass@host/db"
474
+ npx @neondatabase/neon-js gen-types --db-url "postgresql://user:pass@host/db"
362
475
  ```
363
476
 
364
477
  Use generated types for full type safety:
@@ -389,12 +502,12 @@ Generate TypeScript types from your database:
389
502
 
390
503
  ```bash
391
504
  # Generate types
392
- npx neon-js gen-types \
505
+ npx @neondatabase/neon-js gen-types \
393
506
  --db-url "postgresql://user:pass@host/db" \
394
507
  --output ./types/database.ts
395
508
 
396
509
  # With schema filtering
397
- npx neon-js gen-types \
510
+ npx @neondatabase/neon-js gen-types \
398
511
  --db-url "postgresql://user:pass@host/db" \
399
512
  --schemas public,auth \
400
513
  --output ./types/database.ts
@@ -505,42 +618,82 @@ export function useAuth() {
505
618
  }
506
619
  ```
507
620
 
508
- ## Related Packages
621
+ ## Supabase Migration Guide
509
622
 
510
- This package combines two underlying packages:
623
+ neon-js provides a Supabase-compatible API, making migration straightforward.
511
624
 
512
- - [`@neondatabase/auth`](../auth) - Authentication adapters (can be used standalone)
513
- - [`@neondatabase/postgrest-js`](../postgrest-js) - PostgreSQL client (can be used standalone)
625
+ ### 1. Update Dependencies
626
+
627
+ ```diff
628
+ - "@supabase/supabase-js": "^2.74.0"
629
+ + "@neondatabase/neon-js": "^0.1.0"
630
+ ```
631
+
632
+ ### 2. Update Environment Variables
633
+
634
+ ```diff
635
+ - VITE_SUPABASE_URL="https://xxx.supabase.co"
636
+ - VITE_SUPABASE_ANON_KEY="..."
637
+ + VITE_NEON_DATA_API_URL="https://xxx.neon.tech/neondb/rest/v1"
638
+ + VITE_NEON_AUTH_URL="https://your-auth-server.com"
639
+ ```
514
640
 
515
- ## Migration from Previous Version
641
+ ### 3. Update Client Initialization
642
+
643
+ ```diff
644
+ - import { createClient } from '@supabase/supabase-js';
645
+ + import { createClient, SupabaseAuthAdapter } from '@neondatabase/neon-js';
646
+
647
+ - export const client = createClient(
648
+ - import.meta.env.VITE_SUPABASE_URL,
649
+ - import.meta.env.VITE_SUPABASE_ANON_KEY
650
+ - );
651
+ + export const client = createClient<Database>({
652
+ + auth: {
653
+ + adapter: SupabaseAuthAdapter(), // Must call as function!
654
+ + url: import.meta.env.VITE_NEON_AUTH_URL,
655
+ + },
656
+ + dataApi: {
657
+ + url: import.meta.env.VITE_NEON_DATA_API_URL,
658
+ + },
659
+ + });
660
+ ```
661
+
662
+ ### 4. No Code Changes Needed
516
663
 
517
- If you're migrating from the old API that used `dataApiUrl` and `authUrl` directly:
664
+ All authentication methods work the same:
518
665
 
519
666
  ```typescript
520
- // Before (old API)
521
- const client = createClient({
522
- dataApiUrl: 'https://data-api.example.com/rest/v1',
523
- authUrl: 'https://auth.example.com',
524
- });
667
+ // These work identically
668
+ await client.auth.signInWithPassword({ email, password });
669
+ await client.auth.signUp({ email, password });
670
+ const { data: session } = await client.auth.getSession();
671
+ client.auth.onAuthStateChange((event, session) => { /* ... */ });
672
+ ```
525
673
 
526
- // After (new API with adapters)
527
- import { createClient, SupabaseAuthAdapter } from '@neondatabase/neon-js';
674
+ All database queries work the same:
528
675
 
529
- const client = createClient({
530
- auth: {
531
- adapter: SupabaseAuthAdapter(),
532
- url: 'https://auth.example.com',
533
- },
534
- dataApi: {
535
- url: 'https://data-api.example.com/rest/v1',
536
- },
537
- });
676
+ ```typescript
677
+ // These work identically
678
+ const { data } = await client.from('items').select();
679
+ await client.from('items').insert({ name: 'New Item' });
680
+ await client.from('items').update({ status: 'done' }).eq('id', 1);
681
+ await client.from('items').delete().eq('id', 1);
538
682
  ```
539
683
 
684
+ See the [todo-guardian-pro migration PR](https://github.com/pffigueiredo/todo-guardian-pro/pull/1) for a complete migration example.
685
+
686
+ ## Related Packages
687
+
688
+ This package combines two underlying packages:
689
+
690
+ - [`@neondatabase/auth`](../auth) - Authentication adapters (can be used standalone)
691
+ - [`@neondatabase/postgrest-js`](../postgrest-js) - PostgreSQL client (can be used standalone)
692
+
540
693
  ## Resources
541
694
 
542
- - [Neon Documentation](https://neon.tech/docs)
543
- - [Neon Auth Documentation](https://neon.tech/docs/neon-auth)
695
+ - [Neon Documentation](https://neon.com/docs)
696
+ - [Neon Auth Documentation](https://neon.com/docs/neon-auth)
544
697
  - [Better Auth Documentation](https://www.better-auth.com/docs)
545
698
  - [PostgREST Documentation](https://postgrest.org)
546
699
 
@@ -0,0 +1 @@
1
+ export * from "@neondatabase/auth/next/server";
@@ -0,0 +1,3 @@
1
+ export * from "@neondatabase/auth/next/server"
2
+
3
+ export { };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { NeonAuth, NeonAuth as NeonAuth$1, NeonAuthAdapter, NeonAuthAdapter as NeonAuthAdapter$1, NeonAuthConfig, NeonAuthPublicApi, NeonAuthPublicApi as NeonAuthPublicApi$1, ReactBetterAuthClient, VanillaBetterAuthClient } from "@neondatabase/auth";
1
+ import { NeonAuth, NeonAuth as NeonAuth$1, NeonAuthAdapter, NeonAuthAdapter as NeonAuthAdapter$1, NeonAuthConfig, NeonAuthConfig as NeonAuthConfig$1, NeonAuthPublicApi, NeonAuthPublicApi as NeonAuthPublicApi$1, ReactBetterAuthClient, VanillaBetterAuthClient } from "@neondatabase/auth";
2
2
  import { BetterAuthVanillaAdapter, BetterAuthVanillaAdapterInstance, BetterAuthVanillaAdapterInstance as BetterAuthVanillaAdapterInstance$1, BetterAuthVanillaAdapterOptions, SupabaseAuthAdapter, SupabaseAuthAdapterInstance, SupabaseAuthAdapterInstance as SupabaseAuthAdapterInstance$1, SupabaseAuthAdapterOptions } from "@neondatabase/auth/vanilla/adapters";
3
3
  import { BetterAuthReactAdapterInstance } from "@neondatabase/auth/react/adapters";
4
4
  import { AuthRequiredError, DefaultSchemaName, DefaultSchemaName as DefaultSchemaName$1, NeonPostgrestClient, NeonPostgrestClientConstructorOptions, fetchWithToken } from "@neondatabase/postgrest-js";
@@ -27,11 +27,9 @@ declare class NeonClient<Database = any, SchemaName extends string & keyof Datab
27
27
  * Auth configuration for createClient
28
28
  */
29
29
  type CreateClientAuthConfig<T extends NeonAuthAdapter$1> = {
30
- /** The adapter builder to use. Defaults to BetterAuthVanillaAdapter() if not specified. */
31
- adapter?: (url: string) => T;
32
30
  /** The auth service URL */
33
31
  url: string;
34
- };
32
+ } & NeonAuthConfig$1<T>;
35
33
  /**
36
34
  * Data API configuration for createClient
37
35
  */
@@ -101,6 +99,7 @@ type CreateClientResult<Database, TAdapter extends NeonAuthAdapter$1> = NeonClie
101
99
  declare function createClient<Database = any>(config: {
102
100
  auth: {
103
101
  url: string;
102
+ allowAnonymous?: boolean;
104
103
  };
105
104
  dataApi: CreateClientDataApiConfig<DefaultSchemaName$1<Database>, BetterAuthVanillaAdapterInstance$1>;
106
105
  }): CreateClientResult<Database, BetterAuthVanillaAdapterInstance$1>;
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createInternalNeonAuth } from "@neondatabase/auth";
2
2
  import { BetterAuthVanillaAdapter, SupabaseAuthAdapter } from "@neondatabase/auth/vanilla/adapters";
3
3
  import "@neondatabase/auth/react/adapters";
4
- import { AuthRequiredError, NeonPostgrestClient, fetchWithToken, fetchWithToken as fetchWithToken$1 } from "@neondatabase/postgrest-js";
4
+ import { AuthRequiredError, NeonPostgrestClient, X_NEON_CLIENT_INFO_HEADER, fetchWithToken, fetchWithToken as fetchWithToken$1, getClientInfo } from "@neondatabase/postgrest-js";
5
5
 
6
6
  //#region src/client/neon-client.ts
7
7
  /**
@@ -21,13 +21,30 @@ var NeonClient = class extends NeonPostgrestClient {
21
21
  }
22
22
  };
23
23
 
24
+ //#endregion
25
+ //#region package.json
26
+ var name = "@neondatabase/neon-js";
27
+ var version = "0.1.0-beta.22";
28
+
29
+ //#endregion
30
+ //#region src/utils/client-info.ts
31
+ function buildNeonJsClientInfo() {
32
+ const info = getClientInfo(name, version);
33
+ return JSON.stringify(info);
34
+ }
35
+
24
36
  //#endregion
25
37
  //#region src/client/client-factory.ts
26
38
  function createClient(config) {
27
39
  const { auth: authConfig, dataApi: dataApiConfig } = config;
28
- const auth = createInternalNeonAuth(authConfig.url, { adapter: authConfig.adapter });
40
+ const clientInfoHeader = buildNeonJsClientInfo();
41
+ const auth = createInternalNeonAuth(authConfig.url, {
42
+ adapter: authConfig.adapter,
43
+ allowAnonymous: authConfig.allowAnonymous ?? false,
44
+ fetchOptions: { headers: { [X_NEON_CLIENT_INFO_HEADER]: clientInfoHeader } }
45
+ });
29
46
  const getAccessToken = async () => {
30
- return await auth.getJWTToken();
47
+ return auth.getJWTToken();
31
48
  };
32
49
  const authFetch = fetchWithToken$1(getAccessToken, dataApiConfig.options?.global?.fetch);
33
50
  return new NeonClient({
@@ -37,7 +54,11 @@ function createClient(config) {
37
54
  ...dataApiConfig.options,
38
55
  global: {
39
56
  ...dataApiConfig.options?.global,
40
- fetch: authFetch
57
+ fetch: authFetch,
58
+ headers: {
59
+ ...dataApiConfig.options?.global?.headers,
60
+ [X_NEON_CLIENT_INFO_HEADER]: clientInfoHeader
61
+ }
41
62
  }
42
63
  }
43
64
  });
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neondatabase/neon-js",
3
- "version": "0.1.0-beta.8",
3
+ "version": "0.1.0-beta.22",
4
4
  "description": "TypeScript SDK for Neon Auth and Data API - authentication and PostgreSQL querying",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -18,13 +18,13 @@
18
18
  "supabase",
19
19
  "data-api"
20
20
  ],
21
- "homepage": "https://github.com/neondatabase-labs/neon-js/tree/main/packages/neon-js#readme",
21
+ "homepage": "https://github.com/neondatabase/neon-js/tree/main/packages/neon-js#readme",
22
22
  "bugs": {
23
- "url": "https://github.com/neondatabase-labs/neon-js/issues"
23
+ "url": "https://github.com/neondatabase/neon-js/issues"
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
27
- "url": "git+https://github.com/neondatabase-labs/neon-js.git",
27
+ "url": "git+https://github.com/neondatabase/neon-js.git",
28
28
  "directory": "packages/neon-js"
29
29
  },
30
30
  "funding": {
@@ -83,6 +83,10 @@
83
83
  "types": "./dist/auth/next/index.d.mts",
84
84
  "default": "./dist/auth/next/index.mjs"
85
85
  },
86
+ "./auth/next/server": {
87
+ "types": "./dist/auth/next/server/index.d.mts",
88
+ "default": "./dist/auth/next/server/index.mjs"
89
+ },
86
90
  "./ui/css": {
87
91
  "types": "./dist/ui/css.d.ts",
88
92
  "default": "./dist/ui/css.css"
@@ -92,7 +96,8 @@
92
96
  }
93
97
  },
94
98
  "files": [
95
- "dist"
99
+ "dist",
100
+ "llms.txt"
96
101
  ],
97
102
  "publishConfig": {
98
103
  "access": "public"
@@ -102,9 +107,9 @@
102
107
  "dev": "tsdown --watch",
103
108
  "test": "vitest",
104
109
  "test:node": "node --run test",
105
- "test:ci": "vitest run",
110
+ "test:ci": "vitest run --typecheck --passWithNoTests",
106
111
  "typecheck": "tsc --noEmit",
107
- "test:types": "tsc --noEmit",
112
+ "test:types": "vitest --typecheck.only --run",
108
113
  "release": "bun run build && bumpp --tag 'neon-js-v%s' && bun publish --tag latest",
109
114
  "lint": "eslint .",
110
115
  "clean": "rm -rf node_modules dist"
@@ -113,8 +118,8 @@
113
118
  "msw": "2.6.8"
114
119
  },
115
120
  "dependencies": {
116
- "@neondatabase/postgrest-js": "^0.1.0-alpha.1",
117
- "@neondatabase/auth": "^0.1.0-beta.9",
121
+ "@neondatabase/auth": "^0.2.0-beta.1",
122
+ "@neondatabase/postgrest-js": "^0.1.0-alpha.2",
118
123
  "@supabase/postgres-meta": "0.93.1",
119
124
  "meow": "14.0.0",
120
125
  "zod": "4.1.12"
@@ -0,0 +1,3 @@
1
+ <!-- Auto-generated safelist for better-auth-ui classes -->
2
+ <!-- This file ensures all necessary utilities are generated -->
3
+ <div class="!bg-transparent !p-2 !py-4 !py-5 !size-8 !w-auto *:[span]:last:flex *:[span]:last:gap-2 *:[span]:last:items-center *:data-[slot=alert-description]:text-destructive/90 *:data-[slot=select-value]:flex *:data-[slot=select-value]:gap-2 *:data-[slot=select-value]:items-center *:data-[slot=select-value]:line-clamp-1 -mx-1 -my-1 -my-2 @container/card-header @container/field-group @md/field-group:[&>*]:w-auto @md/field-group:[&>[data-slot=field-label]]:flex-auto @md/field-group:flex-row @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:items-center [&>*]:data-[slot=field]:p-4 [&>*]:w-full [&>.sr-only]:w-auto [&>[data-slot=field-group]]:gap-4 [&>[data-slot=field-label]]:flex-auto [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [&>svg]:size-4 [&>svg]:text-current [&>svg]:translate-y-0.5 [&_p]:leading-relaxed [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [.border-b]:pb-6 [.border-t]:pt-6 [[data-variant=legend]+&]:-mt-1.5 absolute animate-caret-blink animate-pulse animate-spin aria-invalid:border-destructive aria-invalid:ring-destructive/20 aspect-square auto-rows-min bg-accent bg-background bg-black/50 bg-border bg-card bg-destructive bg-destructive/15 bg-foreground bg-muted bg-muted/50 bg-popover bg-primary bg-secondary bg-sidebar bg-transparent block border border-b border-border border-destructive/30 border-destructive/40 border-input border-primary/20 border-r border-solid border-t border-transparent border-y break-all col-start-2 container contents cursor-default dark dark:aria-invalid:ring-destructive/40 dark:bg-destructive/60 dark:bg-input/30 dark:border-input dark:data-[active=true]:aria-invalid:ring-destructive/40 dark:data-[state=active]:bg-input/30 dark:data-[state=active]:border-input dark:data-[state=active]:text-foreground dark:data-[state=checked]:bg-primary dark:data-[variant=destructive]:focus:bg-destructive/20 dark:focus-visible:ring-destructive/40 dark:has-data-[state=checked]:bg-primary/10 dark:hover:bg-accent/50 dark:hover:bg-input/50 dark:text-muted-foreground data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 data-[active=true]:border-ring data-[active=true]:ring-[3px] data-[active=true]:ring-ring/50 data-[active=true]:z-10 data-[disabled]:opacity-50 data-[disabled]:pointer-events-none data-[error=true]:text-destructive data-[inset]:pl-8 data-[invalid=true]:text-destructive data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px data-[placeholder]:text-muted-foreground data-[side=bottom]:slide-in-from-top-2 data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1 data-[side=top]:slide-in-from-bottom-2 data-[size=default]:h-9 data-[size=sm]:h-8 data-[slot=checkbox-group]:gap-3 data-[state=active]:bg-background data-[state=active]:shadow-sm data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=checked]:text-primary-foreground data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:bg-accent data-[state=open]:fade-in-0 data-[state=open]:text-accent-foreground data-[state=open]:text-muted-foreground data-[state=open]:zoom-in-95 data-[variant=destructive]:*:[svg]:!text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:text-destructive data-[variant=label]:text-sm data-[variant=legend]:text-base data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:sm:max-w-sm data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:top-0 disabled:cursor-not-allowed disabled:opacity-50 disabled:pointer-events-none duration-1000 duration-200 field-sizing-content file:bg-transparent file:border-0 file:font-medium file:h-7 file:inline-flex file:text-foreground file:text-sm fill-current first:border-l first:rounded-l-md fixed flex flex-1 flex-col flex-col-reverse flex-row flex-shrink-0 flex-wrap focus-visible:border-ring focus-visible:outline-1 focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-destructive/20 focus-visible:ring-ring/50 focus:bg-accent focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-ring focus:text-accent-foreground font-bold font-medium font-mono font-normal font-sans font-semibold gap-0.5 gap-1 gap-1.5 gap-2 gap-3 gap-4 gap-6 gap-7 gap-y-0.5 grid grid-cols-2 grid-cols-[0_1fr] grid-rows-[auto_auto] group group-data-[disabled=true]/field:opacity-50 group-data-[disabled=true]:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[variant=outline]/field-group:-mb-2 group-data-[vaul-drawer-direction=bottom]/drawer-content:block group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center group-has-[[data-orientation=horizontal]]/field:text-balance group/drawer-content group/field group/field-group grow h-10 h-2 h-3 h-3.5 h-4 h-4.5 h-5 h-8 h-9 h-[76px] h-[calc(100%-1px)] h-[var(--radix-select-trigger-height)] h-auto h-fit h-px has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field]]:border has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:w-full has-[>[data-slot=radio-group]]:gap-3 has-[>svg]:gap-x-3 has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:px-2.5 has-[>svg]:px-3 has-[>svg]:px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary has-disabled:opacity-50 hidden hover:bg-accent hover:bg-destructive/90 hover:bg-primary/90 hover:bg-secondary/80 hover:opacity-100 hover:text-accent-foreground hover:underline inline inline-flex inset-0 invisible items-center items-start justify-between justify-center justify-items-center justify-items-start justify-self-end justify-start last:mt-0 last:rounded-r-md leading-[24px] leading-none leading-normal leading-snug leading-tight left-2 left-[50%] lg:w-60 line-clamp-1 list-disc lowercase max-h-(--radix-dropdown-menu-content-available-height) max-h-(--radix-select-content-available-height) max-w-14 max-w-32 max-w-56 max-w-64 max-w-[465px] max-w-[calc(100%-2rem)] max-w-full max-w-md max-w-sm mb-0.5 mb-3 mb-[32px] md:block md:flex-row md:gap-1.5 md:gap-12 md:gap-6 md:h-3.5 md:h-4 md:h-5.5 md:hidden md:ms-auto md:text-left md:text-sm md:text-start md:text-xl md:w-40 md:w-56 md:w-64 me-6 min-h-16 min-h-4 min-w-0 min-w-56 min-w-[8rem] min-w-[var(--radix-select-trigger-width)] ml-1 ml-4 ml-auto ms-auto mt-0.5 mt-1.5 mt-4 mt-[32px] mt-auto mx-0 mx-auto my-0 my-0.5 my-1 my-2 my-[26px] my-[30px] my-[40px] my-auto no-underline nth-last-2:-mt-1 opacity-50 opacity-70 origin-(--radix-dropdown-menu-content-transform-origin) origin-(--radix-select-content-transform-origin) outline outline-hidden outline-none overflow-hidden overflow-x-hidden overflow-y-auto p-0 p-1 p-2 p-4 p-6 p-[20px] p-[3px] pb-0 pb-4 peer peer-disabled:cursor-not-allowed peer-disabled:opacity-50 pl-2 pl-8 placeholder:text-muted-foreground pointer-events-none pr-10 pr-2 pr-8 px-0 px-2 px-3 px-4 px-5 px-6 py-1 py-1.5 py-2 py-3 py-4 py-6 relative right-0 right-2 right-4 ring-offset-background rounded rounded-[4px] rounded-b-xl rounded-full rounded-lg rounded-md rounded-sm rounded-xl rounded-xs row-span-2 row-start-1 scroll-my-1 select-none selection:bg-primary selection:text-primary-foreground self-center self-start shadow-lg shadow-md shadow-sm shadow-xs shrink-0 shrink-2 size-10 size-12 size-16 size-2 size-20 size-3 size-3.5 size-4 size-5 size-6 size-8 size-9 size-[50%] size-fit size-full sm:flex-row sm:justify-end sm:max-w-lg sm:max-w-md sm:text-left space-y-3 space-y-6 sr-only static text-2xl text-[#666666] text-[12px] text-[14px] text-[24px] text-base text-card-foreground text-center text-current text-destructive text-foreground text-foreground/70 text-left text-lg text-muted-foreground text-popover-foreground text-primary text-primary-foreground text-secondary-foreground text-sm text-start text-white text-xs top-0 top-1/2 top-4 top-[50%] tracking-tight tracking-widest transform transition-[color,box-shadow] transition-all transition-none transition-opacity transition-shadow translate-x-[-50%] translate-y-[-50%] truncate underline underline-offset-4 uppercase visible w-1/3 w-12 w-14 w-16 w-2/3 w-24 w-28 w-32 w-40 w-48 w-9 w-[--radix-dropdown-menu-trigger-width] w-[--radix-select-trigger-width] w-[100px] w-[302px] w-fit w-full w-px whitespace-nowrap z-50"></div>