Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/lucky-donuts-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fingerprint/react': minor
---

Remove the `postinstall` script for detecting framework version.
64 changes: 4 additions & 60 deletions __tests__/detect-env.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { version as reactVersion } from 'react'

import { detectEnvironment } from '../src/detect-env'
import { Env } from '../src/env.types'
import { afterEach, describe, expect, it, vi } from 'vitest'
Expand Down Expand Up @@ -33,6 +35,7 @@ describe('Detect user env', () => {

expect(env).toEqual({
name: Env.React,
version: reactVersion,
})
})
})
Expand Down Expand Up @@ -88,6 +91,7 @@ describe('Detect user env', () => {

expect(env).toEqual({
name: Env.React,
version: reactVersion,
})
} finally {
if (originalWindowDescriptor) {
Expand All @@ -99,63 +103,3 @@ describe('Detect user env', () => {
})
})
})

describe('getEnvironment', () => {
afterEach(() => {
vi.resetModules()
vi.doUnmock('../src/env')
})

it('returns parsed env details when the build-time env placeholder is valid JSON', async () => {
vi.resetModules()
vi.doMock('../src/env', () => ({
env: JSON.stringify({ name: 'react', version: '18.0.0' }),
}))

const { getEnvironment: getEnvironmentFresh } = await import('../src/get-env')

expect(
getEnvironmentFresh({
context: { classRenderReceivesAnyArguments: false },
})
).toEqual({
name: 'react',
version: '18.0.0',
})
})

it('falls back to detection when the build-time env JSON is not env details', async () => {
vi.resetModules()
vi.doMock('../src/env', () => ({
env: JSON.stringify({ foo: 'bar' }),
}))

const { getEnvironment: getEnvironmentFresh } = await import('../src/get-env')

expect(
getEnvironmentFresh({
// absence of classRenderReceivesAnyArguments is React signal
context: { classRenderReceivesAnyArguments: false },
})
).toEqual({
name: Env.React,
})
})

it('falls back to detection when the build-time env is invalid', async () => {
vi.resetModules()
vi.doMock('../src/env', () => ({
env: '%DETECTED_ENV%',
}))

const { getEnvironment: getEnvironmentFresh } = await import('../src/get-env')

expect(
getEnvironmentFresh({
context: { classRenderReceivesAnyArguments: false },
})
).toEqual({
name: Env.React,
})
})
})
18 changes: 16 additions & 2 deletions __tests__/fpjs-provider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PropsWithChildren, useContext } from 'react'
import { PropsWithChildren, useContext, version as reactVersion } from 'react'
import { act, render, renderHook } from '@testing-library/react'
import { FingerprintContext, FingerprintProvider, FingerprintProviderOptions, useVisitorData } from '../src'
import { createWrapper, getDefaultStartOptions } from './helpers'
Expand All @@ -7,6 +7,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import * as agent from '@fingerprint/agent'
import type { GetOptions } from '@fingerprint/agent'
import * as ssr from '../src/ssr'
import * as detectEnv from '../src/detect-env'
import { Env } from '../src/env.types'

vi.mock('@fingerprint/agent', { spy: true })

Expand Down Expand Up @@ -67,7 +69,7 @@ describe('FingerprintProvider', () => {
})
expect(mockStart).toHaveBeenCalledWith({
...loadOptions,
integrationInfo: [`react-sdk/${version}/react`],
integrationInfo: [`react-sdk/${version}/react/${reactVersion}`],
cache: {
cachePrefix: 'cache',
storage: 'sessionStorage',
Expand All @@ -88,6 +90,18 @@ describe('FingerprintProvider', () => {
)
})

it('should omit the version in integrationInfo when the framework exposes none', () => {
vi.spyOn(detectEnv, 'detectEnvironment').mockReturnValue({ name: Env.Preact })

renderProvider()

expect(mockStart).toHaveBeenCalledWith(
expect.objectContaining({
integrationInfo: [`react-sdk/${version}/preact`],
})
)
})

it('should rebuild the agent when forceRebuild is enabled and options change', () => {
const { rerender } = renderProvider({ apiKey: 'key-a', forceRebuild: true })

Expand Down
13 changes: 13 additions & 0 deletions __tests__/with-environment.preact.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,18 @@ describe('WithEnvironment', () => {

expect(container.innerHTML).toContain('preact')
})

it('should not report a version', async () => {
const { WithEnvironment } = await import('../src/components/with-environment')
const PrintEnv = (props: { env: { version?: string } }) =>
h('div', null, JSON.stringify(props.env.version ?? null))

// @ts-expect-error -- preact's render signature does not match React's @testing-library/react types
const { container } = preactRender(h(WithEnvironment, { children: (env) => h(PrintEnv, { env }) }))

// `compat.version` is the hardcoded React-compatibility number and must never leak through
expect(compat.version).toBeDefined()
expect(container.innerHTML).toBe('<div>null</div>')
})
})
})
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"privacy"
],
"scripts": {
"postinstall": "node scripts/detect-env.js",
"prepare": "husky",
"watch": "vite build --watch",
"build": "vite build",
Expand All @@ -45,8 +44,7 @@
"changeset:publish": "HUSKY=0 changeset publish"
},
"files": [
"dist",
"scripts"
"dist"
],
"repository": {
"type": "git",
Expand Down
58 changes: 0 additions & 58 deletions scripts/detect-env.js

This file was deleted.

5 changes: 2 additions & 3 deletions src/components/with-environment.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Component, type JSX } from 'react'

import { getEnvironment } from '../get-env'
import { type DetectEnvParams } from '../detect-env'
import { detectEnvironment, type DetectEnvParams } from '../detect-env'
import { type EnvDetails } from '../env.types'

export interface WithEnvironmentProps {
Expand Down Expand Up @@ -31,7 +30,7 @@ class WithEnvironment extends Component<WithEnvironmentProps> {
context: { classRenderReceivesAnyArguments: hasAnyArguments },
}

this.detectedEnv = getEnvironment(detectParams)
this.detectedEnv = detectEnvironment(detectParams)
}

return this.props.children(this.detectedEnv)
Expand Down
18 changes: 4 additions & 14 deletions src/detect-env.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { version as reactVersion } from 'react'

import { Env, type EnvDetails } from './env.types'

export interface DetectEnvContext {
Expand Down Expand Up @@ -34,13 +36,6 @@ function isPreact(context: DetectEnvContext) {
return context.classRenderReceivesAnyArguments
}

/**
* Checks if user is using react.
* */
function isReact(context: DetectEnvContext) {
return !context.classRenderReceivesAnyArguments
}

/**
* Runs checks that determine if user is using next.
* Those checks should have almost 100% accuracy.
Expand Down Expand Up @@ -78,13 +73,8 @@ export function detectEnvironment({ context }: DetectEnvParams): EnvDetails {
}
}

if (isReact(context)) {
return {
name: Env.React,
}
}

return {
name: Env.Unknown,
name: Env.React,
version: reactVersion,
}
}
1 change: 0 additions & 1 deletion src/env.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/env.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@ export enum Env {
React = 'react',
Preact = 'preact',
Next = 'next',
Unknown = 'unknown',
}

export interface EnvDetails {
name: Env
version?: string
}

export function isEnvDetails(value: unknown): value is EnvDetails {
return typeof value === 'object' && value !== null && 'name' in value
}
16 changes: 0 additions & 16 deletions src/get-env.ts

This file was deleted.

Loading