-
Notifications
You must be signed in to change notification settings - Fork 72
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
adborroto/PLAT 5 Convert to Typescript #367
base: master
Are you sure you want to change the base?
Conversation
Plan Error
|
WalkthroughThis pull request represents a comprehensive migration of the project from JavaScript to TypeScript. The changes span across multiple files and involve several key transformations:
The migration aims to improve type safety, developer experience, and maintainability of the project by leveraging TypeScript's static typing and enhanced tooling support. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 23
🧹 Nitpick comments (19)
src/utils/resolveFields.ts (2)
Line range hint
50-60
: Leverage TypeScript's Type System Instead of Runtime Type ChecksSince TypeScript provides static type checking, you can remove the runtime type checks using
Array.isArray
and_.isObject
. This simplification relies on TypeScript to enforce the correct types at compile time.Apply this diff to remove the runtime checks:
-function resolveFields( - desiredFields?: string[] | null, - allowedFields?: Record<string, any> | null, - overrideFields?: Record<string, any> | null -) { - if (desiredFields != null && !Array.isArray(desiredFields)) { - throw new TypeError('expected nullable array for desiredFields'); - } - - if (allowedFields != null && !_.isObject(allowedFields)) { - throw new TypeError('expected nullable plain object for allowedFields'); - } - - if (overrideFields !== undefined && !_.isObject(overrideFields)) { - throw new TypeError('expected optional plain object for overrideFields'); - } +function resolveFields( + desiredFields?: string[] | null, + allowedFields?: Record<string, any> | null, + overrideFields?: Record<string, any> | null +) {
Line range hint
19-33
: Replace_.reduce
with Native JavaScriptObject.entries
To reduce dependencies and improve performance, consider replacing
_.reduce
withObject.entries
and the nativeArray.prototype.reduce
method.Apply this diff to make the change:
-const fields = _.reduce( - projection, - (memo, value, key) => { +const fields = Object.entries(projection).reduce( + (memo, [key, value]) => { if (key !== '_id' && value !== undefined && !value) { throw new TypeError('projection includes exclusion, but we do not support that'); } if (value || (key === '_id' && value === undefined && includeIdDefault)) { memo.push(key); } return memo; }, [] );src/config.ts (1)
15-15
: Consider using a more specific type for COLLATIONUsing
Record<string, any>
reduces TypeScript's type safety benefits. Consider defining a more specific interface for the collation structure if possible.- COLLATION: Record<string, any>; + COLLATION: { + locale?: string; + caseLevel?: boolean; + strength?: number; + // Add other specific collation options + } | null;src/index.ts (1)
1-9
: Consider organizing imports by categoryGroup related imports together for better maintainability:
- Core functionality
- Plugins
- Utils
+// Core functionality import aggregate from './aggregate'; import config from './config'; import find from './find'; import findWithReq from './findWithReq'; -import mongoosePlugin from './mongoose.plugin'; import search from './search'; + +// Plugins +import mongoosePlugin from './mongoose.plugin'; + +// Utils import { encodePaginationTokens } from './utils/query'; import sanitizeQuery from './utils/sanitizeQuery';src/utils/getPropertyViaDotNotation.ts (2)
15-15
: Avoid usingany
typeUsing
any
bypasses TypeScript's type checking. Consider using a more specific type.- let prop: any = object; + let prop: unknown = object;
9-12
: Consider improving return type specificityThe current return type
unknown
could be more specific based on the input typeT
.-): unknown { +): T[keyof T] | undefined {test/support/db.ts (2)
11-11
: Type the environment variableConsider using a const assertion or type guard for the driver version.
-const driver_version = process.env.DRIVER_VERSION; +const driver_version = process.env.DRIVER_VERSION as 'v3' | undefined;
18-18
: Type the driver parameter more strictlyThe
driver
parameter could have a more specific type.-async function db(mongod: MongoMemoryServer, driver: string | null = null): Promise<DbResponse> { +async function db(mongod: MongoMemoryServer, driver: 'mongoist' | null = null): Promise<DbResponse> {src/utils/bsonUrlEncoding.ts (1)
8-8
: Consider using a more specific type forBSON_UNDEFINED
The
as const
assertion is good, but the type could be more specific to prevent potential conflicts.-const BSON_UNDEFINED = '__mixmax__undefined__' as const; +const BSON_UNDEFINED = '__mixmax__undefined__' as '__mixmax__undefined__'; -export type Encodable = Record<string, unknown> | unknown[] | null | string | number | boolean; +export type Encodable = Record<string, unknown> | unknown[] | null | string | number | boolean | undefined;Also applies to: 13-13
src/findWithReq.ts (1)
23-27
: Consider adding request query type safetyThe function could benefit from a more specific type for the expected query parameters.
+interface FindRequestQuery { + limit?: string; + next?: string; + previous?: string; + fields?: string; +} export default async function findWithReq( - req: Request, + req: Request<any, any, any, FindRequestQuery>, collection: Collection<Document>, params: FindParams ): Promise<PaginationResponse<Document>> {test/utils/bsonUrlEncoding.test.ts (1)
11-13
: Use interface for test contextDefine an interface for the test context object to improve type safety.
+interface TestContext { + db: typeof mongo | null; +} - const t = { - db: null, - }; + const t: TestContext = { + db: null, + };src/mongoose.plugin.ts (1)
29-29
: Avoid mutating input parametersThe functions modify the input parameters directly. Consider creating a copy instead.
- params = _.extend({}, params); + const extendedParams = _.extend({}, params); - return find(this.collection, params); + return find(this.collection, extendedParams); - params = _.extend({}, params); + const extendedParams = _.extend({}, params); - return search(this.collection, searchString, params); + return search(this.collection, searchString, extendedParams);Also applies to: 49-49
test/utils/query.test.ts (2)
67-67
: Improve test readability with meaningful test valuesThe test values
'1'
and'2'
in the expected query are not representative of real data and make it hard to understand the test's intent.Consider using more meaningful test values that reflect actual use cases:
- $or: [{ name: { $lt: '1' } }, { name: null }, { _id: { $lt: '2' }, name: { $eq: '1' } }], + $or: [{ name: { $lt: 'Test' } }, { name: null }, { _id: { $lt: '123' }, name: { $eq: 'Test' } }],
51-70
: Add more test cases for edge casesThe current test suite for
generateCursorQuery
only covers basic scenarios. Consider adding tests for:
- Invalid cursor values
- Empty string values
- Special characters in field names
src/utils/sanitizeQuery.ts (2)
5-11
: Consider stricter typing for the index signatureThe current index signature
[key: string]: any
allows any value type, which reduces TypeScript's type safety benefits.Consider using a more specific type or union type for the index signature value:
- [key: string]: any; + [key: string]: string | string[] | undefined;
Line range hint
53-58
: Add type guard for limit parsingThe limit parsing logic could be made more type-safe with a proper type guard.
Consider adding a type guard:
- if (!_.isEmpty(query.limit)) { + if (typeof query.limit === 'string' && query.limit.length > 0) { const limit = parseInt(query.limit, 10); // Don't let the user specify a higher limit than params.limit, if defined. if (!isNaN(limit) && (!params.limit || params.limit > limit)) { params.limit = limit; } }test/search.test.ts (1)
9-12
: Add type definition for test context objectConsider defining an interface for the test context object to improve type safety.
interface TestContext { db: typeof import('mongodb').Db | null; } const t: TestContext = { db: null, };README.md (2)
33-36
: Enhance TypeScript migration documentation.While the new section announces the TypeScript conversion, consider adding:
- Breaking changes (if any)
- Migration guide for existing JavaScript users
- Examples of using TypeScript types and interfaces
- Location of type definitions for TypeScript users
33-36
: Add TypeScript code examples.Consider updating the code examples in the documentation to TypeScript to:
- Show proper type annotations
- Demonstrate type safety benefits
- Help users understand how to use the library with TypeScript
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (43)
.babelrc
(0 hunks).gitignore
(1 hunks).nvmrc
(1 hunks)README.md
(1 hunks)jest.config.js
(1 hunks)package.json
(4 hunks)src/aggregate.js
(0 hunks)src/aggregate.ts
(1 hunks)src/config.js
(0 hunks)src/config.ts
(1 hunks)src/find.js
(0 hunks)src/find.ts
(1 hunks)src/findWithReq.js
(0 hunks)src/findWithReq.ts
(1 hunks)src/index.js
(0 hunks)src/index.ts
(1 hunks)src/mongoose.plugin.js
(0 hunks)src/mongoose.plugin.ts
(1 hunks)src/search.js
(0 hunks)src/search.ts
(1 hunks)src/utils/bsonUrlEncoding.js
(0 hunks)src/utils/bsonUrlEncoding.ts
(1 hunks)src/utils/getPropertyViaDotNotation.js
(0 hunks)src/utils/getPropertyViaDotNotation.ts
(1 hunks)src/utils/query.js
(0 hunks)src/utils/query.ts
(1 hunks)src/utils/resolveFields.ts
(3 hunks)src/utils/sanitizeParams.ts
(4 hunks)src/utils/sanitizeQuery.ts
(3 hunks)test/.eslintrc.json
(0 hunks)test/aggregate.test.ts
(1 hunks)test/find.test.ts
(1 hunks)test/findWithReq.test.ts
(18 hunks)test/mongoosePlugin.test.ts
(4 hunks)test/search.test.ts
(1 hunks)test/support/db.js
(0 hunks)test/support/db.ts
(1 hunks)test/utils/bsonUrlEncoding.test.ts
(2 hunks)test/utils/query.test.js
(0 hunks)test/utils/query.test.ts
(1 hunks)test/utils/resolveFields.test.ts
(1 hunks)tsconfig-lint.json
(1 hunks)tsconfig.json
(1 hunks)
💤 Files with no reviewable changes (14)
- .babelrc
- test/.eslintrc.json
- src/aggregate.js
- src/config.js
- src/find.js
- src/index.js
- src/utils/getPropertyViaDotNotation.js
- test/utils/query.test.js
- src/utils/bsonUrlEncoding.js
- src/search.js
- src/mongoose.plugin.js
- test/support/db.js
- src/utils/query.js
- src/findWithReq.js
✅ Files skipped from review due to trivial changes (5)
- .nvmrc
- .gitignore
- tsconfig-lint.json
- test/utils/resolveFields.test.ts
- tsconfig.json
🧰 Additional context used
🪛 Biome (1.9.4)
test/mongoosePlugin.test.ts
[error] 70-70: Do not shadow the global "hasOwnProperty" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
[error] 91-91: Do not shadow the global "hasOwnProperty" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
🔇 Additional comments (9)
jest.config.js (1)
9-9
: Verify Impact of RemovingmoduleNameMapper
ConfigurationThe
moduleNameMapper
section, which previously handled module path mappings, has been removed. If any tests depended on this mapping, it could lead to module resolution errors.Please ensure that removing
moduleNameMapper
does not affect the ability of Jest to resolve modules, especially if there are custom module paths.test/search.test.ts (1)
1-4
: LGTM! Clean ES module importsThe conversion from CommonJS to ES module imports is done correctly, with proper TypeScript type imports.
test/aggregate.test.ts (2)
1-4
: LGTM! Consistent import patternThe import statements follow the same pattern as other test files, maintaining consistency across the codebase.
10-12
: Maintain consistent type definitions across test filesFor consistency, use the same TestContext interface suggested for search.test.ts.
test/find.test.ts (2)
10-12
: Maintain consistent type definitions across test filesFor consistency, use the same TestContext interface suggested for search.test.ts.
4-4
: Verify the impact of switching ObjectId import sourceThe change from
mongoist
tomongodb
for ObjectId import is correct for TypeScript, but verify that it maintains the same functionality.✅ Verification successful
Import change from mongoist to mongodb ObjectId is correct
The ObjectId is only used to generate string IDs via toString(), which is standard functionality supported by both packages. The change is safe and maintains the same behavior.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for any remaining mongoist ObjectId usage rg "require.*mongoist.*ObjectId" || rg "from.*mongoist.*ObjectId" # Check if mongodb ObjectId is used consistently rg "ObjectId.*mongodb" -A 2Length of output: 222
Script:
#!/bin/bash # Check how ObjectId is used in the test file rg "ObjectId" test/find.test.ts -A 2Length of output: 1032
package.json (3)
14-20
: LGTM! Build and test scripts are properly configured for TypeScript.The scripts section has been correctly updated to support TypeScript:
- Lint script includes TypeScript type checking
- Build script properly cleans and compiles TypeScript
- Test scripts are well-organized for different drivers
55-59
: LGTM! TypeScript tooling is properly configured.All necessary TypeScript development dependencies are present with appropriate versions:
- TypeScript compiler and configuration
- ESLint TypeScript plugins
- ts-jest for TypeScript testing
Also applies to: 71-73
42-42
: 🛠️ Refactor suggestionConsider using a stable version of @types/express.
The current version
^5.0.0
is a pre-release version which could introduce instability. Consider using the stable version^4.17.21
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (15)
src/utils/bsonUrlEncoding.ts (2)
32-34
:⚠️ Potential issueHandle all
undefined
values in arraysThe current implementation replaces
undefined
only at the first index of arrays. This could missundefined
values at other positions, leading to potential encoding issues.Apply this diff to replace all occurrences of
undefined
in arrays:- if (Array.isArray(obj) && obj[0] === undefined) { - obj[0] = BSON_UNDEFINED; + if (Array.isArray(obj)) { + for (let i = 0; i < obj.length; i++) { + if (obj[i] === undefined) { + obj[i] = BSON_UNDEFINED; + } + } }
47-49
:⚠️ Potential issueHandle all
BSON_UNDEFINED
values in arrays during decodingSimilar to the
encode
method, thedecode
method only checks the first element of arrays forBSON_UNDEFINED
. This could missBSON_UNDEFINED
values at other positions.Apply this diff to replace all occurrences of
BSON_UNDEFINED
in arrays:- if (Array.isArray(obj) && obj[0] === BSON_UNDEFINED) { - obj[0] = undefined; + if (Array.isArray(obj)) { + for (let i = 0; i < obj.length; i++) { + if (obj[i] === BSON_UNDEFINED) { + obj[i] = undefined; + } + } }src/aggregate.ts (1)
46-46
:⚠️ Potential issueFix potential error when spreading undefined options
If
params.options
isundefined
, spreading it will cause aTypeError
. To prevent this, defaultparams.options
to an empty object before spreading.Apply this diff to fix the issue:
- const options: Record<string, any> = { ...params.options }; + const options: Record<string, any> = { ...(params.options || {}) };src/search.ts (3)
6-11
:⚠️ Potential issueUpdate
SearchParams.next
type to handle decoded cursor correctlyThe
next
parameter inSearchParams
is currently typed asstring
, but after decoding, it becomes a tuple[number, any]
. This mismatch can lead to type errors and runtime issues when accessingparams.next[0]
andparams.next[1]
.Apply this diff to update the
SearchParams
interface:export interface SearchParams { query?: Record<string, any>; limit?: number; fields?: Record<string, number>; - next?: string; + next?: string | [number, any]; }
38-39
:⚠️ Potential issueCorrect the type casting of
params.next
after decodingAfter decoding
params.next
, it should be cast to[number, any]
instead ofstring
to reflect its actual structure and ensure type safety when accessing its elements.Apply this diff to correct the casting:
if (params.next) { - params.next = bsonUrlEncoding.decode(params.next) as string; + params.next = bsonUrlEncoding.decode(params.next) as [number, any]; }
57-61
:⚠️ Potential issuePrevent
params.fields
from overriding protected fields in$project
stageDirectly spreading
params.fields
into the$project
stage can allow overriding of critical fields like_id
andscore
, which may lead to security risks or unintended behavior. To safeguard these fields, exclude them fromparams.fields
before spreading.Apply this diff to fix the issue:
$project: { - ...params.fields, _id: 1, score: { $meta: 'textScore' }, + ..._.omit(params.fields, ['_id', 'score']), },src/find.ts (2)
14-20
:⚠️ Potential issueInclude
hint
property inFindParams
interfaceThe
hint
property is used in the code (line 75) but is not defined in theFindParams
interface. This can lead to TypeScript type errors and may cause issues during compilation.Apply this diff to include the
hint
property:export interface FindParams extends PaginationParams { query?: Document; limit?: number; fields?: Record<string, number>; collation?: Record<string, any> | null; overrideFields?: Record<string, number>; + hint?: any; }
37-42
:⚠️ Potential issueAwait the asynchronous
aggregate
function callThe
aggregate
function is asynchronous but is not awaited. This meansresponse
will be aPromise
instead of the expected result, which can lead to unexpected behavior when accessingresponse
.Apply this diff to fix the issue:
response = aggregate( + response = await aggregate( collection, Object.assign({}, params, { aggregation: params.query ? [{ $match: params.query }] : [], }) );
test/support/db.ts (1)
25-30
:⚠️ Potential issueImprove error handling and type safety in client connection
The client connection logic needs better error handling and type assertions.
- const clientToConnect = driver_version === 'v3' ? MongoClientV3 : MongoClient; - const [client, dbName] = await Promise.all([clientToConnect.connect(uri), mongod.getDbName()]); - return { - db: client.db(dbName), - client, - }; + const clientToConnect = driver_version === 'v3' ? MongoClientV3 : MongoClient; + try { + const [client, dbName] = await Promise.all([ + clientToConnect.connect(uri), + mongod.getDbName(), + ]) as [MongoClient | MongoClientV3, string]; + return { + db: client.db(dbName), + client, + }; + } catch (error) { + throw new Error(`Failed to connect to MongoDB: ${error instanceof Error ? error.message : 'Unknown error'}`); + }src/findWithReq.ts (1)
28-32
:⚠️ Potential issueAdd input validation for query parameters
The function should validate query parameters before processing.
+ // Validate query parameters before sanitizing + if (req.query.limit && isNaN(Number(req.query.limit))) { + throw new Error('Invalid limit parameter: must be a number'); + } + // Sanitize the query string parameters and merge with additional params const sanitizedParams = sanitizeQuery(req.query, params); // Perform the find operation with the sanitized parameters return find(collection, sanitizedParams);test/utils/bsonUrlEncoding.test.ts (1)
39-39
: 🛠️ Refactor suggestionReplace
any
type with a proper interfaceUsing
any
defeats TypeScript's type checking benefits.- const decoded: any = bsonUrlEncoding.decode(str); + interface DecodedObject { + _id: mongo.ObjectID; + date: Date; + number: number; + string: string; + } + const decoded = bsonUrlEncoding.decode(str) as DecodedObject;src/mongoose.plugin.ts (2)
24-31
: 🛠️ Refactor suggestionImprove type safety in findFn implementation
The function should use proper typing for the Mongoose model context and return value.
- const findFn = async function(this: any, params: FindParams): Promise<any> { + const findFn = async function<T>(this: Model<T>, params: FindParams): Promise<PaginationResponse<T>> { if (!this.collection) { throw new Error('collection property not found'); } params = _.extend({}, params); return find(this.collection, params); };
40-51
: 🛠️ Refactor suggestionImprove type safety in searchFn implementation
The search function needs proper typing for the
this
context and return type.const searchFn = async function( - this: any, + this: Model<T>, searchString: string, params: SearchParams - ): Promise<any> { + ): Promise<PaginationResponse<T>> { if (!this.collection) { throw new Error('collection property not found'); } params = _.extend({}, params); return search(this.collection, searchString, params); };test/mongoosePlugin.test.ts (2)
1-3
: 🛠️ Refactor suggestionProper type definitions needed for plugin methods
While the ES module imports are correct, the file needs proper type definitions for the plugin methods to avoid
as any
casts throughout the tests.Consider adding type definitions as suggested in the previous review:
declare module 'mongoose' { interface Model<T> { paginate(): Promise<PaginationResult<T>>; paginateFN(): Promise<PaginationResult<T>>; search(query: string, options?: SearchOptions): Promise<SearchResult<T>>; searchFN(query: string, options?: SearchOptions): Promise<SearchResult<T>>; } }
70-70
:⚠️ Potential issueFix shadowing of global hasOwnProperty
The variable
hasOwnProperty
shadows the global property of the same name.Apply this fix:
- var hasOwnProperty = Object.prototype.hasOwnProperty; + const hasOwn = Object.prototype.hasOwnProperty; - expect(hasOwnProperty.call(data, 'results')).toBe(true); + expect(hasOwn.call(data, 'results')).toBe(true);Also applies to: 91-91
🧰 Tools
🪛 Biome (1.9.4)
[error] 70-70: Do not shadow the global "hasOwnProperty" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
🧹 Nitpick comments (10)
src/utils/sanitizeQuery.ts (1)
52-52
: Remove redundant assignment ofparams
The variable
params
already has a default value{}
in the function signature. The assignmentparams = params || {};
is unnecessary and can be removed for cleaner code.Apply this diff to remove the redundant line:
- params = params || {};
src/search.ts (1)
46-47
: Remove unnecessary non-null assertions onparams.limit
The non-null assertion operator
!
is unnecessary here becauseparams.limit
has been defaulted earlier. Removing!
makes the code cleaner and avoids potential confusion.Apply this diff to simplify the code:
- if (params.limit! < 1) params.limit = 1; - if (params.limit! > config.MAX_LIMIT) params.limit = config.MAX_LIMIT; + if (params.limit < 1) params.limit = 1; + if (params.limit > config.MAX_LIMIT) params.limit = config.MAX_LIMIT;jest.config.js (3)
3-5
: Simplify Configuration by Removing Redundanttransform
PropertyWhen using the
ts-jest
preset, thetransform
configuration is set automatically. You can remove thetransform
property to simplify the configuration.Apply this diff:
module.exports = { preset: 'ts-jest', - transform: { - '^.+\\.tsx?$': 'ts-jest', - }, moduleFileExtensions: ['ts', 'js', 'json', 'node'],
6-6
: Include'tsx'
inmoduleFileExtensions
If your project includes
.tsx
files (e.g., React components), consider adding'tsx'
to themoduleFileExtensions
array to ensure Jest recognizes these files.Apply this diff:
moduleFileExtensions: ['ts', 'js', 'json', 'node'], +moduleFileExtensions: ['ts', 'tsx', 'js', 'json', 'node'],
8-8
: UpdatecollectCoverageFrom
to Include.tsx
FilesTo include coverage data for
.tsx
files, update thecollectCoverageFrom
pattern.Apply this diff:
-collectCoverageFrom: ['src/**/*.ts'], +collectCoverageFrom: ['src/**/*.{ts,tsx}'],test/support/db.ts (1)
11-11
: Consider using a typed environment variableThe
driver_version
variable could benefit from type safety using a union type of allowed values.-const driver_version = process.env.DRIVER_VERSION; +const driver_version = process.env.DRIVER_VERSION as 'v3' | undefined;test/find.test.ts (1)
10-12
: Consider adding type annotations to the test contextWhile the test setup works, it would be better to add proper TypeScript types to the test context object.
- const t = { - db: null, - }; + interface TestContext { + db: any; // or proper MongoDB type + } + const t: TestContext = { + db: null, + };tsconfig-lint.json (2)
2-5
: Consider adding strict type checking optionsWhile extending the base config is good, consider explicitly enabling strict type checking options for better type safety.
{ "extends": "@mixmaxhq/ts-config/tsconfig.json", "compilerOptions": { - "outDir": "dist/node" + "outDir": "dist/node", + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true },
6-13
: Consider adding more specific exclude patternsThe current exclude patterns are good, but consider adding more specific patterns to exclude test fixtures and generated files.
"exclude": [ "node_modules", - "dist" + "dist", + "coverage", + "**/*.spec.ts", + "**/*.mock.ts", + "**/__fixtures__/*" ]test/utils/resolveFields.test.ts (1)
Line range hint
1-74
: Consider enhancing tests with TypeScript features.While the migration is correct, consider enhancing the tests with TypeScript features:
- Add type annotations for test inputs and expected outputs
- Use TypeScript's
type
orinterface
for complex test data structures- Leverage TypeScript's strict type checking in assertions
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (43)
.babelrc
(0 hunks).gitignore
(1 hunks).nvmrc
(1 hunks)README.md
(1 hunks)jest.config.js
(1 hunks)package.json
(4 hunks)src/aggregate.js
(0 hunks)src/aggregate.ts
(1 hunks)src/config.js
(0 hunks)src/config.ts
(1 hunks)src/find.js
(0 hunks)src/find.ts
(1 hunks)src/findWithReq.js
(0 hunks)src/findWithReq.ts
(1 hunks)src/index.js
(0 hunks)src/index.ts
(1 hunks)src/mongoose.plugin.js
(0 hunks)src/mongoose.plugin.ts
(1 hunks)src/search.js
(0 hunks)src/search.ts
(1 hunks)src/utils/bsonUrlEncoding.js
(0 hunks)src/utils/bsonUrlEncoding.ts
(1 hunks)src/utils/getPropertyViaDotNotation.js
(0 hunks)src/utils/getPropertyViaDotNotation.ts
(1 hunks)src/utils/query.js
(0 hunks)src/utils/query.ts
(1 hunks)src/utils/resolveFields.ts
(3 hunks)src/utils/sanitizeParams.ts
(4 hunks)src/utils/sanitizeQuery.ts
(3 hunks)test/.eslintrc.json
(0 hunks)test/aggregate.test.ts
(1 hunks)test/find.test.ts
(1 hunks)test/findWithReq.test.ts
(18 hunks)test/mongoosePlugin.test.ts
(4 hunks)test/search.test.ts
(1 hunks)test/support/db.js
(0 hunks)test/support/db.ts
(1 hunks)test/utils/bsonUrlEncoding.test.ts
(2 hunks)test/utils/query.test.js
(0 hunks)test/utils/query.test.ts
(1 hunks)test/utils/resolveFields.test.ts
(1 hunks)tsconfig-lint.json
(1 hunks)tsconfig.json
(1 hunks)
💤 Files with no reviewable changes (14)
- test/.eslintrc.json
- .babelrc
- src/utils/bsonUrlEncoding.js
- src/utils/getPropertyViaDotNotation.js
- src/config.js
- src/find.js
- src/aggregate.js
- src/search.js
- src/index.js
- test/support/db.js
- src/mongoose.plugin.js
- src/utils/query.js
- src/findWithReq.js
- test/utils/query.test.js
🧰 Additional context used
🪛 Biome (1.9.4)
test/mongoosePlugin.test.ts
[error] 70-70: Do not shadow the global "hasOwnProperty" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
[error] 91-91: Do not shadow the global "hasOwnProperty" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
🔇 Additional comments (31)
src/search.ts (1)
86-87
: Verify the existence ofaggregateAsCursor
method on theCollection
typeThe check
'aggregateAsCursor' in collection
assumes that thecollection
object may have anaggregateAsCursor
method. Please verify that this method exists on theCollection<T>
type provided by the MongoDB driver. If it does not, this could lead to a runtime error.Since my knowledge cutoff is in 2023-10, please confirm whether
aggregateAsCursor
is a valid method. If it's a custom implementation or from a newer version of the driver, ensure it is correctly typed and handled.src/utils/resolveFields.ts (2)
13-15
: Refine type definitions forprojection
parameterUsing
Record<string, any>
for theprojection
parameter reduces type safety, as it allows any values. Consider defining a more specific type to leverage TypeScript's type system effectively.You can define a type that specifies the allowed values for
projection
. For example, ifprojection
should map field names to booleans:type Projection = Record<string, boolean>; function fieldsFromMongo( projection: Projection = {}, includeIdDefault = false ): ProjectionFieldSet { // function body }
47-49
: Improve type safety forallowedFields
andoverrideFields
parametersCurrently,
allowedFields
andoverrideFields
are typed asRecord<string, any>
, which can reduce type safety. Defining more precise types can help catch errors at compile time and make the code more robust.Consider specifying the expected value types. For example:
type FieldsMap = Record<string, boolean>; function resolveFields( desiredFields?: string[] | null, allowedFields?: FieldsMap | null, overrideFields?: FieldsMap | null ): Record<string, any> | null { // function body }src/utils/query.ts (4)
45-45
: Handle UndefinedpaginatedField
When Accessing Object PropertiesSince
params.paginatedField
is optional, accessing it without checking may lead to runtime errors. Ensure thatpaginatedField
is defined before using it withobjectPath.get
.Consider adding a validation check:
export function encodePaginationTokens<T>( params: PaginationParams, response: PaginationResponse<T>, previous: T | null, next: T | null ): void { + if (!params.paginatedField) { + throw new Error('`paginatedField` is required for pagination tokens'); + } const shouldSecondarySortOnId = params.paginatedField !== '_id';
55-55
: Handle UndefinedpaginatedField
When Accessing Object PropertiesAs with the previous occurrence, ensure that
params.paginatedField
is defined before using it withobjectPath.get
to prevent runtime errors.
107-107
: Default Optional Boolean ParametersortAscending
params.sortAscending
is optional and may beundefined
, which can cause logical inconsistencies. Default this parameter to a boolean value to ensure consistent behavior in sorting.Apply this diff to set a default value:
export function generateSort(params: PaginationParams): SortObject { + const sortAscending = params.sortAscending ?? true; const sortAsc = - (!params.sortAscending && params.previous) || (params.sortAscending && !params.previous); + (!sortAscending && params.previous) || (sortAscending && !params.previous);
124-214
: ValidatepaginatedField
ingenerateCursorQuery
FunctionThe
generateCursorQuery
function assumesparams.paginatedField
is defined. If it'sundefined
, it may lead to incorrect queries or runtime errors. ValidatepaginatedField
before proceeding.Consider adding a validation check:
export function generateCursorQuery(params: PaginationParams): CursorQuery { + if (!params.paginatedField) { + throw new Error('`paginatedField` is required to generate cursor query'); + } if (!params.next && !params.previous) return {}; const sortAsc = (!params.sortAscending && params.previous) || (params.sortAscending && !params.previous);src/utils/getPropertyViaDotNotation.ts (1)
13-13
: Add Validation forpropertyName
ParameterThe function should validate that
propertyName
is a non-empty string to prevent unexpected errors when splitting or accessing properties.Apply this diff:
export default function getPropertyViaDotNotation<T extends Record<string, any>>( propertyName: string, object: T ): unknown { + if (!propertyName || typeof propertyName !== 'string') { + throw new Error('`propertyName` must be a non-empty string'); + } const parts = propertyName.split('.');test/utils/query.test.ts (5)
8-28
: LGTM! Well-structured test suite with proper type safety.The test suite effectively uses TypeScript generics and type annotations to ensure type safety. The
PaginatedType
generic constraint andPaginationResponse
type are used appropriately.
67-67
: Verify the hardcoded test values.The test uses hardcoded values
'1'
and'2'
in the cursor query assertion. These values seem arbitrary and their significance is not clear from the test context.Consider either:
- Adding comments to explain the significance of these values
- Using more meaningful test data that reflects real-world scenarios
17-17
: LGTM! Correct usage of mongoose Schema.Types.ObjectId.The type has been properly updated to use
mongoose.Schema.Types.ObjectId
which is the correct type for ObjectId references.
70-70
: Fix shadowing of global hasOwnProperty.The variable
hasOwnProperty
shadows the global property of the same name.Apply this fix:
- var hasOwnProperty = Object.prototype.hasOwnProperty; + const hasOwn = Object.prototype.hasOwnProperty; - expect(hasOwnProperty.call(data, 'results')).toBe(true); + expect(hasOwn.call(data, 'results')).toBe(true);Also applies to: 91-91
59-59
: Avoid usingas any
type assertions.Multiple instances of
as any
type assertions reduce TypeScript's type safety benefits.Consider creating proper type definitions for the mongoose plugin:
declare module 'mongoose' { interface Model<T> { paginate(): Promise<PaginationResult<T>>; paginateFN(): Promise<PaginationResult<T>>; search(query: string, options?: SearchOptions): Promise<SearchResult<T>>; searchFN(query: string, options?: SearchOptions): Promise<SearchResult<T>>; } }Also applies to: 64-64, 69-69, 80-80, 85-85, 90-90
test/search.test.ts (1)
1-11
: LGTM! Clean conversion to TypeScript with improved type safety.The changes effectively:
- Convert to ES module imports
- Add explicit db property initialization
- Maintain test structure and readability
test/findWithReq.test.ts (1)
73-78
: Improve type safety by creating proper request mock objects.Multiple instances of type assertions with
as any
andas Request
reduce type safety.Consider creating properly typed mock objects:
interface MockQuery { limit?: string; fields?: string; next?: string; previous?: string; } function createMockRequest(query: MockQuery): Request { return { query, } as unknown as Request; } // Usage: const request = createMockRequest({ limit: '2', fields: 'counter,myfield1', });Also applies to: 96-104, 120-121, 145-146, 168-169, 187-188, 207-208, 228-229, 252-253, 281-282, 305-306, 333-334, 360-361, 392-393, 421-422, 444-445, 477-478
test/find.test.ts (1)
1-4
: Import statements look good but consider organizing themThe conversion to ES module syntax is correct. The imports are properly organized with external dependencies first, followed by internal imports.
.nvmrc (1)
1-1
: Verify Node.js version compatibilityThe update to Node.js 18.20.0 is good, as it's a stable LTS version with good TypeScript support. However, please verify that all dependencies are compatible with this version.
✅ Verification successful
Node.js 18.20.0 is compatible with all dependencies
All package dependencies have version requirements that are satisfied by Node.js 18.20.0. The highest minimum requirement found is Node.js 18, and there are no maximum version constraints that would conflict with this version.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for any package.json engines field restrictions if [ -f "package.json" ]; then echo "Checking engines field in package.json..." jq '.engines' package.json fi # Check for any dependency version conflicts if [ -f "package-lock.json" ]; then echo "Checking for any dependency version conflicts..." jq '.packages | to_entries[] | select(.value.engines != null) | .value.engines' package-lock.json fiLength of output: 26851
tsconfig.json (1)
9-13
: Verify test file exclusion patternThe current pattern excludes all test files, but verify if you need to keep any specific test utilities or types.
✅ Verification successful
Test file exclusion pattern is correct
The current exclusion pattern is appropriate. The discovered test utility (test/support/db.ts) is specifically for test infrastructure and should be compiled separately with test-specific configuration, not with the main source code.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for any test utility files that might need to be included echo "Checking for test utility files that might need inclusion..." fd -e ts -E "*.test.ts" -E "*.spec.ts" . test/Length of output: 198
Script:
#!/bin/bash # Check if db.ts is imported in source files ast-grep --pattern 'import $_ from "$_/test/support/db"' # Also check relative imports that might resolve to this file ast-grep --pattern 'import $_ from "$_/db"' # Check actual content of db.ts to understand its purpose cat test/support/db.tsLength of output: 1044
src/config.ts (2)
1-16
: Well-structured interface with clear documentation.The interface definition is clear and well-documented with JSDoc comments.
15-15
: Type mismatch between interface and implementation.The
COLLATION
property is defined asRecord<string, any>
but assignednull
.Also applies to: 21-21
src/index.ts (1)
1-19
: Clean and well-organized module exports.The file demonstrates good module organization with clear imports and a structured export block.
.gitignore (1)
43-43
: Verify broader dist/ ignore pattern.The change from
dist/node
todist/
will ignore all compiled output. Please ensure this won't accidentally exclude any required distribution files.✅ Verification successful
Broader dist/ ignore pattern is correct
The change from
dist/node
todist/
is appropriate as:
- All build output is generated in dist/ directory
- dist/ is properly included in the published npm package
- No other important files are stored in dist/
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for any potentially important files in dist/ that might be accidentally ignored fd . dist/ --type f --hidden --no-ignoreLength of output: 135
Script:
#!/bin/bash # Check configuration files and docs for dist references echo "=== Package.json ===" fd package.json --type f --exec cat {} echo -e "\n=== TypeScript Config ===" fd tsconfig.json --type f --exec cat {} echo -e "\n=== Build References ===" rg -i "(\bdist\b|outDir|build|output)" -g "!.git" -g "!*.lock" -g "!dist/*" -g "!{package,tsconfig}.json" echo -e "\n=== README Build Instructions ===" fd "README" --type f --exec cat {}Length of output: 18019
test/utils/resolveFields.test.ts (1)
1-1
: Clean migration to ES module syntax.The import statement has been properly converted to use ES module syntax.
package.json (1)
14-20
: Well-structured TypeScript build and test scripts.The scripts have been properly updated to support TypeScript:
- Added TypeScript compilation check to lint script
- Added clean build step with
tsc
- Maintained separate test configurations for different drivers
src/utils/sanitizeParams.ts (3)
1-16
: LGTM! Well-structured interface definition.The
SanitizeParams
interface is well-defined with appropriate types for MongoDB pagination parameters.
18-21
: Use proper MongoDB types for better type safety.The
collection
parameter is typed asany
, which reduces type safety.
55-55
: Add type guards for string operations.Type assertions are used without first checking if the value is actually a string.
Also applies to: 80-80
README.md (1)
33-36
: LGTM! Clear documentation update.The new section effectively communicates the transition to TypeScript and its benefits.
test/aggregate.test.ts (2)
1-3
: LGTM! Clean import syntax.The conversion to ES module syntax is correct and consistent.
10-12
: LGTM! Type-safe initialization.The object initialization with explicit null assignment improves type safety.
test/mongoosePlugin.test.ts (1)
17-17
: LGTM! Improved type clarityGood change using the explicit
mongoose.Schema.Types.ObjectId
instead of the deprecatedmongoose.Schema.ObjectId
.
Signed-off-by: Alejandro Dominguez <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (2)
package.json (2)
Line range hint
75-77
: Update Node.js engine requirement.The current engine requirement (
">= 6.9.1"
) is outdated for TypeScript support. Consider updating to match the TypeScript version's requirements."engines": { - "node": ">= 6.9.1" + "node": ">= 14.17.0" },
Line range hint
6-8
: Update files field for TypeScript declaration files.Ensure TypeScript declaration files are included in the published package.
"files": [ "index.js", "dist", - "src" + "src", + "index.d.ts" ],
🧹 Nitpick comments (6)
tsconfig.json (1)
14-18
: Consider separate test files configuration.Since test files are excluded, consider creating a separate
tsconfig.test.json
for test files to ensure proper type checking during testing.// tsconfig.test.json { "extends": "./tsconfig.json", "include": [ "test/**/*" ], "exclude": [ "node_modules", "dist" ] }package.json (1)
14-14
: Add type checking to the build script.Consider adding type checking to the build process to catch type errors before compilation.
- "lint": "eslint . && tsc --noEmit", + "lint": "eslint . && npm run type-check", + "type-check": "tsc --noEmit", - "build": "rm -rf dist/ && tsc" + "build": "rm -rf dist/ && npm run type-check && tsc"Also applies to: 20-20
test/utils/sanitizeParams.test.ts (2)
15-23
: Consider adding more edge cases for parameter decoding.While the basic decoding test is good, consider adding tests for:
- Invalid encoded values
- Empty arrays
- Null/undefined values
60-77
: Enhance test coverage for case-insensitive sorting.The test only verifies the happy path. Consider adding tests for:
- Multiple fields with case-insensitive sorting
- Special characters in field values
- Empty field values
src/aggregate.ts (1)
12-17
: Consider makingaggregation
type more specific.The
Document[]
type foraggregation
is too broad. Consider creating a union type of specific aggregation stages for better type safety.type AggregationStage = | { $match: Document } | { $sort: Document } | { $limit: number } | { $project: Document } | { $addFields: Document }; interface AggregateParams extends PaginationParams { aggregation?: AggregationStage[]; // ... rest of the interface }src/search.ts (1)
6-11
: Consider strengthening thenext
parameter type.The
Encodable
type fornext
might be too permissive. Consider creating a more specific type that matches the expected structure[number, any]
.export interface SearchParams { query?: Record<string, any>; limit?: number; fields?: Record<string, number>; next?: [number, any] | string; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (7)
package.json
(4 hunks)src/aggregate.ts
(1 hunks)src/find.ts
(1 hunks)src/search.ts
(1 hunks)src/utils/sanitizeParams.ts
(4 hunks)test/utils/sanitizeParams.test.ts
(1 hunks)tsconfig.json
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/utils/sanitizeParams.ts
🧰 Additional context used
📓 Learnings (1)
src/find.ts (2)
Learnt from: adborroto
PR: mixmaxhq/mongo-cursor-pagination#367
File: src/find.ts:14-20
Timestamp: 2025-01-07T11:51:25.488Z
Learning: The `hint` property is defined in the `PaginationParams` interface and is inherited by `FindParams` through extension, so it should not be redefined in `FindParams`.
Learnt from: adborroto
PR: mixmaxhq/mongo-cursor-pagination#367
File: src/find.ts:14-20
Timestamp: 2025-01-07T11:51:25.488Z
Learning: The `hint` property is defined in `PaginationParams` as an optional string property (`hint?: string`). Any interface that extends `PaginationParams`, such as `FindParams` or `AggregateParams`, automatically inherits this property through TypeScript's interface extension.
🔇 Additional comments (3)
test/utils/sanitizeParams.test.ts (1)
1-13
: LGTM! Well-structured test setup with proper type definitions.The test file setup is clean with proper TypeScript imports and mock collection initialization.
src/aggregate.ts (1)
46-53
: Previous issue with undefined options is fixed correctly.The spread operator now safely handles undefined options with a fallback to an empty object.
src/search.ts (1)
71-80
:⚠️ Potential issueAdd type assertion for
params.next
array access.The array access on
params.next
needs type safety to prevent runtime errors.if (params.next) { aggregatePipeline.push({ $match: { $or: [ - { score: { $lt: params.next[0] } }, - { score: { $eq: params.next[0] }, _id: { $lt: params.next[1] } }, + { score: { $lt: (params.next as [number, any])[0] } }, + { score: { $eq: (params.next as [number, any])[0] }, _id: { $lt: (params.next as [number, any])[1] } }, ], }, });Likely invalid or redundant comment.
Signed-off-by: Alejandro Dominguez <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
package.json (1)
Line range hint
76-78
: Update Node.js version constraint.The current engines field specifies Node.js ">= 6.9.1" which is incompatible with:
- TypeScript 4.9.5 (requires Node.js >= 12.20)
- Modern development tools and dependencies
Update the engines field to reflect current requirements:
"engines": { - "node": ">= 6.9.1" + "node": ">= 14.17.0" }
♻️ Duplicate comments (1)
package.json (1)
54-59
: 🛠️ Refactor suggestionAddress TypeScript dependency configuration issues.
Previous review comments have identified several issues that need attention:
- Move
@types/express
to devDependencies- Pin TypeScript-related package versions for consistency
- Ensure compatibility with current Node.js releases
Additionally:
- Add
tslib
as a runtime dependency to optimize the TypeScript helpers:"dependencies": { "base64-url": "^2.2.0", + "tslib": "^2.6.2", // ... }
Also applies to: 71-73
🧹 Nitpick comments (4)
package.json (1)
14-20
: LGTM! Consider adding type declaration file generation.The TypeScript-related script changes look good, with proper separation of concerns and comprehensive testing setup.
Consider adding the
--declaration
flag to generate.d.ts
files in the build script:- "build": "rm -rf dist/ && tsc" + "build": "rm -rf dist/ && tsc --declaration"src/find.ts (3)
22-25
: Consider using string literal types for better type safety.Convert the constants to TypeScript string literal types to get better type checking and autocompletion.
-const COLLECTION_METHODS = { +const COLLECTION_METHODS = { FIND: 'find', FIND_AS_CURSOR: 'findAsCursor', -}; +} as const; +type CollectionMethod = typeof COLLECTION_METHODS[keyof typeof COLLECTION_METHODS];
31-32
: Add null check for params.fields access.The condition could throw if
params.fields
is undefined. Consider adding a null check.const removePaginatedFieldInResponse = - params.fields && !params.fields[params.paginatedField || '_id']; + params.fields != null && !params.fields[params.paginatedField || '_id'];
74-75
: Consider combining cursor operations.The cursor operations could be chained for better readability.
- const cursor = collatedQuery.sort($sort).limit(params.limit + 1); - if (params.hint) cursor.hint(params.hint); + const cursor = collatedQuery + .sort($sort) + .limit(params.limit + 1) + .hint(params.hint || {});
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (2)
package.json
(3 hunks)src/find.ts
(1 hunks)
🧰 Additional context used
📓 Learnings (1)
src/find.ts (2)
Learnt from: adborroto
PR: mixmaxhq/mongo-cursor-pagination#367
File: src/find.ts:14-20
Timestamp: 2025-01-07T11:51:25.488Z
Learning: The `hint` property is defined in the `PaginationParams` interface and is inherited by `FindParams` through extension, so it should not be redefined in `FindParams`.
Learnt from: adborroto
PR: mixmaxhq/mongo-cursor-pagination#367
File: src/find.ts:14-20
Timestamp: 2025-01-07T11:51:25.488Z
Learning: The `hint` property is defined in `PaginationParams` as an optional string property (`hint?: string`). Any interface that extends `PaginationParams`, such as `FindParams` or `AggregateParams`, automatically inherits this property through TypeScript's interface extension.
🪛 Biome (1.9.4)
src/find.ts
[error] 91-91: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
🔇 Additional comments (2)
src/find.ts (2)
14-20
: Well-structured interface definition!The
FindParams
interface properly extendsPaginationParams
and defines clear, type-safe optional properties. Good job on not redefining thehint
property since it's inherited fromPaginationParams
.
44-45
: Type assertion could be unsafe.The type assertion to
SanitizeParams
might hide type incompatibilities. Consider adding runtime validation or using a type guard.✅ Verification successful
Type assertion is safe in this context
The type assertion
params as SanitizeParams
is safe because:
- The
sanitizeParams()
function performs thorough runtime validation and transformation- All properties in
SanitizeParams
are optionalFindParams
is compatible withSanitizeParams
(shares common properties)- The function returns a properly validated object
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check the definition of SanitizeParams to ensure compatibility ast-grep --pattern 'interface SanitizeParams { $$$ }'Length of output: 654
Script:
#!/bin/bash # Check the params parameter type and sanitizeParams implementation ast-grep --pattern 'function find($$$) { $$$ }' echo "=== Checking sanitizeParams implementation ===" ast-grep --pattern 'export async function sanitizeParams($$$) { $$$ }'Length of output: 229
Script:
#!/bin/bash # Check find.ts content echo "=== Content of find.ts ===" cat src/find.ts echo -e "\n=== Content of sanitizeParams.ts ===" cat src/utils/sanitizeParams.tsLength of output: 7355
function hasFindAsCursor( | ||
collection: unknown | ||
): collection is Collection<Document> & { findAsCursor: Function } { | ||
return typeof (collection as any).findAsCursor === 'function'; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve type safety of the type guard function.
The function uses unsafe type practices:
- Uses broad 'Function' type (flagged by static analysis)
- Uses type assertion to 'any'
function hasFindAsCursor(
collection: unknown
-): collection is Collection<Document> & { findAsCursor: Function } {
- return typeof (collection as any).findAsCursor === 'function';
+): collection is Collection<Document> & { findAsCursor: (...args: any[]) => any } {
+ return typeof (collection as Partial<Collection<Document>>).findAsCursor === 'function';
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
function hasFindAsCursor( | |
collection: unknown | |
): collection is Collection<Document> & { findAsCursor: Function } { | |
return typeof (collection as any).findAsCursor === 'function'; | |
} | |
function hasFindAsCursor( | |
collection: unknown | |
): collection is Collection<Document> & { findAsCursor: (...args: any[]) => any } { | |
return typeof (collection as Partial<Collection<Document>>).findAsCursor === 'function'; | |
} |
🧰 Tools
🪛 Biome (1.9.4)
[error] 91-91: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
📚 Context/Description Behind The Change
This pull request converts the entire project from JavaScript to TypeScript. The conversion includes adding type annotations, interfaces, and updating the build process to compile TypeScript files.
Motivation and Context:
The conversion to TypeScript enhances type safety, improves developer tooling, and helps prevent runtime errors by catching issues at compile time. This change is part of our ongoing effort to modernize the codebase and improve maintainability.
Types of Changes:
🚨 Potential Risks & What To Monitor After Deployment
🧑🔬 How Has This Been Tested?
🚚 Release Plan
Merge and run
npm run semantic-release
over master.