fix: prevent undefined from overriding defaults in defineBKTConfig#236
Merged
Conversation
d7e110b to
ebceab7
Compare
Replaces use of hasOwnProperty with Object.prototype.hasOwnProperty.call to ensure correct property check for 'fetch' in config. This prevents potential issues if config does not inherit directly from Object.
Refines the check for the 'fetch' property to use the 'in' operator and adds an additional validation to ensure 'fetch' is always defined in the final config. This guarantees the SDK always has a fetch function available for network requests.
Removed special handling that threw an error when fetch was explicitly set to undefined. Now, passing undefined for fetch will use the global fetch as a fallback, and the related test has been updated to reflect this behavior.
Added an internal comment clarifying the fetch validation in defineBKTConfig to ensure a fetch implementation is always available. Also fixed a typo in the related test name ('throws' to 'throw').
Enhanced the validation for the fetch property to ensure it is a function. The error message now provides clearer guidance for environments like Node.js where a fetch implementation must be supplied.
Updated the fetch validation logic to explicitly check for the presence of the fetch property before verifying its type. This ensures that missing or undefined fetch implementations are properly handled and a clear error message is provided.
Introduces a custom ESLint rule 'no-spread-after-defaults' to disallow spreading objects after default properties in object literals. Updates eslint.config.cjs to include the new rule, expands ignore patterns, and sets parser options. Upgrades @typescript-eslint/eslint-plugin and @typescript-eslint/parser to version 8.39.0. Updates tsconfig.json to enable strictNullChecks and expand included files.
Replaces manual lazy initialization patterns with nullish coalescing assignment (??=) in DI modules and related classes for improved readability and conciseness. Updates affected tests to match new initialization style and applies minor formatting improvements.
Corrected indentation in the visitor function to improve code readability and maintain consistent formatting.
Replaces object spread for advanced config properties in BKTConfig with explicit assignments to avoid leaking undefined values. Updates ESLint rule to flag all spreads after defaults, not just identifiers.
Replaces the default fetch assignment from 'fetch' to 'globalThis.fetch' in BKTConfig. This ensures compatibility with environments where 'fetch' is available globally.
Enhanced the no-spread-after-defaults ESLint rule to better detect default property spreads and added explanatory comments with rule disables in event creator functions. Updated ESLint config to ignore build.config.ts and use projectService, and changed tsconfig.vitest.json to allow emitting files.
Simplified the detection logic for spread elements after default properties in the ESLint rule, treating any spread after a property as a violation. Added a comprehensive documentation file explaining the rule, rationale, examples, alternatives, and configuration.
Added unit tests for the no-spread-after-defaults custom ESLint rule and a new npm script to run them. Updated comments in EventCreators.ts to clarify the safety of spreading fields after base objects due to TypeScript's Omit utility.
Adds a step to run custom ESLint rule tests in the build workflow. Updates the test completion log message in no-spread-after-defaults.test.js for clarity.
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a critical bug in the defineBKTConfig function where undefined values in the configuration object could override default values due to improper use of the spread operator. The fix replaces the problematic spread pattern with explicit nullish coalescing operators and adds a custom ESLint rule to prevent similar issues in the future.
Key Changes:
- Fixed the
defineBKTConfigfunction to properly handle undefined values using nullish coalescing - Added comprehensive test coverage for the undefined value scenarios
- Implemented a custom ESLint rule
no-spread-after-defaultsto prevent similar bugs - Applied code style improvements throughout the codebase
Reviewed Changes
Copilot reviewed 16 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/BKTConfig.ts | Main fix: replaced spread operator with explicit property assignment using nullish coalescing |
| test/BKTConfig.spec.ts | Added comprehensive tests for undefined value handling scenarios |
| eslint-rules/no-spread-after-defaults.js | Custom ESLint rule to prevent spread-after-defaults pattern |
| eslint-rules/no-spread-after-defaults.test.js | Test suite for the custom ESLint rule |
| eslint-rules/no-spread-after-defaults.md | Documentation for the custom ESLint rule |
| eslint.config.cjs | ESLint configuration updates to include custom rule and new formatting rules |
| src/internal/event/EventCreators.ts | Added ESLint disable comments for legitimate spread usage |
| Multiple test/internal files | Code style improvements using nullish coalescing and formatting |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
defineBKTConfig"Bug Report: Undefined Values Override Defaults in
defineBKTConfigIssue Summary
The
defineBKTConfigfunction has a critical bug where the spread operator...configcan override default values withundefined, causing properties that should have defaults to become undefined and potentially break the application.It was related to an issue found in the React Native SDK: the SDK is not using InMemoryStorage when AsyncStorage not available
Root Cause
Location:
src/BKTConfig.ts, line 88The spread operation happens after setting defaults, so any property in
configthat is explicitly set toundefinedwill override the intended default value.Affected Properties
Properties with NO validation (can remain undefined):
eventsMaxQueueSize- No check, can be undefinedstorageKeyPrefix- No check, can be undefinedstorageFactory- No check, can be undefinedProperties with inadequate validation:
pollingInterval- Uses< MINIMUM_POLLING_INTERVAL_MILLIScheck, butundefined < numberisfalse, so undefined passes througheventsFlushInterval- Same issue as aboveProperties with working validation:
featureTag- Has explicit=== undefinedcheckuserAgent- Has!result.userAgentcheckfetch- Has!result.fetchcheck that throws errorHow to Reproduce
Impact
storageFactory)