or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dependency-injection.mdindex.mdmodule-configuration.mdschema-definition.mdschema-factories.mdutility-functions.mdvalidation-pipes.md

schema-factories.mddocs/

0

# Schema Factories

1

2

Factory classes for generating Mongoose schemas and definitions from decorated TypeScript classes. The factory system transforms class-based schema definitions into proper Mongoose schemas with all decorators processed.

3

4

## Capabilities

5

6

### SchemaFactory

7

8

Creates complete Mongoose schemas from decorated TypeScript classes.

9

10

```typescript { .api }

11

class SchemaFactory {

12

/**

13

* Creates a Mongoose schema from a decorated TypeScript class

14

* @param target - The decorated class constructor

15

* @returns Mongoose schema instance

16

*/

17

static createForClass<TClass>(target: Type<TClass>): mongoose.Schema<TClass>;

18

}

19

```

20

21

**Usage Examples:**

22

23

```typescript

24

import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose';

25

26

// Define schema class

27

@Schema()

28

export class User {

29

@Prop({ required: true })

30

name: string;

31

32

@Prop({ unique: true })

33

email: string;

34

35

@Prop({ default: Date.now })

36

createdAt: Date;

37

}

38

39

// Generate Mongoose schema

40

export const UserSchema = SchemaFactory.createForClass(User);

41

42

// Use in module registration

43

@Module({

44

imports: [

45

MongooseModule.forFeature([

46

{ name: User.name, schema: UserSchema }

47

])

48

],

49

})

50

export class UserModule {}

51

52

// Schema with complex properties

53

@Schema({

54

timestamps: true,

55

collection: 'products'

56

})

57

export class Product {

58

@Prop({ required: true, index: true })

59

name: string;

60

61

@Prop({ required: true, min: 0 })

62

price: number;

63

64

@Prop([String])

65

tags: string[];

66

67

@Prop({

68

type: {

69

street: String,

70

city: String,

71

country: { type: String, default: 'US' }

72

}

73

})

74

address: {

75

street: string;

76

city: string;

77

country: string;

78

};

79

80

@Virtual()

81

get displayPrice(): string {

82

return `$${this.price.toFixed(2)}`;

83

}

84

}

85

86

export const ProductSchema = SchemaFactory.createForClass(Product);

87

88

// Schema with references

89

@Schema()

90

export class Order {

91

@Prop({ type: mongoose.Types.ObjectId, ref: 'User', required: true })

92

user: mongoose.Types.ObjectId;

93

94

@Prop([{

95

product: { type: mongoose.Types.ObjectId, ref: 'Product', required: true },

96

quantity: { type: Number, required: true, min: 1 },

97

price: { type: Number, required: true }

98

}])

99

items: {

100

product: mongoose.Types.ObjectId;

101

quantity: number;

102

price: number;

103

}[];

104

105

@Prop({ enum: ['pending', 'processing', 'shipped', 'delivered'] })

106

status: string;

107

108

@Virtual()

109

get totalAmount(): number {

110

return this.items.reduce((sum, item) => sum + (item.price * item.quantity), 0);

111

}

112

}

113

114

export const OrderSchema = SchemaFactory.createForClass(Order);

115

```

116

117

### DefinitionsFactory

118

119

Creates Mongoose schema definitions (plain objects) from decorated classes for advanced schema customization.

120

121

```typescript { .api }

122

class DefinitionsFactory {

123

/**

124

* Creates a Mongoose schema definition from a decorated TypeScript class

125

* @param target - The decorated class constructor

126

* @returns Mongoose schema definition object

127

*/

128

static createForClass(target: Type<unknown>): mongoose.SchemaDefinition;

129

}

130

```

131

132

**Usage Examples:**

133

134

