From 36ef704d45f61bb6911ddc625207687df21365af Mon Sep 17 00:00:00 2001 From: "hugo.prunaux" Date: Thu, 19 Mar 2026 15:46:50 +0100 Subject: [PATCH 1/7] chore: [NOTHING TO REVIEW] split type-checked options --- tsconfig.json | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index c6b005d..ee20a86 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,14 @@ { "compilerOptions": { + /* Type Checking */ + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "strictNullChecks": true, + "target": "es2022", "module": "commonjs", "lib": ["ES2022"], @@ -10,14 +19,7 @@ "allowSyntheticDefaultImports": true, "alwaysStrict": true, "sourceMap": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitAny": false, - "noImplicitThis": false, - "strictNullChecks": false + "forceConsistentCasingInFileNames": true }, "include": [ "jest.config.ts", From 538adbd23d99baf61db7494036716431e9e8be3d Mon Sep 17 00:00:00 2001 From: "hugo.prunaux" Date: Thu, 19 Mar 2026 15:47:32 +0100 Subject: [PATCH 2/7] feat: add a few flags --- src/tools/arrayFilters.ts | 6 ++++-- tsconfig.json | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tools/arrayFilters.ts b/src/tools/arrayFilters.ts index 93579b1..c7b90c3 100644 --- a/src/tools/arrayFilters.ts +++ b/src/tools/arrayFilters.ts @@ -1,3 +1,5 @@ +import type { Document } from 'mongodb'; + /** * Spots "positional operator" path in string for array filters * Example: xxx.$[element_name].yyy @@ -72,7 +74,7 @@ export function hasPathMatchingPositionalOperators( */ export function buildArrayFiltersOptionToUnset(path: string) { let positionalElementNameMatch; - const arrayFilters = []; + const arrayFilters: Document[] = []; do { positionalElementNameMatch = ARRAY_FILTER_OPERATION_PATTERN.exec(path); if (positionalElementNameMatch) { @@ -115,7 +117,7 @@ function _buildSubPathWithPositionalElementAndNextChild( `\\$\\[${positionalElementName}]\\.(\\w+)(?:\\.|$)`, ); - const nextChildName = matchRegexp.exec(completePath)[1]; + const nextChildName = matchRegexp.exec(completePath)?.[1]; return `${positionalElementName}.${nextChildName}`; } diff --git a/tsconfig.json b/tsconfig.json index ee20a86..9153af5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,18 @@ { "compilerOptions": { /* Type Checking */ + "allowUnreachableCode": false, + "allowUnusedLabels": false, "noFallthroughCasesInSwitch": true, "noImplicitAny": false, "noImplicitReturns": true, "noImplicitThis": true, "noUnusedLocals": true, "noUnusedParameters": true, + "strict": false, + "strictBindCallApply": true, + "strictBuiltinIteratorReturn": true, + "strictFunctionTypes": true, "strictNullChecks": true, "target": "es2022", From ecc188881aeb5dce1b756e7c2ed185f3ab2c65d6 Mon Sep 17 00:00:00 2001 From: "hugo.prunaux" Date: Thu, 19 Mar 2026 13:25:37 +0100 Subject: [PATCH 3/7] feat: enable `noImplicitAny` (1/3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 👉 Fix simple cases. - ⏳ Add missing test types. - ⏳ Fix missing semver typing. --- __tests__/MongoBulkDataMigration.update.test.ts | 2 +- src/lib/computeRollbackQuery.ts | 2 +- src/testUtils/doRollbackAndAssertForInitialState.ts | 4 ++-- tsconfig.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/__tests__/MongoBulkDataMigration.update.test.ts b/__tests__/MongoBulkDataMigration.update.test.ts index 10bfc96..82b9bf0 100644 --- a/__tests__/MongoBulkDataMigration.update.test.ts +++ b/__tests__/MongoBulkDataMigration.update.test.ts @@ -226,7 +226,7 @@ describe('MongoBulkDataMigration', () => { describe('Bulk splitting', () => { const END_OF_BULK_LOG = 'Documents migration is successful'; - let update: UpdateFilter<{ value: number }>; + let update: (arg: { value: number }) => UpdateFilter<{ value: number }>; beforeEach(async () => { await collection.insertMany( Array.from({ length: 100 }, (_, i) => ({ value: i + 1 })), diff --git a/src/lib/computeRollbackQuery.ts b/src/lib/computeRollbackQuery.ts index 1278fb7..275b96c 100644 --- a/src/lib/computeRollbackQuery.ts +++ b/src/lib/computeRollbackQuery.ts @@ -43,7 +43,7 @@ function computeArrayFilterAndUnsetWithPositionals( updateQuery: any, backup: any, ): { arrayFilters: Document[]; unsetAdditionalPositional: any } { - const unsetAdditionalPositional = {}; + const unsetAdditionalPositional: Record = {}; const filteredObject = Object.keys(flattenDocument(backup)); const arrayFilters: Document[] = []; const update = Object.keys(flattenDocument(updateQuery.$set ?? {})); diff --git a/src/testUtils/doRollbackAndAssertForInitialState.ts b/src/testUtils/doRollbackAndAssertForInitialState.ts index 2ecb6d7..a7eb65a 100644 --- a/src/testUtils/doRollbackAndAssertForInitialState.ts +++ b/src/testUtils/doRollbackAndAssertForInitialState.ts @@ -2,7 +2,7 @@ import _ from 'lodash'; import MongoBulkDataMigration from '../MongoBulkDataMigration'; import { BulkOperationResult } from '../lib/AbstractBulkOperationResults'; -let globalExpect = null; +let globalExpect: ((value: unknown) => unknown) | null = null; export function setGlobalExpect(expect: any) { globalExpect = expect; @@ -59,7 +59,7 @@ function assertDeepHaveMembers( effectiveDocs: any, expectedDocs: any, ) { - const compareObjectId = (objA, objB) => { + const compareObjectId = (objA: string, objB: string) => { const sortedIds = [objA, objB].sort(); return sortedIds[0] === objA ? -1 : 1; }; diff --git a/tsconfig.json b/tsconfig.json index 9153af5..2f47aba 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "allowUnreachableCode": false, "allowUnusedLabels": false, "noFallthroughCasesInSwitch": true, - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitReturns": true, "noImplicitThis": true, "noUnusedLocals": true, From 7f7bc1fd3deaf02cc833bc55b5d3809c1293a339 Mon Sep 17 00:00:00 2001 From: "hugo.prunaux" Date: Thu, 19 Mar 2026 13:26:31 +0100 Subject: [PATCH 4/7] feat: enable `noImplicitAny` (2/3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ✅ Fix simple cases. - 👉 Add missing test types. - ⏳ Fix missing semver typing. --- __testsUtils__/globals.d.ts | 8 ++++++++ __testsUtils__/mongoValidation.ts | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 __testsUtils__/globals.d.ts diff --git a/__testsUtils__/globals.d.ts b/__testsUtils__/globals.d.ts new file mode 100644 index 0000000..700a279 --- /dev/null +++ b/__testsUtils__/globals.d.ts @@ -0,0 +1,8 @@ +import type { MongoMemoryServer } from 'mongodb-memory-server'; +import type { MongoClient, Db } from 'mongodb'; + +declare global { + var mongoServer: MongoMemoryServer; + var mongoClient: MongoClient; + var db: Db; +} diff --git a/__testsUtils__/mongoValidation.ts b/__testsUtils__/mongoValidation.ts index 3d243bd..9c6d500 100644 --- a/__testsUtils__/mongoValidation.ts +++ b/__testsUtils__/mongoValidation.ts @@ -13,7 +13,7 @@ async function setValidationLevel( const errors: Record = {}; for (const collection of collections) { try { - await global.db.runCommand({ + await global.db.command({ collMod: collection, validationLevel: validationLevel, }); From 94b7b91e0ff8b1f0fbd8eb3b24d1162aa79b585d Mon Sep 17 00:00:00 2001 From: "hugo.prunaux" Date: Thu, 19 Mar 2026 13:26:51 +0100 Subject: [PATCH 5/7] feat: enable `noImplicitAny` (3/3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ✅ Fix simple cases. - ✅ Add missing test types. - 👉 Fix missing semver typing. - An alternative to `"skipLibCheck": true` would have been to install types for `semver`. --- tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tsconfig.json b/tsconfig.json index 2f47aba..7e0c24d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,7 @@ "noImplicitThis": true, "noUnusedLocals": true, "noUnusedParameters": true, + "skipLibCheck": true, "strict": false, "strictBindCallApply": true, "strictBuiltinIteratorReturn": true, From f4ad3f787c8713e25f9dcee126da18c3a7aaa018 Mon Sep 17 00:00:00 2001 From: "hugo.prunaux" Date: Thu, 19 Mar 2026 13:32:37 +0100 Subject: [PATCH 6/7] feat: enable `useUnknownInCatchVariables` - We can probably do something simpler by checking if the error is an instance of `MongoServerError`, but I prefer not to introduce this runtime change here for safety. --- src/MongoBulkDataMigration.ts | 7 ++++++- tsconfig.json | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/MongoBulkDataMigration.ts b/src/MongoBulkDataMigration.ts index 50e03e0..1a55f89 100644 --- a/src/MongoBulkDataMigration.ts +++ b/src/MongoBulkDataMigration.ts @@ -441,7 +441,12 @@ export default class MongoBulkDataMigration< try { await migrationCollection.drop(); } catch (err) { - if (err?.message === 'ns not found') { + if ( + err && + typeof err === 'object' && + 'message' in err && + err.message === 'ns not found' + ) { return; } throw err; diff --git a/tsconfig.json b/tsconfig.json index 7e0c24d..189f430 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ "strictBuiltinIteratorReturn": true, "strictFunctionTypes": true, "strictNullChecks": true, + "useUnknownInCatchVariables": true, "target": "es2022", "module": "commonjs", From 97e6a4ad7b6a54699bf22d61b9e66f802dcb80ac Mon Sep 17 00:00:00 2001 From: "hugo.prunaux" Date: Thu, 19 Mar 2026 15:56:29 +0100 Subject: [PATCH 7/7] feat: enable `strict: true` --- src/lib/AbstractBulkOperationResults.ts | 13 +++++-------- tsconfig.json | 6 +----- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/lib/AbstractBulkOperationResults.ts b/src/lib/AbstractBulkOperationResults.ts index 0f8868a..35bfb79 100644 --- a/src/lib/AbstractBulkOperationResults.ts +++ b/src/lib/AbstractBulkOperationResults.ts @@ -54,9 +54,9 @@ export abstract class AbstractBulkOperationResults { this.collection = collection; this.totalOperations = totalOperations; this.logger = logger; + this.bulk = this.collection.initializeUnorderedBulkOp(); this.totalBulkOps = 0; this.results = _.cloneDeep(INITIAL_BULK_INFOS); - this.initialize(); } abstract logExecutionStatus(executionResults: BulkOperationResult): this; @@ -78,12 +78,6 @@ export abstract class AbstractBulkOperationResults { ); } - private initialize(): this { - this.bulk = this.collection.initializeUnorderedBulkOp(); - this.totalBulkOps = 0; - return this; - } - public async execute(continueOnBulkWriteError = false): Promise { if (this.totalBulkOps === 0) { return this; @@ -117,7 +111,10 @@ export abstract class AbstractBulkOperationResults { this.mergeResults(resultPartial); this.logExecutionStatus(resultPartial); - return this.initialize(); + this.bulk = this.collection.initializeUnorderedBulkOp(); + this.totalBulkOps = 0; + + return this; } private mergeResults(resultB: BulkOperationResult): this { diff --git a/tsconfig.json b/tsconfig.json index 189f430..dc3c13c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,11 +10,7 @@ "noUnusedLocals": true, "noUnusedParameters": true, "skipLibCheck": true, - "strict": false, - "strictBindCallApply": true, - "strictBuiltinIteratorReturn": true, - "strictFunctionTypes": true, - "strictNullChecks": true, + "strict": true, "useUnknownInCatchVariables": true, "target": "es2022",