All files / src/operations list_collections.ts

100% Statements 21/21
100% Branches 8/8
100% Functions 4/4
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116  139x             139x 139x 139x                                       139x                               82635x   82635x 82635x 82635x 82635x 82635x 82635x   82635x 239x         83663x               83515x                     83543x                   83543x 76x     83543x                               139x          
import type { Binary, Document } from '../bson';
import { CursorResponse } from '../cmap/wire_protocol/responses';
import { type CursorTimeoutContext, type CursorTimeoutMode } from '../cursor/abstract_cursor';
import type { Db } from '../db';
import { type Abortable } from '../mongo_types';
import type { Server } from '../sdam/server';
import type { ClientSession } from '../sessions';
import { type TimeoutContext } from '../timeout';
import { maxWireVersion } from '../utils';
import { CommandOperation, type CommandOperationOptions } from './command';
import { Aspect, defineAspects } from './operation';
 
/** @public */
export interface ListCollectionsOptions
  extends Omit<CommandOperationOptions, 'writeConcern'>,
    Abortable {
  /** Since 4.0: If true, will only return the collection name in the response, and will omit additional info */
  nameOnly?: boolean;
  /** Since 4.0: If true and nameOnly is true, allows a user without the required privilege (i.e. listCollections action on the database) to run the command when access control is enforced. */
  authorizedCollections?: boolean;
  /** The batchSize for the returned command cursor or if pre 2.8 the systems batch collection */
  batchSize?: number;
  /** @internal */
  timeoutMode?: CursorTimeoutMode;
 
  /** @internal */
  timeoutContext?: CursorTimeoutContext;
}
 
/** @internal */
export class ListCollectionsOperation extends CommandOperation<CursorResponse> {
  /**
   * @remarks WriteConcern can still be present on the options because
   * we inherit options from the client/db/collection.  The
   * key must be present on the options in order to delete it.
   * This allows typescript to delete the key but will
   * not allow a writeConcern to be assigned as a property on options.
   */
  override options: ListCollectionsOptions & { writeConcern?: never };
  db: Db;
  filter: Document;
  nameOnly: boolean;
  authorizedCollections: boolean;
  batchSize?: number;
 
  constructor(db: Db, filter: Document, options?: ListCollectionsOptions) {
    super(db, options);
 
    this.options = { ...options };
    delete this.options.writeConcern;
    this.db = db;
    this.filter = filter;
    this.nameOnly = !!this.options.nameOnly;
    this.authorizedCollections = !!this.options.authorizedCollections;
 
    if (typeof this.options.batchSize === 'number') {
      this.batchSize = this.options.batchSize;
    }
  }
 
  override get commandName() {
    return 'listCollections' as const;
  }
 
  override async execute(
    server: Server,
    session: ClientSession | undefined,
    timeoutContext: TimeoutContext
  ): Promise<CursorResponse> {
    return await super.executeCommand(
      server,
      session,
      this.generateCommand(maxWireVersion(server)),
      timeoutContext,
      CursorResponse
    );
  }
 
  /* This is here for the purpose of unit testing the final command that gets sent. */
  generateCommand(wireVersion: number): Document {
    const command: Document = {
      listCollections: 1,
      filter: this.filter,
      cursor: this.batchSize ? { batchSize: this.batchSize } : {},
      nameOnly: this.nameOnly,
      authorizedCollections: this.authorizedCollections
    };
 
    // we check for undefined specifically here to allow falsy values
    // eslint-disable-next-line no-restricted-syntax
    if (wireVersion >= 9 && this.options.comment !== undefined) {
      command.comment = this.options.comment;
    }
 
    return command;
  }
}
 
/** @public */
export interface CollectionInfo extends Document {
  name: string;
  type?: string;
  options?: Document;
  info?: {
    readOnly?: false;
    uuid?: Binary;
  };
  idIndex?: Document;
}
 
defineAspects(ListCollectionsOperation, [
  Aspect.READ_OPERATION,
  Aspect.RETRYABLE,
  Aspect.CURSOR_CREATING
]);