```typescript

135

import { DefinitionsFactory } from '@nestjs/mongoose';

136

137

@Schema()

138

export class BaseDocument {

139

@Prop({ required: true })

140

name: string;

141

142

@Prop({ default: Date.now })

143

createdAt: Date;

144

}

145

146

// Get schema definition for customization

147

const baseDefinition = DefinitionsFactory.createForClass(BaseDocument);

148

149

// Create custom schema with definition

150

const customSchema = new mongoose.Schema({

151

...baseDefinition,

152

// Add additional fields

153

customField: { type: String, default: 'custom-value' },

154

// Override existing fields

155

name: { type: String, required: true, uppercase: true },

156

}, {

157

timestamps: true,

158

collection: 'custom_documents'

159

});

160

161

// Use with discriminators

162

const AnimalSchema = SchemaFactory.createForClass(Animal);

163

const DogSchema = new mongoose.Schema(DefinitionsFactory.createForClass(Dog));

164

const CatSchema = new mongoose.Schema(DefinitionsFactory.createForClass(Cat));

165

166

AnimalSchema.discriminator('Dog', DogSchema);

167

AnimalSchema.discriminator('Cat', CatSchema);

168

```

169

170

### VirtualsFactory

171

172

Processes virtual properties and adds them to existing schemas.

173

174

```typescript { .api }

175

class VirtualsFactory {

176

/**

177

* Inspects a class for virtual properties and adds them to a schema

178

* @param target - The decorated class constructor

179

* @param schema - The Mongoose schema to add virtuals to

180

*/

181

static inspect<TClass>(target: Type<TClass>, schema: mongoose.Schema<TClass>): void;

182

}

183

```

184

185

**Usage Examples:**

186

187

```typescript

188

import { VirtualsFactory } from '@nestjs/mongoose';

189

190

@Schema()

191

export class User {

192

@Prop({ required: true })

193

firstName: string;

194

195

@Prop({ required: true })

196

lastName: string;

197

198

@Prop()

199

email: string;

200

201

@Virtual()

202

get fullName(): string {

203

return `${this.firstName} ${this.lastName}`;

204

}

205

206

@Virtual({

207

options: {

208

ref: 'Post',

209

localField: '_id',

210

foreignField: 'author'

211

}

212

})

213

posts: any[];

214

}

215

216

// Create schema without virtuals first

217

const userSchema = new mongoose.Schema({

218

firstName: { type: String, required: true },

219

lastName: { type: String, required: true },

220

email: String,

221

});

222

223

// Add virtuals from decorated class

224

VirtualsFactory.inspect(User, userSchema);

225

226

// Schema now includes virtual properties

227

export const UserSchema = userSchema;

228

```

229

230

## Advanced Factory Usage

231

232

### Custom Schema Creation Pipeline

233

234

```typescript

235

import { SchemaFactory, DefinitionsFactory, VirtualsFactory } from '@nestjs/mongoose';

236

237

export class CustomSchemaFactory {

238

static createAdvancedSchema<T>(target: Type<T>, options?: any): mongoose.Schema<T> {

239

// Get base definition

240

const definition = DefinitionsFactory.createForClass(target);

241

242

// Create schema with custom options

243

const schema = new mongoose.Schema(definition, {

244

timestamps: true,

245

versionKey: false,

246

...options,

247

});

248

249

// Add virtuals

250

VirtualsFactory.inspect(target, schema);

251

252

// Add custom middleware

253

schema.pre('save', function() {

254

if (this.isNew) {

255

this.createdAt = new Date();

256

}

257

});

258

259

// Add custom methods

260

schema.methods.toJSON = function() {

261

const obj = this.toObject();

262

delete obj.__v;

263

return obj;

264

};

265

266

return schema;

267

}

268

}

269

270

// Usage

271

@Schema()

272

export class CustomDocument {

273

@Prop({ required: true })

274

title: string;

275

276

@Virtual()

277

get slug(): string {

278

return this.title.toLowerCase().replace(/\s+/g, '-');

279

}

280

}

281

282

export const CustomDocumentSchema = CustomSchemaFactory.createAdvancedSchema(

283

CustomDocument,

284

{ collection: 'custom_docs' }

285

);

286

```

287

288

### Schema Composition

289

290

