ottoman
Version:
Ottoman Couchbase ODM
388 lines (387 loc) • 12 kB
TypeScript
import { ApplyStrategy, CastOptions } from '../utils/cast-strategy';
import { ModelMetadata } from './interfaces/model-metadata.interface';
import { removeOptions, saveOptions } from './model.types';
import { PopulateFieldsType, PopulateOptionsType } from './populate.types';
type CleanDocument = Omit<Document, '$' | '$isNew'>;
export type IDocument<T = any> = CleanDocument & T;
/**
* Document class represents a database document and provides useful methods to work with.
*
* @example
* ```javascript
* import { connect, model } from "ottoman";
* connect("couchbase://localhost/travel-sample@admin:password");
*
* // Create an `User` model
* const User = model('User', { name: String });
*
* // Create a document from the `User` Model
* const jane = new User({ name: "Jane Doe" })
* ```
*/
export declare abstract class Document {
#private;
/**
* @ignore
*/
[key: string]: any;
/**
* @ignore
*/
protected constructor(data: any, options?: CastOptions);
/**
* @ignore
*/
get $(): ModelMetadata;
/**
* Returns id value, useful when working with dynamic ID_KEY.
*
* @example
* ```javascript
* console.log(user._getId()); // 'userId'
* console.log(user.id); // 'userId'
* ```
*/
_getId(): string;
/**
* Returns id key.
*/
_getIdField(): string;
/**
* Saves or Updates the document.
*
* @example
* ```javascript
* const user = new User({ name: "John Doe" }); //user document created, it's not saved yet
*
* await user.save(); // user saved into the DB
*
* // You also can force save function to only create new Documents by passing true as argument
* await user.save(true); // ensure to execute a insert operation
* ```
*/
save(onlyCreate?: boolean, options?: saveOptions): Promise<any>;
/**
* Removes the document from the database.
*
* @example
* ```javascript
* const user = User.findById('userId')
*
* await user.remove();
* ```
*/
remove(options?: removeOptions): Promise<any>;
/**
* Allows to load document references.
*
*
* @example
* Getting context to explain populate.
* ```typescript
* // Defining the schemas
* const addressSchema = new Schema({
* address: String,
* });
* const personSchema = new Schema({
* name: String,
* age: Number,
* address: { type: addressSchema, ref: 'Address' },
* });
* const companySchema = new Schema({
* president: { type: personSchema, ref: 'Person' },
* ceo: { type: personSchema, ref: 'Person' },
* name: String,
* workers: [{ type: personSchema, ref: 'Person' }],
* });
*
* // Initializing the models
* const Address = model('Address', addressSchema);
* const Person = model('Person', personSchema);
* const Company = model('Company', companySchema);
*
* // Adding some data
* const johnAddress = await Address.create({ address: '13 Washington Square S, New York, NY 10012, USA' });
* const john = await Person.create({ name: 'John Smith', age: 52, address: johnAddress });
*
* const janeAddress = await Address.create({ address: '55 Clark St, Brooklyn, NY 11201, USA' });
* const jane = await Person.create({ name: 'Jane Doe', age: 45, address: janeAddress });
*
* const company = await Company.create({ name: 'Space X', president: john, ceo: jane });
*
*
* // Getting saved company data
* const spaceX = await Company.findById(company.id);
* console.log(`Company: `, company);
* ```
*
* Will get:
* ```
* Company: {
* name: 'Space X',
* president: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
* ceo: '32c2e85a-cc91-4db2-935f-f7d2768168de',
* id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
* _type: 'Company'
* }
* ```
*
* Now we will see how the _populate methods works.
* ```typescript
* const result = await spaceX._populate('ceo');
* console.log(`Result: `, result);
* ```
* ```
* Result: {
* name: 'Space X',
* president: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
* ceo: {
* name: 'Jane Doe',
* age: 45,
* address: '235dd441-b445-4b88-b6aa-2ce35a958a32',
* id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
* _type: 'Person'
* },
* id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
* _type: 'Company'
* }
* ```
*
* Can also pass an array or a string separated by a comma
* ```typescript
* const result = await spaceX._populate('ceo,president');
* // or
* const result = await spaceX._populate(['ceo', 'president']);
* console.log(`Result: `, result);
* ```
* ```
* Result: {
* name: 'Space X',
* president: {
* name: 'John Smith',
* age: 52,
* address: 'bc7ea8a8-8d1c-4ab6-990c-d3a0163f7e10',
* id: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
* _type: 'Person'
* },
* ceo: {
* name: 'Jane Doe',
* age: 45,
* address: '235dd441-b445-4b88-b6aa-2ce35a958a32',
* id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
* _type: 'Person'
* },
* id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
* _type: 'Company'
* }
* ```
*
* If you want to get only a portion of the object
* ```typescript
* const result = await spaceX._populate({
* ceo: ['age', 'address'], // or 'age,addres'
* president: 'name',
* });
* console.log(`Result: `, result);
* ```
* ```
* Result: {
* name: 'Space X',
* president: { name: 'John Smith' },
* ceo: { age: 45, address: '235dd441-b445-4b88-b6aa-2ce35a958a32' },
* id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
* _type: 'Company'
* }
* ```
*
* Now let's to go deeper
* ```typescript
* const result = await spaceX._populate(
* {
* ceo: {
* select: 'age,id', // remember you can use ['age','address']
* populate: 'address', // will populate all the fields
* },
* president: {
* select: 'name',
* populate: {
* address: 'address', // will populate address field only
* },
* },
* },
* 2, // for populate up to the second level
* );
* console.log(`Result: `, result);
* ```
* ```
* Result: {
* name: 'Space X',
* president: {
* name: 'John Smith',
* address: { address: '13 Washington Square S, New York, NY 10012, USA' }
* },
* ceo: {
* age: 45,
* id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
* address: {
* address: '55 Clark St, Brooklyn, NY 11201, USA',
* id: '235dd441-b445-4b88-b6aa-2ce35a958a32',
* _type: 'Address'
* }
* },
* id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
* _type: 'Company'
* }
*```
* Below is another way through the find functions
* ```typescript
* const result = await Company.findOne(
* { name: 'Space X' },
* {
* select: 'president,ceo',
* populate: {
* president: { select: 'address,id', populate: 'address' },
* ceo: { select: ['age', 'name'], populate: { address: { select: 'id' } } },
* },
* populateMaxDeep: 2,
* },
* );
* console.log(`Result: `, result);
* ```
* ```
* Result: {
* ceo: {
* age: 45,
* name: 'Jane Doe',
* address: { id: '235dd441-b445-4b88-b6aa-2ce35a958a32' }
* },
* president: {
* address: {
* address: '13 Washington Square S, New York, NY 10012, USA',
* id: 'bc7ea8a8-8d1c-4ab6-990c-d3a0163f7e10',
* _type: 'Address'
* },
* id: '50e85ac9-5b4f-4587-aeb6-b287527794c9'
* }
* }
* ```
*/
_populate(fieldsName?: PopulateFieldsType, options?: PopulateOptionsType): Promise<this>;
/**
* Reverts population. Switches back document reference.
*
* @example
* To get in context about the Card and Issue Models [see the populate example.](/docs/api/classes/document.html).
* ```javascript
* const card = await Card.findById(cardId);
* console.log(card.issues); // ['issueId']
*
* await card._populate('issues')
* console.log(card.issues); // [{ id: 'issueId', title: 'Broken card' }]
*
* card._depopulate('issues')
* console.log(card.issues); // ['issueId']
* ```
*/
_depopulate(fieldsName: string | string[]): this;
/**
* Allows to know if a document field is populated.
*
* @example
* To get in context about the Card and Issue Models [see the populate example.](/docs/api/classes/document.html).
* ```javascript
* const card = await Card.findById(cardId);
* console.log(card.issues); // ['issueId']
* console.log(card._populated('issues')); // false
*
* await card._populate('issues')
* console.log(card.issues); // [{ id: 'issueId', title: 'Broken card' }]
* console.log(card._populated('issues')); // true
* ```
*/
_populated(fieldName: string): boolean;
/**
* Allows to easily apply data from an object to current document.
*
* @example
* ```typescript
* const user = new User({ name: "John Doe" });
*
* user._applyData({ name: "Jane Doe" });
* console.log(user) // { name: "Jane Doe" }
* ```
*
* @example With strategies on immutable properties
* ```typescript
* const User = model('Card', { name: { type: String, immutable: true } });
* const user = new User({ name: 'John Doe' });
*
* // with strategy:false is like above example
* user._applyData({ name: 'Jane Doe' }, false);
* console.log(user); // { name: "Jane Doe" }
*
* // with strategy:true remains immutable
* user._applyData({ name: 'Jane Doe' }, true);
* console.log(user); // { name: "John Doe" }
*
* // trying to update it directly
* user.name = 'Jane Doe';
* console.log(user); // { name: "John Doe" }
*
* // with strategy:CAST_STRATEGY.THROW
* user._applyData({ name: 'Jane Doe' }, CAST_STRATEGY.THROW);
* // ImmutableError: Field 'name' is immutable and current cast strategy is set to 'throw'
* ```
*/
_applyData(data: any, strategy?: ApplyStrategy): this;
/**
* Runs schema validations over current document.
* @example
* ```javascript
* const user = new User( { name: "John Doe" } );
*
* try {
* await user._validate()
* } catch(errors) {
* console.log(errors)
* }
* ```
*/
_validate(): any;
/**
* Returns a Javascript object with data
*/
toObject(): this;
/**
* Returns a Javascript object to be serialized to JSON
*/
toJSON(): this;
/**
* Encapsulate logic for toObject and toJson
* @ignore
*/
$toObject(): this;
/**
* Boolean flag specifying if the document is new.
* @example
* ```typescript
* const CardSchema = new Schema({
* cardNumber: { type: String, immutable: true },
* zipCode: String,
* });
*
* // Create model
* const Card = model('Card', CardSchema);
*
* // Create document
* const myCard = new Card({ cardNumber: '4321 4321 4321 4321', zipCode: '43210' });
* myCard.$isNew; // true
*
* // Save document
* const myCardSaved = await myCard.save();
* myCardSaved.$isNew; // false
* ```
*/
get $isNew(): boolean;
}
export {};