Skip to content

Commit

Permalink
Merge branch 'master' into elements-chain-string
Browse files Browse the repository at this point in the history
  • Loading branch information
davemurphysf authored Nov 7, 2023
2 parents d89ac78 + 10fd7f4 commit 7d95577
Show file tree
Hide file tree
Showing 98 changed files with 5,764 additions and 3,980 deletions.
31 changes: 30 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const rules = {
'@typescript-eslint/no-unused-vars': ['error'],
'no-prototype-builtins': 'off',
'no-empty': 'off',
'no-console': 'error',
}

const extend = [
Expand All @@ -18,6 +19,7 @@ const extend = [
'plugin:react-hooks/recommended',
'prettier',
'plugin:compat/recommended',
'plugin:posthog-js/all',
]

module.exports = {
Expand All @@ -43,6 +45,12 @@ module.exports = {
react: {
version: '17.0',
},
'import/resolver': {
node: {
paths: ['eslint-rules'], // Add the directory containing your custom rules
extensions: ['.js', '.jsx', '.ts', '.tsx'], // Ensure ESLint resolves both JS and TS files
},
},
},
overrides: [
{
Expand All @@ -51,7 +59,28 @@ module.exports = {
// but excluding the 'plugin:compat/recommended' rule
// we don't mind using the latest features in our tests
extends: extend.filter((s) => s !== 'plugin:compat/recommended'),
rules,
rules: {
...rules,
'no-console': 'off',
},
},
{
files: 'eslint-rules/**/*',
extends: ['eslint:recommended', 'prettier'],
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/no-var-requires': 'off',
'posthog-js/no-direct-null-check': 'off',
},
env: {
node: true,
},
},
{
files: 'cypress/**/*',
globals: {
cy: true,
},
},
],
root: true,
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/library-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,5 @@ jobs:

- run: |
yarn prettier --check
yarn eslint
yarn lint
yarn tsc -b
2 changes: 1 addition & 1 deletion .github/workflows/testcafe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest

strategy:
matrix:
matrix:
browserstack:
- chrome
- ie
Expand Down
111 changes: 111 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,114 @@
## 1.88.1 - 2023-11-02

- chore(deps): bump next from 13.1.6 to 13.5.0 in /playground/nextjs (#855)
- Tweak session prop names (#873)

## 1.88.0 - 2023-11-02

- feat(web-analytics): Add client-side session params (#869)

## 1.87.6 - 2023-10-31

- fix: add tests for browser and browser version detection (#870)

## 1.87.5 - 2023-10-30

- fix: include raw user agent in event properties (#868)

## 1.87.4 - 2023-10-30

- fix: logging pointless error when offline (#866)

## 1.87.3 - 2023-10-30

- feat: retry count in url (#864)

## 1.87.2 - 2023-10-27

- fix(surveys): Publish types in module (#863)

## 1.87.1 - 2023-10-26

- fix(surveys): clearer user property names (#861)

## 1.87.0 - 2023-10-26

- feat(surveys): Make selector targeting work, add user props (#858)

## 1.86.0 - 2023-10-26

- feat: allow backend to specify a custom analytics endpoint (#831)

## 1.85.4 - 2023-10-26

- fix: checkout every X minutes (#860)
- feat: lazily load exception autocapture (#856)

## 1.85.3 - 2023-10-25

- feat: Toolbar loading from state faster (#849)

## 1.85.2 - 2023-10-24

- fix(surveys): cancel listener should be on all questions (#854)
- Fix changelog.md (#853)
- fix: eslint does not fail build (#852)

## 1.85.1 - 2023-10-24

- fix: Disable the string reduction code until we can battle test it more. (#851)

## 1.85.0 - 2023-10-24

- feat: allow sampling based on decide response (#839)

## 1.84.4 - 2023-10-24

- log when browser offline (#850)
- chore: type checking in one place makes bundle smaller (#843)

## 1.84.3 - 2023-10-23

- fix: full snapshot every 10 minutes (#847)
- fix: really fix subdomain check to satisfy codeql (#845)

## 1.84.2 - 2023-10-23

- fix: heroku subdomain check (#842)

## 1.84.1 - 2023-10-19

- fix(surveys): fix multiple choice input unique ID bug (#841)

## 1.84.0 - 2023-10-18

- Fix bot user agent detection (#840)

## 1.83.3 - 2023-10-17

- fix(surveys): add listener to 0th element (#837)

## 1.83.2 - 2023-10-17

- chore: Make ratings start at 0 (#834)

## 1.83.1 - 2023-10-11

- feat: Move all logs everything over to logger (#830)
- Update DOMAIN_MATCH_REGEX (#787)

## 1.83.0 - 2023-10-10

- feat(surveys): Optional survey questions (#826)

## 1.82.3 - 2023-10-06

- fix: Typescript compilation of survey types (#827)

## 1.82.2 - 2023-10-05

- fix(surveys): open text value bug (#825)

## 1.82.1 - 2023-10-04

- fix(surveys): multiple choice survey submit button bug (#822)
Expand Down
10 changes: 1 addition & 9 deletions cypress/e2e/capture.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('Event capture', () => {
sessionRecording: given.sessionRecording,
supportedCompression: given.supportedCompression,
excludedDomains: [],
autocaptureExceptions: true,
autocaptureExceptions: false,
},
}).as('decide')

Expand Down Expand Up @@ -53,14 +53,6 @@ describe('Event capture', () => {
cy.phCaptures().should('include', 'custom-event')
})

it('captures exceptions', () => {
start()

cy.get('[data-cy-exception-button]').click()
cy.phCaptures().should('have.length', 3)
cy.phCaptures().should('include', '$exception')
})

describe('autocapture config', () => {
it('dont capture click when configured not to', () => {
given('options', () => ({
Expand Down
1 change: 1 addition & 0 deletions cypress/support/e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import 'given2/setup'
// require('./commands')

// Add console errors into cypress logs.
// eslint-disable-next-line no-undef
Cypress.on('window:before:load', (win) => {
cy.spy(win.console, 'error')
cy.spy(win.console, 'warn')
Expand Down
8 changes: 8 additions & 0 deletions eslint-rules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# PostHog JS Custom ESLint rules

This package contains custom ESLint rules for PostHog's JS codebase.

For example, we have a number of functions that check types like `_isNull` or `isBoolean`.
In most projects these don't help very much but since posthog-js is bundled and included in many different projects,
we want to ensure the bundle size is as small as possible. Moving to these functions reduced bundle by 1%, so we
use a set of custom linters to ensure we don't accidentally add new code that does not use these helpers.
124 changes: 124 additions & 0 deletions eslint-rules/custom-eslint-rules.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
const noDirectNullCheck = require('./no-direct-null-check')
const noDirectUndefinedCheck = require('./no-direct-undefined-check')
const noDirectArrayCheck = require('./no-direct-array-check')
const noDirectIsFunctionCheck = require('./no-direct-function-check')
const noDirectObjectCheck = require('./no-direct-object-check')
const noDirectStringCheck = require('./no-direct-string-check')
const noDirectDateCheck = require('./no-direct-date-check')
const noDirectNumberCheck = require('./no-direct-number-check')
const noDirectBooleanCheck = require('./no-direct-boolean-check')

const { RuleTester } = require('eslint')

const ruleTester = new RuleTester()

ruleTester.run('no-direct-null-check', noDirectNullCheck, {
valid: [{ code: `_isNull(x)` }],
invalid: [{ code: `x === null`, errors: [{ message: 'Use _isNull() instead of direct null checks.' }] }],
})

ruleTester.run('no-direct-undefined-check', noDirectUndefinedCheck, {
valid: [{ code: `_isUndefined(x)` }],
invalid: [
{
code: `typeof x === undefined`,
errors: [{ message: 'Use _isUndefined() instead of direct undefined checks.' }],
},
],
})

ruleTester.run('no-direct-array-check', noDirectArrayCheck, {
valid: [{ code: `_isArray(x)` }],
invalid: [
{
code: `Array.isArray(x)`,
errors: [{ message: 'Use _isArray() instead of direct array checks.' }],
},
],
})

ruleTester.run('no-direct-is-function-check', noDirectIsFunctionCheck, {
valid: [{ code: `_isFunction(x)` }],
invalid: [
{
code: `/^\\s*\\bfunction\\b/.test(x)`,
errors: [{ message: 'Do not use regex to check for functions. Use _isFunction instead.' }],
},
{
code: `x instanceof Function`,
errors: [{ message: "Do not use 'instanceof Function' to check for functions. Use _isFunction instead." }],
},
{
code: `typeof x === "function"`,
errors: [
{ message: 'Do not use \'typeof x === "function"\' to check for functions. Use _isFunction instead.' },
],
},
],
})

ruleTester.run('no-direct-object-check', noDirectObjectCheck, {
valid: [{ code: `_isObject(x)` }],
invalid: [
{
code: `obj === Object(obj)`,
errors: [{ message: "Do not use 'obj === Object(obj)'. Use _isObject instead." }],
},
],
})

ruleTester.run('no-direct-string-check', noDirectStringCheck, {
valid: [{ code: `_isString(x)` }],
invalid: [
{
code: `toString.call(x) == '[object String]'`,
errors: [{ message: 'Use _isString instead of direct string checks.' }],
},
{
code: `x instanceof String`,
errors: [{ message: 'Use _isString instead of direct string checks.' }],
},
],
})

ruleTester.run('no-direct-date-check', noDirectDateCheck, {
valid: [{ code: `_isDate(x)` }],
invalid: [
{
code: `toString.call(obj) == '[object Date]'`,
errors: [{ message: 'Use _isDate instead of direct date checks.' }],
},
{
code: `x instanceof Date`,
errors: [{ message: 'Use _isDate instead of direct date checks.' }],
},
],
})

ruleTester.run('no-direct-number-check', noDirectNumberCheck, {
valid: [{ code: `_isNumber(x)` }],
invalid: [
{
code: `toString.call(obj) == '[object Number]'`,
errors: [{ message: 'Use _isNumber instead of direct number checks.' }],
},
{
code: `typeof x === 'number'`,
errors: [{ message: 'Use _isNumber instead of direct number checks.' }],
},
],
})

ruleTester.run('no-direct-boolean-check', noDirectBooleanCheck, {
valid: [{ code: `_isBoolean(x)` }],
invalid: [
{
code: `toString.call(obj) == '[object Boolean]'`,
errors: [{ message: 'Use _isBoolean instead of direct boolean checks.' }],
},
{
code: `typeof x === 'boolean'`,
errors: [{ message: 'Use _isBoolean instead of direct boolean checks.' }],
},
],
})
17 changes: 17 additions & 0 deletions eslint-rules/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const { readdirSync } = require('fs')
const { basename } = require('path')

const projectName = 'posthog-js'
const ruleFiles = readdirSync('eslint-rules').filter(
(file) => file.endsWith('.js') && file !== 'index.js' && !file.endsWith('test.js')
)
const configs = {
all: {
plugins: [projectName],
rules: Object.fromEntries(ruleFiles.map((file) => [`${projectName}/${basename(file, '.js')}`, 'error'])),
},
}

const rules = Object.fromEntries(ruleFiles.map((file) => [basename(file, '.js'), require('./' + file)]))

module.exports = { configs, rules }
20 changes: 20 additions & 0 deletions eslint-rules/no-direct-array-check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
create(context) {
return {
MemberExpression: function (node) {
// Check if the object is 'Array' and the property is 'isArray'
if (
node.object.type === 'Identifier' &&
node.object.name === 'Array' &&
node.property.type === 'Identifier' &&
node.property.name === 'isArray'
) {
context.report({
node,
message: 'Use _isArray() instead of direct array checks.',
})
}
},
}
},
}
Loading

0 comments on commit 7d95577

Please sign in to comment.