```typescript

291

// Base schema components

292

@Schema()

293

export class Timestamped {

294

@Prop({ default: Date.now })

295

createdAt: Date;

296

297

@Prop({ default: Date.now })

298

updatedAt: Date;

299

}

300

301

@Schema()

302

export class SoftDeleted {

303

@Prop({ default: false })

304

isDeleted: boolean;

305

306

@Prop()

307

deletedAt: Date;

308

}

309

310

// Composed schema

311

@Schema()

312

export class BlogPost extends Timestamped {

313

@Prop({ required: true })

314

title: string;

315

316

@Prop({ required: true })

317

content: string;

318

319

@Prop([String])

320

tags: string[];

321

322

@Virtual()

323

get excerpt(): string {

324

return this.content.substring(0, 150) + '...';

325

}

326

}

327

328

// Create with multiple inheritance patterns

329

export function createComposedSchema<T>(

330

target: Type<T>,

331

mixins: Type<any>[] = []

332

): mongoose.Schema<T> {

333

const baseDefinition = DefinitionsFactory.createForClass(target);

334

335

// Merge definitions from mixins

336

const composedDefinition = mixins.reduce((def, mixin) => {

337

const mixinDef = DefinitionsFactory.createForClass(mixin);

338

return { ...def, ...mixinDef };

339

}, baseDefinition);

340

341

const schema = new mongoose.Schema(composedDefinition);

342

343

// Add virtuals from all classes

344

[target, ...mixins].forEach(cls => {

345

VirtualsFactory.inspect(cls, schema);

346

});

347

348

return schema;

349

}

350

351

// Usage

352

export const BlogPostSchema = createComposedSchema(BlogPost, [Timestamped, SoftDeleted]);

353

```

354

355

## Provider Functions

356

357

Internal functions used by the module system to create NestJS providers.

358

359

### createMongooseProviders

360

361

Creates NestJS providers for synchronous model registration.

362

363

```typescript { .api }

364

/**

365

* Creates NestJS providers for synchronous models

366

* @param connectionName - Optional connection name

367

* @param options - Array of model definitions

368

* @returns Array of NestJS providers

369

*/

370

function createMongooseProviders(

371

connectionName?: string,

372

options?: ModelDefinition[]

373

): Provider[];

374

```

375

376

### createMongooseAsyncProviders

377

378

Creates NestJS providers for asynchronous model registration.

379

380

```typescript { .api }

381

/**

382

* Creates NestJS providers for asynchronous models

383

* @param connectionName - Optional connection name

384

* @param modelFactories - Array of async model factories

385

* @returns Array of NestJS providers

386

*/

387

function createMongooseAsyncProviders(

388

connectionName?: string,

389

modelFactories?: AsyncModelFactory[]

390

): Provider[];

391

```

392

393

## Type Metadata Storage

394

395

Advanced internal system for storing and retrieving decorator metadata.

396

397

```typescript { .api }

398

class TypeMetadataStorage {

399

/**

400

* Add property metadata from @Prop decorators

401

* @param metadata - Property metadata object

402

*/

403

addPropertyMetadata(metadata: PropertyMetadata): void;

404

405

/**

406

* Add schema metadata from @Schema decorators

407

* @param metadata - Schema metadata object

408

*/

409

addSchemaMetadata(metadata: SchemaMetadata): void;

410

411

/**

412

* Add virtual metadata from @Virtual decorators

413

* @param metadata - Virtual metadata object

414

*/

415

addVirtualMetadata(metadata: VirtualMetadataInterface): void;

416

417

/**

418

* Get schema metadata for a target class

419

* @param target - Class constructor

420

* @returns Schema metadata or undefined

421

*/

422

getSchemaMetadataByTarget(target: Type<unknown>): SchemaMetadata | undefined;

423

424

/**

425

* Get virtual metadata for a target class

426

* @param targetFilter - Class constructor to filter by

427

* @returns Array of virtual metadata

428

*/

429

getVirtualsMetadataByTarget<TClass>(targetFilter: Type<TClass>): VirtualMetadataInterface[];

430

}

431

```