From 858a354923114aa3ae1ebc4c22e44cb43cee6343 Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 4 Apr 2025 13:11:17 -0400 Subject: [PATCH 1/5] chore: Connect Backend API Client --- packages/backend/package.json | 1 + pnpm-lock.yaml | 80 ++++++++++++++++++++++++++++++++++- pnpm-workspace.yaml | 1 - 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 9d88dc880b8..73f31040248 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -107,6 +107,7 @@ "test:watch:cloudflare-miniflare": "vitest watch --environment miniflare" }, "dependencies": { + "@clerk/backend-api-client": "workspace:^", "@clerk/shared": "workspace:^", "@clerk/types": "workspace:^", "cookie": "1.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 66b5d9da750..3323f160e1d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -357,6 +357,9 @@ importers: packages/backend: dependencies: + '@clerk/backend-api-client': + specifier: workspace:^ + version: link:../backend-api-client '@clerk/shared': specifier: workspace:^ version: link:../shared @@ -389,6 +392,30 @@ importers: specifier: 2.14.4 version: 2.14.4(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + packages/backend-api-client: + devDependencies: + '@eslint/js': + specifier: ^9.19.0 + version: 9.23.0 + eslint: + specifier: ^9.19.0 + version: 9.23.0(jiti@2.4.2) + globals: + specifier: ^15.14.0 + version: 15.15.0 + tshy: + specifier: ^2.0.0 + version: 2.0.1 + typescript: + specifier: ^5.4.5 + version: 5.8.2 + typescript-eslint: + specifier: ^8.22.0 + version: 8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + zod: + specifier: ^3.23.4 + version: 3.24.2 + packages/chrome-extension: dependencies: '@clerk/clerk-js': @@ -2966,7 +2993,7 @@ packages: '@expo/bunyan@4.0.1': resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==} - engines: {node: '>=0.10.0'} + engines: {'0': node >=0.10.0} '@expo/cli@0.22.22': resolution: {integrity: sha512-sOttVuk/8gdnsiSeDpnRNpLgBJHLbyQQC0QBGd2iHpr/x6xSYpgoRO6AqwAwGtQsk4ZEPZ83ulvccei1IIPdwg==} @@ -11391,6 +11418,10 @@ packages: resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} engines: {node: '>=4.0.0'} + polite-json@5.0.0: + resolution: {integrity: sha512-OLS/0XeUAcE8a2fdwemNja+udKgXNnY6yKVIXqAD2zVRx1KvY6Ato/rZ2vdzbxqYwPW0u6SCNC/bAMPNzpzxbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + portfinder@1.0.32: resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} engines: {node: '>= 0.12.0'} @@ -12152,6 +12183,10 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve-import@1.4.6: + resolution: {integrity: sha512-CIw9e64QcKcCFUj9+KxUCJPy8hYofv6eVfo3U9wdhCm2E4IjvFnZ6G4/yIC4yP3f11+h6uU5b3LdS7O64LgqrA==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -13002,6 +13037,11 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + sync-content@1.0.2: + resolution: {integrity: sha512-znd3rYiiSxU3WteWyS9a6FXkTA/Wjk8WQsOyzHbineeL837dLn3DA4MRhsIX3qGcxDMH6+uuFV4axztssk7wEQ==} + engines: {node: '>=14'} + hasBin: true + synckit@0.9.2: resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -13314,6 +13354,11 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tshy@2.0.1: + resolution: {integrity: sha512-U5fC+3pMaGfmULhPTVpxKMd62AcX13yfsFrjhAP/daTLG6LFRLIuxqYOmkejJ4MT/s5bEa29+1Jy/9mXkMiMfA==} + engines: {node: 16 >=16.17 || 18 >=18.15.0 || >=20.6.1} + hasBin: true + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -14124,6 +14169,9 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -28006,6 +28054,8 @@ snapshots: pngjs@3.4.0: {} + polite-json@5.0.0: {} + portfinder@1.0.32: dependencies: async: 2.6.4 @@ -28794,6 +28844,11 @@ snapshots: resolve-from@5.0.0: {} + resolve-import@1.4.6: + dependencies: + glob: 10.4.5 + walk-up-path: 3.0.1 + resolve-pkg-maps@1.0.0: {} resolve-workspace-root@2.0.0: {} @@ -29833,6 +29888,13 @@ snapshots: symbol-tree@3.2.4: {} + sync-content@1.0.2: + dependencies: + glob: 10.4.5 + mkdirp: 3.0.1 + path-scurry: 1.11.1 + rimraf: 5.0.10 + synckit@0.9.2: dependencies: '@pkgr/core': 0.1.1 @@ -30124,6 +30186,20 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tshy@2.0.1: + dependencies: + chalk: 5.4.1 + chokidar: 3.6.0 + foreground-child: 3.1.1 + minimatch: 9.0.5 + mkdirp: 3.0.1 + polite-json: 5.0.0 + resolve-import: 1.4.6 + rimraf: 5.0.10 + sync-content: 1.0.2 + typescript: 5.8.2 + walk-up-path: 3.0.1 + tslib@2.8.1: {} tsscmp@1.0.6: {} @@ -31069,6 +31145,8 @@ snapshots: xml-name-validator: 5.0.0 optional: true + walk-up-path@3.0.1: {} + walker@1.0.8: dependencies: makeerror: 1.0.12 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3ac74504600..cf4af27650f 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,6 +1,5 @@ packages: - 'packages/*' - - '!packages/backend-api-client' catalogs: # Can be referenced through "catalog:react" From bf6f78ca49cfa1ae76d38ea93b13266b37d12c3c Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 4 Apr 2025 13:20:54 -0400 Subject: [PATCH 2/5] feat: Implement factory function --- packages/backend/src/api/factory.ts | 13 +++++++++++++ packages/backend/src/index.ts | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/api/factory.ts b/packages/backend/src/api/factory.ts index 47098188dbe..efce5638d7d 100644 --- a/packages/backend/src/api/factory.ts +++ b/packages/backend/src/api/factory.ts @@ -1,3 +1,6 @@ +import { ClerkBackendApi } from '@clerk/backend-api-client'; +import { joinPaths } from 'src/util/path'; + import { AccountlessApplicationAPI, AllowlistIdentifierAPI, @@ -42,3 +45,13 @@ export function createBackendApiClient(options: CreateBackendApiOptions) { testingTokens: new TestingTokenAPI(request), }; } + +export function createGeneratedBackendApiClient(options: CreateBackendApiOptions) { + const serverURL = options.apiUrl ? joinPaths(options.apiUrl, options.apiVersion || 'v1') : undefined; + + // TODO: Add dynamic user agent + return new ClerkBackendApi({ + bearerAuth: options.secretKey, + serverURL, + }); +} diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index c9e3e8cd224..4662e5d2f69 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -1,9 +1,10 @@ +import type { ClerkBackendApi } from '@clerk/backend-api-client'; import type { TelemetryCollectorOptions } from '@clerk/shared/telemetry'; import { TelemetryCollector } from '@clerk/shared/telemetry'; import type { SDKMetadata } from '@clerk/types'; import type { ApiClient, CreateBackendApiOptions } from './api'; -import { createBackendApiClient } from './api'; +import { createBackendApiClient, createGeneratedBackendApiClient } from './api'; import { withLegacyReturn } from './jwt/legacyReturn'; import type { CreateAuthenticateRequestOptions } from './tokens/factory'; import { createAuthenticateRequest } from './tokens/factory'; @@ -23,12 +24,14 @@ export type ClerkOptions = CreateBackendApiOptions & // TS4023: Exported variable 'clerkClient' has or is using name 'AuthErrorReason' from external module "/packages/backend/dist/index" but cannot be named. export type ClerkClient = { telemetry: TelemetryCollector; + api: ClerkBackendApi; } & ApiClient & ReturnType; export function createClerkClient(options: ClerkOptions): ClerkClient { const opts = { ...options }; const apiClient = createBackendApiClient(opts); + const backendApiClient = createGeneratedBackendApiClient(opts); const requestState = createAuthenticateRequest({ options: opts, apiClient }); const telemetry = new TelemetryCollector({ ...options.telemetry, @@ -40,6 +43,7 @@ export function createClerkClient(options: ClerkOptions): ClerkClient { return { ...apiClient, + api: backendApiClient, ...requestState, telemetry, }; From d90210af3ef6156afb75dbf5e086b15db32bbe3a Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 4 Apr 2025 13:41:17 -0400 Subject: [PATCH 3/5] test(backend): Add factory tests for generated API client --- packages/backend-api-client/package.json | 87 +++- .../backend-api-client/src/hooks/clerk.ts | 2 +- .../backend/src/api/__tests__/factory.test.ts | 370 ++++++++++++++- pnpm-lock.yaml | 441 ++++++++++++------ 4 files changed, 753 insertions(+), 147 deletions(-) diff --git a/packages/backend-api-client/package.json b/packages/backend-api-client/package.json index 1ff2aa7f6c1..480f4e520d5 100644 --- a/packages/backend-api-client/package.json +++ b/packages/backend-api-client/package.json @@ -36,7 +36,88 @@ "typescript-eslint": "^8.22.0", "zod": "^3.23.4" }, - "dependencies": { - - } + "dependencies": {}, + "exports": { + ".": { + "import": { + "@clerk/backend-api-client/source": "./src/index.ts", + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + }, + "./package.json": "./package.json", + "./types": { + "import": { + "@clerk/backend-api-client/source": "./src/types/index.ts", + "types": "./dist/esm/types/index.d.ts", + "default": "./dist/esm/types/index.js" + }, + "require": { + "types": "./dist/commonjs/types/index.d.ts", + "default": "./dist/commonjs/types/index.js" + } + }, + "./models/errors": { + "import": { + "@clerk/backend-api-client/source": "./src/models/errors/index.ts", + "types": "./dist/esm/models/errors/index.d.ts", + "default": "./dist/esm/models/errors/index.js" + }, + "require": { + "types": "./dist/commonjs/models/errors/index.d.ts", + "default": "./dist/commonjs/models/errors/index.js" + } + }, + "./models/components": { + "import": { + "@clerk/backend-api-client/source": "./src/models/components/index.ts", + "types": "./dist/esm/models/components/index.d.ts", + "default": "./dist/esm/models/components/index.js" + }, + "require": { + "types": "./dist/commonjs/models/components/index.d.ts", + "default": "./dist/commonjs/models/components/index.js" + } + }, + "./models/operations": { + "import": { + "@clerk/backend-api-client/source": "./src/models/operations/index.ts", + "types": "./dist/esm/models/operations/index.d.ts", + "default": "./dist/esm/models/operations/index.js" + }, + "require": { + "types": "./dist/commonjs/models/operations/index.d.ts", + "default": "./dist/commonjs/models/operations/index.js" + } + }, + "./*.js": { + "import": { + "@clerk/backend-api-client/source": "./src/*.ts", + "types": "./dist/esm/*.d.ts", + "default": "./dist/esm/*.js" + }, + "require": { + "types": "./dist/commonjs/*.d.ts", + "default": "./dist/commonjs/*.js" + } + }, + "./*": { + "import": { + "@clerk/backend-api-client/source": "./src/*.ts", + "types": "./dist/esm/*.d.ts", + "default": "./dist/esm/*.js" + }, + "require": { + "types": "./dist/commonjs/*.d.ts", + "default": "./dist/commonjs/*.js" + } + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js" } diff --git a/packages/backend-api-client/src/hooks/clerk.ts b/packages/backend-api-client/src/hooks/clerk.ts index 165bd36e1dd..3c5195c67dd 100644 --- a/packages/backend-api-client/src/hooks/clerk.ts +++ b/packages/backend-api-client/src/hooks/clerk.ts @@ -6,7 +6,7 @@ import { } from './types.js'; export const SUPPORTED_BAPI_VERSION = '2024-10-01'; -export const USER_AGENT = '@clerk/backend-api-client@0.0.0-test'; // TODO: Replace with the actual user agent: `${PACKAGE_NAME}@${PACKAGE_VERSION}` +export const USER_AGENT = '@clerk/backend@0.0.0-test'; // TODO: Replace with the actual user agent: `${PACKAGE_NAME}@${PACKAGE_VERSION}` const SKIP_SECRET_KEY_OPERATION_IDS = new Set([ 'CreateAccountlessApplication', diff --git a/packages/backend/src/api/__tests__/factory.test.ts b/packages/backend/src/api/__tests__/factory.test.ts index f722c890f94..9133cb743b5 100644 --- a/packages/backend/src/api/__tests__/factory.test.ts +++ b/packages/backend/src/api/__tests__/factory.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest'; import userJson from '../../fixtures/user.json'; import { server, validateHeaders } from '../../mock-server'; -import { createBackendApiClient } from '../factory'; +import { createBackendApiClient, createGeneratedBackendApiClient } from '../factory'; describe('api.client', () => { const apiClient = createBackendApiClient({ @@ -276,3 +276,371 @@ describe('api.client', () => { expect(data[0].scopes).toEqual(['email', 'profile']); }); }); + +// import { http, HttpResponse } from 'msw'; +// import { describe, expect, it } from 'vitest'; + +// import userJson from '../../fixtures/user.json'; +// import { server, validateHeaders } from '../../mock-server'; +// import { createBackendApiClient } from '../factory'; + +describe('api.client (generated)', () => { + const apiClient = createGeneratedBackendApiClient({ + apiUrl: 'https://api.clerk.test', + apiVersion: 'v1', + secretKey: 'deadbeef', + }); + + it('executes a successful backend API request for a single resource and parses the response', async () => { + server.use( + http.get( + `https://api.clerk.test/v1/users/:userId`, + validateHeaders(() => HttpResponse.json(userJson)), + ), + ); + + const res = await apiClient.users.get('user_deadbeef'); + + expect(res.firstName).toBe('John'); + expect(res.lastName).toBe('Doe'); + expect(res.emailAddresses?.[0].emailAddress).toBe('john.doe@clerk.test'); + expect(res.phoneNumbers?.[0].phoneNumber).toBe('+311-555-2368'); + expect(res.externalAccounts?.[0].emailAddress).toBe('john.doe@clerk.test'); + expect(res.publicMetadata?.zodiac_sign).toBe('leo'); + }); + + it('executes a successful backend API request and extends getters off user model', async () => { + server.use( + http.get( + `https://api.clerk.test/v1/users/:userId`, + validateHeaders(() => HttpResponse.json(userJson)), + ), + ); + + const res = await apiClient.users.get('user_deadbeef'); + + // fullName + expect(res.firstName).toBe('John'); + expect(res.lastName).toBe('Doe'); + expect(res.fullName).toBe('John Doe'); + + // primaryEmailAddress + expect(res.emailAddresses?.[0].emailAddress).toBe('john.doe@clerk.test'); + expect(res.primaryEmailAddress?.emailAddress).toBe('john.doe@clerk.test'); + + // primaryPhoneNumber + expect(res.phoneNumbers?.[0].phoneNumber).toBe('+311-555-2368'); + expect(res.primaryPhoneNumber?.phoneNumber).toBe('+311-555-2368'); + + // primaryWeb3Wallet + expect(res.web3Wallets?.[0].web3Wallet).toBe('0x0000000000000000000000000000000000000000'); + expect(res.primaryWeb3Wallet?.web3Wallet).toBe('0x0000000000000000000000000000000000000000'); + }); + + it('executes 2 backend API request for users.list() / users.count()', async () => { + server.use( + http.get( + `https://api.clerk.test/v1/users`, + validateHeaders(() => HttpResponse.json([userJson])), + ), + http.get( + `https://api.clerk.test/v1/users/count`, + validateHeaders(() => HttpResponse.json({ object: 'total_count', total_count: 2 })), + ), + ); + + const res = await apiClient.users.list({ + offset: 2, + limit: 5, + userId: ['user_cafebabe'], + }); + + expect(res[0].firstName).toBe('John'); + expect(res[0].id).toBe('user_cafebabe'); + expect(res.length).toBe(1); + + const resCount = await apiClient.users.count({ + userId: ['user_cafebabe'], + }); + + expect(resCount.object).toBe('total_count'); + expect(resCount.totalCount).toBe(2); + }); + + it('executes a successful backend API request for a paginated response', async () => { + const userId = 'user_123'; + + server.use( + http.get( + `https://api.clerk.test/v1/users/:userId/organization_memberships`, + validateHeaders(() => { + return HttpResponse.json({ + data: [ + { + object: 'organization_membership', + id: '1', + role: 'member', + role_name: 'Member', + permissions: ['read'], + public_metadata: {}, + organization: { + object: 'organization', + id: 'org_123', + name: 'Test Organization', + public_metadata: {}, + private_metadata: {}, + slug: 'test-organization', + members_count: 1, + missing_member_with_elevated_permissions: false, + pending_invitations_count: 0, + max_allowed_memberships: 1, + admin_delete_enabled: false, + created_at: 1742849028, + updated_at: 1742849029, + }, + created_at: 1742849026, + updated_at: 1742849027, + }, + ], + total_count: 3, + }); + }), + ), + ); + + const res = await apiClient.users.getOrganizationMemberships({ + offset: 2, + limit: 3, + userId, + }); + + expect(res.data[0].id).toBe('1'); + expect(res.totalCount).toBe(3); + expect(res.data.length).toBe(1); + }); + + it('executes a successful backend API request to create a new resource', async () => { + server.use(http.post('https://api.clerk.test/v1/users', () => HttpResponse.json(userJson))); + + const res = await apiClient.users.create({ + externalId: 'user_123', + firstName: 'John', + lastName: 'Doe', + publicMetadata: { + zodiac_sign: 'Leon', + }, + }); + + expect(res.firstName).toBe('John'); + expect(res.lastName).toBe('Doe'); + expect(res.publicMetadata?.zodiac_sign).toBe('leo'); + }); + + it('executes a failed backend API request and parses the error response', async () => { + const mockErrorPayload = { + code: 'whatever_error', + message: 'whatever error', + long_message: 'some long message', + meta: { param_name: 'some param' }, + }; + const traceId = 'trace_id_123'; + + server.use( + http.get( + `https://api.clerk.test/v1/users/user_deadbeef`, + validateHeaders(() => { + return HttpResponse.json( + { errors: [mockErrorPayload], clerk_trace_id: traceId }, + { status: 422, headers: { 'cf-ray': traceId } }, + ); + }), + ), + ); + + const res = await apiClient.users.get('user_deadbeef', { retries: { strategy: 'none' } }).catch(err => err); + + expect(res.cause.clerkTraceId).toBe(traceId); + expect(res.cause.status).toBe(422); + + // TODO: Parse the error response in the SDK + // expect(res.response.errors[0].code).toBe('whatever_error'); + // expect(res.response.errors[0].message).toBe('whatever error'); + // expect(res.response.errors[0].longMessage).toBe('some long message'); + // expect(res.response.errors[0].meta.paramName).toBe('some param'); + }); + + it('executes a failed backend API request and include cf ray id when trace not present', async () => { + server.use( + http.get( + 'https://api.clerk.test/v1/users/:userId', + validateHeaders(() => HttpResponse.json({ errors: [] }, { status: 500, headers: { 'cf-ray': 'mock_cf_ray' } })), + ), + ); + + const res = await apiClient.users.get('user_123', { retries: { strategy: 'none' } }).catch(err => err); + + expect(res.cause.status).toBe(500); + expect(res.cause.clerkTraceId).toBe('mock_cf_ray'); + }); + + it.skip('retries a failed backend API request', async () => { + server.use( + http.get( + 'https://api.clerk.test/v1/users/:userId', + validateHeaders(() => { + return HttpResponse.json({ errors: [] }, { status: 500, headers: { 'cf-ray': 'mock_cf_ray' } }); + }), + { once: true }, + ), + http.get( + 'https://api.clerk.test/v1/users/:userId', + validateHeaders(() => HttpResponse.json(userJson)), + ), + ); + + const _res = await apiClient.users + .get('user_123', { + retries: { + strategy: 'backoff', + backoff: { + initialInterval: 50, + maxInterval: 100, + exponent: 0.1, + maxElapsedTime: 1000, + }, + retryConnectionErrors: false, + }, + }) + .catch(err => err); + + // try { + // const res = await apiClient.users.get( + // { userId: 'user_123' }, + // { retries: { + // strategy: "backoff", + // backoff: { + // initialInterval: 50, + // maxInterval: 100, + // exponent: 0.1, + // maxElapsedTime: 1000, + // }, + // retryConnectionErrors: false + // } + // }); + + // expect(res.id).toBe('user_123'); + // } catch (_) { + // throw new Error('Retries are not working'); + // } + }); + + it('executes a failed backend API request and includes Retry-After header', async () => { + server.use( + http.get( + `https://api.clerk.test/v1/users/user_deadbeef`, + validateHeaders(() => { + return HttpResponse.json({ errors: [] }, { status: 429, headers: { 'retry-after': '123' } }); + }), + ), + ); + + const errResponse = await apiClient.users.get('user_deadbeef').catch(err => err.cause); + + expect(errResponse.status).toBe(429); + expect(errResponse.retryAfter).toBe(123); + }); + + it('executes a failed backend API request and ignores invalid Retry-After header', async () => { + server.use( + http.get( + `https://api.clerk.test/v1/users/user_deadbeef`, + validateHeaders(() => { + return HttpResponse.json({ errors: [] }, { status: 429, headers: { 'retry-after': 'abc' } }); + }), + ), + ); + + const errResponse = await apiClient.users.get('user_deadbeef').catch(err => err.cause); + + expect(errResponse.status).toBe(429); + expect(errResponse.retryAfter).toBe(undefined); + }); + + it('executes a successful backend API request to delete a domain', async () => { + const domainId = 'dmn_123'; + + server.use( + http.delete( + `https://api.clerk.test/v1/domains/:domainId`, + validateHeaders(() => { + return HttpResponse.json({ + object: 'domain', + id: domainId, + deleted: true, + }); + }), + ), + ); + + const res = await apiClient.domains.delete(domainId); + + expect(res.object).toBe('domain'); + expect(res.id).toBe(domainId); + expect(res.deleted).toBe(true); + }); + + it('successfully retrieves user access tokens from backend API for a specific provider (with prefix)', async () => { + const userId = 'user_deadbeef'; + const provider = 'oauth_google'; + + server.use( + http.get( + 'https://api.clerk.test/v1/users/:userId/oauth_access_tokens/:provider', + validateHeaders(({ request }) => { + const paginated = new URL(request.url).searchParams.get('paginated'); + + if (!paginated) { + return new HttpResponse(null, { status: 404 }); + } + + return HttpResponse.json([ + { + object: 'oauth_access_token', + external_account_id: 'eac_2dYS7stz9bgxQsSRvNqEAHhuxvW', + provider_user_id: 'foo', + token: '', + provider: 'oauth_google', + public_metadata: {}, + label: null, + scopes: ['email', 'profile'], + expires_at: 1742849028, + }, + ]); + + // TODO: Doesn't return total_count + // return HttpResponse.json({ + // data: [ + // { + // external_account_id: 'eac_2dYS7stz9bgxQsSRvNqEAHhuxvW', + // object: 'oauth_access_token', + // token: '', + // provider: 'oauth_google', + // public_metadata: {}, + // label: null, + // scopes: ['email', 'profile'], + // }, + // ], + // total_count: 1, + // }); + }), + ), + ); + + const res = await apiClient.users.getOAuthAccessToken({ userId, provider, paginated: true }); + + expect(res[0].externalAccountId).toBe('eac_2dYS7stz9bgxQsSRvNqEAHhuxvW'); + expect(res[0].provider).toBe('oauth_google'); + expect(res[0].token).toBe(''); + expect(res[0].scopes).toEqual(['email', 'profile']); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3323f160e1d..76d3ea71dac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,7 +102,7 @@ importers: version: 10.1.0 '@testing-library/jest-dom': specifier: ^6.4.6 - version: 6.4.6(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.13.14)(typescript@5.8.2)))(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + version: 6.4.6(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.13.14)(typescript@5.8.2)))(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@testing-library/react': specifier: ^16.0.0 version: 16.0.0(@testing-library/dom@10.1.0)(@types/react-dom@18.3.5(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -126,7 +126,7 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitest/coverage-v8': specifier: 3.0.2 - version: 3.0.2(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + version: 3.0.2(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) chalk: specifier: 4.1.2 version: 4.1.2 @@ -294,7 +294,7 @@ importers: version: 5.33.0(typanion@3.14.0) vitest: specifier: 3.0.5 - version: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + version: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) yalc: specifier: 1.0.0-pre.53 version: 1.0.0-pre.53(patch_hash=nepk7g7jbppq422nppscin4xqm) @@ -353,7 +353,7 @@ importers: devDependencies: astro: specifier: ^5.5.5 - version: 5.5.5(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(rollup@4.36.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) + version: 5.5.5(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(rollup@4.36.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) packages/backend: dependencies: @@ -390,7 +390,7 @@ importers: version: 1.62.0 vitest-environment-miniflare: specifier: 2.14.4 - version: 2.14.4(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + version: 2.14.4(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) packages/backend-api-client: devDependencies: @@ -798,7 +798,7 @@ importers: devDependencies: nuxt: specifier: ^3.16.1 - version: 3.16.1(@parcel/watcher@2.5.1)(@types/node@22.13.14)(db0@0.3.1)(eslint@9.23.0(jiti@2.4.2))(ioredis@5.6.0)(lightningcss@1.27.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.36.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2))(yaml@2.7.0) + version: 3.16.1(@parcel/watcher@2.5.1)(@types/node@22.14.0)(db0@0.3.1)(eslint@9.23.0(jiti@2.4.2))(ioredis@5.6.0)(lightningcss@1.27.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.36.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2))(yaml@2.7.0) typescript: specifier: catalog:repo version: 5.8.2 @@ -977,7 +977,7 @@ importers: version: 1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-start': specifier: ^1.114.29 - version: 1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))(yaml@2.7.0) + version: 1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))(yaml@2.7.0) esbuild-plugin-file-path-extensions: specifier: ^2.1.4 version: 2.1.4 @@ -1100,13 +1100,13 @@ importers: version: 8.1.0(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.2)) '@vitejs/plugin-vue': specifier: ^5.2.3 - version: 5.2.3(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + version: 5.2.3(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) '@vue.ts/tsx-auto-props': specifier: ^0.6.0 version: 0.6.0(rollup@4.36.0)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)) unplugin-vue: specifier: ^5.2.1 - version: 5.2.1(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0) + version: 5.2.1(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0) vue: specifier: 3.5.13 version: 3.5.13(typescript@5.8.2) @@ -1193,6 +1193,9 @@ packages: resolution: {integrity: sha512-Izvir8iIoU+X4SKtDAa5kpb+9cpifclzsbA8x/AZY0k0gIfXYQ1fa1B6Epfe6vNA2YfDX8VtrZFgvnXB6aPEoQ==} engines: {node: '>=18'} + '@asamuzakjp/css-color@3.1.1': + resolution: {integrity: sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA==} + '@astrojs/compiler@2.11.0': resolution: {integrity: sha512-zZOO7i+JhojO8qmlyR/URui6LyfHJY6m+L9nwyX5GiKD78YoRaZ5tzz6X0fkl+5bD3uwlDHayf6Oe8Fu36RKNg==} @@ -2129,6 +2132,34 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@csstools/color-helpers@5.0.2': + resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.2': + resolution: {integrity: sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-color-parser@3.0.8': + resolution: {integrity: sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-parser-algorithms@3.0.4': + resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-tokenizer@3.0.3': + resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} + engines: {node: '>=18'} + '@cypress/request@3.0.6': resolution: {integrity: sha512-fi0eVdCOtKu5Ed6+E8mYxUF6ZTFJDZvHogCBelM0xVXmrDEkyM22gRArQzq1YcHPm1V47Vf/iAD+WgVdUlJCGg==} engines: {node: '>= 6'} @@ -2993,7 +3024,7 @@ packages: '@expo/bunyan@4.0.1': resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==} - engines: {'0': node >=0.10.0} + engines: {node: '>=0.10.0'} '@expo/cli@0.22.22': resolution: {integrity: sha512-sOttVuk/8gdnsiSeDpnRNpLgBJHLbyQQC0QBGd2iHpr/x6xSYpgoRO6AqwAwGtQsk4ZEPZ83ulvccei1IIPdwg==} @@ -4987,6 +5018,9 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/express-serve-static-core@4.17.35': resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} @@ -5083,6 +5117,9 @@ packages: '@types/node@22.13.14': resolution: {integrity: sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==} + '@types/node@22.14.0': + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -7040,8 +7077,8 @@ packages: resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} engines: {node: '>=8'} - cssstyle@4.1.0: - resolution: {integrity: sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==} + cssstyle@4.3.0: + resolution: {integrity: sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ==} engines: {node: '>=18'} csstype@3.1.3: @@ -7192,6 +7229,9 @@ packages: decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} @@ -7537,6 +7577,10 @@ packages: resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==} engines: {node: '>=10.13.0'} + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -8318,6 +8362,10 @@ packages: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + formidable@2.1.2: resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} @@ -10879,6 +10927,9 @@ packages: nwsapi@2.2.13: resolution: {integrity: sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==} + nwsapi@2.2.20: + resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + nypm@0.6.0: resolution: {integrity: sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==} engines: {node: ^14.16.0 || >=16.10.0} @@ -12297,6 +12348,9 @@ packages: rrweb-cssom@0.7.1: resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + rslog@1.2.3: resolution: {integrity: sha512-antALPJaKBRPBU1X2q9t085K4htWDOOv/K1qhTUk7h0l1ePU/KbDqKJn19eKP0dk7PqMioeA0+fu3gyPXCsXxQ==} engines: {node: '>=14.17.6'} @@ -13003,6 +13057,10 @@ packages: resolution: {integrity: sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==} engines: {node: '>=14.18'} + supports-hyperlinks@3.2.0: + resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} + engines: {node: '>=14.18'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -13100,8 +13158,8 @@ packages: resolution: {integrity: sha512-flFL3m4wuixmf6IfhFJd1YPiLiMuxEc8uHRM1buzIeZPm22Au2pDqBJQgdo7n1WfPU1ONFGv7YDwpFBmHGF6lg==} engines: {node: '>=12'} - terser-webpack-plugin@5.3.11: - resolution: {integrity: sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==} + terser-webpack-plugin@5.3.14: + resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -13121,6 +13179,11 @@ packages: engines: {node: '>=10'} hasBin: true + terser@5.39.0: + resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + engines: {node: '>=10'} + hasBin: true + test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -13270,8 +13333,8 @@ packages: resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} engines: {node: '>=12'} - tr46@5.0.0: - resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + tr46@5.1.0: + resolution: {integrity: sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==} engines: {node: '>=18'} tree-dump@1.0.2: @@ -13581,6 +13644,9 @@ packages: undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} @@ -14297,8 +14363,8 @@ packages: resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} engines: {node: '>=12'} - whatwg-url@14.0.0: - resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==} + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} whatwg-url@5.0.0: @@ -14715,6 +14781,15 @@ snapshots: typescript: 5.6.1-rc validate-npm-package-name: 5.0.1 + '@asamuzakjp/css-color@3.1.1': + dependencies: + '@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-color-parser': 3.0.8(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + lru-cache: 10.4.3 + optional: true + '@astrojs/compiler@2.11.0': {} '@astrojs/internal-helpers@0.6.1': {} @@ -16015,6 +16090,31 @@ snapshots: '@jridgewell/trace-mapping': 0.3.9 optional: true + '@csstools/color-helpers@5.0.2': + optional: true + + '@csstools/css-calc@2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + optional: true + + '@csstools/css-color-parser@3.0.8(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/color-helpers': 5.0.2 + '@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + optional: true + + '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/css-tokenizer': 3.0.3 + optional: true + + '@csstools/css-tokenizer@3.0.3': + optional: true + '@cypress/request@3.0.6': dependencies: aws-sign2: 0.7.0 @@ -17663,12 +17763,12 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@2.3.1(magicast@0.3.5)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))': + '@nuxt/devtools-kit@2.3.1(magicast@0.3.5)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: '@nuxt/kit': 3.16.1(magicast@0.3.5) '@nuxt/schema': 3.16.1 execa: 8.0.1 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - magicast @@ -17683,12 +17783,12 @@ snapshots: prompts: 2.4.2 semver: 7.7.1 - '@nuxt/devtools@2.3.1(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@nuxt/devtools@2.3.1(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': dependencies: - '@nuxt/devtools-kit': 2.3.1(magicast@0.3.5)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + '@nuxt/devtools-kit': 2.3.1(magicast@0.3.5)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@nuxt/devtools-wizard': 2.3.1 '@nuxt/kit': 3.16.1(magicast@0.3.5) - '@vue/devtools-core': 7.7.2(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + '@vue/devtools-core': 7.7.2(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) '@vue/devtools-kit': 7.7.2 birpc: 2.2.0 consola: 3.4.2 @@ -17713,9 +17813,9 @@ snapshots: sirv: 3.0.1 structured-clone-es: 1.0.0 tinyglobby: 0.2.12 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - vite-plugin-inspect: 11.0.0(@nuxt/kit@3.16.1(magicast@0.3.5))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) - vite-plugin-vue-tracer: 0.1.1(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite-plugin-inspect: 11.0.0(@nuxt/kit@3.16.1(magicast@0.3.5))(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + vite-plugin-vue-tracer: 0.1.1(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) which: 5.0.0 ws: 8.18.1 transitivePeerDependencies: @@ -17775,12 +17875,12 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/vite-builder@3.16.1(@types/node@22.13.14)(eslint@9.23.0(jiti@2.4.2))(lightningcss@1.27.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.36.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(vue-tsc@2.2.8(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0)': + '@nuxt/vite-builder@3.16.1(@types/node@22.14.0)(eslint@9.23.0(jiti@2.4.2))(lightningcss@1.27.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.36.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(vue-tsc@2.2.8(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0)': dependencies: '@nuxt/kit': 3.16.1(magicast@0.3.5) '@rollup/plugin-replace': 6.0.2(rollup@4.36.0) - '@vitejs/plugin-vue': 5.2.3(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) - '@vitejs/plugin-vue-jsx': 4.1.2(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + '@vitejs/plugin-vue': 5.2.3(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + '@vitejs/plugin-vue-jsx': 4.1.2(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) autoprefixer: 10.4.21(postcss@8.5.3) consola: 3.4.2 cssnano: 7.0.6(postcss@8.5.3) @@ -17806,9 +17906,9 @@ snapshots: ufo: 1.5.4 unenv: 2.0.0-rc.15 unplugin: 2.2.2 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - vite-node: 3.0.9(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - vite-plugin-checker: 0.9.1(eslint@9.23.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.2)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2)) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite-node: 3.0.9(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite-plugin-checker: 0.9.1(eslint@9.23.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.2)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2)) vue: 3.5.13(typescript@5.8.2) vue-bundle-renderer: 2.1.1 transitivePeerDependencies: @@ -19076,7 +19176,7 @@ snapshots: '@swc/counter': 0.1.3 tslib: 2.8.1 - '@tanstack/directive-functions-plugin@1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)': + '@tanstack/directive-functions-plugin@1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.26.9 @@ -19089,7 +19189,7 @@ snapshots: babel-dead-code-elimination: 1.0.10 dedent: 1.5.3(babel-plugin-macros@3.1.0) tiny-invariant: 1.3.3 - vite: 6.1.2(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.1.2(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -19118,7 +19218,7 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-start-client@1.114.29(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0)': + '@tanstack/react-start-client@1.114.29(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0)': dependencies: '@tanstack/react-router': 1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/router-core': 1.114.29 @@ -19129,7 +19229,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - vinxi: 0.5.3(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) + vinxi: 0.5.3(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -19173,22 +19273,22 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-config@1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))(yaml@2.7.0)': + '@tanstack/react-start-config@1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))(yaml@2.7.0)': dependencies: - '@tanstack/react-start-plugin': 1.114.30(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/react-start-plugin': 1.114.30(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) '@tanstack/router-core': 1.114.29 '@tanstack/router-generator': 1.114.29(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@tanstack/router-plugin': 1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0)) - '@tanstack/server-functions-plugin': 1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/router-plugin': 1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0)) + '@tanstack/server-functions-plugin': 1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) '@tanstack/start-server-functions-handler': 1.114.29 - '@vitejs/plugin-react': 4.3.4(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + '@vitejs/plugin-react': 4.3.4(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) import-meta-resolve: 4.1.0 nitropack: 2.11.7(typescript@5.8.2) ofetch: 1.4.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - vinxi: 0.5.3(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vinxi: 0.5.3(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) zod: 3.24.2 transitivePeerDependencies: - '@azure/app-configuration' @@ -19238,7 +19338,7 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-plugin@1.114.30(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)': + '@tanstack/react-start-plugin@1.114.30(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.26.9 @@ -19250,7 +19350,7 @@ snapshots: '@tanstack/router-utils': 1.114.29 babel-dead-code-elimination: 1.0.10 tiny-invariant: 1.3.3 - vite: 6.1.2(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.1.2(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -19265,11 +19365,11 @@ snapshots: - tsx - yaml - '@tanstack/react-start-router-manifest@1.114.29(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0)': + '@tanstack/react-start-router-manifest@1.114.29(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0)': dependencies: '@tanstack/router-core': 1.114.29 tiny-invariant: 1.3.3 - vinxi: 0.5.3(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) + vinxi: 0.5.3(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -19328,20 +19428,20 @@ snapshots: tiny-warning: 1.0.3 unctx: 2.4.1 - '@tanstack/react-start@1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))(yaml@2.7.0)': + '@tanstack/react-start@1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))(yaml@2.7.0)': dependencies: - '@tanstack/react-start-client': 1.114.29(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) - '@tanstack/react-start-config': 1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))(yaml@2.7.0) - '@tanstack/react-start-router-manifest': 1.114.29(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) + '@tanstack/react-start-client': 1.114.29(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) + '@tanstack/react-start-config': 1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))(yaml@2.7.0) + '@tanstack/react-start-router-manifest': 1.114.29(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) '@tanstack/react-start-server': 1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tanstack/start-api-routes': 1.114.29(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) - '@tanstack/start-server-functions-client': 1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/start-api-routes': 1.114.29(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) + '@tanstack/start-server-functions-client': 1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) '@tanstack/start-server-functions-handler': 1.114.29 - '@tanstack/start-server-functions-server': 1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - '@tanstack/start-server-functions-ssr': 1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/start-server-functions-server': 1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/start-server-functions-ssr': 1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -19412,7 +19512,7 @@ snapshots: optionalDependencies: '@tanstack/react-router': 1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tanstack/router-plugin@1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))': + '@tanstack/router-plugin@1.114.31(@tanstack/react-router@1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(webpack@5.94.0(esbuild@0.25.0))': dependencies: '@babel/core': 7.26.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) @@ -19433,7 +19533,7 @@ snapshots: zod: 3.24.2 optionalDependencies: '@tanstack/react-router': 1.114.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) webpack: 5.94.0(esbuild@0.25.0) transitivePeerDependencies: - supports-color @@ -19445,7 +19545,7 @@ snapshots: ansis: 3.16.0 diff: 7.0.0 - '@tanstack/server-functions-plugin@1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)': + '@tanstack/server-functions-plugin@1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.26.9 @@ -19454,7 +19554,7 @@ snapshots: '@babel/template': 7.26.9 '@babel/traverse': 7.26.9 '@babel/types': 7.26.9 - '@tanstack/directive-functions-plugin': 1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/directive-functions-plugin': 1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) babel-dead-code-elimination: 1.0.10 dedent: 1.5.3(babel-plugin-macros@3.1.0) tiny-invariant: 1.3.3 @@ -19473,11 +19573,11 @@ snapshots: - tsx - yaml - '@tanstack/start-api-routes@1.114.29(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0)': + '@tanstack/start-api-routes@1.114.29(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0)': dependencies: '@tanstack/router-core': 1.114.29 '@tanstack/start-server-core': 1.114.29 - vinxi: 0.5.3(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) + vinxi: 0.5.3(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -19539,9 +19639,9 @@ snapshots: tiny-warning: 1.0.3 unctx: 2.4.1 - '@tanstack/start-server-functions-client@1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)': + '@tanstack/start-server-functions-client@1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)': dependencies: - '@tanstack/server-functions-plugin': 1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/server-functions-plugin': 1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) '@tanstack/start-server-functions-fetcher': 1.114.29 transitivePeerDependencies: - '@types/node' @@ -19570,9 +19670,9 @@ snapshots: '@tanstack/start-server-core': 1.114.29 tiny-invariant: 1.3.3 - '@tanstack/start-server-functions-server@1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)': + '@tanstack/start-server-functions-server@1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)': dependencies: - '@tanstack/server-functions-plugin': 1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/server-functions-plugin': 1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) tiny-invariant: 1.3.3 transitivePeerDependencies: - '@types/node' @@ -19589,9 +19689,9 @@ snapshots: - tsx - yaml - '@tanstack/start-server-functions-ssr@1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)': + '@tanstack/start-server-functions-ssr@1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)': dependencies: - '@tanstack/server-functions-plugin': 1.114.30(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + '@tanstack/server-functions-plugin': 1.114.30(@types/node@22.14.0)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) '@tanstack/start-client-core': 1.114.29 '@tanstack/start-server-core': 1.114.29 '@tanstack/start-server-functions-fetcher': 1.114.29 @@ -19637,7 +19737,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.6(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.13.14)(typescript@5.8.2)))(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))': + '@testing-library/jest-dom@6.4.6(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.13.14)(typescript@5.8.2)))(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: '@adobe/css-tools': 4.4.0 '@babel/runtime': 7.26.0 @@ -19651,7 +19751,7 @@ snapshots: '@jest/globals': 29.7.0 '@types/jest': 29.5.12 jest: 29.7.0(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.13.14)(typescript@5.8.2)) - vitest: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vitest: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) '@testing-library/react@16.0.0(@testing-library/dom@10.1.0)(@types/react-dom@18.3.5(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -19779,6 +19879,8 @@ snapshots: '@types/estree@1.0.6': {} + '@types/estree@1.0.7': {} + '@types/express-serve-static-core@4.17.35': dependencies: '@types/node': 22.13.14 @@ -19892,6 +19994,10 @@ snapshots: dependencies: undici-types: 6.20.0 + '@types/node@22.14.0': + dependencies: + undici-types: 6.21.0 + '@types/normalize-package-data@2.4.4': {} '@types/parse-json@4.0.0': {} @@ -20332,33 +20438,33 @@ snapshots: untun: 0.1.3 uqr: 0.1.2 - '@vitejs/plugin-react@4.3.4(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))': + '@vitejs/plugin-react@4.3.4(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: '@babel/core': 7.26.9 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.9) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.9) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.1.2(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@vitejs/plugin-vue-jsx@4.1.2(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': dependencies: '@babel/core': 7.26.9 '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.9) '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.9) - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) vue: 3.5.13(typescript@5.8.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.3(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@vitejs/plugin-vue@5.2.3(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': dependencies: - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) vue: 3.5.13(typescript@5.8.2) - '@vitest/coverage-v8@3.0.2(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))': + '@vitest/coverage-v8@3.0.2(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -20372,7 +20478,7 @@ snapshots: std-env: 3.8.1 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vitest: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - supports-color @@ -20383,14 +20489,14 @@ snapshots: chai: 5.1.2 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.5(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))': + '@vitest/mocker@3.0.5(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': dependencies: '@vitest/spy': 3.0.5 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: msw: 2.7.3(@types/node@22.13.14)(typescript@5.8.2) - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) '@vitest/pretty-format@3.0.5': dependencies: @@ -20548,14 +20654,14 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/devtools-core@7.7.2(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@vue/devtools-core@7.7.2(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': dependencies: '@vue/devtools-kit': 7.7.2 '@vue/devtools-shared': 7.7.2 mitt: 3.0.1 nanoid: 5.0.9 pathe: 2.0.3 - vite-hot-client: 0.2.4(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + vite-hot-client: 0.2.4(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) vue: 3.5.13(typescript@5.8.2) transitivePeerDependencies: - vite @@ -21063,7 +21169,7 @@ snapshots: astral-regex@2.0.0: {} - astro@5.5.5(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(rollup@4.36.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0): + astro@5.5.5(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(rollup@4.36.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0): dependencies: '@astrojs/compiler': 2.11.0 '@astrojs/internal-helpers': 0.6.1 @@ -21114,8 +21220,8 @@ snapshots: unist-util-visit: 5.0.0 unstorage: 1.15.0(db0@0.3.1)(ioredis@5.6.0) vfile: 6.0.3 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - vitefu: 1.0.6(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vitefu: 1.0.6(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.1 @@ -22327,9 +22433,10 @@ snapshots: dependencies: cssom: 0.3.8 - cssstyle@4.1.0: + cssstyle@4.3.0: dependencies: - rrweb-cssom: 0.7.1 + '@asamuzakjp/css-color': 3.1.1 + rrweb-cssom: 0.8.0 optional: true csstype@3.1.3: {} @@ -22396,7 +22503,7 @@ snapshots: data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 + whatwg-url: 14.2.0 optional: true data-view-buffer@1.0.2: @@ -22481,6 +22588,9 @@ snapshots: decimal.js@10.4.3: {} + decimal.js@10.5.0: + optional: true + decode-named-character-reference@1.0.2: dependencies: character-entities: 2.0.2 @@ -22818,6 +22928,11 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + enquirer@2.4.1: dependencies: ansi-colors: 4.1.3 @@ -24082,6 +24197,14 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + form-data@4.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + optional: true + formidable@2.1.2: dependencies: dezalgo: 1.0.4 @@ -25609,7 +25732,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.13.14 + '@types/node': 22.14.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -25796,15 +25919,15 @@ snapshots: jsdom@24.1.3: dependencies: - cssstyle: 4.1.0 + cssstyle: 4.3.0 data-urls: 5.0.0 - decimal.js: 10.4.3 - form-data: 4.0.1 + decimal.js: 10.5.0 + form-data: 4.0.2 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.13 + nwsapi: 2.2.20 parse5: 7.2.1 rrweb-cssom: 0.7.1 saxes: 6.0.0 @@ -25814,7 +25937,7 @@ snapshots: webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 + whatwg-url: 14.2.0 ws: 8.18.1 xml-name-validator: 5.0.0 transitivePeerDependencies: @@ -26322,7 +26445,7 @@ snapshots: cli-table3: 0.6.5 marked: 11.2.0 node-emoji: 2.2.0 - supports-hyperlinks: 3.1.0 + supports-hyperlinks: 3.2.0 marked@11.2.0: {} @@ -27362,15 +27485,15 @@ snapshots: nullthrows@1.1.1: {} - nuxt@3.16.1(@parcel/watcher@2.5.1)(@types/node@22.13.14)(db0@0.3.1)(eslint@9.23.0(jiti@2.4.2))(ioredis@5.6.0)(lightningcss@1.27.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.36.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2))(yaml@2.7.0): + nuxt@3.16.1(@parcel/watcher@2.5.1)(@types/node@22.14.0)(db0@0.3.1)(eslint@9.23.0(jiti@2.4.2))(ioredis@5.6.0)(lightningcss@1.27.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.36.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2))(yaml@2.7.0): dependencies: '@nuxt/cli': 3.23.1(magicast@0.3.5) '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 2.3.1(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + '@nuxt/devtools': 2.3.1(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) '@nuxt/kit': 3.16.1(magicast@0.3.5) '@nuxt/schema': 3.16.1 '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 3.16.1(@types/node@22.13.14)(eslint@9.23.0(jiti@2.4.2))(lightningcss@1.27.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.36.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(vue-tsc@2.2.8(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0) + '@nuxt/vite-builder': 3.16.1(@types/node@22.14.0)(eslint@9.23.0(jiti@2.4.2))(lightningcss@1.27.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.36.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(vue-tsc@2.2.8(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0) '@oxc-parser/wasm': 0.60.0 '@unhead/vue': 2.0.0-rc.13(vue@3.5.13(typescript@5.8.2)) '@vue/shared': 3.5.13 @@ -27429,7 +27552,7 @@ snapshots: vue-router: 4.5.0(vue@3.5.13(typescript@5.8.2)) optionalDependencies: '@parcel/watcher': 2.5.1 - '@types/node': 22.13.14 + '@types/node': 22.14.0 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -27485,6 +27608,9 @@ snapshots: nwsapi@2.2.13: {} + nwsapi@2.2.20: + optional: true + nypm@0.6.0: dependencies: citty: 0.1.6 @@ -28983,6 +29109,9 @@ snapshots: rrweb-cssom@0.7.1: optional: true + rrweb-cssom@0.8.0: + optional: true + rslog@1.2.3: {} run-applescript@7.0.0: {} @@ -29836,6 +29965,11 @@ snapshots: has-flag: 4.0.0 supports-color: 7.2.0 + supports-hyperlinks@3.2.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + supports-preserve-symlinks-flag@1.0.0: {} svg-parser@2.0.4: {} @@ -29963,13 +30097,13 @@ snapshots: ansi-escapes: 5.0.0 supports-hyperlinks: 2.3.0 - terser-webpack-plugin@5.3.11(esbuild@0.25.0)(webpack@5.94.0(esbuild@0.25.0)): + terser-webpack-plugin@5.3.14(esbuild@0.25.0)(webpack@5.94.0(esbuild@0.25.0)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 - terser: 5.37.0 + terser: 5.39.0 webpack: 5.94.0(esbuild@0.25.0) optionalDependencies: esbuild: 0.25.0 @@ -29981,6 +30115,13 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 + terser@5.39.0: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.14.1 + commander: 2.20.3 + source-map-support: 0.5.21 + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 @@ -30113,7 +30254,7 @@ snapshots: dependencies: punycode: 2.3.1 - tr46@5.0.0: + tr46@5.1.0: dependencies: punycode: 2.3.1 optional: true @@ -30413,6 +30554,8 @@ snapshots: undici-types@6.20.0: {} + undici-types@6.21.0: {} + undici@5.28.4: dependencies: '@fastify/busboy': 2.0.0 @@ -30582,12 +30725,12 @@ snapshots: transitivePeerDependencies: - vue - unplugin-vue@5.2.1(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0): + unplugin-vue@5.2.1(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(vue@3.5.13(typescript@5.8.2))(yaml@2.7.0): dependencies: '@vue/reactivity': 3.5.13 debug: 4.4.0(supports-color@8.1.1) unplugin: 1.16.1 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) vue: 3.5.13(typescript@5.8.2) transitivePeerDependencies: - '@types/node' @@ -30834,7 +30977,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vinxi@0.5.3(@types/node@22.13.14)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0): + vinxi@0.5.3(@types/node@22.14.0)(db0@0.3.1)(ioredis@5.6.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.8.2)(yaml@2.7.0): dependencies: '@babel/core': 7.26.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) @@ -30868,7 +31011,7 @@ snapshots: unctx: 2.4.1 unenv: 1.10.0 unstorage: 1.15.0(db0@0.3.1)(ioredis@5.6.0) - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) zod: 3.24.2 transitivePeerDependencies: - '@azure/app-configuration' @@ -30913,27 +31056,27 @@ snapshots: - xml2js - yaml - vite-dev-rpc@1.0.7(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)): + vite-dev-rpc@1.0.7(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): dependencies: birpc: 2.2.0 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - vite-hot-client: 2.0.4(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite-hot-client: 2.0.4(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) - vite-hot-client@0.2.4(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)): + vite-hot-client@0.2.4(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): dependencies: - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vite-hot-client@2.0.4(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)): + vite-hot-client@2.0.4(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): dependencies: - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vite-node@3.0.5(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0): + vite-node@3.0.5(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: cac: 6.7.14 debug: 4.4.0(supports-color@8.1.1) es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -30948,13 +31091,13 @@ snapshots: - tsx - yaml - vite-node@3.0.9(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0): + vite-node@3.0.9(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: cac: 6.7.14 debug: 4.4.0(supports-color@8.1.1) es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -30969,7 +31112,7 @@ snapshots: - tsx - yaml - vite-plugin-checker@0.9.1(eslint@9.23.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.2)(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2)): + vite-plugin-checker@0.9.1(eslint@9.23.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.8.2)(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue-tsc@2.2.8(typescript@5.8.2)): dependencies: '@babel/code-frame': 7.26.2 chokidar: 4.0.3 @@ -30979,7 +31122,7 @@ snapshots: strip-ansi: 7.1.0 tiny-invariant: 1.3.3 tinyglobby: 0.2.12 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) vscode-uri: 3.1.0 optionalDependencies: eslint: 9.23.0(jiti@2.4.2) @@ -30987,7 +31130,7 @@ snapshots: typescript: 5.8.2 vue-tsc: 2.2.8(typescript@5.8.2) - vite-plugin-inspect@11.0.0(@nuxt/kit@3.16.1(magicast@0.3.5))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)): + vite-plugin-inspect@11.0.0(@nuxt/kit@3.16.1(magicast@0.3.5))(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): dependencies: ansis: 3.16.0 debug: 4.4.0(supports-color@8.1.1) @@ -30997,37 +31140,37 @@ snapshots: perfect-debounce: 1.0.0 sirv: 3.0.1 unplugin-utils: 0.2.4 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - vite-dev-rpc: 1.0.7(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite-dev-rpc: 1.0.7(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) optionalDependencies: '@nuxt/kit': 3.16.1(magicast@0.3.5) transitivePeerDependencies: - supports-color - vite-plugin-vue-tracer@0.1.1(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)): + vite-plugin-vue-tracer@0.1.1(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)): dependencies: estree-walker: 3.0.3 magic-string: 0.30.17 pathe: 2.0.3 source-map-js: 1.2.1 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) vue: 3.5.13(typescript@5.8.2) - vite@6.1.2(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0): + vite@6.1.2(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: esbuild: 0.24.2 postcss: 8.5.3 rollup: 4.36.0 optionalDependencies: - '@types/node': 22.13.14 + '@types/node': 22.14.0 fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.27.0 - terser: 5.37.0 + terser: 5.39.0 tsx: 4.19.2 yaml: 2.7.0 - vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0): + vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: esbuild: 0.25.0 postcss: 8.5.3 @@ -31037,30 +31180,44 @@ snapshots: fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.27.0 - terser: 5.37.0 + terser: 5.39.0 tsx: 4.19.2 yaml: 2.7.0 - vitefu@1.0.6(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)): + vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): + dependencies: + esbuild: 0.25.0 + postcss: 8.5.3 + rollup: 4.36.0 + optionalDependencies: + '@types/node': 22.14.0 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.27.0 + terser: 5.39.0 + tsx: 4.19.2 + yaml: 2.7.0 + + vitefu@1.0.6(vite@6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): optionalDependencies: - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vitest-environment-miniflare@2.14.4(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)): + vitest-environment-miniflare@2.14.4(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): dependencies: '@miniflare/queues': 2.14.4 '@miniflare/runner-vm': 2.14.4 '@miniflare/shared': 2.14.4 '@miniflare/shared-test-environment': 2.14.4 undici: 5.28.4 - vitest: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vitest: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - bufferutil - utf-8-validate - vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0): + vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: '@vitest/expect': 3.0.5 - '@vitest/mocker': 3.0.5(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)) + '@vitest/mocker': 3.0.5(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) '@vitest/pretty-format': 3.0.5 '@vitest/runner': 3.0.5 '@vitest/snapshot': 3.0.5 @@ -31076,8 +31233,8 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - vite-node: 3.0.5(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) + vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite-node: 3.0.5(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) why-is-node-running: 2.3.0 optionalDependencies: '@edge-runtime/vm': 5.0.0 @@ -31274,7 +31431,7 @@ snapshots: webpack@5.94.0(esbuild@0.25.0): dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 @@ -31282,7 +31439,7 @@ snapshots: acorn-import-attributes: 1.9.5(acorn@8.14.1) browserslist: 4.24.4 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.0 + enhanced-resolve: 5.18.1 es-module-lexer: 1.6.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -31294,7 +31451,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.11(esbuild@0.25.0)(webpack@5.94.0(esbuild@0.25.0)) + terser-webpack-plugin: 5.3.14(esbuild@0.25.0)(webpack@5.94.0(esbuild@0.25.0)) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -31337,9 +31494,9 @@ snapshots: tr46: 3.0.0 webidl-conversions: 7.0.0 - whatwg-url@14.0.0: + whatwg-url@14.2.0: dependencies: - tr46: 5.0.0 + tr46: 5.1.0 webidl-conversions: 7.0.0 optional: true From 3246ebb0b6ad34398269322e82cc81e53d6342de Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 4 Apr 2025 17:19:54 -0400 Subject: [PATCH 4/5] feat: Apply generated API client to downstream SDKs --- .../src/lib/tools/invitations.ts | 60 +-- .../src/lib/tools/organizations.ts | 413 ++++++++++-------- packages/agent-toolkit/src/lib/tools/users.ts | 94 ++-- packages/astro/src/server/current-user.ts | 6 +- packages/backend/src/api/factory.ts | 1 + packages/backend/src/api/index.ts | 1 + packages/backend/src/index.ts | 8 +- packages/backend/src/tokens/authObjects.ts | 13 +- packages/backend/src/tokens/factory.ts | 4 +- packages/backend/src/tokens/request.ts | 22 +- packages/backend/src/tokens/types.ts | 4 +- .../src/util/decorateObjectWithResources.ts | 20 +- packages/express/README.md | 4 +- .../src/app-router/server/currentUser.ts | 6 +- packages/nextjs/src/server/buildClerkProps.ts | 2 +- packages/nextjs/src/server/createGetAuth.ts | 2 +- packages/testing/src/common/setup.ts | 2 +- pnpm-lock.yaml | 134 +++++- 18 files changed, 509 insertions(+), 287 deletions(-) diff --git a/packages/agent-toolkit/src/lib/tools/invitations.ts b/packages/agent-toolkit/src/lib/tools/invitations.ts index df75bf0725c..064a0893bf1 100644 --- a/packages/agent-toolkit/src/lib/tools/invitations.ts +++ b/packages/agent-toolkit/src/lib/tools/invitations.ts @@ -3,6 +3,26 @@ import { z } from 'zod'; import { ClerkTool } from '../clerk-tool'; import { prunePrivateData } from '../utils'; +const createInvitationParameters = z.object({ + emailAddress: z.string().describe('(string): Email address to send the invitation to. Required.'), + redirectUrl: z + .string() + .optional() + .describe('(string, optional): URL to redirect users to after they accept the invitation.'), + publicMetadata: z + .record(z.string(), z.any()) + .optional() + .describe('(Record, optional): Public metadata for the invitation.'), + notify: z + .boolean() + .optional() + .describe('(boolean, optional): Whether to send an email notification. Defaults to true.'), + ignoreExisting: z + .boolean() + .optional() + .describe('(boolean, optional): Whether to ignore if an invitation already exists. Defaults to false.'), +}); + const createInvitation = ClerkTool({ name: 'createInvitation', description: ` @@ -17,31 +37,17 @@ const createInvitation = ClerkTool({ 2. Creating a closed registration system where only invited users can join 3. Pre-configuring user attributes via publicMetadata before they sign up `, - parameters: z.object({ - emailAddress: z.string().describe('(string): Email address to send the invitation to. Required.'), - redirectUrl: z - .string() - .optional() - .describe('(string, optional): URL to redirect users to after they accept the invitation.'), - publicMetadata: z - .record(z.string(), z.any()) - .optional() - .describe('(Record, optional): Public metadata for the invitation.'), - notify: z - .boolean() - .optional() - .describe('(boolean, optional): Whether to send an email notification. Defaults to true.'), - ignoreExisting: z - .boolean() - .optional() - .describe('(boolean, optional): Whether to ignore if an invitation already exists. Defaults to false.'), - }), - execute: (clerkClient, context) => async params => { - const res = await clerkClient.invitations.createInvitation(params); - return prunePrivateData(context, res.raw); + parameters: createInvitationParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const res = await clerkClient.api.invitations.create(params); + return prunePrivateData(context, res); // TODO: Use raw JSON response }, }); +const revokeInvitationParameters = z.object({ + invitationId: z.string().describe('(string): The ID of the invitation to revoke. Required.'), +}); + const revokeInvitation = ClerkTool({ name: 'revokeInvitation', description: ` @@ -56,12 +62,10 @@ const revokeInvitation = ClerkTool({ 2. Revoking access when a prospective user should no longer be invited 3. Implementing invitation management controls for administrators `, - parameters: z.object({ - invitationId: z.string().describe('(string): The ID of the invitation to revoke. Required.'), - }), - execute: (clerkClient, context) => async params => { - const res = await clerkClient.invitations.revokeInvitation(params.invitationId); - return prunePrivateData(context, res.raw); + parameters: revokeInvitationParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const res = await clerkClient.api.invitations.revoke(params.invitationId); + return prunePrivateData(context, res); // TODO: Use raw JSON response }, }); diff --git a/packages/agent-toolkit/src/lib/tools/organizations.ts b/packages/agent-toolkit/src/lib/tools/organizations.ts index 4babfad3b6a..5ad9a6c8f5f 100644 --- a/packages/agent-toolkit/src/lib/tools/organizations.ts +++ b/packages/agent-toolkit/src/lib/tools/organizations.ts @@ -3,6 +3,23 @@ import { z } from 'zod'; import { ClerkTool } from '../clerk-tool'; import { prunePrivateData } from '../utils'; +const getOrganizationParameters = z.object({ + organizationId: z + .string() + .optional() + .describe('(string, optional): The ID of the organization to retrieve. Required if slug is not provided.'), + slug: z + .string() + .optional() + .describe( + '(string, optional): The slug of the organization to retrieve. Required if organizationId is not provided.', + ), + includeMembersCount: z + .boolean() + .optional() + .describe('(boolean, optional): Whether to include the members count for the organization.'), +}); + const getOrganization = ClerkTool({ name: 'getOrganization', description: ` @@ -16,34 +33,51 @@ const getOrganization = ClerkTool({ 2. Checking if an organization exists before performing operations on it 3. Retrieving organization metadata for application-specific functionality `, - parameters: z.object({ - organizationId: z - .string() - .optional() - .describe('(string, optional): The ID of the organization to retrieve. Required if slug is not provided.'), - slug: z - .string() - .optional() - .describe( - '(string, optional): The slug of the organization to retrieve. Required if organizationId is not provided.', - ), - includeMembersCount: z - .boolean() - .optional() - .describe('(boolean, optional): Whether to include the members count for the organization.'), - }), - execute: (clerkClient, context) => async params => { - if (!params.organizationId && !params.slug) { + parameters: getOrganizationParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const organizationId = (context.orgId || params.organizationId) as string; // TODO: Is it safe to assume this is a string? + + if (!organizationId && !params.slug) { throw new Error('Either organizationId or slug must be provided'); } - const res = await clerkClient.organizations.getOrganization({ + + const res = await clerkClient.api.organizations.get({ ...params, - organizationId: context.orgId || params.organizationId, + organizationId, }); - return prunePrivateData(context, res.raw); + + return prunePrivateData(context, res); }, }); +const createOrganizationParameters = z.object({ + name: z.string().describe('(string): The name of the new organization. Required.'), + slug: z + .string() + .optional() + .describe( + '(string, optional): A URL-friendly identifier for the organization. If not provided, created from the name.', + ), + createdBy: z + .string() + .optional() + .describe( + '(string, optional): The user ID of the user creating the organization. Defaults to the current authenticated user.', + ), + maxAllowedMemberships: z + .number() + .optional() + .describe('(number, optional): Maximum number of members allowed in the organization.'), + publicMetadata: z + .record(z.string(), z.any()) + .optional() + .describe('(Record, optional): Public metadata for the organization.'), + privateMetadata: z + .record(z.string(), z.any()) + .optional() + .describe('(Record, optional): Private metadata for the organization (backend-only).'), +}); + const createOrganization = ClerkTool({ name: 'createOrganization', description: ` @@ -58,41 +92,33 @@ const createOrganization = ClerkTool({ 2. Building a self-service organization creation flow 3. Migrating organizations from another system `, - parameters: z.object({ - name: z.string().describe('(string): The name of the new organization. Required.'), - slug: z - .string() - .optional() - .describe( - '(string, optional): A URL-friendly identifier for the organization. If not provided, created from the name.', - ), - createdBy: z - .string() - .optional() - .describe( - '(string, optional): The user ID of the user creating the organization. Defaults to the current authenticated user.', - ), - maxAllowedMemberships: z - .number() - .optional() - .describe('(number, optional): Maximum number of members allowed in the organization.'), - publicMetadata: z - .record(z.string(), z.any()) - .optional() - .describe('(Record, optional): Public metadata for the organization.'), - privateMetadata: z - .record(z.string(), z.any()) - .optional() - .describe('(Record, optional): Private metadata for the organization (backend-only).'), - }), - execute: (clerkClient, context) => async params => { - const { createdBy, ...createParams } = params; - // Use provided createdBy or fall back to context userId - const createParamsWithUser = - createdBy || context.userId ? { ...createParams, createdBy: createdBy || context.userId } : createParams; - const res = await clerkClient.organizations.createOrganization(createParamsWithUser); - return prunePrivateData(context, res.raw); - }, + parameters: createOrganizationParameters, + + execute: + (clerkClient, context) => + async ({ createdBy, ...restParams }: z.infer) => { + // Use provided createdBy or fall back to context userId + const createParamsWithUser = + createdBy || context.userId ? { ...restParams, createdBy: createdBy || context.userId } : restParams; + const res = await clerkClient.api.organizations.create(createParamsWithUser); + + return prunePrivateData(context, res); + }, +}); + +const updateOrganizationParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization to update. Required.'), + name: z.string().optional().describe('(string, optional): New name for the organization.'), + slug: z.string().optional().describe('(string, optional): New slug for the organization.'), + maxAllowedMemberships: z.number().optional().describe('(number, optional): New maximum number of members allowed.'), + publicMetadata: z + .record(z.string(), z.any()) + .optional() + .describe('(Record, optional): New public metadata for the organization.'), + privateMetadata: z + .record(z.string(), z.any()) + .optional() + .describe('(Record, optional): New private metadata for the organization (backend-only).'), }); const updateOrganization = ClerkTool({ @@ -109,27 +135,34 @@ const updateOrganization = ClerkTool({ 2. Changing the maximum allowed memberships 3. Updating multiple organization attributes at once `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization to update. Required.'), - name: z.string().optional().describe('(string, optional): New name for the organization.'), - slug: z.string().optional().describe('(string, optional): New slug for the organization.'), - maxAllowedMemberships: z.number().optional().describe('(number, optional): New maximum number of members allowed.'), - publicMetadata: z - .record(z.string(), z.any()) - .optional() - .describe('(Record, optional): New public metadata for the organization.'), - privateMetadata: z - .record(z.string(), z.any()) - .optional() - .describe('(Record, optional): New private metadata for the organization (backend-only).'), - }), - execute: (clerkClient, context) => async params => { - const { organizationId, ...updateParams } = params; - const res = await clerkClient.organizations.updateOrganization(context.orgId || organizationId, updateParams); - return prunePrivateData(context, res.raw); + parameters: updateOrganizationParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const { organizationId, ...requestBody } = params; + const res = await clerkClient.api.organizations.update({ + organizationId: context.orgId || organizationId, + requestBody, + }); + + return prunePrivateData(context, res); }, }); +const updateOrganizationMetadataParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization to update. Required.'), + publicMetadata: z + .record(z.string(), z.any()) + .optional() + .describe( + '(Record, optional): The public metadata to set or update. Use null values to remove specific keys.', + ), + privateMetadata: z + .record(z.string(), z.any()) + .optional() + .describe( + '(Record, optional): The private metadata to set or update. Backend-only data. Use null values to remove specific keys.', + ), +}); + const updateOrganizationMetadata = ClerkTool({ name: 'updateOrganizationMetadata', description: ` @@ -147,31 +180,22 @@ const updateOrganizationMetadata = ClerkTool({ 2. Keeping track of organization-specific application state 3. Adding custom attributes to organizations `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization to update. Required.'), - publicMetadata: z - .record(z.string(), z.any()) - .optional() - .describe( - '(Record, optional): The public metadata to set or update. Use null values to remove specific keys.', - ), - privateMetadata: z - .record(z.string(), z.any()) - .optional() - .describe( - '(Record, optional): The private metadata to set or update. Backend-only data. Use null values to remove specific keys.', - ), - }), - execute: (clerkClient, context) => async params => { - const { organizationId, ...metadataParams } = params; - const res = await clerkClient.organizations.updateOrganizationMetadata( - context.orgId || organizationId, - metadataParams, - ); - return prunePrivateData(context, res.raw); + parameters: updateOrganizationMetadataParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const { organizationId, ...requestBody } = params; + const res = await clerkClient.api.organizations.mergeMetadata({ + organizationId: context.orgId || organizationId, + requestBody, + }); + + return prunePrivateData(context, res); }, }); +const deleteOrganizationParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization to delete. Required.'), +}); + const deleteOrganization = ClerkTool({ name: 'deleteOrganization', description: ` @@ -186,15 +210,19 @@ const deleteOrganization = ClerkTool({ 2. Allowing users to delete their own organizations 3. Administrative operations to remove unwanted organizations `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization to delete. Required.'), - }), - execute: (clerkClient, context) => async params => { - const res = await clerkClient.organizations.deleteOrganization(context.orgId || params.organizationId); - return prunePrivateData(context, res.raw); + parameters: deleteOrganizationParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const res = await clerkClient.api.organizations.delete(context.orgId || params.organizationId); + return prunePrivateData(context, res); }, }); +const createOrganizationMembershipParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization to add the member to. Required.'), + userId: z.string().describe('(string): The ID of the user to add as a member. Required.'), + role: z.string().describe('(string): The role to assign to the user in the organization. Required.'), +}); + const createOrganizationMembership = ClerkTool({ name: 'createOrganizationMembership', description: ` @@ -209,21 +237,26 @@ const createOrganizationMembership = ClerkTool({ 2. Building administrative interfaces for member management 3. Migrating memberships from another system `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization to add the member to. Required.'), - userId: z.string().describe('(string): The ID of the user to add as a member. Required.'), - role: z.string().describe('(string): The role to assign to the user in the organization. Required.'), - }), - execute: (clerkClient, context) => async params => { - const res = await clerkClient.organizations.createOrganizationMembership({ - ...params, + parameters: createOrganizationMembershipParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const res = await clerkClient.api.organizationMemberships.create({ organizationId: context.orgId || params.organizationId, - userId: context.userId || params.userId, + requestBody: { + role: params.role, + userId: context.userId || params.userId, + }, }); - return prunePrivateData(context, res.raw); + + return prunePrivateData(context, res); }, }); +const updateOrganizationMembershipParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization containing the membership. Required.'), + userId: z.string().describe('(string): The ID of the user whose membership is being updated. Required.'), + role: z.string().describe('(string): The new role to assign to the user. Required.'), +}); + const updateOrganizationMembership = ClerkTool({ name: 'updateOrganizationMembership', description: ` @@ -238,20 +271,36 @@ const updateOrganizationMembership = ClerkTool({ 2. Building role management interfaces 3. Implementing admin-level controls for organization management `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization containing the membership. Required.'), - userId: z.string().describe('(string): The ID of the user whose membership is being updated. Required.'), - role: z.string().describe('(string): The new role to assign to the user. Required.'), - }), - execute: (clerkClient, context) => async params => { - const res = await clerkClient.organizations.updateOrganizationMembership({ - ...params, - organizationId: context.orgId || params.organizationId, + parameters: updateOrganizationMembershipParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const { organizationId, userId, ...requestBody } = params; + const res = await clerkClient.api.organizationMemberships.update({ + organizationId: context.orgId || organizationId, + userId, + requestBody, }); - return prunePrivateData(context, res.raw); + + return prunePrivateData(context, res); }, }); +const updateOrganizationMembershipMetadataParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization containing the membership. Required.'), + userId: z.string().describe('(string): The ID of the user whose membership metadata is being updated. Required.'), + publicMetadata: z + .record(z.string(), z.any()) + .optional() + .describe( + '(Record, optional): The public metadata to set or update. Use null values to remove specific keys.', + ), + privateMetadata: z + .record(z.string(), z.any()) + .optional() + .describe( + '(Record, optional): The private metadata to set or update. Backend-only data. Use null values to remove specific keys.', + ), +}); + const updateOrganizationMembershipMetadata = ClerkTool({ name: 'updateOrganizationMembershipMetadata', description: ` @@ -269,31 +318,24 @@ const updateOrganizationMembershipMetadata = ClerkTool({ 2. Adding custom attributes to track member activity or status 3. Customizing a user's experience within a specific organization `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization containing the membership. Required.'), - userId: z.string().describe('(string): The ID of the user whose membership metadata is being updated. Required.'), - publicMetadata: z - .record(z.string(), z.any()) - .optional() - .describe( - '(Record, optional): The public metadata to set or update. Use null values to remove specific keys.', - ), - privateMetadata: z - .record(z.string(), z.any()) - .optional() - .describe( - '(Record, optional): The private metadata to set or update. Backend-only data. Use null values to remove specific keys.', - ), - }), - execute: (clerkClient, context) => async params => { - const res = await clerkClient.organizations.updateOrganizationMembershipMetadata({ - ...params, + parameters: updateOrganizationMembershipMetadataParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const { organizationId, userId, ...requestBody } = params; + const res = await clerkClient.api.organizationMemberships.updateMetadata({ organizationId: context.orgId || params.organizationId, + userId, + requestBody, }); - return prunePrivateData(context, res.raw); + + return prunePrivateData(context, res); }, }); +const deleteOrganizationMembershipParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization to remove the member from. Required.'), + userId: z.string().describe('(string): The ID of the user to remove from the organization. Required.'), +}); + const deleteOrganizationMembership = ClerkTool({ name: 'deleteOrganizationMembership', description: ` @@ -308,19 +350,36 @@ const deleteOrganizationMembership = ClerkTool({ 2. Building membership management interfaces with removal capability 3. Implementing self-service leave organization functionality `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization to remove the member from. Required.'), - userId: z.string().describe('(string): The ID of the user to remove from the organization. Required.'), - }), - execute: (clerkClient, context) => async params => { - const res = await clerkClient.organizations.deleteOrganizationMembership({ + parameters: deleteOrganizationMembershipParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const res = await clerkClient.api.organizationMemberships.delete({ ...params, userId: context.userId || params.userId, }); - return prunePrivateData(context, res.raw); + return prunePrivateData(context, res); }, }); +const createOrganizationInvitationParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization to create an invitation for. Required.'), + emailAddress: z.string().describe('(string): Email address to send the invitation to. Required.'), + role: z.string().describe('(string): Role to assign to the user upon accepting the invitation. Required.'), + inviterUserId: z + .string() + .optional() + .describe( + '(string, optional): User ID of the person sending the invitation. Defaults to the current authenticated user.', + ), + redirectUrl: z + .string() + .optional() + .describe('(string, optional): URL to redirect users to after they accept the invitation.'), + publicMetadata: z + .record(z.string(), z.any()) + .optional() + .describe('(Record, optional): Public metadata for the invitation.'), +}); + const createOrganizationInvitation = ClerkTool({ name: 'createOrganizationInvitation', description: ` @@ -335,38 +394,33 @@ const createOrganizationInvitation = ClerkTool({ 2. Implementing team expansion functionality 3. Creating administrative tools for organization growth `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization to create an invitation for. Required.'), - emailAddress: z.string().describe('(string): Email address to send the invitation to. Required.'), - role: z.string().describe('(string): Role to assign to the user upon accepting the invitation. Required.'), - inviterUserId: z - .string() - .optional() - .describe( - '(string, optional): User ID of the person sending the invitation. Defaults to the current authenticated user.', - ), - redirectUrl: z - .string() - .optional() - .describe('(string, optional): URL to redirect users to after they accept the invitation.'), - publicMetadata: z - .record(z.string(), z.any()) - .optional() - .describe('(Record, optional): Public metadata for the invitation.'), - }), - execute: (clerkClient, context) => async params => { + parameters: createOrganizationInvitationParameters, + execute: (clerkClient, context) => async (params: z.infer) => { const { inviterUserId, ...inviteParams } = params; + // Use provided inviterUserId or fall back to context userId const inviteParamsWithUser = inviterUserId || context.userId ? { ...inviteParams, inviterUserId: inviterUserId || context.userId } : inviteParams; - const res = await clerkClient.organizations.createOrganizationInvitation(inviteParamsWithUser); - return prunePrivateData(context, res.raw); + const res = await clerkClient.api.organizationInvitations.create(inviteParamsWithUser); + + return prunePrivateData(context, res); }, }); +const revokeOrganizationInvitationParameters = z.object({ + organizationId: z.string().describe('(string): The ID of the organization containing the invitation. Required.'), + invitationId: z.string().describe('(string): The ID of the invitation to revoke. Required.'), + requestingUserId: z + .string() + .optional() + .describe( + '(string, optional): User ID of the person revoking the invitation. Defaults to the current authenticated user.', + ), +}); + const revokeOrganizationInvitation = ClerkTool({ name: 'revokeOrganizationInvitation', description: ` @@ -381,17 +435,8 @@ const revokeOrganizationInvitation = ClerkTool({ 2. Building invitation management interfaces with revocation capability 3. Implementing security measures to quickly revoke access `, - parameters: z.object({ - organizationId: z.string().describe('(string): The ID of the organization containing the invitation. Required.'), - invitationId: z.string().describe('(string): The ID of the invitation to revoke. Required.'), - requestingUserId: z - .string() - .optional() - .describe( - '(string, optional): User ID of the person revoking the invitation. Defaults to the current authenticated user.', - ), - }), - execute: (clerkClient, context) => async params => { + parameters: revokeOrganizationInvitationParameters, + execute: (clerkClient, context) => async (params: z.infer) => { const { requestingUserId, ...revokeParams } = params; // Use provided requestingUserId or fall back to context userId const revokeParamsWithUser = @@ -399,8 +444,8 @@ const revokeOrganizationInvitation = ClerkTool({ ? { ...revokeParams, requestingUserId: requestingUserId || context.userId } : revokeParams; - const res = await clerkClient.organizations.revokeOrganizationInvitation(revokeParamsWithUser); - return prunePrivateData(context, res.raw); + const res = await clerkClient.api.organizationInvitations.revoke(revokeParamsWithUser); + return prunePrivateData(context, res); }, }); diff --git a/packages/agent-toolkit/src/lib/tools/users.ts b/packages/agent-toolkit/src/lib/tools/users.ts index a3c8848121a..1b3e54569e9 100644 --- a/packages/agent-toolkit/src/lib/tools/users.ts +++ b/packages/agent-toolkit/src/lib/tools/users.ts @@ -12,11 +12,15 @@ const getUserId = ClerkTool({ Example use case: When you need to verify if a user is logged in before performing user-specific operations. `, parameters: z.object({}), - execute: (clerkClient, context) => () => { + execute: (_, context) => () => { return Promise.resolve(context.userId || null); }, }); +const getUserParameters = z.object({ + userId: z.string().describe('(string): The userId of the User to retrieve.'), +}); + const getUser = ClerkTool({ name: 'getUser', description: ` @@ -26,12 +30,10 @@ const getUser = ClerkTool({ If the userId parameter is not provided, it will use the current authenticated user's ID. Example use case: When you need to display user profile information or check user attributes. `, - parameters: z.object({ - userId: z.string().describe('(string): The userId of the User to retrieve.'), - }), - execute: (clerkClient, context) => async params => { - const res = await clerkClient.users.getUser(context.userId || params.userId); - return prunePrivateData(context, res.raw); + parameters: getUserParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const res = await clerkClient.api.users.get(context.userId || params.userId); + return prunePrivateData(context, res); }, }); @@ -44,10 +46,17 @@ const getUserCount = ClerkTool({ `, parameters: z.object({}), execute: (clerkClient, _) => async () => { - return await clerkClient.users.getCount(); + return await clerkClient.api.users.count({}); // TODO: Mark requestBody as optional }, }); +const updateUserPublicMetadataParameters = z.object({ + userId: z.string().describe('(string): The userId of the User to update.'), + metadata: z + .record(z.string(), z.any()) + .describe('(Record): The public metadata to set or update. Use null values to remove specific keys.'), +}); + const updateUserPublicMetadata = ClerkTool({ name: 'updateUserPublicMetadata', description: ` @@ -61,19 +70,25 @@ const updateUserPublicMetadata = ClerkTool({ Example use case: Storing user preferences, feature flags, or application-specific data that persists across sessions. `, - parameters: z.object({ - userId: z.string().describe('(string): The userId of the User to update.'), - metadata: z - .record(z.string(), z.any()) - .describe('(Record): The public metadata to set or update. Use null values to remove specific keys.'), - }), - execute: (clerkClient, context) => async params => { + parameters: updateUserPublicMetadataParameters, + execute: (clerkClient, context) => async (params: z.infer) => { const { userId, metadata } = params; - const res = await clerkClient.users.updateUserMetadata(context.userId || userId, { publicMetadata: metadata }); - return prunePrivateData(context, res.raw); + const res = await clerkClient.api.users.updateMetadata({ + userId: context.userId || userId, + requestBody: { publicMetadata: metadata }, + }); + + return prunePrivateData(context, res); }, }); +const updateUserUnsafeMetadataParameters = z.object({ + userId: z.string().describe('(string): The userId of the User to update.'), + metadata: z + .record(z.string(), z.any()) + .describe('(Record): The unsafe metadata to set or update. Use null values to remove specific keys.'), +}); + const updateUserUnsafeMetadata = ClerkTool({ name: 'updateUserUnsafeMetadata', description: ` @@ -88,19 +103,26 @@ const updateUserUnsafeMetadata = ClerkTool({ Example use case: Storing user data that should be modifiable from the frontend but not included in authentication tokens. `, - parameters: z.object({ - userId: z.string().describe('(string): The userId of the User to update.'), - metadata: z - .record(z.string(), z.any()) - .describe('(Record): The unsafe metadata to set or update. Use null values to remove specific keys.'), - }), - execute: (clerkClient, context) => async params => { + parameters: updateUserUnsafeMetadataParameters, + execute: (clerkClient, context) => async (params: z.infer) => { const { userId, metadata } = params; - const res = await clerkClient.users.updateUserMetadata(context.userId || userId, { unsafeMetadata: metadata }); - return prunePrivateData(context, res.raw); + const res = await clerkClient.api.users.updateMetadata({ + userId: context.userId || userId, + requestBody: { unsafeMetadata: metadata }, + }); + + return prunePrivateData(context, res); }, }); +const updateUserParameters = z.object({ + userId: z.string().describe('(string): The userId of the User to update.'), + firstName: z.string().optional().describe('(string): New first name for the user'), + lastName: z.string().optional().describe('(string): New last name for the user'), + username: z.string().optional().describe('(string): New username for the user'), + profileImageUrl: z.string().optional().describe('(string): URL for the user profile image'), +}); + const updateUser = ClerkTool({ name: 'updateUser', description: ` @@ -118,17 +140,15 @@ const updateUser = ClerkTool({ 2. Enabling or disabling a user account 3. Setting a user's primary contact information `, - parameters: z.object({ - userId: z.string().describe('(string): The userId of the User to update.'), - firstName: z.string().optional().describe('(string): New first name for the user'), - lastName: z.string().optional().describe('(string): New last name for the user'), - username: z.string().optional().describe('(string): New username for the user'), - profileImageUrl: z.string().optional().describe('(string): URL for the user profile image'), - }), - execute: (clerkClient, context) => async params => { - const { userId, ...updateParams } = params; - const res = await clerkClient.users.updateUser(context.userId || userId, updateParams); - return prunePrivateData(context, res.raw); + parameters: updateUserParameters, + execute: (clerkClient, context) => async (params: z.infer) => { + const { userId, ...requestBody } = params; + const res = await clerkClient.api.users.update({ + userId: context.userId || userId, + requestBody, + }); + + return prunePrivateData(context, res); }, }); diff --git a/packages/astro/src/server/current-user.ts b/packages/astro/src/server/current-user.ts index 5c1dc7e7c65..e279ae0850d 100644 --- a/packages/astro/src/server/current-user.ts +++ b/packages/astro/src/server/current-user.ts @@ -1,16 +1,16 @@ -import type { User } from '@clerk/backend'; +import type { apiTypes } from '@clerk/backend'; import type { APIContext } from 'astro'; import { clerkClient } from './clerk-client'; import { getAuth } from './get-auth'; export const createCurrentUser = (req: Request, context: APIContext) => { - return async (): Promise => { + return async (): Promise => { const { userId } = getAuth(req, context.locals); if (!userId) { return null; } - return clerkClient(context).users.getUser(userId); + return clerkClient(context).api.users.get(userId); }; }; diff --git a/packages/backend/src/api/factory.ts b/packages/backend/src/api/factory.ts index efce5638d7d..2950abe292d 100644 --- a/packages/backend/src/api/factory.ts +++ b/packages/backend/src/api/factory.ts @@ -22,6 +22,7 @@ import { buildRequest } from './request'; export type CreateBackendApiOptions = Parameters[0]; export type ApiClient = ReturnType; +export type BackendApiClient = ReturnType; export function createBackendApiClient(options: CreateBackendApiOptions) { const request = buildRequest(options); diff --git a/packages/backend/src/api/index.ts b/packages/backend/src/api/index.ts index b710e0d7f27..774ada564f6 100644 --- a/packages/backend/src/api/index.ts +++ b/packages/backend/src/api/index.ts @@ -1,2 +1,3 @@ export * from './factory'; export * from './resources'; +export type * as apiTypes from '@clerk/backend-api-client/models/components'; diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 4662e5d2f69..81507eb5a18 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -32,7 +32,7 @@ export function createClerkClient(options: ClerkOptions): ClerkClient { const opts = { ...options }; const apiClient = createBackendApiClient(opts); const backendApiClient = createGeneratedBackendApiClient(opts); - const requestState = createAuthenticateRequest({ options: opts, apiClient }); + const requestState = createAuthenticateRequest({ options: opts, apiClient: backendApiClient }); const telemetry = new TelemetryCollector({ ...options.telemetry, publishableKey: opts.publishableKey, @@ -54,6 +54,12 @@ export function createClerkClient(options: ClerkOptions): ClerkClient { */ export type { OrganizationMembershipRole } from './api/resources'; export type { VerifyTokenOptions } from './tokens/verify'; + +/** + * Generated Types + */ +export type { apiTypes } from './api'; + /** * JSON types */ diff --git a/packages/backend/src/tokens/authObjects.ts b/packages/backend/src/tokens/authObjects.ts index 8f652eadfd3..fba57f8e863 100644 --- a/packages/backend/src/tokens/authObjects.ts +++ b/packages/backend/src/tokens/authObjects.ts @@ -11,7 +11,7 @@ import type { } from '@clerk/types'; import type { CreateBackendApiOptions } from '../api'; -import { createBackendApiClient } from '../api'; +import { createGeneratedBackendApiClient } from '../api'; import type { AuthenticateContext } from './authenticateContext'; type AuthObjectDebugData = Record; @@ -127,11 +127,18 @@ export function signedInAuthObject( ): SignedInAuthObject { const { actor, sessionId, sessionStatus, userId, orgId, orgRole, orgSlug, orgPermissions, factorVerificationAge } = generateSignedInAuthObjectProperties(sessionClaims); - const apiClient = createBackendApiClient(authenticateContext); + const apiClient = createGeneratedBackendApiClient(authenticateContext); const getToken = createGetToken({ sessionId, sessionToken, - fetcher: async (...args) => (await apiClient.sessions.getToken(...args)).jwt, + fetcher: async (sessionId, templateName = '') => { + const res = await apiClient.sessions.createTokenFromTemplate({ + sessionId, + templateName, + }); + + return res.jwt!; // eslint-disable-line @typescript-eslint/no-non-null-assertion + }, }); return { diff --git a/packages/backend/src/tokens/factory.ts b/packages/backend/src/tokens/factory.ts index c6369d2baf4..4e97728b491 100644 --- a/packages/backend/src/tokens/factory.ts +++ b/packages/backend/src/tokens/factory.ts @@ -1,4 +1,4 @@ -import type { ApiClient } from '../api'; +import type { BackendApiClient } from '../api'; import { mergePreDefinedOptions } from '../util/mergePreDefinedOptions'; import { authenticateRequest as authenticateRequestOriginal, debugRequestState } from './request'; import type { AuthenticateRequestOptions } from './types'; @@ -36,7 +36,7 @@ const defaultOptions = { */ export type CreateAuthenticateRequestOptions = { options: BuildTimeOptions; - apiClient: ApiClient; + apiClient: BackendApiClient; }; /** diff --git a/packages/backend/src/tokens/request.ts b/packages/backend/src/tokens/request.ts index 9d714029618..33d91707a47 100644 --- a/packages/backend/src/tokens/request.ts +++ b/packages/backend/src/tokens/request.ts @@ -1,3 +1,4 @@ +import type { Cookies } from '@clerk/backend-api-client/models/components'; import type { Match, MatchFunction } from '@clerk/shared/pathToRegexp'; import { match } from '@clerk/shared/pathToRegexp'; import type { JwtPayload } from '@clerk/types'; @@ -273,17 +274,30 @@ ${error.getFullMessage()}`, } try { - // Perform the actual token refresh. - const response = await options.apiClient.sessions.refreshSession(decodeResult.payload.sid, { - format: 'cookie', + const params = { + format: 'cookie' as const, suffixed_cookies: authenticateContext.usesSuffixedCookies(), expired_token: expiredSessionToken || '', refresh_token: refreshToken || '', request_origin: authenticateContext.clerkUrl.origin, // The refresh endpoint expects headers as Record, so we need to transform it. request_headers: Object.fromEntries(Array.from(request.headers.entries()).map(([k, v]) => [k, [v]])), + }; + + // Perform the actual token refresh + const response = await options.apiClient.sessions.refresh({ + sessionId: decodeResult.payload.sid, + requestBody: { + format: params.format, + // suffixedCookies: params.suffixed_cookies, // TODO: Doesn't seem to be handled in BAPI, but exists in the Backend SDK + expiredToken: params.expired_token, + refreshToken: params.refresh_token, + requestOrigin: params.request_origin, + requestHeaders: params.request_headers, + }, }); - return { data: response.cookies, error: null }; + + return { data: (response as Cookies).cookies, error: null }; } catch (err: any) { if (err?.errors?.length) { if (err.errors[0].code === 'unexpected_error') { diff --git a/packages/backend/src/tokens/types.ts b/packages/backend/src/tokens/types.ts index 3fb22480e39..d77160685dc 100644 --- a/packages/backend/src/tokens/types.ts +++ b/packages/backend/src/tokens/types.ts @@ -1,4 +1,4 @@ -import type { ApiClient } from '../api'; +import type { BackendApiClient } from '../api'; import type { VerifyTokenOptions } from './verify'; export type AuthenticateRequestOptions = { @@ -43,7 +43,7 @@ export type AuthenticateRequestOptions = { /** * @internal */ - apiClient?: ApiClient; + apiClient?: BackendApiClient; } & VerifyTokenOptions; /** diff --git a/packages/backend/src/util/decorateObjectWithResources.ts b/packages/backend/src/util/decorateObjectWithResources.ts index 4e90ff94ccd..9a08c6be228 100644 --- a/packages/backend/src/util/decorateObjectWithResources.ts +++ b/packages/backend/src/util/decorateObjectWithResources.ts @@ -1,5 +1,5 @@ -import type { CreateBackendApiOptions, Organization, Session, User } from '../api'; -import { createBackendApiClient } from '../api'; +import type { apiTypes, CreateBackendApiOptions } from '../api'; +import { createGeneratedBackendApiClient } from '../api'; import type { AuthObject } from '../tokens/authObjects'; type DecorateAuthWithResourcesOptions = { @@ -9,9 +9,9 @@ type DecorateAuthWithResourcesOptions = { }; type WithResources = T & { - session?: Session | null; - user?: User | null; - organization?: Organization | null; + session?: apiTypes.Session | null; + user?: apiTypes.User | null; + organization?: apiTypes.Organization | null; }; /** @@ -25,12 +25,12 @@ export const decorateObjectWithResources = async ( const { loadSession, loadUser, loadOrganization } = opts || {}; const { userId, sessionId, orgId } = authObj; - const { sessions, users, organizations } = createBackendApiClient({ ...opts }); + const { sessions, users, organizations } = createGeneratedBackendApiClient(opts); const [sessionResp, userResp, organizationResp] = await Promise.all([ - loadSession && sessionId ? sessions.getSession(sessionId) : Promise.resolve(undefined), - loadUser && userId ? users.getUser(userId) : Promise.resolve(undefined), - loadOrganization && orgId ? organizations.getOrganization({ organizationId: orgId }) : Promise.resolve(undefined), + loadSession && sessionId ? sessions.get(sessionId) : Promise.resolve(undefined), + loadUser && userId ? users.get(userId) : Promise.resolve(undefined), + loadOrganization && orgId ? organizations.get({ organizationId: orgId }) : Promise.resolve(undefined), ]); const resources = stripPrivateDataFromObject({ @@ -52,7 +52,7 @@ export function stripPrivateDataFromObject>(auth return { ...authObject, user, organization }; } -function prunePrivateMetadata(resource?: { private_metadata: any } | { privateMetadata: any } | null) { +function prunePrivateMetadata(resource?: { private_metadata?: any } | { privateMetadata?: any } | null) { // Delete sensitive private metadata from resource before rendering in SSR if (resource) { if ('privateMetadata' in resource) { diff --git a/packages/express/README.md b/packages/express/README.md index 43b785a5b6b..109334baf00 100644 --- a/packages/express/README.md +++ b/packages/express/README.md @@ -133,7 +133,7 @@ app.get('/path', requireAuth, hasPermission, (req, res) => res.json(req.auth)); ### `clerkClient` -[Clerk's JavaScript Backend SDK](/docs/references/backend/overview) exposes Clerk's Backend API resources and low-level authentication utilities for JavaScript environments. For example, if you wanted to get a list of all users in your application, instead of creating a fetch to Clerk's `https://api.clerk.com/v1/users` endpoint, you can use the `users.getUserList()` method provided by the JavaScript Backend SDK. +[Clerk's JavaScript Backend SDK](/docs/references/backend/overview) exposes Clerk's Backend API resources and low-level authentication utilities for JavaScript environments. For example, if you wanted to get a list of all users in your application, instead of creating a fetch to Clerk's `https://api.clerk.com/v1/users` endpoint, you can use the `users.list()` method provided by the JavaScript Backend SDK. All resource operations are mounted as sub-APIs on the `clerkClient` object. See the [reference documentation](/docs/references/backend/overview#usage) for more information. @@ -144,7 +144,7 @@ import express from 'express'; const app = express(); app.get('/users', requireAuth, async (req, res) => { - const users = await clerkClient.users.getUserList(); + const users = await clerkClient.api.users.list(); return res.json({ users }); }); ``` diff --git a/packages/nextjs/src/app-router/server/currentUser.ts b/packages/nextjs/src/app-router/server/currentUser.ts index 11fc0ad9d11..ffd5eb0ffb8 100644 --- a/packages/nextjs/src/app-router/server/currentUser.ts +++ b/packages/nextjs/src/app-router/server/currentUser.ts @@ -1,4 +1,4 @@ -import type { User } from '@clerk/backend'; +import type { apiTypes } from '@clerk/backend'; import { clerkClient } from '../../server/clerkClient'; import { auth } from './auth'; @@ -24,7 +24,7 @@ import { auth } from './auth'; * } * ``` */ -export async function currentUser(): Promise { +export async function currentUser(): Promise { // eslint-disable-next-line @typescript-eslint/no-require-imports require('server-only'); @@ -33,5 +33,5 @@ export async function currentUser(): Promise { return null; } - return (await clerkClient()).users.getUser(userId); + return (await clerkClient()).api.users.get(userId); } diff --git a/packages/nextjs/src/server/buildClerkProps.ts b/packages/nextjs/src/server/buildClerkProps.ts index cfbd4686d23..63be948feae 100644 --- a/packages/nextjs/src/server/buildClerkProps.ts +++ b/packages/nextjs/src/server/buildClerkProps.ts @@ -42,7 +42,7 @@ type BuildClerkProps = (req: RequestLike, authState?: BuildClerkPropsInitState) * export const getServerSideProps: GetServerSideProps = async (ctx) => { * const { userId } = getAuth(ctx.req) * - * const user = userId ? await clerkClient().users.getUser(userId) : undefined + * const user = userId ? await clerkClient().api.users.get(userId) : undefined * * return { props: { ...buildClerkProps(ctx.req, { user }) } } * } diff --git a/packages/nextjs/src/server/createGetAuth.ts b/packages/nextjs/src/server/createGetAuth.ts index 86c3f83b8e0..eaf81ee5b37 100644 --- a/packages/nextjs/src/server/createGetAuth.ts +++ b/packages/nextjs/src/server/createGetAuth.ts @@ -140,7 +140,7 @@ export const createSyncGetAuth = ({ * * const client = await clerkClient() * - * const user = userId ? await client.users.getUser(userId) : null + * const user = userId ? await client.api.users.get(userId) : null * * return res.status(200).json({}) * } diff --git a/packages/testing/src/common/setup.ts b/packages/testing/src/common/setup.ts index d6486ccaa4b..674ebb9243e 100644 --- a/packages/testing/src/common/setup.ts +++ b/packages/testing/src/common/setup.ts @@ -45,7 +45,7 @@ export const fetchEnvVars = async (options?: ClerkSetupOptions): Promise=0.10.0'} + engines: {'0': node >=0.10.0} '@expo/cli@0.22.22': resolution: {integrity: sha512-sOttVuk/8gdnsiSeDpnRNpLgBJHLbyQQC0QBGd2iHpr/x6xSYpgoRO6AqwAwGtQsk4ZEPZ83ulvccei1IIPdwg==} @@ -17179,6 +17179,13 @@ snapshots: '@inquirer/core': 10.1.0(@types/node@22.13.14) '@inquirer/type': 3.0.1(@types/node@22.13.14) '@types/node': 22.13.14 + optional: true + + '@inquirer/confirm@5.0.2(@types/node@22.14.0)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@22.14.0) + '@inquirer/type': 3.0.1(@types/node@22.14.0) + '@types/node': 22.14.0 '@inquirer/core@10.1.0(@types/node@22.13.14)': dependencies: @@ -17193,12 +17200,32 @@ snapshots: yoctocolors-cjs: 2.1.2 transitivePeerDependencies: - '@types/node' + optional: true + + '@inquirer/core@10.1.0(@types/node@22.14.0)': + dependencies: + '@inquirer/figures': 1.0.8 + '@inquirer/type': 3.0.1(@types/node@22.14.0) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + transitivePeerDependencies: + - '@types/node' '@inquirer/figures@1.0.8': {} '@inquirer/type@3.0.1(@types/node@22.13.14)': dependencies: '@types/node': 22.13.14 + optional: true + + '@inquirer/type@3.0.1(@types/node@22.14.0)': + dependencies: + '@types/node': 22.14.0 '@ioredis/commands@1.2.0': {} @@ -20498,6 +20525,15 @@ snapshots: msw: 2.7.3(@types/node@22.13.14)(typescript@5.8.2) vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + '@vitest/mocker@3.0.5(msw@2.7.3(@types/node@22.14.0)(typescript@5.8.2))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))': + dependencies: + '@vitest/spy': 3.0.5 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + msw: 2.7.3(@types/node@22.14.0)(typescript@5.8.2) + vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + '@vitest/pretty-format@3.0.5': dependencies: tinyrainbow: 2.0.0 @@ -27149,6 +27185,32 @@ snapshots: typescript: 5.8.2 transitivePeerDependencies: - '@types/node' + optional: true + + msw@2.7.3(@types/node@22.14.0)(typescript@5.8.2): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.0.2(@types/node@22.14.0) + '@mswjs/interceptors': 0.37.5 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + graphql: 16.9.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + strict-event-emitter: 0.5.1 + type-fest: 4.38.0 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - '@types/node' muggle-string@0.4.1: {} @@ -31091,6 +31153,27 @@ snapshots: - tsx - yaml + vite-node@3.0.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): + dependencies: + cac: 6.7.14 + debug: 4.4.0(supports-color@8.1.1) + es-module-lexer: 1.6.0 + pathe: 2.0.3 + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite-node@3.0.9(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: cac: 6.7.14 @@ -31202,14 +31285,14 @@ snapshots: optionalDependencies: vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) - vitest-environment-miniflare@2.14.4(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): + vitest-environment-miniflare@2.14.4(vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.14.0)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)): dependencies: '@miniflare/queues': 2.14.4 '@miniflare/runner-vm': 2.14.4 '@miniflare/shared': 2.14.4 '@miniflare/shared-test-environment': 2.14.4 undici: 5.28.4 - vitest: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.13.14)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vitest: 3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.14.0)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -31255,6 +31338,47 @@ snapshots: - tsx - yaml + vitest@3.0.5(@edge-runtime/vm@5.0.0)(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@24.1.3)(lightningcss@1.27.0)(msw@2.7.3(@types/node@22.14.0)(typescript@5.8.2))(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0): + dependencies: + '@vitest/expect': 3.0.5 + '@vitest/mocker': 3.0.5(msw@2.7.3(@types/node@22.14.0)(typescript@5.8.2))(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0)) + '@vitest/pretty-format': 3.0.5 + '@vitest/runner': 3.0.5 + '@vitest/snapshot': 3.0.5 + '@vitest/spy': 3.0.5 + '@vitest/utils': 3.0.5 + chai: 5.1.2 + debug: 4.4.0(supports-color@8.1.1) + expect-type: 1.1.0 + magic-string: 0.30.17 + pathe: 2.0.3 + std-env: 3.8.1 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 2.0.0 + vite: 6.2.3(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + vite-node: 3.0.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.27.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@edge-runtime/vm': 5.0.0 + '@types/debug': 4.1.12 + '@types/node': 22.14.0 + jsdom: 24.1.3 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vlq@1.0.1: {} vscode-uri@3.1.0: {} From f8f00f6b751085183aa87d4b5945a45cb88f75cc Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 4 Apr 2025 18:39:06 -0400 Subject: [PATCH 5/5] chore: Re-export API types --- packages/astro/env.d.ts | 2 +- packages/astro/src/server/index.ts | 1 + packages/nextjs/src/server/index.ts | 1 + packages/react-router/src/ssr/index.ts | 1 + packages/remix/src/ssr/index.ts | 1 + packages/tanstack-react-start/src/server/index.ts | 1 + 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/astro/env.d.ts b/packages/astro/env.d.ts index 294c409d808..51283079a1d 100644 --- a/packages/astro/env.d.ts +++ b/packages/astro/env.d.ts @@ -9,6 +9,6 @@ declare namespace App { auth: () => import('@clerk/astro/server').GetAuthReturn & { redirectToSignIn: import('@clerk/backend/internal').RedirectFun; }; - currentUser: () => Promise; + currentUser: () => Promise; } } diff --git a/packages/astro/src/server/index.ts b/packages/astro/src/server/index.ts index cef1456a20e..27344388b57 100644 --- a/packages/astro/src/server/index.ts +++ b/packages/astro/src/server/index.ts @@ -7,6 +7,7 @@ export { verifyToken, createClerkClient } from '@clerk/backend'; * Re-export types */ export type { + apiTypes, OrganizationMembershipRole, // Webhook event types WebhookEvent, diff --git a/packages/nextjs/src/server/index.ts b/packages/nextjs/src/server/index.ts index 93348d9d7f5..c2c771dc0fb 100644 --- a/packages/nextjs/src/server/index.ts +++ b/packages/nextjs/src/server/index.ts @@ -50,6 +50,7 @@ export type { ClerkMiddlewareAuth, ClerkMiddlewareAuthObject, ClerkMiddlewareOpt * Re-export resource types from @clerk/backend */ export type { + apiTypes, OrganizationMembershipRole, // Resources AllowlistIdentifier, diff --git a/packages/react-router/src/ssr/index.ts b/packages/react-router/src/ssr/index.ts index fcd02aa9159..3b644c1140e 100644 --- a/packages/react-router/src/ssr/index.ts +++ b/packages/react-router/src/ssr/index.ts @@ -5,6 +5,7 @@ export * from './getAuth'; * Re-export resource types from @clerk/backend */ export type { + apiTypes, OrganizationMembershipRole, // Webhook event types WebhookEvent, diff --git a/packages/remix/src/ssr/index.ts b/packages/remix/src/ssr/index.ts index fcd02aa9159..3b644c1140e 100644 --- a/packages/remix/src/ssr/index.ts +++ b/packages/remix/src/ssr/index.ts @@ -5,6 +5,7 @@ export * from './getAuth'; * Re-export resource types from @clerk/backend */ export type { + apiTypes, OrganizationMembershipRole, // Webhook event types WebhookEvent, diff --git a/packages/tanstack-react-start/src/server/index.ts b/packages/tanstack-react-start/src/server/index.ts index 4a56c1e5c15..698a9057245 100644 --- a/packages/tanstack-react-start/src/server/index.ts +++ b/packages/tanstack-react-start/src/server/index.ts @@ -7,6 +7,7 @@ export { clerkClient } from './clerkClient'; * Re-export resource types from @clerk/backend */ export type { + apiTypes, OrganizationMembershipRole, // Webhook event types WebhookEvent,