Skip to content

Commit

Permalink
Merge pull request #1 from BetterCallSky/master
Browse files Browse the repository at this point in the history
merge with master
  • Loading branch information
lchimaru authored Jun 3, 2019
2 parents e6027fc + a7c9252 commit 18caff6
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 12 deletions.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ const AddressSchema = new Schema({
zip: String,
});

const PhoneSchema = new Schema({
phoneNumber: { type: Schema.Types.Number, required: true },
name: String
})

const UserSchema = new Schema({
title: { type: String, required: true },
author: { type: String, required: true },
Expand Down Expand Up @@ -61,6 +66,10 @@ const UserSchema = new Schema({
type: AddressSchema,
required: true,
},
phones: {
type: [PhoneSchema],
required: true,
},
});

interface UserProps extends Document {
Expand All @@ -83,6 +92,11 @@ const AddressSchema = createSchema({
city: Type.string(),
country: Type.optionalString(),
zip: Type.optionalString(),
}, { _id: false });

const PhoneSchema = createSchema({
phoneNumber: Type.number(),
name: Type.optionalString(),
});

const UserSchema = createSchema({
Expand All @@ -102,6 +116,7 @@ const UserSchema = createSchema({
m: Type.mixed(),
otherId: Type.objectId(),
address: Type.schema().of(AddressSchema),
phones: Type.array().of(PhoneSchema),
});

const User = typedModel('User', UserSchema);
Expand Down Expand Up @@ -137,6 +152,24 @@ User.findById('123').then(user => {
tags: Type.array().of(Type.string())
}
```
- `schema.of(ExampleSchema)` has typical for Subdocument additional fields and methods. Setting `{ _id: false }` in SchemaOptions won't attach `_id` property in Subdocument
```ts
const AddressSchema = createSchema({city: Type.string()}, { _id: false });
{
// same as {type: AddressSchema}
address: Type.schema().of(AddressSchema)
}
// address property has city property, other Subdocument methods and properties except '_id'
```
- `array.of(ExampleSchema)` will return DocumentArray instead of standard array
```ts
const PhoneSchema = createSchema({phoneNumber: Type.number()}, { _id: false });
{
// same as {type: [PhoneSchema]}
phones: Type.schema().of(PhoneSchema)
}
// phones property has such methods as create(), id(), but also those typical for arrays like map(), filter() etc
```
- `ref` is a special type for creating references
```ts
{
Expand Down
8 changes: 7 additions & 1 deletion example/example1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ const AddressSchema = createSchema({
city: Type.string(),
country: Type.optionalString(),
zip: Type.optionalString(),
}, { _id: false });

const PhoneSchema = createSchema({
phone: Type.number(),
name: Type.optionalString(),
});

const UserSchema = createSchema({
Expand All @@ -23,6 +28,7 @@ const UserSchema = createSchema({
m: Type.mixed(),
otherId: Type.objectId(),
address: Type.schema().of(AddressSchema),
phones: Type.array().of(PhoneSchema),
});

const User = typedModel('User', UserSchema);
Expand All @@ -32,6 +38,6 @@ User.findById('123').then(user => {
}
});

type UserDoc = ExtractDoc<typeof User>;
type UserDoc = ExtractDoc<typeof UserSchema>;

function blockUser(user: UserDoc) {}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ts-mongoose",
"version": "0.0.14",
"version": "0.0.15",
"description": "",
"main": "index.js",
"module": "es/index.js",
Expand Down
15 changes: 10 additions & 5 deletions src/Type.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { SchemaTypeOpts, Schema, Types } from 'mongoose';
import { Extract, ConvertObject } from './types';
import {
Extract,
ConvertObject,
ExtractSchema,
ArrayOfElements,
} from './types';

const createType = <T>(type: any) => (options: SchemaTypeOpts<T> = {}) => {
return ({
Expand Down Expand Up @@ -54,15 +59,15 @@ export const Type = {
required: true,
...options,
type: [schema],
} as any) as ConvertObject<T>[];
} as any) as ArrayOfElements<T>;
},
}),
optionalArray: (options: SchemaTypeOpts<Array<any>> = {}) => ({
of<T>(schema: T) {
return ({
...options,
type: [schema],
} as any) as ConvertObject<T>[] | null | undefined;
} as any) as ArrayOfElements<T> | null | undefined;
},
}),
schema: (options: SchemaTypeOpts<object> = {}) => ({
Expand All @@ -71,15 +76,15 @@ export const Type = {
required: true,
...options,
type: schema,
} as any) as Extract<T>;
} as any) as ExtractSchema<T>;
},
}),
optionalSchema: (options: SchemaTypeOpts<object> = {}) => ({
of<T>(schema: T) {
return ({
...options,
type: schema,
} as any) as Extract<T> | null | undefined;
} as any) as ExtractSchema<T> | null | undefined;
},
}),
ref: <T>(schema: T) => ({
Expand Down
11 changes: 7 additions & 4 deletions src/createSchema.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { SchemaOptions, Schema } from 'mongoose';
import { ConvertObject } from './types';

type CreateSchema = <T extends { [x: string]: any }>(
type CreateSchema = <T extends { [x: string]: any }, O extends SchemaOptions>(
definition?: T,
options?: SchemaOptions
) => Schema & { definition: ConvertObject<T> };
options?: O extends SchemaOptions ? SchemaOptions : O
) => Schema & {
definition: ConvertObject<T>;
options: O;
};

export const createSchema: CreateSchema = (definition?, options?) => {
return new Schema(definition, options) as any;
};
};
20 changes: 19 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
import { Types, Document } from 'mongoose';

export type Extract<T> = T extends { definition: infer U } ? U : never;
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type ExtractOptions<T> = T extends { options: infer U } ? U : never;
type DisabledIdOption = { _id: false };
type IsSchemaType<T, IS, NOT> = T extends { definition: any } ? IS : NOT;
type SubdocumentsArrayWithoutId<T extends Types.Subdocument> = {
[P in keyof Types.DocumentArray<T>]: Omit<T, '_id'>
};

export type ExtractSchema<T> = Extract<T> &
(ExtractOptions<T> extends DisabledIdOption
? Omit<Types.Subdocument, '_id'>
: Types.Subdocument);
export type ArrayOfElements<T> = IsSchemaType<
T,
ExtractOptions<T> extends DisabledIdOption
? SubdocumentsArrayWithoutId<Extract<T> & Types.Subdocument>
: Types.DocumentArray<Extract<T> & Types.Subdocument>,
Array<T>
>;

type ExcludeBaseType<T> = Exclude<T, string | number | Types.ObjectId>;

Expand Down

0 comments on commit 18caff6

Please sign in to comment.