MCPcopy
hub / github.com/mongodb/node-mongodb-native / command

Method command

src/cmap/connection.ts:872–937  ·  view source on GitHub ↗
(
    ns: MongoDBNamespace,
    cmd: Document,
    options?: CommandOptions,
    responseType?: T
  )

Source from the content-addressed store, hash-verified

870 ): Promise<Document>;
871
872 override async command<T extends MongoDBResponseConstructor>(
873 ns: MongoDBNamespace,
874 cmd: Document,
875 options?: CommandOptions,
876 responseType?: T
877 ): Promise<Document> {
878 const { autoEncrypter } = this;
879 if (!autoEncrypter) {
880 throw new MongoRuntimeError('No AutoEncrypter available for encryption');
881 }
882
883 const serverWireVersion = maxWireVersion(this);
884 if (serverWireVersion === 0) {
885 // This means the initial handshake hasn't happened yet
886 return await super.command<T>(ns, cmd, options, responseType);
887 }
888
889 // Save sort or indexKeys based on the command being run
890 // the encrypt API serializes our JS objects to BSON to pass to the native code layer
891 // and then deserializes the encrypted result, the protocol level components
892 // of the command (ex. sort) are then converted to JS objects potentially losing
893 // import key order information. These fields are never encrypted so we can save the values
894 // from before the encryption and replace them after encryption has been performed
895 const sort: Map<string, number> | null = cmd.find || cmd.findAndModify ? cmd.sort : null;
896 const indexKeys: Map<string, number>[] | null = cmd.createIndexes
897 ? cmd.indexes.map((index: { key: Map<string, number> }) => index.key)
898 : null;
899
900 const encrypted = await autoEncrypter.encrypt(ns.toString(), cmd, options);
901
902 // Replace the saved values
903 if (sort != null && (cmd.find || cmd.findAndModify)) {
904 encrypted.sort = sort;
905 }
906
907 if (indexKeys != null && cmd.createIndexes) {
908 for (const [offset, index] of indexKeys.entries()) {
909 // @ts-expect-error `encrypted` is a generic "command", but we've narrowed for only `createIndexes` commands here
910 encrypted.indexes[offset].key = index;
911 }
912 }
913
914 const encryptedResponse = await super.command(
915 ns,
916 encrypted,
917 options,
918 // Eventually we want to require `responseType` which means we would satisfy `T` as the return type.
919 // In the meantime, we want encryptedResponse to always be _at least_ a MongoDBResponse if not a more specific subclass
920 // So that we can ensure we have access to the on-demand APIs for decorate response
921 responseType ?? MongoDBResponse
922 );
923
924 const result = await autoEncrypter.decrypt(encryptedResponse.toBytes(), options);
925
926 const decryptedResponse = responseType?.make(result) ?? deserialize(result, options);
927
928 if (autoEncrypter[kDecorateResult]) {
929 if (responseType == null) {

Callers

nothing calls this directly

Calls 10

maxWireVersionFunction · 0.90
decorateDecryptionResultFunction · 0.90
toBytesMethod · 0.80
makeMethod · 0.80
mapMethod · 0.45
encryptMethod · 0.45
toStringMethod · 0.45
commandMethod · 0.45
decryptMethod · 0.45
toObjectMethod · 0.45

Tested by

no test coverage detected