mirror of
https://github.com/FlipsideCrypto/DefinitelyTyped.git
synced 2026-02-06 10:56:53 +00:00
fix(mongoose): allow specifying objectids as strings in create (#45610)
* fix(mongoose): allow specifying objectids as strings in create * add additional types * allow number for decimal128 * refactor * ensure bad enum value is not allowed and add additional tests * improve performance and refactor
This commit is contained in:
parent
070f243047
commit
3839e8d6ed
39
types/mongoose/index.d.ts
vendored
39
types/mongoose/index.d.ts
vendored
@ -101,27 +101,36 @@ declare module "mongoose" {
|
||||
|
||||
type OmitReadonly<T> = Omit<T, ReadonlyKeysOf<T>>;
|
||||
|
||||
// used to exclude functions from all levels of the schema
|
||||
type DeepNonFunctionProperties<T> =
|
||||
type MongooseBuiltIns = mongodb.ObjectID | mongodb.Decimal128 | Date | number | boolean;
|
||||
|
||||
type ImplicitMongooseConversions<T> =
|
||||
T extends MongooseBuiltIns
|
||||
? T extends (boolean | mongodb.Decimal128 | Date) ? T | string | number // accept numbers for these
|
||||
: T | string
|
||||
: T;
|
||||
|
||||
type DeepCreateObjectTransformer<T> =
|
||||
T extends MongooseBuiltIns
|
||||
? T
|
||||
: T extends object
|
||||
? { [V in keyof NonFunctionProperties<OmitReadonly<T>>]: T[V] extends object | undefined
|
||||
? ImplicitMongooseConversions<DeepCreateTransformer<NonNullable<T[V]>>>
|
||||
: ImplicitMongooseConversions<T[V]> }
|
||||
:
|
||||
T;
|
||||
|
||||
// removes functions from schema from all levels
|
||||
type DeepCreateTransformer<T> =
|
||||
T extends Map<infer KM, infer KV>
|
||||
// handle map values
|
||||
// Maps are not scrubbed, replace below line with this once minimum TS version is 3.7:
|
||||
// ? Map<KM, DeepNonFunctionProperties<KV>>
|
||||
? { [key: string]: DeepNonFunctionProperties<KV> } | [KM, KV][] | Map<KM, KV>
|
||||
? { [key: string]: DeepCreateTransformer<KV> } | [KM, KV][] | Map<KM, KV>
|
||||
:
|
||||
T extends Array<infer U>
|
||||
? (U extends object
|
||||
? { [V in keyof NonFunctionProperties<OmitReadonly<U>>]: U[V] extends object | undefined
|
||||
? DeepNonFunctionProperties<NonNullable<U[V]>>
|
||||
: U[V] }
|
||||
: U)[]
|
||||
? Array<DeepCreateObjectTransformer<U>>
|
||||
:
|
||||
T extends object
|
||||
? { [V in keyof NonFunctionProperties<OmitReadonly<T>>]: T[V] extends object | undefined
|
||||
? DeepNonFunctionProperties<NonNullable<T[V]>>
|
||||
: T[V] }
|
||||
:
|
||||
T;
|
||||
DeepCreateObjectTransformer<T>;
|
||||
|
||||
// mongoose allows Map<K, V> to be specified either as a Map or a Record<K, V>
|
||||
type DeepMapAsObject<T> = T extends object | undefined
|
||||
@ -140,7 +149,7 @@ declare module "mongoose" {
|
||||
/* Helper type to extract a definition type from a Document type */
|
||||
type DocumentDefinition<T> = Omit<T, Exclude<keyof Document, '_id'>>;
|
||||
|
||||
type ScrubCreateDefinition<T> = DeepMapAsObject<DeepNonFunctionProperties<T>>
|
||||
type ScrubCreateDefinition<T> = DeepMapAsObject<DeepCreateTransformer<T>>
|
||||
|
||||
type CreateDocumentDefinition<T> = ScrubCreateDefinition<DocumentDefinition<T>>;
|
||||
|
||||
|
||||
@ -612,13 +612,31 @@ enum SchemaEnum {
|
||||
Bar
|
||||
}
|
||||
|
||||
enum StringSchemaEnum {
|
||||
Foo = "foo",
|
||||
Bar = "bar"
|
||||
}
|
||||
|
||||
interface ModelWithFunction extends mongoose.Document {
|
||||
name: string;
|
||||
|
||||
someFunc: () => any;
|
||||
|
||||
objectId?: mongoose.Types.ObjectId;
|
||||
|
||||
date?: Date;
|
||||
|
||||
boolean?: boolean;
|
||||
|
||||
decimal?: mongodb.Decimal128;
|
||||
|
||||
number?: number;
|
||||
|
||||
enum?: SchemaEnum;
|
||||
|
||||
enum2?: StringSchemaEnum;
|
||||
|
||||
|
||||
selfRef?: ModelWithFunction | mongodb.ObjectID;
|
||||
|
||||
selfRef2?: ModelWithFunction | mongodb.ObjectID;
|
||||
@ -650,6 +668,7 @@ interface ModelWithFunction extends mongoose.Document {
|
||||
title: string,
|
||||
func: () => {}, // should be excluded in CreateQuery<T>
|
||||
tuple?: [number, number]
|
||||
objectId?: mongoose.Types.ObjectId;
|
||||
|
||||
mapWithFuncs?: Map<string, {
|
||||
title: string,
|
||||
@ -658,6 +677,7 @@ interface ModelWithFunction extends mongoose.Document {
|
||||
title: string,
|
||||
func: () => {} // should be excluded in CreateQuery<T>
|
||||
readonly readonly: unknown; // should be excluded in CreateQuery<T>
|
||||
objectId?: mongoose.Types.ObjectId;
|
||||
}>
|
||||
}>;
|
||||
}>
|
||||
@ -699,13 +719,15 @@ ModelWithFunctionInSchema.create({
|
||||
deepArray: [{
|
||||
title: "test",
|
||||
tuple: [1, 2],
|
||||
objectId: "valid-object-id-source",
|
||||
mapWithFuncs: {
|
||||
test: {
|
||||
title: "test",
|
||||
innerMap: {
|
||||
test: {
|
||||
title: "hello"
|
||||
}
|
||||
title: "hello",
|
||||
objectId: "valid-object-id-source"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -762,3 +784,33 @@ ModelWithFunctionInSchema.create({ name: "test", jobs: [] }).then(ref => {
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], selfRefArray2: [id, id] });
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], selfRefArray2: [ref, ref] });
|
||||
});
|
||||
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], objectId: "valid-object-id-source" });
|
||||
ModelWithFunctionInSchema.create({
|
||||
name: "test",
|
||||
jobs: [],
|
||||
objectId: new mongodb.ObjectID("valid-object-id-source")
|
||||
});
|
||||
|
||||
ModelWithFunctionInSchema.create({
|
||||
name: "test",
|
||||
jobs: [],
|
||||
date: new Date()
|
||||
});
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], date: "2020-01-01" });
|
||||
|
||||
// allow strings, since mongoose can cast them
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], boolean: "true" });
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], boolean: 1 });
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], decimal: "1" });
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], decimal: 1 });
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], number: "1" });
|
||||
|
||||
// $ExpectError
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], enum2: "bad value" });
|
||||
|
||||
// $ExpectError
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], date: [123] });
|
||||
|
||||
// $ExpectError
|
||||
ModelWithFunctionInSchema.create({ name: "test", jobs: [], objectId: [123] });
|
||||
|
||||
Loading…
Reference in New Issue
Block a user