diff --git a/.changeset/strange-maps-marry.md b/.changeset/strange-maps-marry.md new file mode 100644 index 00000000000..08d48cc6402 --- /dev/null +++ b/.changeset/strange-maps-marry.md @@ -0,0 +1,5 @@ +--- +"@clerk/astro": patch +--- + +Implement telemetry for nanostores and middleware usage; include SDK metadata. diff --git a/packages/astro/src/integration/create-integration.ts b/packages/astro/src/integration/create-integration.ts index 112f354ac94..90a088e41df 100644 --- a/packages/astro/src/integration/create-integration.ts +++ b/packages/astro/src/integration/create-integration.ts @@ -1,6 +1,7 @@ +import type { ClerkOptions } from '@clerk/types'; import type { AstroIntegration } from 'astro'; -import { name as packageName } from '../../package.json'; +import { name as packageName, version as packageVersion } from '../../package.json'; import type { AstroClerkIntegrationParams } from '../types'; const buildEnvVarFromOption = (valueToBeStored: unknown, envName: string) => { @@ -24,6 +25,16 @@ function createIntegration
({ mode }: const clerkJSVariant = (params as any)?.clerkJSVariant as string | undefined; const clerkJSVersion = (params as any)?.clerkJSVersion as string | undefined; + const internalParams: ClerkOptions = { + ...params, + sdkMetadata: { + version: packageVersion, + name: packageName, + // eslint-disable-next-line turbo/no-undeclared-env-vars + environment: import.meta.env.MODE, + }, + }; + return { name: '@clerk/astro/integration', hooks: { @@ -96,7 +107,7 @@ function createIntegration
({ mode }: ` ${command === 'dev' ? `console.log('${packageName}',"Initialize Clerk: before-hydration")` : ''} import { runInjectionScript } from "${buildImportPath}"; - await runInjectionScript(${JSON.stringify(params)});`, + await runInjectionScript(${JSON.stringify(internalParams)});`, ); /** @@ -110,7 +121,7 @@ function createIntegration
({ mode }: ` ${command === 'dev' ? `console.log("${packageName}","Initialize Clerk: page")` : ''} import { runInjectionScript } from "${buildImportPath}"; - await runInjectionScript(${JSON.stringify(params)});`, + await runInjectionScript(${JSON.stringify(internalParams)});`, ); }, }, diff --git a/packages/astro/src/server/clerk-client.ts b/packages/astro/src/server/clerk-client.ts index 6e0999ace3e..a1e7178cab4 100644 --- a/packages/astro/src/server/clerk-client.ts +++ b/packages/astro/src/server/clerk-client.ts @@ -11,12 +11,16 @@ const createClerkClientWithOptions: CreateClerkClientWithOptions = (context, opt publishableKey: getSafeEnv(context).pk, apiUrl: getSafeEnv(context).apiUrl, apiVersion: getSafeEnv(context).apiVersion, - // userAgent proxyUrl: getSafeEnv(context).proxyUrl, domain: getSafeEnv(context).domain, isSatellite: getSafeEnv(context).isSatellite, - // TODO: Support telemetry and sdkMetadata - + userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`, + sdkMetadata: { + name: PACKAGE_NAME, + version: PACKAGE_VERSION, + // eslint-disable-next-line turbo/no-undeclared-env-vars + environment: import.meta.env.MODE, + }, ...options, }); diff --git a/packages/astro/src/server/clerk-middleware.ts b/packages/astro/src/server/clerk-middleware.ts index 6991c9b732e..753df636cd8 100644 --- a/packages/astro/src/server/clerk-middleware.ts +++ b/packages/astro/src/server/clerk-middleware.ts @@ -2,6 +2,7 @@ import type { ClerkClient } from '@clerk/backend'; import type { AuthenticateRequestOptions, AuthObject, ClerkRequest, RequestState } from '@clerk/backend/internal'; import { AuthStatus, constants, createClerkRequest, createRedirect } from '@clerk/backend/internal'; import { handleValueOrFn, isDevelopmentFromSecretKey, isHttpOrHttps } from '@clerk/shared'; +import { eventMethodCalled } from '@clerk/shared/telemetry'; import type { APIContext } from 'astro'; // @ts-ignore @@ -60,6 +61,14 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => { const astroMiddleware: AstroMiddleware = async (context, next) => { const clerkRequest = createClerkRequest(context.request); + clerkClient(context).telemetry.record( + eventMethodCalled('clerkMiddleware', { + handler: Boolean(handler), + satellite: Boolean(options.isSatellite), + proxy: Boolean(options.proxyUrl), + }), + ); + const requestState = await clerkClient(context).authenticateRequest( clerkRequest, createAuthenticateRequestOptions(clerkRequest, options, context), diff --git a/packages/astro/src/stores/external.ts b/packages/astro/src/stores/external.ts index 1f129ee2f7c..9ed82c6a8cc 100644 --- a/packages/astro/src/stores/external.ts +++ b/packages/astro/src/stores/external.ts @@ -1,4 +1,5 @@ -import { computed } from 'nanostores'; +import { eventMethodCalled } from '@clerk/shared/telemetry'; +import { computed, onMount, type Store } from 'nanostores'; import { $clerk, $csrState, $initialState } from './internal'; import { deriveState } from './utils'; @@ -36,10 +37,6 @@ export const $authStore = computed([$csrState, $initialState], (state, initialSt * $userStore.subscribe((user) => console.log(user.id)) */ export const $userStore = computed([$authStore], auth => auth.user); -// TODO: on mounted subscriber log telemetry -// onMount($userStore, () => { -// // isomorphicClerk.telemetry?.record(eventMethodCalled('useSignIn')); -// }); /** * A client side store that is populated after clerk-js has loaded. @@ -124,3 +121,19 @@ export const $signInStore = computed([$clientStore], client => client?.signIn); * $signUpStore.subscribe((signUp) => console.log(signUp.status)) */ export const $signUpStore = computed([$clientStore], client => client?.signUp); + +/** + * Records a telemetry event when a store is used to match React hooks telemetry. + * + * @param {Store} store - The nanostore instance to monitor. + * @param {string} method - The name of the method associated with the store usage. + */ +const recordTelemetryEvent = (store: Store, method: string) => { + onMount(store, () => { + $clerk.get()?.telemetry?.record(eventMethodCalled(method)); + }); +}; + +recordTelemetryEvent($signInStore, '$signInStore'); +recordTelemetryEvent($signUpStore, '$signUpStore'); +recordTelemetryEvent($organizationStore, '$organizationStore');