import Conf from "conf" ; import chalk from "chalk" ; import { BinaryLike , createHash , randomBytes } from "crypto" ; import { postPayload } from "./post-payload" ; import { getRawProjectId } from "./project-id" ; import { getEnvironmentData } from "./environment" ; const TELEMETRY_API = "https://telemetry.serverless-stack.com/events" ; const TELEMETRY_KEY_ENABLED = "telemetry.enabled" ; const TELEMETRY_KEY_NOTIFY_DATE = "telemetry.notifiedAt" ; const TELEMETRY_KEY_ID = `telemetry.anonymousId` ; type EventContext = { anonymousId : string ; projectId : string ; sessionId : string ; } ; const conf = initializeConf ( ) ; const sessionId = randomBytes ( 32 ) . toString ( "hex" ) ; const projectId = hash ( getRawProjectId ( ) ) ; const anonymousId = getAnonymousId ( ) ; notify ( ) ; export function enable ( ) { conf && conf . set ( TELEMETRY_KEY_ENABLED , true ) ; } export function disable ( ) { conf && conf . set ( TELEMETRY_KEY_ENABLED , false ) ; } export function isEnabled ( ) { if ( ! conf ) { return false ; } return conf . get ( TELEMETRY_KEY_ENABLED , true ) !== false ; } export function trackCli ( command ) { record ( "CLI_COMMAND" , { command , } ) ; } function initializeConf ( ) { try { return new Conf ( { projectName : "sst" } ) ; } catch ( _ ) { return null ; } } function notify ( ) { if ( ! conf || willNotRecord ( ) ) { return ; } if ( conf . get ( TELEMETRY_KEY_NOTIFY_DATE ) !== undefined ) { return ; } conf . set ( TELEMETRY_KEY_NOTIFY_DATE , Date . now ( ) . toString ( ) ) ; console . log ( `${ chalk . cyan . bold ( "Attention" ) }: SST now collects completely anonymous telemetry regarding usage. This is used to guide SST's roadmap.` ) ; console . log ( `You can learn more, including how to opt-out of this anonymous program, by heading over to:` ) ; console . log ( "https://docs.serverless-stack.com/anonymous-telemetry" ) ; console . log ( ) ; } function willNotRecord ( ) { return ! isEnabled ( ) || ! ! process . env . SST_TELEMETRY_DISABLED ; } function record ( name , properties ) { if ( willNotRecord ( ) ) { return Promise . resolve ( ) ; } const context = { anonymousId , projectId , sessionId , } ; return postPayload ( TELEMETRY_API , { context , environment : getEnvironmentData ( ) , events : [ { name , properties , } , ] , } ) ; } function getAnonymousId ( ) { const val = conf && conf . get ( TELEMETRY_KEY_ID ) ; if ( val ) { return val as string ; } const generated = randomBytes ( 32 ) . toString ( "hex" ) ; conf && conf . set ( TELEMETRY_KEY_ID , generated ) ; return generated ; } function hash ( payload ) { return createHash ( "sha256" ) . update ( payload ) . digest ( "hex" ) ; }