From a6b79ca2bf3f110a7d161ea25ef71d09f3419c5c Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 15 Dec 2023 11:18:51 +0100 Subject: [PATCH] fix: use prototypeless objects for field-to-type mappings Fixes: https://github.com/mongodb-js/mongodb-schema/issues/211 --- src/schema-analyzer.ts | 6 +++--- test/basic.test.ts | 7 +++++-- test/mixed-type-nested.test.ts | 5 +++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/schema-analyzer.ts b/src/schema-analyzer.ts index 7d641cb..9280a39 100644 --- a/src/schema-analyzer.ts +++ b/src/schema-analyzer.ts @@ -1,6 +1,6 @@ import Reservoir from 'reservoir'; -import type { +import { Document, ObjectId, MinKey, @@ -432,7 +432,7 @@ export class SchemaAnalyzer { options: SchemaParseOptions; documentsAnalyzed = 0; schemaAnalysisRoot: SchemaAnalysisRoot = { - fields: {}, + fields: Object.create(null), count: 0 }; @@ -513,7 +513,7 @@ export class SchemaAnalyzer { (value as BSONValue[]).forEach((v: BSONValue) => addToType(path, v, type.types)); } else if (isDocumentType(type)) { // Recurse into nested documents by calling `addToField` for all sub-fields. - type.fields = type.fields ?? {}; + type.fields = type.fields ?? Object.create(null); Object.entries(value as Document).forEach( ([fieldName, v]) => addToField(fieldName, [...path, fieldName], v, type.fields) ); diff --git a/test/basic.test.ts b/test/basic.test.ts index 6f01c5d..bd60159 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -19,7 +19,8 @@ describe('using only basic fields', function() { last_address_longitude: null, created_at: new Date(), length: 29, - 'name[]': 'Annabeth Frankie' + 'name[]': 'Annabeth Frankie', + toString: 42 } ]; @@ -38,7 +39,8 @@ describe('using only basic fields', function() { 'name', 'stats_friends', 'twitter_username', - 'name[]' + 'name[]', + 'toString' ]; assert.deepEqual(users.fields.map(v => v.name).sort(), fieldNames.sort()); }); @@ -59,5 +61,6 @@ describe('using only basic fields', function() { assert.equal(users.fields.find(v => v.name === 'name')?.type, 'String'); assert.equal(users.fields.find(v => v.name === 'stats_friends')?.type, 'Number'); assert.equal(users.fields.find(v => v.name === 'twitter_username')?.type, 'String'); + assert.equal(users.fields.find(v => v.name === 'toString')?.type, 'Number'); }); }); diff --git a/test/mixed-type-nested.test.ts b/test/mixed-type-nested.test.ts index e52551c..ef2d9b5 100644 --- a/test/mixed-type-nested.test.ts +++ b/test/mixed-type-nested.test.ts @@ -30,10 +30,11 @@ describe('mixed types nested', function() { { _id: 5, address: { - valid: true + valid: true, + toString: { value: false } } } - ]; + ] as const; let schema: Schema; let valid: SchemaField | undefined;