diff --git a/packages/mongodb-constants/src/filter.spec.ts b/packages/mongodb-constants/src/filter.spec.ts index f1f169d7..edc68264 100644 --- a/packages/mongodb-constants/src/filter.spec.ts +++ b/packages/mongodb-constants/src/filter.spec.ts @@ -193,6 +193,29 @@ describe('completer', function () { }); }); + describe('$$IDX system variable', function () { + it('should include $$IDX system variable gated to MongoDB 8.3+', function () { + const idx = ALL_CONSTANTS.find((c) => c.value === '$$IDX'); + expect(idx).to.exist; + expect(idx?.version).to.eq('8.3.0'); + expect(idx?.meta).to.eq('variable:system'); + }); + + it('should return $$IDX for server 8.3+ but not for older servers', function () { + const withIdx = getFilteredCompletions( + { serverVersion: '8.3.0' }, + ALL_CONSTANTS, + ).map((c) => c.value); + expect(withIdx).to.include('$$IDX'); + + const withoutIdx = getFilteredCompletions( + { serverVersion: '8.2.0' }, + ALL_CONSTANTS, + ).map((c) => c.value); + expect(withoutIdx).to.not.include('$$IDX'); + }); + }); + describe('all completions', function () { it('should have valid semver version or range specified', function () { ALL_CONSTANTS.forEach(({ name, version }) => { diff --git a/packages/mongodb-constants/src/system-variables.ts b/packages/mongodb-constants/src/system-variables.ts index 2fe23abf..e5251243 100644 --- a/packages/mongodb-constants/src/system-variables.ts +++ b/packages/mongodb-constants/src/system-variables.ts @@ -90,6 +90,15 @@ const SYSTEM_VARIABLES = [ description: 'A variable that stores the role names of the authenticated user running the command.', }, + { + name: '$$IDX', + value: '$$IDX', + score: 1, + meta: 'variable:system', + version: '8.3.0', + description: + 'A variable that references the index of the current array element in $map, $filter, and $reduce expressions. Use arrayIndexAs to specify a custom name instead.', + }, ] as const; export { SYSTEM_VARIABLES }; diff --git a/packages/mongodb-ts-autocomplete/src/autocompleter.spec.ts b/packages/mongodb-ts-autocomplete/src/autocompleter.spec.ts index d869a96a..6a5f9fca 100644 --- a/packages/mongodb-ts-autocomplete/src/autocompleter.spec.ts +++ b/packages/mongodb-ts-autocomplete/src/autocompleter.spec.ts @@ -321,6 +321,26 @@ service host, so typescript wouldn't load all the dependencies. } }); + it('suggests arrayIndexAs inside $filter, $map, $reduce operators', async function () { + // $filter narrows its type precisely — 'arrayIn' is needed to avoid + // JavaScript built-ins (Array, ArrayBuffer) shadowing the suggestion. + // $map and $reduce resolve via Expression and work with 'array'. + const cases: [string, string][] = [ + ['$filter', 'arrayIn'], + ['$map', 'array'], + ['$reduce', 'array'], + ]; + for (const [op, prefix] of cases) { + const completions = await autocompleter.autocomplete( + `db.foo.aggregate([{ $project: { result: { ${op}: { ${prefix}`, + ); + const names = completions.map((c) => c.name); + expect(names, `${op} should suggest arrayIndexAs`).to.include( + 'arrayIndexAs', + ); + } + }); + describe('getConnectionSchemaCode', function () { it('generates code for a connection', async function () { const docs = [