@depup/mongodb 7.1.0-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +201 -0
- package/README.md +33 -0
- package/etc/prepare.js +12 -0
- package/lib/admin.js +136 -0
- package/lib/admin.js.map +1 -0
- package/lib/bson.js +85 -0
- package/lib/bson.js.map +1 -0
- package/lib/bulk/common.js +835 -0
- package/lib/bulk/common.js.map +1 -0
- package/lib/bulk/ordered.js +67 -0
- package/lib/bulk/ordered.js.map +1 -0
- package/lib/bulk/unordered.js +92 -0
- package/lib/bulk/unordered.js.map +1 -0
- package/lib/change_stream.js +513 -0
- package/lib/change_stream.js.map +1 -0
- package/lib/client-side-encryption/auto_encrypter.js +272 -0
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -0
- package/lib/client-side-encryption/client_encryption.js +609 -0
- package/lib/client-side-encryption/client_encryption.js.map +1 -0
- package/lib/client-side-encryption/errors.js +138 -0
- package/lib/client-side-encryption/errors.js.map +1 -0
- package/lib/client-side-encryption/mongocryptd_manager.js +85 -0
- package/lib/client-side-encryption/mongocryptd_manager.js.map +1 -0
- package/lib/client-side-encryption/providers/aws.js +23 -0
- package/lib/client-side-encryption/providers/aws.js.map +1 -0
- package/lib/client-side-encryption/providers/azure.js +132 -0
- package/lib/client-side-encryption/providers/azure.js.map +1 -0
- package/lib/client-side-encryption/providers/gcp.js +16 -0
- package/lib/client-side-encryption/providers/gcp.js.map +1 -0
- package/lib/client-side-encryption/providers/index.js +43 -0
- package/lib/client-side-encryption/providers/index.js.map +1 -0
- package/lib/client-side-encryption/state_machine.js +427 -0
- package/lib/client-side-encryption/state_machine.js.map +1 -0
- package/lib/cmap/auth/auth_provider.js +51 -0
- package/lib/cmap/auth/auth_provider.js.map +1 -0
- package/lib/cmap/auth/aws4.js +161 -0
- package/lib/cmap/auth/aws4.js.map +1 -0
- package/lib/cmap/auth/aws_temporary_credentials.js +103 -0
- package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -0
- package/lib/cmap/auth/gssapi.js +155 -0
- package/lib/cmap/auth/gssapi.js.map +1 -0
- package/lib/cmap/auth/mongo_credentials.js +169 -0
- package/lib/cmap/auth/mongo_credentials.js.map +1 -0
- package/lib/cmap/auth/mongodb_aws.js +128 -0
- package/lib/cmap/auth/mongodb_aws.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js +84 -0
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js +62 -0
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +141 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/command_builders.js +44 -0
- package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js +39 -0
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js +122 -0
- package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +32 -0
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/token_cache.js +52 -0
- package/lib/cmap/auth/mongodb_oidc/token_cache.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js +23 -0
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc.js +73 -0
- package/lib/cmap/auth/mongodb_oidc.js.map +1 -0
- package/lib/cmap/auth/plain.js +26 -0
- package/lib/cmap/auth/plain.js.map +1 -0
- package/lib/cmap/auth/providers.js +22 -0
- package/lib/cmap/auth/providers.js.map +1 -0
- package/lib/cmap/auth/scram.js +254 -0
- package/lib/cmap/auth/scram.js.map +1 -0
- package/lib/cmap/auth/x509.js +36 -0
- package/lib/cmap/auth/x509.js.map +1 -0
- package/lib/cmap/command_monitoring_events.js +223 -0
- package/lib/cmap/command_monitoring_events.js.map +1 -0
- package/lib/cmap/commands.js +535 -0
- package/lib/cmap/commands.js.map +1 -0
- package/lib/cmap/connect.js +381 -0
- package/lib/cmap/connect.js.map +1 -0
- package/lib/cmap/connection.js +571 -0
- package/lib/cmap/connection.js.map +1 -0
- package/lib/cmap/connection_pool.js +558 -0
- package/lib/cmap/connection_pool.js.map +1 -0
- package/lib/cmap/connection_pool_events.js +190 -0
- package/lib/cmap/connection_pool_events.js.map +1 -0
- package/lib/cmap/errors.js +108 -0
- package/lib/cmap/errors.js.map +1 -0
- package/lib/cmap/handshake/client_metadata.js +242 -0
- package/lib/cmap/handshake/client_metadata.js.map +1 -0
- package/lib/cmap/metrics.js +62 -0
- package/lib/cmap/metrics.js.map +1 -0
- package/lib/cmap/stream_description.js +70 -0
- package/lib/cmap/stream_description.js.map +1 -0
- package/lib/cmap/wire_protocol/compression.js +178 -0
- package/lib/cmap/wire_protocol/compression.js.map +1 -0
- package/lib/cmap/wire_protocol/constants.js +21 -0
- package/lib/cmap/wire_protocol/constants.js.map +1 -0
- package/lib/cmap/wire_protocol/on_data.js +111 -0
- package/lib/cmap/wire_protocol/on_data.js.map +1 -0
- package/lib/cmap/wire_protocol/on_demand/document.js +222 -0
- package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -0
- package/lib/cmap/wire_protocol/responses.js +315 -0
- package/lib/cmap/wire_protocol/responses.js.map +1 -0
- package/lib/cmap/wire_protocol/shared.js +35 -0
- package/lib/cmap/wire_protocol/shared.js.map +1 -0
- package/lib/collection.js +751 -0
- package/lib/collection.js.map +1 -0
- package/lib/connection_string.js +1090 -0
- package/lib/connection_string.js.map +1 -0
- package/lib/constants.js +170 -0
- package/lib/constants.js.map +1 -0
- package/lib/cursor/abstract_cursor.js +924 -0
- package/lib/cursor/abstract_cursor.js.map +1 -0
- package/lib/cursor/aggregation_cursor.js +164 -0
- package/lib/cursor/aggregation_cursor.js.map +1 -0
- package/lib/cursor/change_stream_cursor.js +104 -0
- package/lib/cursor/change_stream_cursor.js.map +1 -0
- package/lib/cursor/client_bulk_write_cursor.js +52 -0
- package/lib/cursor/client_bulk_write_cursor.js.map +1 -0
- package/lib/cursor/explainable_cursor.js +36 -0
- package/lib/cursor/explainable_cursor.js.map +1 -0
- package/lib/cursor/find_cursor.js +399 -0
- package/lib/cursor/find_cursor.js.map +1 -0
- package/lib/cursor/list_collections_cursor.js +34 -0
- package/lib/cursor/list_collections_cursor.js.map +1 -0
- package/lib/cursor/list_indexes_cursor.js +32 -0
- package/lib/cursor/list_indexes_cursor.js.map +1 -0
- package/lib/cursor/list_search_indexes_cursor.js +14 -0
- package/lib/cursor/list_search_indexes_cursor.js.map +1 -0
- package/lib/cursor/run_command_cursor.js +94 -0
- package/lib/cursor/run_command_cursor.js.map +1 -0
- package/lib/db.js +419 -0
- package/lib/db.js.map +1 -0
- package/lib/deps.js +112 -0
- package/lib/deps.js.map +1 -0
- package/lib/encrypter.js +106 -0
- package/lib/encrypter.js.map +1 -0
- package/lib/error.js +1380 -0
- package/lib/error.js.map +1 -0
- package/lib/explain.js +59 -0
- package/lib/explain.js.map +1 -0
- package/lib/gridfs/download.js +305 -0
- package/lib/gridfs/download.js.map +1 -0
- package/lib/gridfs/index.js +164 -0
- package/lib/gridfs/index.js.map +1 -0
- package/lib/gridfs/upload.js +358 -0
- package/lib/gridfs/upload.js.map +1 -0
- package/lib/index.js +193 -0
- package/lib/index.js.map +1 -0
- package/lib/mongo_client.js +557 -0
- package/lib/mongo_client.js.map +1 -0
- package/lib/mongo_client_auth_providers.js +80 -0
- package/lib/mongo_client_auth_providers.js.map +1 -0
- package/lib/mongo_logger.js +655 -0
- package/lib/mongo_logger.js.map +1 -0
- package/lib/mongo_types.js +56 -0
- package/lib/mongo_types.js.map +1 -0
- package/lib/operations/aggregate.js +90 -0
- package/lib/operations/aggregate.js.map +1 -0
- package/lib/operations/client_bulk_write/client_bulk_write.js +51 -0
- package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -0
- package/lib/operations/client_bulk_write/command_builder.js +340 -0
- package/lib/operations/client_bulk_write/command_builder.js.map +1 -0
- package/lib/operations/client_bulk_write/common.js +3 -0
- package/lib/operations/client_bulk_write/common.js.map +1 -0
- package/lib/operations/client_bulk_write/executor.js +120 -0
- package/lib/operations/client_bulk_write/executor.js.map +1 -0
- package/lib/operations/client_bulk_write/results_merger.js +204 -0
- package/lib/operations/client_bulk_write/results_merger.js.map +1 -0
- package/lib/operations/command.js +83 -0
- package/lib/operations/command.js.map +1 -0
- package/lib/operations/count.js +45 -0
- package/lib/operations/count.js.map +1 -0
- package/lib/operations/create_collection.js +109 -0
- package/lib/operations/create_collection.js.map +1 -0
- package/lib/operations/delete.js +125 -0
- package/lib/operations/delete.js.map +1 -0
- package/lib/operations/distinct.js +61 -0
- package/lib/operations/distinct.js.map +1 -0
- package/lib/operations/drop.js +93 -0
- package/lib/operations/drop.js.map +1 -0
- package/lib/operations/end_sessions.js +34 -0
- package/lib/operations/end_sessions.js.map +1 -0
- package/lib/operations/estimated_document_count.js +41 -0
- package/lib/operations/estimated_document_count.js.map +1 -0
- package/lib/operations/execute_operation.js +239 -0
- package/lib/operations/execute_operation.js.map +1 -0
- package/lib/operations/find.js +148 -0
- package/lib/operations/find.js.map +1 -0
- package/lib/operations/find_and_modify.js +158 -0
- package/lib/operations/find_and_modify.js.map +1 -0
- package/lib/operations/get_more.js +62 -0
- package/lib/operations/get_more.js.map +1 -0
- package/lib/operations/indexes.js +186 -0
- package/lib/operations/indexes.js.map +1 -0
- package/lib/operations/insert.js +70 -0
- package/lib/operations/insert.js.map +1 -0
- package/lib/operations/kill_cursors.js +43 -0
- package/lib/operations/kill_cursors.js.map +1 -0
- package/lib/operations/list_collections.js +53 -0
- package/lib/operations/list_collections.js.map +1 -0
- package/lib/operations/list_databases.js +40 -0
- package/lib/operations/list_databases.js.map +1 -0
- package/lib/operations/operation.js +102 -0
- package/lib/operations/operation.js.map +1 -0
- package/lib/operations/profiling_level.js +43 -0
- package/lib/operations/profiling_level.js.map +1 -0
- package/lib/operations/remove_user.js +27 -0
- package/lib/operations/remove_user.js.map +1 -0
- package/lib/operations/rename.js +38 -0
- package/lib/operations/rename.js.map +1 -0
- package/lib/operations/run_command.js +47 -0
- package/lib/operations/run_command.js.map +1 -0
- package/lib/operations/search_indexes/create.js +33 -0
- package/lib/operations/search_indexes/create.js.map +1 -0
- package/lib/operations/search_indexes/drop.js +43 -0
- package/lib/operations/search_indexes/drop.js.map +1 -0
- package/lib/operations/search_indexes/update.js +35 -0
- package/lib/operations/search_indexes/update.js.map +1 -0
- package/lib/operations/set_profiling_level.js +53 -0
- package/lib/operations/set_profiling_level.js.map +1 -0
- package/lib/operations/stats.js +27 -0
- package/lib/operations/stats.js.map +1 -0
- package/lib/operations/update.js +188 -0
- package/lib/operations/update.js.map +1 -0
- package/lib/operations/validate_collection.js +37 -0
- package/lib/operations/validate_collection.js.map +1 -0
- package/lib/read_concern.js +73 -0
- package/lib/read_concern.js.map +1 -0
- package/lib/read_preference.js +191 -0
- package/lib/read_preference.js.map +1 -0
- package/lib/sdam/common.js +49 -0
- package/lib/sdam/common.js.map +1 -0
- package/lib/sdam/events.js +146 -0
- package/lib/sdam/events.js.map +1 -0
- package/lib/sdam/monitor.js +544 -0
- package/lib/sdam/monitor.js.map +1 -0
- package/lib/sdam/server.js +404 -0
- package/lib/sdam/server.js.map +1 -0
- package/lib/sdam/server_description.js +204 -0
- package/lib/sdam/server_description.js.map +1 -0
- package/lib/sdam/server_selection.js +294 -0
- package/lib/sdam/server_selection.js.map +1 -0
- package/lib/sdam/server_selection_events.js +85 -0
- package/lib/sdam/server_selection_events.js.map +1 -0
- package/lib/sdam/srv_polling.js +108 -0
- package/lib/sdam/srv_polling.js.map +1 -0
- package/lib/sdam/topology.js +652 -0
- package/lib/sdam/topology.js.map +1 -0
- package/lib/sdam/topology_description.js +383 -0
- package/lib/sdam/topology_description.js.map +1 -0
- package/lib/sessions.js +892 -0
- package/lib/sessions.js.map +1 -0
- package/lib/sort.js +103 -0
- package/lib/sort.js.map +1 -0
- package/lib/timeout.js +296 -0
- package/lib/timeout.js.map +1 -0
- package/lib/transactions.js +135 -0
- package/lib/transactions.js.map +1 -0
- package/lib/utils.js +1163 -0
- package/lib/utils.js.map +1 -0
- package/lib/write_concern.js +100 -0
- package/lib/write_concern.js.map +1 -0
- package/mongodb.d.ts +9018 -0
- package/package.json +197 -0
- package/src/admin.ts +173 -0
- package/src/bson.ts +149 -0
- package/src/bulk/common.ts +1251 -0
- package/src/bulk/ordered.ts +83 -0
- package/src/bulk/unordered.ts +115 -0
- package/src/change_stream.ts +1160 -0
- package/src/client-side-encryption/auto_encrypter.ts +469 -0
- package/src/client-side-encryption/client_encryption.ts +1150 -0
- package/src/client-side-encryption/errors.ts +144 -0
- package/src/client-side-encryption/mongocryptd_manager.ts +100 -0
- package/src/client-side-encryption/providers/aws.ts +33 -0
- package/src/client-side-encryption/providers/azure.ts +181 -0
- package/src/client-side-encryption/providers/gcp.ts +16 -0
- package/src/client-side-encryption/providers/index.ts +207 -0
- package/src/client-side-encryption/state_machine.ts +651 -0
- package/src/cmap/auth/auth_provider.ts +77 -0
- package/src/cmap/auth/aws4.ts +207 -0
- package/src/cmap/auth/aws_temporary_credentials.ts +129 -0
- package/src/cmap/auth/gssapi.ts +203 -0
- package/src/cmap/auth/mongo_credentials.ts +292 -0
- package/src/cmap/auth/mongodb_aws.ts +179 -0
- package/src/cmap/auth/mongodb_oidc/automated_callback_workflow.ts +88 -0
- package/src/cmap/auth/mongodb_oidc/azure_machine_workflow.ts +73 -0
- package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +188 -0
- package/src/cmap/auth/mongodb_oidc/command_builders.ts +53 -0
- package/src/cmap/auth/mongodb_oidc/gcp_machine_workflow.ts +46 -0
- package/src/cmap/auth/mongodb_oidc/human_callback_workflow.ts +141 -0
- package/src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts +31 -0
- package/src/cmap/auth/mongodb_oidc/token_cache.ts +62 -0
- package/src/cmap/auth/mongodb_oidc/token_machine_workflow.ts +22 -0
- package/src/cmap/auth/mongodb_oidc.ts +185 -0
- package/src/cmap/auth/plain.ts +25 -0
- package/src/cmap/auth/providers.ts +22 -0
- package/src/cmap/auth/scram.ts +344 -0
- package/src/cmap/auth/x509.ts +43 -0
- package/src/cmap/command_monitoring_events.ts +316 -0
- package/src/cmap/commands.ts +788 -0
- package/src/cmap/connect.ts +518 -0
- package/src/cmap/connection.ts +931 -0
- package/src/cmap/connection_pool.ts +831 -0
- package/src/cmap/connection_pool_events.ts +300 -0
- package/src/cmap/errors.ts +119 -0
- package/src/cmap/handshake/client_metadata.ts +353 -0
- package/src/cmap/metrics.ts +58 -0
- package/src/cmap/stream_description.ts +96 -0
- package/src/cmap/wire_protocol/compression.ts +211 -0
- package/src/cmap/wire_protocol/constants.ts +17 -0
- package/src/cmap/wire_protocol/on_data.ts +139 -0
- package/src/cmap/wire_protocol/on_demand/document.ts +358 -0
- package/src/cmap/wire_protocol/responses.ts +393 -0
- package/src/cmap/wire_protocol/shared.ts +48 -0
- package/src/collection.ts +1314 -0
- package/src/connection_string.ts +1297 -0
- package/src/constants.ts +176 -0
- package/src/cursor/abstract_cursor.ts +1247 -0
- package/src/cursor/aggregation_cursor.ts +245 -0
- package/src/cursor/change_stream_cursor.ts +171 -0
- package/src/cursor/client_bulk_write_cursor.ts +83 -0
- package/src/cursor/explainable_cursor.ts +51 -0
- package/src/cursor/find_cursor.ts +497 -0
- package/src/cursor/list_collections_cursor.ts +50 -0
- package/src/cursor/list_indexes_cursor.ts +37 -0
- package/src/cursor/list_search_indexes_cursor.ts +20 -0
- package/src/cursor/run_command_cursor.ts +178 -0
- package/src/db.ts +621 -0
- package/src/deps.ts +227 -0
- package/src/encrypter.ts +127 -0
- package/src/error.ts +1567 -0
- package/src/explain.ts +124 -0
- package/src/gridfs/download.ts +483 -0
- package/src/gridfs/index.ts +264 -0
- package/src/gridfs/upload.ts +537 -0
- package/src/index.ts +633 -0
- package/src/mongo_client.ts +1155 -0
- package/src/mongo_client_auth_providers.ts +87 -0
- package/src/mongo_logger.ts +1081 -0
- package/src/mongo_types.ts +678 -0
- package/src/operations/aggregate.ts +153 -0
- package/src/operations/client_bulk_write/client_bulk_write.ts +72 -0
- package/src/operations/client_bulk_write/command_builder.ts +487 -0
- package/src/operations/client_bulk_write/common.ts +276 -0
- package/src/operations/client_bulk_write/executor.ts +149 -0
- package/src/operations/client_bulk_write/results_merger.ts +260 -0
- package/src/operations/command.ts +171 -0
- package/src/operations/count.ts +74 -0
- package/src/operations/create_collection.ts +218 -0
- package/src/operations/delete.ts +183 -0
- package/src/operations/distinct.ts +92 -0
- package/src/operations/drop.ts +130 -0
- package/src/operations/end_sessions.ts +44 -0
- package/src/operations/estimated_document_count.ts +61 -0
- package/src/operations/execute_operation.ts +319 -0
- package/src/operations/find.ts +254 -0
- package/src/operations/find_and_modify.ts +319 -0
- package/src/operations/get_more.ts +108 -0
- package/src/operations/indexes.ts +418 -0
- package/src/operations/insert.ts +108 -0
- package/src/operations/kill_cursors.ts +64 -0
- package/src/operations/list_collections.ts +108 -0
- package/src/operations/list_databases.ts +68 -0
- package/src/operations/operation.ts +181 -0
- package/src/operations/profiling_level.ts +46 -0
- package/src/operations/remove_user.ts +36 -0
- package/src/operations/rename.ts +60 -0
- package/src/operations/run_command.ts +79 -0
- package/src/operations/search_indexes/create.ts +56 -0
- package/src/operations/search_indexes/drop.ts +58 -0
- package/src/operations/search_indexes/update.ts +45 -0
- package/src/operations/set_profiling_level.ts +74 -0
- package/src/operations/stats.ts +37 -0
- package/src/operations/update.ts +318 -0
- package/src/operations/validate_collection.ts +50 -0
- package/src/read_concern.ts +88 -0
- package/src/read_preference.ts +256 -0
- package/src/sdam/common.ts +74 -0
- package/src/sdam/events.ts +219 -0
- package/src/sdam/monitor.ts +771 -0
- package/src/sdam/server.ts +595 -0
- package/src/sdam/server_description.ts +297 -0
- package/src/sdam/server_selection.ts +415 -0
- package/src/sdam/server_selection_events.ts +142 -0
- package/src/sdam/srv_polling.ts +146 -0
- package/src/sdam/topology.ts +1100 -0
- package/src/sdam/topology_description.ts +548 -0
- package/src/sessions.ts +1244 -0
- package/src/sort.ts +141 -0
- package/src/timeout.ts +405 -0
- package/src/transactions.ts +181 -0
- package/src/utils.ts +1434 -0
- package/src/write_concern.ts +183 -0
- package/tsconfig.json +46 -0
package/src/explain.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { type Document } from './bson';
|
|
2
|
+
import { MongoAPIError } from './error';
|
|
3
|
+
|
|
4
|
+
/** @public */
|
|
5
|
+
export const ExplainVerbosity = Object.freeze({
|
|
6
|
+
queryPlanner: 'queryPlanner',
|
|
7
|
+
queryPlannerExtended: 'queryPlannerExtended',
|
|
8
|
+
executionStats: 'executionStats',
|
|
9
|
+
allPlansExecution: 'allPlansExecution'
|
|
10
|
+
} as const);
|
|
11
|
+
|
|
12
|
+
/** @public */
|
|
13
|
+
export type ExplainVerbosity = string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* For backwards compatibility, true is interpreted as "allPlansExecution"
|
|
17
|
+
* and false as "queryPlanner".
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export type ExplainVerbosityLike = ExplainVerbosity | boolean;
|
|
21
|
+
|
|
22
|
+
/** @public */
|
|
23
|
+
export interface ExplainCommandOptions {
|
|
24
|
+
/** The explain verbosity for the command. */
|
|
25
|
+
verbosity: ExplainVerbosity;
|
|
26
|
+
/** The maxTimeMS setting for the command. */
|
|
27
|
+
maxTimeMS?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @public
|
|
32
|
+
*
|
|
33
|
+
* When set, this configures an explain command. Valid values are boolean (for legacy compatibility,
|
|
34
|
+
* see {@link ExplainVerbosityLike}), a string containing the explain verbosity, or an object containing the verbosity and
|
|
35
|
+
* an optional maxTimeMS.
|
|
36
|
+
*
|
|
37
|
+
* Examples of valid usage:
|
|
38
|
+
*
|
|
39
|
+
* ```typescript
|
|
40
|
+
* collection.find({ name: 'john doe' }, { explain: true });
|
|
41
|
+
* collection.find({ name: 'john doe' }, { explain: false });
|
|
42
|
+
* collection.find({ name: 'john doe' }, { explain: 'queryPlanner' });
|
|
43
|
+
* collection.find({ name: 'john doe' }, { explain: { verbosity: 'queryPlanner' } });
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* maxTimeMS can be configured to limit the amount of time the server
|
|
47
|
+
* spends executing an explain by providing an object:
|
|
48
|
+
*
|
|
49
|
+
* ```typescript
|
|
50
|
+
* // limits the `explain` command to no more than 2 seconds
|
|
51
|
+
* collection.find({ name: 'john doe' }, {
|
|
52
|
+
* explain: {
|
|
53
|
+
* verbosity: 'queryPlanner',
|
|
54
|
+
* maxTimeMS: 2000
|
|
55
|
+
* }
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export interface ExplainOptions {
|
|
60
|
+
/** Specifies the verbosity mode for the explain output. */
|
|
61
|
+
explain?: ExplainVerbosityLike | ExplainCommandOptions;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** @internal */
|
|
65
|
+
export class Explain {
|
|
66
|
+
readonly verbosity: ExplainVerbosity;
|
|
67
|
+
readonly maxTimeMS?: number;
|
|
68
|
+
|
|
69
|
+
private constructor(verbosity: ExplainVerbosityLike, maxTimeMS?: number) {
|
|
70
|
+
if (typeof verbosity === 'boolean') {
|
|
71
|
+
this.verbosity = verbosity
|
|
72
|
+
? ExplainVerbosity.allPlansExecution
|
|
73
|
+
: ExplainVerbosity.queryPlanner;
|
|
74
|
+
} else {
|
|
75
|
+
this.verbosity = verbosity;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.maxTimeMS = maxTimeMS;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static fromOptions({ explain }: ExplainOptions = {}): Explain | undefined {
|
|
82
|
+
if (explain == null) return;
|
|
83
|
+
|
|
84
|
+
if (typeof explain === 'boolean' || typeof explain === 'string') {
|
|
85
|
+
return new Explain(explain);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const { verbosity, maxTimeMS } = explain;
|
|
89
|
+
return new Explain(verbosity, maxTimeMS);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function validateExplainTimeoutOptions(options: Document, explain?: Explain) {
|
|
94
|
+
const { maxTimeMS, timeoutMS } = options;
|
|
95
|
+
if (timeoutMS != null && (maxTimeMS != null || explain?.maxTimeMS != null)) {
|
|
96
|
+
throw new MongoAPIError('Cannot use maxTimeMS with timeoutMS for explain commands.');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Applies an explain to a given command.
|
|
102
|
+
* @internal
|
|
103
|
+
*
|
|
104
|
+
* @param command - the command on which to apply the explain
|
|
105
|
+
* @param options - the options containing the explain verbosity
|
|
106
|
+
*/
|
|
107
|
+
export function decorateWithExplain(
|
|
108
|
+
command: Document,
|
|
109
|
+
explain: Explain
|
|
110
|
+
): {
|
|
111
|
+
explain: Document;
|
|
112
|
+
verbosity: ExplainVerbosity;
|
|
113
|
+
maxTimeMS?: number;
|
|
114
|
+
} {
|
|
115
|
+
type ExplainCommand = ReturnType<typeof decorateWithExplain>;
|
|
116
|
+
const { verbosity, maxTimeMS } = explain;
|
|
117
|
+
const baseCommand: ExplainCommand = { explain: command, verbosity };
|
|
118
|
+
|
|
119
|
+
if (typeof maxTimeMS === 'number') {
|
|
120
|
+
baseCommand.maxTimeMS = maxTimeMS;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return baseCommand;
|
|
124
|
+
}
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
import { Readable } from 'stream';
|
|
2
|
+
|
|
3
|
+
import type { Document, ObjectId } from '../bson';
|
|
4
|
+
import type { Collection } from '../collection';
|
|
5
|
+
import { CursorTimeoutMode } from '../cursor/abstract_cursor';
|
|
6
|
+
import type { FindCursor } from '../cursor/find_cursor';
|
|
7
|
+
import {
|
|
8
|
+
MongoGridFSChunkError,
|
|
9
|
+
MongoGridFSStreamError,
|
|
10
|
+
MongoInvalidArgumentError,
|
|
11
|
+
MongoRuntimeError
|
|
12
|
+
} from '../error';
|
|
13
|
+
import type { FindOptions } from '../operations/find';
|
|
14
|
+
import type { ReadPreference } from '../read_preference';
|
|
15
|
+
import type { Sort } from '../sort';
|
|
16
|
+
import { CSOTTimeoutContext } from '../timeout';
|
|
17
|
+
import type { Callback } from '../utils';
|
|
18
|
+
import type { GridFSChunk } from './upload';
|
|
19
|
+
|
|
20
|
+
/** @public */
|
|
21
|
+
export interface GridFSBucketReadStreamOptions {
|
|
22
|
+
sort?: Sort;
|
|
23
|
+
skip?: number;
|
|
24
|
+
/**
|
|
25
|
+
* 0-indexed non-negative byte offset from the beginning of the file
|
|
26
|
+
*/
|
|
27
|
+
start?: number;
|
|
28
|
+
/**
|
|
29
|
+
* 0-indexed non-negative byte offset to the end of the file contents
|
|
30
|
+
* to be returned by the stream. `end` is non-inclusive
|
|
31
|
+
*/
|
|
32
|
+
end?: number;
|
|
33
|
+
/**
|
|
34
|
+
* @experimental
|
|
35
|
+
* Specifies the time an operation will run until it throws a timeout error
|
|
36
|
+
*/
|
|
37
|
+
timeoutMS?: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** @public */
|
|
41
|
+
export interface GridFSBucketReadStreamOptionsWithRevision extends GridFSBucketReadStreamOptions {
|
|
42
|
+
/** The revision number relative to the oldest file with the given filename. 0
|
|
43
|
+
* gets you the oldest file, 1 gets you the 2nd oldest, -1 gets you the
|
|
44
|
+
* newest. */
|
|
45
|
+
revision?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** @public */
|
|
49
|
+
export interface GridFSFile {
|
|
50
|
+
_id: ObjectId;
|
|
51
|
+
length: number;
|
|
52
|
+
chunkSize: number;
|
|
53
|
+
filename: string;
|
|
54
|
+
metadata?: Document;
|
|
55
|
+
uploadDate: Date;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @internal */
|
|
59
|
+
export interface GridFSBucketReadStreamPrivate {
|
|
60
|
+
/**
|
|
61
|
+
* The running total number of bytes read from the chunks collection.
|
|
62
|
+
*/
|
|
63
|
+
bytesRead: number;
|
|
64
|
+
/**
|
|
65
|
+
* The number of bytes to remove from the last chunk read in the file. This is non-zero
|
|
66
|
+
* if `end` is not equal to the length of the document and `end` is not a multiple
|
|
67
|
+
* of the chunkSize.
|
|
68
|
+
*/
|
|
69
|
+
bytesToTrim: number;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The number of bytes to remove from the first chunk read in the file. This is non-zero
|
|
73
|
+
* if `start` is not equal to the 0 and `start` is not a multiple
|
|
74
|
+
* of the chunkSize.
|
|
75
|
+
*/
|
|
76
|
+
bytesToSkip: number;
|
|
77
|
+
|
|
78
|
+
files: Collection<GridFSFile>;
|
|
79
|
+
chunks: Collection<GridFSChunk>;
|
|
80
|
+
cursor?: FindCursor<GridFSChunk>;
|
|
81
|
+
|
|
82
|
+
/** The running total number of chunks read from the chunks collection. */
|
|
83
|
+
expected: number;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The filter used to search in the _files_ collection (i.e., `{ _id: <> }`)
|
|
87
|
+
* This is not the same filter used when reading chunks from the chunks collection.
|
|
88
|
+
*/
|
|
89
|
+
filter: Document;
|
|
90
|
+
|
|
91
|
+
/** Indicates whether or not download has started. */
|
|
92
|
+
init: boolean;
|
|
93
|
+
|
|
94
|
+
/** The expected number of chunks to read, calculated from start, end, chunkSize and file length. */
|
|
95
|
+
expectedEnd: number;
|
|
96
|
+
file?: GridFSFile;
|
|
97
|
+
options: {
|
|
98
|
+
sort?: Sort;
|
|
99
|
+
skip?: number;
|
|
100
|
+
start: number;
|
|
101
|
+
end: number;
|
|
102
|
+
timeoutMS?: number;
|
|
103
|
+
};
|
|
104
|
+
readPreference?: ReadPreference;
|
|
105
|
+
timeoutContext?: CSOTTimeoutContext;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* A readable stream that enables you to read buffers from GridFS.
|
|
110
|
+
*
|
|
111
|
+
* Do not instantiate this class directly. Use `openDownloadStream()` instead.
|
|
112
|
+
* @public
|
|
113
|
+
*/
|
|
114
|
+
export class GridFSBucketReadStream extends Readable {
|
|
115
|
+
/** @internal */
|
|
116
|
+
s: GridFSBucketReadStreamPrivate;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Fires when the stream loaded the file document corresponding to the provided id.
|
|
120
|
+
* @event
|
|
121
|
+
*/
|
|
122
|
+
static readonly FILE = 'file' as const;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @param chunks - Handle for chunks collection
|
|
126
|
+
* @param files - Handle for files collection
|
|
127
|
+
* @param readPreference - The read preference to use
|
|
128
|
+
* @param filter - The filter to use to find the file document
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
constructor(
|
|
132
|
+
chunks: Collection<GridFSChunk>,
|
|
133
|
+
files: Collection<GridFSFile>,
|
|
134
|
+
readPreference: ReadPreference | undefined,
|
|
135
|
+
filter: Document,
|
|
136
|
+
options?: GridFSBucketReadStreamOptions
|
|
137
|
+
) {
|
|
138
|
+
super({ emitClose: true });
|
|
139
|
+
this.s = {
|
|
140
|
+
bytesToTrim: 0,
|
|
141
|
+
bytesToSkip: 0,
|
|
142
|
+
bytesRead: 0,
|
|
143
|
+
chunks,
|
|
144
|
+
expected: 0,
|
|
145
|
+
files,
|
|
146
|
+
filter,
|
|
147
|
+
init: false,
|
|
148
|
+
expectedEnd: 0,
|
|
149
|
+
options: {
|
|
150
|
+
start: 0,
|
|
151
|
+
end: 0,
|
|
152
|
+
...options
|
|
153
|
+
},
|
|
154
|
+
readPreference,
|
|
155
|
+
timeoutContext:
|
|
156
|
+
options?.timeoutMS != null
|
|
157
|
+
? new CSOTTimeoutContext({ timeoutMS: options.timeoutMS, serverSelectionTimeoutMS: 0 })
|
|
158
|
+
: undefined
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Reads from the cursor and pushes to the stream.
|
|
164
|
+
* Private Impl, do not call directly
|
|
165
|
+
* @internal
|
|
166
|
+
*/
|
|
167
|
+
override _read(): void {
|
|
168
|
+
if (this.destroyed) return;
|
|
169
|
+
waitForFile(this, () => doRead(this));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Sets the 0-based offset in bytes to start streaming from. Throws
|
|
174
|
+
* an error if this stream has entered flowing mode
|
|
175
|
+
* (e.g. if you've already called `on('data')`)
|
|
176
|
+
*
|
|
177
|
+
* @param start - 0-based offset in bytes to start streaming from
|
|
178
|
+
*/
|
|
179
|
+
start(start = 0): this {
|
|
180
|
+
throwIfInitialized(this);
|
|
181
|
+
this.s.options.start = start;
|
|
182
|
+
return this;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Sets the 0-based offset in bytes to start streaming from. Throws
|
|
187
|
+
* an error if this stream has entered flowing mode
|
|
188
|
+
* (e.g. if you've already called `on('data')`)
|
|
189
|
+
*
|
|
190
|
+
* @param end - Offset in bytes to stop reading at
|
|
191
|
+
*/
|
|
192
|
+
end(end = 0): this {
|
|
193
|
+
throwIfInitialized(this);
|
|
194
|
+
this.s.options.end = end;
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Marks this stream as aborted (will never push another `data` event)
|
|
200
|
+
* and kills the underlying cursor. Will emit the 'end' event, and then
|
|
201
|
+
* the 'close' event once the cursor is successfully killed.
|
|
202
|
+
*/
|
|
203
|
+
async abort(): Promise<void> {
|
|
204
|
+
this.push(null);
|
|
205
|
+
this.destroy();
|
|
206
|
+
const remainingTimeMS = this.s.timeoutContext?.getRemainingTimeMSOrThrow();
|
|
207
|
+
await this.s.cursor?.close({ timeoutMS: remainingTimeMS });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function throwIfInitialized(stream: GridFSBucketReadStream): void {
|
|
212
|
+
if (stream.s.init) {
|
|
213
|
+
throw new MongoGridFSStreamError('Options cannot be changed after the stream is initialized');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function doRead(stream: GridFSBucketReadStream): void {
|
|
218
|
+
if (stream.destroyed) return;
|
|
219
|
+
if (!stream.s.cursor) return;
|
|
220
|
+
if (!stream.s.file) return;
|
|
221
|
+
|
|
222
|
+
const handleReadResult = (doc: Document | null) => {
|
|
223
|
+
if (stream.destroyed) return;
|
|
224
|
+
|
|
225
|
+
if (!doc) {
|
|
226
|
+
stream.push(null);
|
|
227
|
+
|
|
228
|
+
stream.s.cursor?.close().then(undefined, error => stream.destroy(error));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (!stream.s.file) return;
|
|
233
|
+
|
|
234
|
+
const bytesRemaining = stream.s.file.length - stream.s.bytesRead;
|
|
235
|
+
const expectedN = stream.s.expected++;
|
|
236
|
+
const expectedLength = Math.min(stream.s.file.chunkSize, bytesRemaining);
|
|
237
|
+
if (doc.n > expectedN) {
|
|
238
|
+
return stream.destroy(
|
|
239
|
+
new MongoGridFSChunkError(
|
|
240
|
+
`ChunkIsMissing: Got unexpected n: ${doc.n}, expected: ${expectedN}`
|
|
241
|
+
)
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (doc.n < expectedN) {
|
|
246
|
+
return stream.destroy(
|
|
247
|
+
new MongoGridFSChunkError(`ExtraChunk: Got unexpected n: ${doc.n}, expected: ${expectedN}`)
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
let buf = Buffer.isBuffer(doc.data) ? doc.data : doc.data.buffer;
|
|
252
|
+
|
|
253
|
+
if (buf.byteLength !== expectedLength) {
|
|
254
|
+
if (bytesRemaining <= 0) {
|
|
255
|
+
return stream.destroy(
|
|
256
|
+
new MongoGridFSChunkError(
|
|
257
|
+
`ExtraChunk: Got unexpected n: ${doc.n}, expected file length ${stream.s.file.length} bytes but already read ${stream.s.bytesRead} bytes`
|
|
258
|
+
)
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return stream.destroy(
|
|
263
|
+
new MongoGridFSChunkError(
|
|
264
|
+
`ChunkIsWrongSize: Got unexpected length: ${buf.byteLength}, expected: ${expectedLength}`
|
|
265
|
+
)
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
stream.s.bytesRead += buf.byteLength;
|
|
270
|
+
|
|
271
|
+
if (buf.byteLength === 0) {
|
|
272
|
+
return stream.push(null);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
let sliceStart = null;
|
|
276
|
+
let sliceEnd = null;
|
|
277
|
+
|
|
278
|
+
if (stream.s.bytesToSkip != null) {
|
|
279
|
+
sliceStart = stream.s.bytesToSkip;
|
|
280
|
+
stream.s.bytesToSkip = 0;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const atEndOfStream = expectedN === stream.s.expectedEnd - 1;
|
|
284
|
+
const bytesLeftToRead = stream.s.options.end - stream.s.bytesToSkip;
|
|
285
|
+
if (atEndOfStream && stream.s.bytesToTrim != null) {
|
|
286
|
+
sliceEnd = stream.s.file.chunkSize - stream.s.bytesToTrim;
|
|
287
|
+
} else if (stream.s.options.end && bytesLeftToRead < doc.data.byteLength) {
|
|
288
|
+
sliceEnd = bytesLeftToRead;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (sliceStart != null || sliceEnd != null) {
|
|
292
|
+
buf = buf.slice(sliceStart || 0, sliceEnd || buf.byteLength);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
stream.push(buf);
|
|
296
|
+
return;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
stream.s.cursor.next().then(handleReadResult, error => {
|
|
300
|
+
if (stream.destroyed) return;
|
|
301
|
+
stream.destroy(error);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function init(stream: GridFSBucketReadStream): void {
|
|
306
|
+
const findOneOptions: FindOptions = {};
|
|
307
|
+
if (stream.s.readPreference) {
|
|
308
|
+
findOneOptions.readPreference = stream.s.readPreference;
|
|
309
|
+
}
|
|
310
|
+
if (stream.s.options && stream.s.options.sort) {
|
|
311
|
+
findOneOptions.sort = stream.s.options.sort;
|
|
312
|
+
}
|
|
313
|
+
if (stream.s.options && stream.s.options.skip) {
|
|
314
|
+
findOneOptions.skip = stream.s.options.skip;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const handleReadResult = (doc: Document | null) => {
|
|
318
|
+
if (stream.destroyed) return;
|
|
319
|
+
|
|
320
|
+
if (!doc) {
|
|
321
|
+
const identifier = stream.s.filter._id
|
|
322
|
+
? stream.s.filter._id.toString()
|
|
323
|
+
: stream.s.filter.filename;
|
|
324
|
+
const errmsg = `FileNotFound: file ${identifier} was not found`;
|
|
325
|
+
// TODO(NODE-3483)
|
|
326
|
+
const err = new MongoRuntimeError(errmsg);
|
|
327
|
+
err.code = 'ENOENT'; // TODO: NODE-3338 set property as part of constructor
|
|
328
|
+
return stream.destroy(err);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// If document is empty, kill the stream immediately and don't
|
|
332
|
+
// execute any reads
|
|
333
|
+
if (doc.length <= 0) {
|
|
334
|
+
stream.push(null);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (stream.destroyed) {
|
|
339
|
+
// If user destroys the stream before we have a cursor, wait
|
|
340
|
+
// until the query is done to say we're 'closed' because we can't
|
|
341
|
+
// cancel a query.
|
|
342
|
+
stream.destroy();
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
try {
|
|
347
|
+
stream.s.bytesToSkip = handleStartOption(stream, doc, stream.s.options);
|
|
348
|
+
} catch (error) {
|
|
349
|
+
return stream.destroy(error);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const filter: Document = { files_id: doc._id };
|
|
353
|
+
|
|
354
|
+
// Currently (MongoDB 3.4.4) skip function does not support the index,
|
|
355
|
+
// it needs to retrieve all the documents first and then skip them. (CS-25811)
|
|
356
|
+
// As work around we use $gte on the "n" field.
|
|
357
|
+
if (stream.s.options && stream.s.options.start != null) {
|
|
358
|
+
const skip = Math.floor(stream.s.options.start / doc.chunkSize);
|
|
359
|
+
if (skip > 0) {
|
|
360
|
+
filter['n'] = { $gte: skip };
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
let remainingTimeMS: number | undefined;
|
|
365
|
+
try {
|
|
366
|
+
remainingTimeMS = stream.s.timeoutContext?.getRemainingTimeMSOrThrow(
|
|
367
|
+
`Download timed out after ${stream.s.timeoutContext?.timeoutMS}ms`
|
|
368
|
+
);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
return stream.destroy(error);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
stream.s.cursor = stream.s.chunks
|
|
374
|
+
.find(filter, {
|
|
375
|
+
timeoutMode: stream.s.options.timeoutMS != null ? CursorTimeoutMode.LIFETIME : undefined,
|
|
376
|
+
timeoutMS: remainingTimeMS
|
|
377
|
+
})
|
|
378
|
+
.sort({ n: 1 });
|
|
379
|
+
|
|
380
|
+
if (stream.s.readPreference) {
|
|
381
|
+
stream.s.cursor.withReadPreference(stream.s.readPreference);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
stream.s.expectedEnd = Math.ceil(doc.length / doc.chunkSize);
|
|
385
|
+
stream.s.file = doc as GridFSFile;
|
|
386
|
+
|
|
387
|
+
try {
|
|
388
|
+
stream.s.bytesToTrim = handleEndOption(stream, doc, stream.s.cursor, stream.s.options);
|
|
389
|
+
} catch (error) {
|
|
390
|
+
return stream.destroy(error);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
stream.emit(GridFSBucketReadStream.FILE, doc);
|
|
394
|
+
return;
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
let remainingTimeMS: number | undefined;
|
|
398
|
+
try {
|
|
399
|
+
remainingTimeMS = stream.s.timeoutContext?.getRemainingTimeMSOrThrow(
|
|
400
|
+
`Download timed out after ${stream.s.timeoutContext?.timeoutMS}ms`
|
|
401
|
+
);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
if (!stream.destroyed) stream.destroy(error);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
findOneOptions.timeoutMS = remainingTimeMS;
|
|
408
|
+
|
|
409
|
+
stream.s.files.findOne(stream.s.filter, findOneOptions).then(handleReadResult, error => {
|
|
410
|
+
if (stream.destroyed) return;
|
|
411
|
+
stream.destroy(error);
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function waitForFile(stream: GridFSBucketReadStream, callback: Callback): void {
|
|
416
|
+
if (stream.s.file) {
|
|
417
|
+
return callback();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (!stream.s.init) {
|
|
421
|
+
init(stream);
|
|
422
|
+
stream.s.init = true;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
stream.once('file', () => {
|
|
426
|
+
callback();
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function handleStartOption(
|
|
431
|
+
stream: GridFSBucketReadStream,
|
|
432
|
+
doc: Document,
|
|
433
|
+
options: GridFSBucketReadStreamOptions
|
|
434
|
+
): number {
|
|
435
|
+
if (options && options.start != null) {
|
|
436
|
+
if (options.start > doc.length) {
|
|
437
|
+
throw new MongoInvalidArgumentError(
|
|
438
|
+
`Stream start (${options.start}) must not be more than the length of the file (${doc.length})`
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
if (options.start < 0) {
|
|
442
|
+
throw new MongoInvalidArgumentError(`Stream start (${options.start}) must not be negative`);
|
|
443
|
+
}
|
|
444
|
+
if (options.end != null && options.end < options.start) {
|
|
445
|
+
throw new MongoInvalidArgumentError(
|
|
446
|
+
`Stream start (${options.start}) must not be greater than stream end (${options.end})`
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
stream.s.bytesRead = Math.floor(options.start / doc.chunkSize) * doc.chunkSize;
|
|
451
|
+
stream.s.expected = Math.floor(options.start / doc.chunkSize);
|
|
452
|
+
|
|
453
|
+
return options.start - stream.s.bytesRead;
|
|
454
|
+
}
|
|
455
|
+
throw new MongoInvalidArgumentError('Start option must be defined');
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function handleEndOption(
|
|
459
|
+
stream: GridFSBucketReadStream,
|
|
460
|
+
doc: Document,
|
|
461
|
+
cursor: FindCursor<GridFSChunk>,
|
|
462
|
+
options: GridFSBucketReadStreamOptions
|
|
463
|
+
) {
|
|
464
|
+
if (options && options.end != null) {
|
|
465
|
+
if (options.end > doc.length) {
|
|
466
|
+
throw new MongoInvalidArgumentError(
|
|
467
|
+
`Stream end (${options.end}) must not be more than the length of the file (${doc.length})`
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
if (options.start == null || options.start < 0) {
|
|
471
|
+
throw new MongoInvalidArgumentError(`Stream end (${options.end}) must not be negative`);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
const start = options.start != null ? Math.floor(options.start / doc.chunkSize) : 0;
|
|
475
|
+
|
|
476
|
+
cursor.limit(Math.ceil(options.end / doc.chunkSize) - start);
|
|
477
|
+
|
|
478
|
+
stream.s.expectedEnd = Math.ceil(options.end / doc.chunkSize);
|
|
479
|
+
|
|
480
|
+
return Math.ceil(options.end / doc.chunkSize) * doc.chunkSize - options.end;
|
|
481
|
+
}
|
|
482
|
+
throw new MongoInvalidArgumentError('End option must be defined');
|
|
483
|
+
}
|