You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.2 KiB
TypeScript
130 lines
3.2 KiB
TypeScript
import type { Document } from './bson';
|
|
import { BSONValue } from './bson_value';
|
|
import type { EJSONOptions } from './extended_json';
|
|
import type { ObjectId } from './objectid';
|
|
import { type InspectFn, defaultInspect } from './parser/utils';
|
|
|
|
/** @public */
|
|
export interface DBRefLike {
|
|
$ref: string;
|
|
$id: ObjectId;
|
|
$db?: string;
|
|
}
|
|
|
|
/** @internal */
|
|
export function isDBRefLike(value: unknown): value is DBRefLike {
|
|
return (
|
|
value != null &&
|
|
typeof value === 'object' &&
|
|
'$id' in value &&
|
|
value.$id != null &&
|
|
'$ref' in value &&
|
|
typeof value.$ref === 'string' &&
|
|
// If '$db' is defined it MUST be a string, otherwise it should be absent
|
|
(!('$db' in value) || ('$db' in value && typeof value.$db === 'string'))
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A class representation of the BSON DBRef type.
|
|
* @public
|
|
* @category BSONType
|
|
*/
|
|
export class DBRef extends BSONValue {
|
|
get _bsontype(): 'DBRef' {
|
|
return 'DBRef';
|
|
}
|
|
|
|
collection!: string;
|
|
oid!: ObjectId;
|
|
db?: string;
|
|
fields!: Document;
|
|
|
|
/**
|
|
* @param collection - the collection name.
|
|
* @param oid - the reference ObjectId.
|
|
* @param db - optional db name, if omitted the reference is local to the current db.
|
|
*/
|
|
constructor(collection: string, oid: ObjectId, db?: string, fields?: Document) {
|
|
super();
|
|
// check if namespace has been provided
|
|
const parts = collection.split('.');
|
|
if (parts.length === 2) {
|
|
db = parts.shift();
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
collection = parts.shift()!;
|
|
}
|
|
|
|
this.collection = collection;
|
|
this.oid = oid;
|
|
this.db = db;
|
|
this.fields = fields || {};
|
|
}
|
|
|
|
// Property provided for compatibility with the 1.x parser
|
|
// the 1.x parser used a "namespace" property, while 4.x uses "collection"
|
|
|
|
/** @internal */
|
|
get namespace(): string {
|
|
return this.collection;
|
|
}
|
|
|
|
set namespace(value: string) {
|
|
this.collection = value;
|
|
}
|
|
|
|
toJSON(): DBRefLike & Document {
|
|
const o = Object.assign(
|
|
{
|
|
$ref: this.collection,
|
|
$id: this.oid
|
|
},
|
|
this.fields
|
|
);
|
|
|
|
if (this.db != null) o.$db = this.db;
|
|
return o;
|
|
}
|
|
|
|
/** @internal */
|
|
toExtendedJSON(options?: EJSONOptions): DBRefLike {
|
|
options = options || {};
|
|
let o: DBRefLike = {
|
|
$ref: this.collection,
|
|
$id: this.oid
|
|
};
|
|
|
|
if (options.legacy) {
|
|
return o;
|
|
}
|
|
|
|
if (this.db) o.$db = this.db;
|
|
o = Object.assign(o, this.fields);
|
|
return o;
|
|
}
|
|
|
|
/** @internal */
|
|
static fromExtendedJSON(doc: DBRefLike): DBRef {
|
|
const copy = Object.assign({}, doc) as Partial<DBRefLike>;
|
|
delete copy.$ref;
|
|
delete copy.$id;
|
|
delete copy.$db;
|
|
return new DBRef(doc.$ref, doc.$id, doc.$db, copy);
|
|
}
|
|
|
|
inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {
|
|
inspect ??= defaultInspect;
|
|
|
|
const args = [
|
|
inspect(this.namespace, options),
|
|
inspect(this.oid, options),
|
|
...(this.db ? [inspect(this.db, options)] : []),
|
|
...(Object.keys(this.fields).length > 0 ? [inspect(this.fields, options)] : [])
|
|
];
|
|
|
|
args[1] = inspect === defaultInspect ? `new ObjectId(${args[1]})` : args[1];
|
|
|
|
return `new DBRef(${args.join(', ')})`;
|
|
}
|
|
}
|