| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 | import { BSONValue } from './bson_value';import { BSONError } from './error';import type { EJSONOptions } from './extended_json';import { type InspectFn, defaultInspect, getStylizeFunction } from './parser/utils';function alphabetize(str: string): string {  return str.split('').sort().join('');}/** @public */export interface BSONRegExpExtendedLegacy {  $regex: string | BSONRegExp;  $options: string;}/** @public */export interface BSONRegExpExtended {  $regularExpression: {    pattern: string;    options: string;  };}/** * A class representation of the BSON RegExp type. * @public * @category BSONType */export class BSONRegExp extends BSONValue {  get _bsontype(): 'BSONRegExp' {    return 'BSONRegExp';  }  pattern!: string;  options!: string;  /**   * @param pattern - The regular expression pattern to match   * @param options - The regular expression options   */  constructor(pattern: string, options?: string) {    super();    this.pattern = pattern;    this.options = alphabetize(options ?? '');    if (this.pattern.indexOf('\x00') !== -1) {      throw new BSONError(        `BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`      );    }    if (this.options.indexOf('\x00') !== -1) {      throw new BSONError(        `BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`      );    }    // Validate options    for (let i = 0; i < this.options.length; i++) {      if (        !(          this.options[i] === 'i' ||          this.options[i] === 'm' ||          this.options[i] === 'x' ||          this.options[i] === 'l' ||          this.options[i] === 's' ||          this.options[i] === 'u'        )      ) {        throw new BSONError(`The regular expression option [${this.options[i]}] is not supported`);      }    }  }  static parseOptions(options?: string): string {    return options ? options.split('').sort().join('') : '';  }  /** @internal */  toExtendedJSON(options?: EJSONOptions): BSONRegExpExtendedLegacy | BSONRegExpExtended {    options = options || {};    if (options.legacy) {      return { $regex: this.pattern, $options: this.options };    }    return { $regularExpression: { pattern: this.pattern, options: this.options } };  }  /** @internal */  static fromExtendedJSON(doc: BSONRegExpExtendedLegacy | BSONRegExpExtended): BSONRegExp {    if ('$regex' in doc) {      if (typeof doc.$regex !== 'string') {        // This is for $regex query operators that have extended json values.        if (doc.$regex._bsontype === 'BSONRegExp') {          return doc as unknown as BSONRegExp;        }      } else {        return new BSONRegExp(doc.$regex, BSONRegExp.parseOptions(doc.$options));      }    }    if ('$regularExpression' in doc) {      return new BSONRegExp(        doc.$regularExpression.pattern,        BSONRegExp.parseOptions(doc.$regularExpression.options)      );    }    throw new BSONError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`);  }  inspect(depth?: number, options?: unknown, inspect?: InspectFn): string {    const stylize = getStylizeFunction(options) ?? (v => v);    inspect ??= defaultInspect;    const pattern = stylize(inspect(this.pattern), 'regexp');    const flags = stylize(inspect(this.options), 'regexp');    return `new BSONRegExp(${pattern}, ${flags})`;  }}
 |