Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(gatsby-telemetry): Migrate package to TS #22532

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/gatsby-cli/src/create-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ Creating a plugin:
}),

handler: handlerP(({ enable, disable }: yargs.Arguments) => {
const enabled = enable || !disable
const enabled = !!enable || !disable
setTelemetryEnabled(enabled)
report.log(`Telemetry collection ${enabled ? `enabled` : `disabled`}`)
}),
Expand Down
10 changes: 9 additions & 1 deletion packages/gatsby-telemetry/.babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
{
"presets": [["babel-preset-gatsby-package"]]
"presets": [
["babel-preset-gatsby-package"]
],
"overrides": [
{
"test": ["**/*.ts", "**/*.tsx"],
"plugins": [["@babel/plugin-transform-typescript", { "isTSX": true }]]
}
]
}
5 changes: 4 additions & 1 deletion packages/gatsby-telemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
"devDependencies": {
"@babel/cli": "^7.10.1",
"@babel/core": "^7.10.2",
"@types/node-fetch": "^2.5.5",
"@types/uuid": "^7.0.2",
"babel-jest": "^24.9.0",
"babel-preset-gatsby-package": "^0.4.4",
"cross-env": "^5.2.1",
Expand All @@ -52,7 +54,8 @@
},
"scripts": {
"build": "babel src --out-dir lib --ignore \"**/__tests__\",\"**/__mocks__\" --extensions \".ts,.js\"",
"prepare": "cross-env NODE_ENV=production npm run build",
"typegen": "tsc --emitDeclarationOnly --declaration --declarationDir lib/",
"prepare": "cross-env NODE_ENV=production npm run build && npm run typegen",
"jest": "jest",
"postinstall": "node src/postinstall.js || true",
"watch": "babel -w src --out-dir lib --ignore \"**/__tests__\",\"**/__mocks__\" --extensions \".ts,.js\""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { sanitizeError, cleanPaths } = require(`../error-helpers`)
import { sanitizeError, cleanPaths } from "../error-helpers"

describe(`Errors Helpers`, () => {
describe(`sanitizeError`, () => {
Expand Down Expand Up @@ -90,7 +90,7 @@ describe(`Errors Helpers`, () => {
expect(sanitizedErrorString).toEqual(
expect.not.stringContaining(`sidharthachatterjee`)
)
expect(sanitizedErrorString.match(/\$SNIP/g).length).toBe(4)
expect(sanitizedErrorString.match(/\$SNIP/g)!.length).toBe(4)

mockCwd.mockRestore()
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const isTruthy = require(`../is-truthy`)
import { isTruthy } from "../is-truthy"

describe(`isTruthy`, () => {
it(`handles Booleans`, () => {
Expand Down
23 changes: 0 additions & 23 deletions packages/gatsby-telemetry/src/__tests__/telemetry.js

This file was deleted.

26 changes: 26 additions & 0 deletions packages/gatsby-telemetry/src/__tests__/telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
jest.mock(`../event-storage`)
import { EventStorage as RealEventStorage } from "../event-storage"
import { Telemetry } from "../telemetry"

let telemetry: Telemetry
let EventStorage: jest.Mock<RealEventStorage>

beforeEach(() => {
EventStorage = RealEventStorage as jest.Mock<RealEventStorage>
EventStorage.mockReset()
telemetry = new Telemetry()
})

describe(`Telemetry`, () => {
it(`Adds event to store`, () => {
telemetry.buildAndStoreEvent(`demo`, {})
expect(EventStorage).toHaveBeenCalledTimes(1)
expect(EventStorage.mock.instances[0].addEvent).toHaveBeenCalledTimes(1)
})

it(`Doesn't add event to store if telemetry tracking is turned off`, () => {
telemetry.trackingEnabled = false
telemetry.trackActivity(`demo`)
expect(EventStorage.mock.instances[0].addEvent).not.toHaveBeenCalled()
})
})
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
const { sep } = require(`path`)
import { sep } from "path"

// Removes all user paths
const regexpEscape = str => str.replace(/[-[/{}()*+?.\\^$|]/g, `\\$&`)
const cleanPaths = (str, separator = sep) => {
const regexpEscape = (str: string): string =>
str.replace(/[-[/{}()*+?.\\^$|]/g, `\\$&`)
export const cleanPaths = (str: string, separator = sep): string => {
const stack = process.cwd().split(separator)

while (stack.length > 1) {
Expand All @@ -20,7 +21,10 @@ const cleanPaths = (str, separator = sep) => {
}

// Takes an Error and returns a sanitized JSON String
const sanitizeError = (error, pathSeparator = sep) => {
export const sanitizeError = (
error: { [x: string]: unknown; stderr?: unknown; stdout?: unknown },
pathSeparator = sep
): string => {
// Convert Buffers to Strings
if (error.stderr) error.stderr = String(error.stderr)
if (error.stdout)
Expand All @@ -37,8 +41,3 @@ const sanitizeError = (error, pathSeparator = sep) => {
// Removes all user paths
return cleanPaths(errorString, pathSeparator)
}

module.exports = {
sanitizeError,
cleanPaths,
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,58 @@
const os = require(`os`)
const path = require(`path`)
const Store = require(`./store`)
const fetch = require(`node-fetch`)
const Configstore = require(`configstore`)
const { ensureDirSync } = require(`fs-extra`)

const isTruthy = require(`./is-truthy`)
import os from "os"
import path from "path"
import { Store } from "./store"
import fetch from "node-fetch"
import Configstore from "configstore"
import { ensureDirSync } from "fs-extra"

import { isTruthy } from "./is-truthy"

interface IConfigTypes {
"telemetry.machineId": string
"telemetry.enabled": boolean
}

/* The events data collection is a spooled process that
/**
* The events data collection is a spooled process that
* buffers events to a local fs based buffer
* which then is asynchronously flushed to the server.
* This both increases the fault tolerancy and allows collection
* to continue even when working offline.
*/
module.exports = class EventStorage {
analyticsApi =
export class EventStorage {
private analyticsApi =
process.env.GATSBY_TELEMETRY_API || `https://analytics.gatsbyjs.com/events`
private config: Configstore
private store: Store
private verbose: boolean
private debugEvents: boolean
private disabled: boolean

constructor() {
try {
this.config = new Configstore(`gatsby`, {}, { globalConfigPath: true })
} catch (e) {
// This should never happen
this.config = {
get: key => this.config[key],
set: (key, value) => (this.config[key] = value),
all: this.config,
set: (key: string | [string, unknown][], value?: unknown) => {
// This function has two overloads.
// 1. (key: string, value: unknown)
// 2. (values: [string, unknown][])
if (typeof key === `string`) {
this.config[key] = value
} else {
for (const [k, v] of key) {
this.config[k] = v
}
}
},
path: path.join(os.tmpdir(), `gatsby`),
"telemetry.enabled": true,
"telemetry.machineId": `not-a-machine-id`,
}
} as Configstore

this.config.all = this.config
this.config[`telemetry.machineId`] = `not-a-machine-id`
this.config[`telemetry.enabled`] = true
}

const baseDir = path.dirname(this.config.path)
Expand All @@ -45,11 +69,11 @@ module.exports = class EventStorage {
this.disabled = isTruthy(process.env.GATSBY_TELEMETRY_DISABLED)
}

isTrackingDisabled() {
isTrackingDisabled(): boolean {
return this.disabled
}

addEvent(event) {
addEvent(event: unknown): void {
if (this.disabled) {
return
}
Expand All @@ -68,7 +92,7 @@ module.exports = class EventStorage {
this.store.appendToBuffer(eventString + `\n`)
}

async sendEvents() {
async sendEvents(): Promise<void> {
return this.store.startFlushEvents(async eventsData => {
const events = eventsData
.split(`\n`)
Expand All @@ -79,7 +103,7 @@ module.exports = class EventStorage {
})
}

async submitEvents(events) {
async submitEvents(events: unknown): Promise<boolean> {
try {
const res = await fetch(this.analyticsApi, {
method: `POST`,
Expand All @@ -95,7 +119,7 @@ module.exports = class EventStorage {
}
}

getUserAgent() {
getUserAgent(): string {
try {
const { name, version } = require(`../package.json`)
return `${name}:${version}`
Expand All @@ -104,14 +128,17 @@ module.exports = class EventStorage {
}
}

getConfig(key) {
getConfig<TKey extends keyof IConfigTypes>(key: TKey): IConfigTypes[TKey] {
if (key) {
return this.config.get(key)
}
return this.config.all
}

updateConfig(key, value) {
updateConfig<TKey extends keyof IConfigTypes>(
key: TKey,
value: IConfigTypes[TKey] | undefined
): void {
return this.config.set(key, value)
}
}
17 changes: 0 additions & 17 deletions packages/gatsby-telemetry/src/flush.js

This file was deleted.

19 changes: 19 additions & 0 deletions packages/gatsby-telemetry/src/flush.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { join } from "path"
import { fork } from "child_process"

export const makeFlush = (isTrackingEnabled: boolean) => async (): Promise<
void
> => {
if (!isTrackingEnabled) {
return
}

// Submit events on background w/o blocking the main process
// nor relying on it's lifecycle
const forked = fork(join(__dirname, `send.js`), /* args= */ undefined, {
detached: true,
stdio: `ignore`,
execArgv: [],
})
forked.unref()
}
42 changes: 0 additions & 42 deletions packages/gatsby-telemetry/src/index.js

This file was deleted.

Loading