Skip to content

Commit

Permalink
Merge pull request #14967 from Automattic/vkarpov15/gh-14902
Browse files Browse the repository at this point in the history
types: make Buffers into mongodb.Binary in lean result type to match runtime behavior
  • Loading branch information
vkarpov15 authored Oct 17, 2024
2 parents 0752c5d + 0b152ee commit de211db
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
22 changes: 20 additions & 2 deletions test/types/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import {
Types,
Query,
model,
ValidateOpts
ValidateOpts,
BufferToBinary
} from 'mongoose';
import { Binary } from 'mongodb';
import { IsPathRequired } from '../../types/inferschematype';
import { expectType, expectError, expectAssignable } from 'tsd';
import { ObtainDocumentPathType, ResolvePathType } from '../../types/inferschematype';
Expand Down Expand Up @@ -917,7 +919,7 @@ async function gh12593() {
expectType<Buffer | undefined | null>(doc2.x);

const doc3 = await Test.findOne({}).orFail().lean();
expectType<Buffer | undefined | null>(doc3.x);
expectType<Binary | undefined | null>(doc3.x);

const arrSchema = new Schema({ arr: [{ type: Schema.Types.UUID }] });

Expand Down Expand Up @@ -1663,3 +1665,19 @@ async function gh14950() {
expectType<string>(doc.location!.type);
expectType<number[]>(doc.location!.coordinates);
}

async function gh14902() {
const exampleSchema = new Schema({
image: { type: Buffer },
subdoc: {
type: new Schema({
testBuf: Buffer
})
}
});
const Test = model('Test', exampleSchema);

const doc = await Test.findOne().lean().orFail();
expectType<Binary | null | undefined>(doc.image);
expectType<Binary | null | undefined>(doc.subdoc!.testBuf);
}
14 changes: 13 additions & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,18 @@ declare module 'mongoose' {
[K in keyof T]: FlattenProperty<T[K]>;
};

export type BufferToBinary<T> = T extends TreatAsPrimitives ? T : T extends Record<string, any> ? {
[K in keyof T]: T[K] extends Buffer
? mongodb.Binary
: T[K] extends (Buffer | null | undefined)
? mongodb.Binary | null | undefined
: T[K] extends Types.DocumentArray<infer ItemType>
? Types.DocumentArray<BufferToBinary<ItemType>>
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
? HydratedSingleSubdocument<SubdocType>
: BufferToBinary<T[K]>;
} : T;

/**
* Separate type is needed for properties of union type (for example, Types.DocumentArray | undefined) to apply conditional check to each member of it
* https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
Expand All @@ -716,7 +728,7 @@ declare module 'mongoose' {
? Types.DocumentArray<FlattenMaps<ItemType>> : FlattenMaps<T>;

export type actualPrimitives = string | boolean | number | bigint | symbol | null | undefined;
export type TreatAsPrimitives = actualPrimitives | NativeDate | RegExp | symbol | Error | BigInt | Types.ObjectId | Buffer | Function;
export type TreatAsPrimitives = actualPrimitives | NativeDate | RegExp | symbol | Error | BigInt | Types.ObjectId | Buffer | Function | mongodb.Binary;

export type SchemaDefinitionType<T> = T extends Document ? Omit<T, Exclude<keyof Document, '_id' | 'id' | '__v'>> : T;

Expand Down
2 changes: 1 addition & 1 deletion types/query.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ declare module 'mongoose' {
type QueryOpThatReturnsDocument = 'find' | 'findOne' | 'findOneAndUpdate' | 'findOneAndReplace' | 'findOneAndDelete';

type GetLeanResultType<RawDocType, ResultType, QueryOp> = QueryOp extends QueryOpThatReturnsDocument
? (ResultType extends any[] ? Require_id<FlattenMaps<RawDocType>>[] : Require_id<FlattenMaps<RawDocType>>)
? (ResultType extends any[] ? Require_id<BufferToBinary<FlattenMaps<RawDocType>>>[] : Require_id<BufferToBinary<FlattenMaps<RawDocType>>>)
: ResultType;

type MergePopulatePaths<RawDocType, ResultType, QueryOp, Paths, TQueryHelpers, TInstanceMethods = Record<string, never>> = QueryOp extends QueryOpThatReturnsDocument
Expand Down

0 comments on commit de211db

Please sign in to comment.