Skip to content

Commit

Permalink
feat(cli): cache telemetry consent status
Browse files Browse the repository at this point in the history
  • Loading branch information
juice49 authored and bjoerge committed Dec 11, 2023
1 parent 7053829 commit cd555ca
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 6 deletions.
4 changes: 4 additions & 0 deletions packages/@sanity/cli/src/actions/login/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {getCliToken} from '../../util/clientWrapper'
import {getUserConfig} from '../../util/getUserConfig'
import {canLaunchBrowser} from '../../util/canLaunchBrowser'
import type {CliApiClient, CliCommandArguments, CliCommandContext, CliPrompter} from '../../types'
import {TELEMETRY_CONSENT_CONFIG_KEY} from '../../util/createTelemetryStore'
import type {LoginProvider, ProvidersResponse, SamlLoginProvider} from './types'
import {LoginTrace} from './login.telemetry'

Expand Down Expand Up @@ -122,6 +123,9 @@ export async function login(
authType: 'normal',
})

// Clear cached telemetry consent
getUserConfig().delete(TELEMETRY_CONSENT_CONFIG_KEY)

// If we had a session previously, attempt to clear it
if (hasExistingToken) {
await apiClient({requireUser: true, requireProject: false})
Expand Down
4 changes: 4 additions & 0 deletions packages/@sanity/cli/src/commands/logout/logoutCommand.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import chalk from 'chalk'
import type {CliCommandDefinition} from '../../types'
import {getUserConfig} from '../../util/getUserConfig'
import {TELEMETRY_CONSENT_CONFIG_KEY} from '../../util/createTelemetryStore'

const helpText = `
Examples
Expand Down Expand Up @@ -40,6 +41,9 @@ const logoutCommand: CliCommandDefinition = {
cfg.delete('authType')
cfg.delete('authToken')

// Clear cached telemetry consent
cfg.delete(TELEMETRY_CONSENT_CONFIG_KEY)

output.print(chalk.green('Logged out'))
},
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {CliCommandDefinition} from '../../types'
import {resolveConsent} from '../../util/initTelemetry'
import {resolveConsent} from '../../util/createTelemetryStore'

const helpText = `
Examples
Expand Down
9 changes: 8 additions & 1 deletion packages/@sanity/cli/src/util/createExpiringConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function createExpiringConfig<Type>({
onFetch = () => null,
onCacheHit = () => null,
}: ExpiringConfigOptions<Type>): ExpiringConfigApi<Type> {
let currentFetch: Promise<Type> | null = null
return {
async get() {
const {value, updatedAt} = store.get(key) ?? {}
Expand All @@ -56,8 +57,14 @@ export function createExpiringConfig<Type>({
onRevalidate()
}

if (currentFetch) {
return currentFetch
}
onFetch()
const nextValue = await fetchValue()

currentFetch = Promise.resolve(fetchValue())
const nextValue = await currentFetch
currentFetch = null

store.set(key, {
value: nextValue,
Expand Down
32 changes: 28 additions & 4 deletions packages/@sanity/cli/src/util/createTelemetryStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ import {createClient, SanityClient} from '@sanity/client'
import {ConsentStatus, createBatchedStore, createSessionId, TelemetryEvent} from '@sanity/telemetry'
import {debug as baseDebug} from '../debug'
import {getCliToken} from './clientWrapper'
import {getUserConfig} from './getUserConfig'
import {createExpiringConfig} from './createExpiringConfig'

const debug = baseDebug.extend('telemetry')

const FIVE_MINUTES = 1000 * 60 * 5

export const TELEMETRY_CONSENT_CONFIG_KEY = 'telemetryConsent'

function isTrueish(value: string | undefined) {
if (value === undefined) return false
if (value.toLowerCase() === 'true') return true
Expand Down Expand Up @@ -96,15 +102,33 @@ export function resolveConsent({env}: Options): Promise<ConsentInformation> {

const client = getCachedClient(token)

function fetchConsent(): Promise<{
status: ValidConsentStatus
}> {
function fetchConsent() {
const telemetryConsentConfig = createExpiringConfig<{
status: ValidConsentStatus
}>({
store: getUserConfig(),
key: TELEMETRY_CONSENT_CONFIG_KEY,
ttl: FIVE_MINUTES,
fetchValue: () => client.request({uri: '/users/me/consents/telemetry'}),
onRevalidate() {
debug('Revalidating cached telemetry consent status...')
},
onFetch() {
debug('Fetching telemetry consent status...')
},
onCacheHit() {
debug('Retrieved telemetry consent status from cache')
},
})

if (env.MOCK_CONSENT) {
debug('Mocking telemetry consent status')
return Promise.resolve({
status: isTrueish(env.MOCK_CONSENT) ? 'granted' : parseConsent(env.MOCK_CONSENT),
})
}
return client.request({uri: '/users/me/consents/telemetry'})

return telemetryConsentConfig.get()
}

return fetchConsent()
Expand Down

0 comments on commit cd555ca

Please sign in to comment.