1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | var crypto = require('crypto');
|
6 | var uuid$3 = require('uuid');
|
7 | var logger$4 = require('@azure/logger');
|
8 | var tslib = require('tslib');
|
9 | var stableStringify = require('fast-json-stable-stringify');
|
10 | var PriorityQueue = require('priorityqueuejs');
|
11 | var semaphore = require('semaphore');
|
12 | var coreRestPipeline = require('@azure/core-rest-pipeline');
|
13 | var nodeAbortController = require('node-abort-controller');
|
14 | var universalUserAgent = require('universal-user-agent');
|
15 | var JSBI = require('jsbi');
|
16 | var abortController = require('@azure/abort-controller');
|
17 |
|
18 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
19 |
|
20 | var stableStringify__default = _interopDefaultLegacy(stableStringify);
|
21 | var PriorityQueue__default = _interopDefaultLegacy(PriorityQueue);
|
22 | var semaphore__default = _interopDefaultLegacy(semaphore);
|
23 | var JSBI__default = _interopDefaultLegacy(JSBI);
|
24 |
|
25 |
|
26 |
|
27 | const DEFAULT_PARTITION_KEY_PATH = "/_partitionKey";
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 | const Constants = {
|
35 | HttpHeaders: {
|
36 | Authorization: "authorization",
|
37 | ETag: "etag",
|
38 | MethodOverride: "X-HTTP-Method",
|
39 | Slug: "Slug",
|
40 | ContentType: "Content-Type",
|
41 | LastModified: "Last-Modified",
|
42 | ContentEncoding: "Content-Encoding",
|
43 | CharacterSet: "CharacterSet",
|
44 | UserAgent: "User-Agent",
|
45 | IfModifiedSince: "If-Modified-Since",
|
46 | IfMatch: "If-Match",
|
47 | IfNoneMatch: "If-None-Match",
|
48 | ContentLength: "Content-Length",
|
49 | AcceptEncoding: "Accept-Encoding",
|
50 | KeepAlive: "Keep-Alive",
|
51 | CacheControl: "Cache-Control",
|
52 | TransferEncoding: "Transfer-Encoding",
|
53 | ContentLanguage: "Content-Language",
|
54 | ContentLocation: "Content-Location",
|
55 | ContentMd5: "Content-Md5",
|
56 | ContentRange: "Content-Range",
|
57 | Accept: "Accept",
|
58 | AcceptCharset: "Accept-Charset",
|
59 | AcceptLanguage: "Accept-Language",
|
60 | IfRange: "If-Range",
|
61 | IfUnmodifiedSince: "If-Unmodified-Since",
|
62 | MaxForwards: "Max-Forwards",
|
63 | ProxyAuthorization: "Proxy-Authorization",
|
64 | AcceptRanges: "Accept-Ranges",
|
65 | ProxyAuthenticate: "Proxy-Authenticate",
|
66 | RetryAfter: "Retry-After",
|
67 | SetCookie: "Set-Cookie",
|
68 | WwwAuthenticate: "Www-Authenticate",
|
69 | Origin: "Origin",
|
70 | Host: "Host",
|
71 | AccessControlAllowOrigin: "Access-Control-Allow-Origin",
|
72 | AccessControlAllowHeaders: "Access-Control-Allow-Headers",
|
73 | KeyValueEncodingFormat: "application/x-www-form-urlencoded",
|
74 | WrapAssertionFormat: "wrap_assertion_format",
|
75 | WrapAssertion: "wrap_assertion",
|
76 | WrapScope: "wrap_scope",
|
77 | SimpleToken: "SWT",
|
78 | HttpDate: "date",
|
79 | Prefer: "Prefer",
|
80 | Location: "Location",
|
81 | Referer: "referer",
|
82 | A_IM: "A-IM",
|
83 |
|
84 | Query: "x-ms-documentdb-query",
|
85 | IsQuery: "x-ms-documentdb-isquery",
|
86 | IsQueryPlan: "x-ms-cosmos-is-query-plan-request",
|
87 | SupportedQueryFeatures: "x-ms-cosmos-supported-query-features",
|
88 | QueryVersion: "x-ms-cosmos-query-version",
|
89 |
|
90 | Continuation: "x-ms-continuation",
|
91 | PageSize: "x-ms-max-item-count",
|
92 | ItemCount: "x-ms-item-count",
|
93 |
|
94 | ActivityId: "x-ms-activity-id",
|
95 | PreTriggerInclude: "x-ms-documentdb-pre-trigger-include",
|
96 | PreTriggerExclude: "x-ms-documentdb-pre-trigger-exclude",
|
97 | PostTriggerInclude: "x-ms-documentdb-post-trigger-include",
|
98 | PostTriggerExclude: "x-ms-documentdb-post-trigger-exclude",
|
99 | IndexingDirective: "x-ms-indexing-directive",
|
100 | SessionToken: "x-ms-session-token",
|
101 | ConsistencyLevel: "x-ms-consistency-level",
|
102 | XDate: "x-ms-date",
|
103 | CollectionPartitionInfo: "x-ms-collection-partition-info",
|
104 | CollectionServiceInfo: "x-ms-collection-service-info",
|
105 |
|
106 | RetryAfterInMilliseconds: "x-ms-retry-after-ms",
|
107 | RetryAfterInMs: "x-ms-retry-after-ms",
|
108 | IsFeedUnfiltered: "x-ms-is-feed-unfiltered",
|
109 | ResourceTokenExpiry: "x-ms-documentdb-expiry-seconds",
|
110 | EnableScanInQuery: "x-ms-documentdb-query-enable-scan",
|
111 | EmitVerboseTracesInQuery: "x-ms-documentdb-query-emit-traces",
|
112 | EnableCrossPartitionQuery: "x-ms-documentdb-query-enablecrosspartition",
|
113 | ParallelizeCrossPartitionQuery: "x-ms-documentdb-query-parallelizecrosspartitionquery",
|
114 | ResponseContinuationTokenLimitInKB: "x-ms-documentdb-responsecontinuationtokenlimitinkb",
|
115 |
|
116 |
|
117 | PopulateQueryMetrics: "x-ms-documentdb-populatequerymetrics",
|
118 |
|
119 | QueryMetrics: "x-ms-documentdb-query-metrics",
|
120 |
|
121 | Version: "x-ms-version",
|
122 |
|
123 | OwnerFullName: "x-ms-alt-content-path",
|
124 |
|
125 | OwnerId: "x-ms-content-path",
|
126 |
|
127 | PartitionKey: "x-ms-documentdb-partitionkey",
|
128 | PartitionKeyRangeID: "x-ms-documentdb-partitionkeyrangeid",
|
129 |
|
130 | MaxEntityCount: "x-ms-root-entity-max-count",
|
131 | CurrentEntityCount: "x-ms-root-entity-current-count",
|
132 | CollectionQuotaInMb: "x-ms-collection-quota-mb",
|
133 | CollectionCurrentUsageInMb: "x-ms-collection-usage-mb",
|
134 | MaxMediaStorageUsageInMB: "x-ms-max-media-storage-usage-mb",
|
135 | CurrentMediaStorageUsageInMB: "x-ms-media-storage-usage-mb",
|
136 | RequestCharge: "x-ms-request-charge",
|
137 | PopulateQuotaInfo: "x-ms-documentdb-populatequotainfo",
|
138 | MaxResourceQuota: "x-ms-resource-quota",
|
139 |
|
140 | OfferType: "x-ms-offer-type",
|
141 | OfferThroughput: "x-ms-offer-throughput",
|
142 | AutoscaleSettings: "x-ms-cosmos-offer-autopilot-settings",
|
143 |
|
144 | DisableRUPerMinuteUsage: "x-ms-documentdb-disable-ru-per-minute-usage",
|
145 | IsRUPerMinuteUsed: "x-ms-documentdb-is-ru-per-minute-used",
|
146 | OfferIsRUPerMinuteThroughputEnabled: "x-ms-offer-is-ru-per-minute-throughput-enabled",
|
147 |
|
148 | IndexTransformationProgress: "x-ms-documentdb-collection-index-transformation-progress",
|
149 | LazyIndexingProgress: "x-ms-documentdb-collection-lazy-indexing-progress",
|
150 |
|
151 | IsUpsert: "x-ms-documentdb-is-upsert",
|
152 |
|
153 | SubStatus: "x-ms-substatus",
|
154 |
|
155 | EnableScriptLogging: "x-ms-documentdb-script-enable-logging",
|
156 | ScriptLogResults: "x-ms-documentdb-script-log-results",
|
157 |
|
158 | ALLOW_MULTIPLE_WRITES: "x-ms-cosmos-allow-tentative-writes",
|
159 |
|
160 | IsBatchRequest: "x-ms-cosmos-is-batch-request",
|
161 | IsBatchAtomic: "x-ms-cosmos-batch-atomic",
|
162 | BatchContinueOnError: "x-ms-cosmos-batch-continue-on-error",
|
163 |
|
164 | DedicatedGatewayPerRequestCacheStaleness: "x-ms-dedicatedgateway-max-age",
|
165 |
|
166 | ForceRefresh: "x-ms-force-refresh",
|
167 | },
|
168 |
|
169 | WritableLocations: "writableLocations",
|
170 | ReadableLocations: "readableLocations",
|
171 | LocationUnavailableExpirationTimeInMs: 5 * 60 * 1000,
|
172 |
|
173 | ENABLE_MULTIPLE_WRITABLE_LOCATIONS: "enableMultipleWriteLocations",
|
174 |
|
175 | DefaultUnavailableLocationExpirationTimeMS: 5 * 60 * 1000,
|
176 |
|
177 | ThrottleRetryCount: "x-ms-throttle-retry-count",
|
178 | ThrottleRetryWaitTimeInMs: "x-ms-throttle-retry-wait-time-ms",
|
179 |
|
180 | CurrentVersion: "2020-07-15",
|
181 | AzureNamespace: "Azure.Cosmos",
|
182 | AzurePackageName: "@azure/cosmos",
|
183 | SDKName: "azure-cosmos-js",
|
184 | SDKVersion: "3.17.3",
|
185 |
|
186 | DefaultMaxBulkRequestBodySizeInBytes: 220201,
|
187 | Quota: {
|
188 | CollectionSize: "collectionSize",
|
189 | },
|
190 | Path: {
|
191 | Root: "/",
|
192 | DatabasesPathSegment: "dbs",
|
193 | CollectionsPathSegment: "colls",
|
194 | UsersPathSegment: "users",
|
195 | DocumentsPathSegment: "docs",
|
196 | PermissionsPathSegment: "permissions",
|
197 | StoredProceduresPathSegment: "sprocs",
|
198 | TriggersPathSegment: "triggers",
|
199 | UserDefinedFunctionsPathSegment: "udfs",
|
200 | ConflictsPathSegment: "conflicts",
|
201 | AttachmentsPathSegment: "attachments",
|
202 | PartitionKeyRangesPathSegment: "pkranges",
|
203 | SchemasPathSegment: "schemas",
|
204 | OffersPathSegment: "offers",
|
205 | TopologyPathSegment: "topology",
|
206 | DatabaseAccountPathSegment: "databaseaccount",
|
207 | },
|
208 | PartitionKeyRange: {
|
209 |
|
210 | MinInclusive: "minInclusive",
|
211 | MaxExclusive: "maxExclusive",
|
212 | Id: "id",
|
213 | },
|
214 | QueryRangeConstants: {
|
215 |
|
216 | MinInclusive: "minInclusive",
|
217 | MaxExclusive: "maxExclusive",
|
218 | min: "min",
|
219 | },
|
220 | |
221 |
|
222 |
|
223 | EffectiveParitionKeyConstants: {
|
224 | MinimumInclusiveEffectivePartitionKey: "",
|
225 | MaximumExclusiveEffectivePartitionKey: "FF",
|
226 | },
|
227 | EffectivePartitionKeyConstants: {
|
228 | MinimumInclusiveEffectivePartitionKey: "",
|
229 | MaximumExclusiveEffectivePartitionKey: "FF",
|
230 | },
|
231 | };
|
232 |
|
233 |
|
234 |
|
235 | exports.ResourceType = void 0;
|
236 | (function (ResourceType) {
|
237 | ResourceType["none"] = "";
|
238 | ResourceType["database"] = "dbs";
|
239 | ResourceType["offer"] = "offers";
|
240 | ResourceType["user"] = "users";
|
241 | ResourceType["permission"] = "permissions";
|
242 | ResourceType["container"] = "colls";
|
243 | ResourceType["conflicts"] = "conflicts";
|
244 | ResourceType["sproc"] = "sprocs";
|
245 | ResourceType["udf"] = "udfs";
|
246 | ResourceType["trigger"] = "triggers";
|
247 | ResourceType["item"] = "docs";
|
248 | ResourceType["pkranges"] = "pkranges";
|
249 | ResourceType["partitionkey"] = "partitionKey";
|
250 | })(exports.ResourceType || (exports.ResourceType = {}));
|
251 |
|
252 |
|
253 |
|
254 | exports.HTTPMethod = void 0;
|
255 | (function (HTTPMethod) {
|
256 | HTTPMethod["get"] = "GET";
|
257 | HTTPMethod["patch"] = "PATCH";
|
258 | HTTPMethod["post"] = "POST";
|
259 | HTTPMethod["put"] = "PUT";
|
260 | HTTPMethod["delete"] = "DELETE";
|
261 | })(exports.HTTPMethod || (exports.HTTPMethod = {}));
|
262 |
|
263 |
|
264 |
|
265 | exports.OperationType = void 0;
|
266 | (function (OperationType) {
|
267 | OperationType["Create"] = "create";
|
268 | OperationType["Replace"] = "replace";
|
269 | OperationType["Upsert"] = "upsert";
|
270 | OperationType["Delete"] = "delete";
|
271 | OperationType["Read"] = "read";
|
272 | OperationType["Query"] = "query";
|
273 | OperationType["Execute"] = "execute";
|
274 | OperationType["Batch"] = "batch";
|
275 | OperationType["Patch"] = "patch";
|
276 | })(exports.OperationType || (exports.OperationType = {}));
|
277 |
|
278 |
|
279 |
|
280 | var CosmosKeyType;
|
281 | (function (CosmosKeyType) {
|
282 | CosmosKeyType["PrimaryMaster"] = "PRIMARY_MASTER";
|
283 | CosmosKeyType["SecondaryMaster"] = "SECONDARY_MASTER";
|
284 | CosmosKeyType["PrimaryReadOnly"] = "PRIMARY_READONLY";
|
285 | CosmosKeyType["SecondaryReadOnly"] = "SECONDARY_READONLY";
|
286 | })(CosmosKeyType || (CosmosKeyType = {}));
|
287 |
|
288 |
|
289 |
|
290 | var CosmosContainerChildResourceKind;
|
291 | (function (CosmosContainerChildResourceKind) {
|
292 | CosmosContainerChildResourceKind["Item"] = "ITEM";
|
293 | CosmosContainerChildResourceKind["StoredProcedure"] = "STORED_PROCEDURE";
|
294 | CosmosContainerChildResourceKind["UserDefinedFunction"] = "USER_DEFINED_FUNCTION";
|
295 | CosmosContainerChildResourceKind["Trigger"] = "TRIGGER";
|
296 | })(CosmosContainerChildResourceKind || (CosmosContainerChildResourceKind = {}));
|
297 |
|
298 |
|
299 |
|
300 | var PermissionScopeValues;
|
301 | (function (PermissionScopeValues) {
|
302 | |
303 |
|
304 |
|
305 | PermissionScopeValues[PermissionScopeValues["ScopeAccountReadValue"] = 1] = "ScopeAccountReadValue";
|
306 | PermissionScopeValues[PermissionScopeValues["ScopeAccountListDatabasesValue"] = 2] = "ScopeAccountListDatabasesValue";
|
307 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseReadValue"] = 4] = "ScopeDatabaseReadValue";
|
308 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseReadOfferValue"] = 8] = "ScopeDatabaseReadOfferValue";
|
309 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseListContainerValue"] = 16] = "ScopeDatabaseListContainerValue";
|
310 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReadValue"] = 32] = "ScopeContainerReadValue";
|
311 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReadOfferValue"] = 64] = "ScopeContainerReadOfferValue";
|
312 | PermissionScopeValues[PermissionScopeValues["ScopeAccountCreateDatabasesValue"] = 1] = "ScopeAccountCreateDatabasesValue";
|
313 | PermissionScopeValues[PermissionScopeValues["ScopeAccountDeleteDatabasesValue"] = 2] = "ScopeAccountDeleteDatabasesValue";
|
314 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseDeleteValue"] = 4] = "ScopeDatabaseDeleteValue";
|
315 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseReplaceOfferValue"] = 8] = "ScopeDatabaseReplaceOfferValue";
|
316 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseCreateContainerValue"] = 16] = "ScopeDatabaseCreateContainerValue";
|
317 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseDeleteContainerValue"] = 32] = "ScopeDatabaseDeleteContainerValue";
|
318 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReplaceValue"] = 64] = "ScopeContainerReplaceValue";
|
319 | PermissionScopeValues[PermissionScopeValues["ScopeContainerDeleteValue"] = 128] = "ScopeContainerDeleteValue";
|
320 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReplaceOfferValue"] = 256] = "ScopeContainerReplaceOfferValue";
|
321 | PermissionScopeValues[PermissionScopeValues["ScopeAccountReadAllAccessValue"] = 65535] = "ScopeAccountReadAllAccessValue";
|
322 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseReadAllAccessValue"] = 124] = "ScopeDatabaseReadAllAccessValue";
|
323 | PermissionScopeValues[PermissionScopeValues["ScopeContainersReadAllAccessValue"] = 96] = "ScopeContainersReadAllAccessValue";
|
324 | PermissionScopeValues[PermissionScopeValues["ScopeAccountWriteAllAccessValue"] = 65535] = "ScopeAccountWriteAllAccessValue";
|
325 | PermissionScopeValues[PermissionScopeValues["ScopeDatabaseWriteAllAccessValue"] = 508] = "ScopeDatabaseWriteAllAccessValue";
|
326 | PermissionScopeValues[PermissionScopeValues["ScopeContainersWriteAllAccessValue"] = 448] = "ScopeContainersWriteAllAccessValue";
|
327 | |
328 |
|
329 |
|
330 | PermissionScopeValues[PermissionScopeValues["ScopeContainerExecuteQueriesValue"] = 1] = "ScopeContainerExecuteQueriesValue";
|
331 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReadFeedsValue"] = 2] = "ScopeContainerReadFeedsValue";
|
332 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReadStoredProceduresValue"] = 4] = "ScopeContainerReadStoredProceduresValue";
|
333 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReadUserDefinedFunctionsValue"] = 8] = "ScopeContainerReadUserDefinedFunctionsValue";
|
334 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReadTriggersValue"] = 16] = "ScopeContainerReadTriggersValue";
|
335 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReadConflictsValue"] = 32] = "ScopeContainerReadConflictsValue";
|
336 | PermissionScopeValues[PermissionScopeValues["ScopeItemReadValue"] = 64] = "ScopeItemReadValue";
|
337 | PermissionScopeValues[PermissionScopeValues["ScopeStoredProcedureReadValue"] = 128] = "ScopeStoredProcedureReadValue";
|
338 | PermissionScopeValues[PermissionScopeValues["ScopeUserDefinedFunctionReadValue"] = 256] = "ScopeUserDefinedFunctionReadValue";
|
339 | PermissionScopeValues[PermissionScopeValues["ScopeTriggerReadValue"] = 512] = "ScopeTriggerReadValue";
|
340 | PermissionScopeValues[PermissionScopeValues["ScopeContainerCreateItemsValue"] = 1] = "ScopeContainerCreateItemsValue";
|
341 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReplaceItemsValue"] = 2] = "ScopeContainerReplaceItemsValue";
|
342 | PermissionScopeValues[PermissionScopeValues["ScopeContainerUpsertItemsValue"] = 4] = "ScopeContainerUpsertItemsValue";
|
343 | PermissionScopeValues[PermissionScopeValues["ScopeContainerDeleteItemsValue"] = 8] = "ScopeContainerDeleteItemsValue";
|
344 | PermissionScopeValues[PermissionScopeValues["ScopeContainerCreateStoredProceduresValue"] = 16] = "ScopeContainerCreateStoredProceduresValue";
|
345 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReplaceStoredProceduresValue"] = 32] = "ScopeContainerReplaceStoredProceduresValue";
|
346 | PermissionScopeValues[PermissionScopeValues["ScopeContainerDeleteStoredProceduresValue"] = 64] = "ScopeContainerDeleteStoredProceduresValue";
|
347 | PermissionScopeValues[PermissionScopeValues["ScopeContainerExecuteStoredProceduresValue"] = 128] = "ScopeContainerExecuteStoredProceduresValue";
|
348 | PermissionScopeValues[PermissionScopeValues["ScopeContainerCreateTriggersValue"] = 256] = "ScopeContainerCreateTriggersValue";
|
349 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReplaceTriggersValue"] = 512] = "ScopeContainerReplaceTriggersValue";
|
350 | PermissionScopeValues[PermissionScopeValues["ScopeContainerDeleteTriggersValue"] = 1024] = "ScopeContainerDeleteTriggersValue";
|
351 | PermissionScopeValues[PermissionScopeValues["ScopeContainerCreateUserDefinedFunctionsValue"] = 2048] = "ScopeContainerCreateUserDefinedFunctionsValue";
|
352 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReplaceUserDefinedFunctionsValue"] = 4096] = "ScopeContainerReplaceUserDefinedFunctionsValue";
|
353 | PermissionScopeValues[PermissionScopeValues["ScopeContainerDeleteUserDefinedFunctionSValue"] = 8192] = "ScopeContainerDeleteUserDefinedFunctionSValue";
|
354 | PermissionScopeValues[PermissionScopeValues["ScopeContainerDeleteCONFLICTSValue"] = 16384] = "ScopeContainerDeleteCONFLICTSValue";
|
355 | PermissionScopeValues[PermissionScopeValues["ScopeItemReplaceValue"] = 65536] = "ScopeItemReplaceValue";
|
356 | PermissionScopeValues[PermissionScopeValues["ScopeItemUpsertValue"] = 131072] = "ScopeItemUpsertValue";
|
357 | PermissionScopeValues[PermissionScopeValues["ScopeItemDeleteValue"] = 262144] = "ScopeItemDeleteValue";
|
358 | PermissionScopeValues[PermissionScopeValues["ScopeStoredProcedureReplaceValue"] = 1048576] = "ScopeStoredProcedureReplaceValue";
|
359 | PermissionScopeValues[PermissionScopeValues["ScopeStoredProcedureDeleteValue"] = 2097152] = "ScopeStoredProcedureDeleteValue";
|
360 | PermissionScopeValues[PermissionScopeValues["ScopeStoredProcedureExecuteValue"] = 4194304] = "ScopeStoredProcedureExecuteValue";
|
361 | PermissionScopeValues[PermissionScopeValues["ScopeUserDefinedFunctionReplaceValue"] = 8388608] = "ScopeUserDefinedFunctionReplaceValue";
|
362 | PermissionScopeValues[PermissionScopeValues["ScopeUserDefinedFunctionDeleteValue"] = 16777216] = "ScopeUserDefinedFunctionDeleteValue";
|
363 | PermissionScopeValues[PermissionScopeValues["ScopeTriggerReplaceValue"] = 33554432] = "ScopeTriggerReplaceValue";
|
364 | PermissionScopeValues[PermissionScopeValues["ScopeTriggerDeleteValue"] = 67108864] = "ScopeTriggerDeleteValue";
|
365 | PermissionScopeValues[PermissionScopeValues["ScopeContainerReadAllAccessValue"] = 4294967295] = "ScopeContainerReadAllAccessValue";
|
366 | PermissionScopeValues[PermissionScopeValues["ScopeItemReadAllAccessValue"] = 65] = "ScopeItemReadAllAccessValue";
|
367 | PermissionScopeValues[PermissionScopeValues["ScopeContainerWriteAllAccessValue"] = 4294967295] = "ScopeContainerWriteAllAccessValue";
|
368 | PermissionScopeValues[PermissionScopeValues["ScopeItemWriteAllAccessValue"] = 458767] = "ScopeItemWriteAllAccessValue";
|
369 | PermissionScopeValues[PermissionScopeValues["NoneValue"] = 0] = "NoneValue";
|
370 | })(PermissionScopeValues || (PermissionScopeValues = {}));
|
371 |
|
372 |
|
373 |
|
374 | exports.SasTokenPermissionKind = void 0;
|
375 | (function (SasTokenPermissionKind) {
|
376 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerCreateItems"] = 1] = "ContainerCreateItems";
|
377 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReplaceItems"] = 2] = "ContainerReplaceItems";
|
378 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerUpsertItems"] = 4] = "ContainerUpsertItems";
|
379 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerDeleteItems"] = 128] = "ContainerDeleteItems";
|
380 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerExecuteQueries"] = 1] = "ContainerExecuteQueries";
|
381 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReadFeeds"] = 2] = "ContainerReadFeeds";
|
382 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerCreateStoreProcedure"] = 16] = "ContainerCreateStoreProcedure";
|
383 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReadStoreProcedure"] = 4] = "ContainerReadStoreProcedure";
|
384 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReplaceStoreProcedure"] = 32] = "ContainerReplaceStoreProcedure";
|
385 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerDeleteStoreProcedure"] = 64] = "ContainerDeleteStoreProcedure";
|
386 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerCreateTriggers"] = 256] = "ContainerCreateTriggers";
|
387 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReadTriggers"] = 16] = "ContainerReadTriggers";
|
388 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReplaceTriggers"] = 512] = "ContainerReplaceTriggers";
|
389 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerDeleteTriggers"] = 1024] = "ContainerDeleteTriggers";
|
390 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerCreateUserDefinedFunctions"] = 2048] = "ContainerCreateUserDefinedFunctions";
|
391 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReadUserDefinedFunctions"] = 8] = "ContainerReadUserDefinedFunctions";
|
392 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReplaceUserDefinedFunctions"] = 4096] = "ContainerReplaceUserDefinedFunctions";
|
393 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerDeleteUserDefinedFunctions"] = 8192] = "ContainerDeleteUserDefinedFunctions";
|
394 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerExecuteStoredProcedure"] = 128] = "ContainerExecuteStoredProcedure";
|
395 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReadConflicts"] = 32] = "ContainerReadConflicts";
|
396 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerDeleteConflicts"] = 16384] = "ContainerDeleteConflicts";
|
397 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerReadAny"] = 64] = "ContainerReadAny";
|
398 | SasTokenPermissionKind[SasTokenPermissionKind["ContainerFullAccess"] = 4294967295] = "ContainerFullAccess";
|
399 | SasTokenPermissionKind[SasTokenPermissionKind["ItemReadAny"] = 65536] = "ItemReadAny";
|
400 | SasTokenPermissionKind[SasTokenPermissionKind["ItemFullAccess"] = 65] = "ItemFullAccess";
|
401 | SasTokenPermissionKind[SasTokenPermissionKind["ItemRead"] = 64] = "ItemRead";
|
402 | SasTokenPermissionKind[SasTokenPermissionKind["ItemReplace"] = 65536] = "ItemReplace";
|
403 | SasTokenPermissionKind[SasTokenPermissionKind["ItemUpsert"] = 131072] = "ItemUpsert";
|
404 | SasTokenPermissionKind[SasTokenPermissionKind["ItemDelete"] = 262144] = "ItemDelete";
|
405 | SasTokenPermissionKind[SasTokenPermissionKind["StoreProcedureRead"] = 128] = "StoreProcedureRead";
|
406 | SasTokenPermissionKind[SasTokenPermissionKind["StoreProcedureReplace"] = 1048576] = "StoreProcedureReplace";
|
407 | SasTokenPermissionKind[SasTokenPermissionKind["StoreProcedureDelete"] = 2097152] = "StoreProcedureDelete";
|
408 | SasTokenPermissionKind[SasTokenPermissionKind["StoreProcedureExecute"] = 4194304] = "StoreProcedureExecute";
|
409 | SasTokenPermissionKind[SasTokenPermissionKind["UserDefinedFuntionRead"] = 256] = "UserDefinedFuntionRead";
|
410 | SasTokenPermissionKind[SasTokenPermissionKind["UserDefinedFuntionReplace"] = 8388608] = "UserDefinedFuntionReplace";
|
411 | SasTokenPermissionKind[SasTokenPermissionKind["UserDefinedFuntionDelete"] = 16777216] = "UserDefinedFuntionDelete";
|
412 | SasTokenPermissionKind[SasTokenPermissionKind["TriggerRead"] = 512] = "TriggerRead";
|
413 | SasTokenPermissionKind[SasTokenPermissionKind["TriggerReplace"] = 33554432] = "TriggerReplace";
|
414 | SasTokenPermissionKind[SasTokenPermissionKind["TriggerDelete"] = 67108864] = "TriggerDelete";
|
415 | })(exports.SasTokenPermissionKind || (exports.SasTokenPermissionKind = {}));
|
416 |
|
417 | const trimLeftSlashes = new RegExp("^[/]+");
|
418 | const trimRightSlashes = new RegExp("[/]+$");
|
419 | const illegalResourceIdCharacters = new RegExp("[/\\\\?#]");
|
420 | const illegalItemResourceIdCharacters = new RegExp("[/\\\\#]");
|
421 |
|
422 | function jsonStringifyAndEscapeNonASCII(arg) {
|
423 |
|
424 |
|
425 | return JSON.stringify(arg).replace(/[\u007F-\uFFFF]/g, (m) => {
|
426 | return "\\u" + ("0000" + m.charCodeAt(0).toString(16)).slice(-4);
|
427 | });
|
428 | }
|
429 |
|
430 |
|
431 |
|
432 | function parseLink(resourcePath) {
|
433 | if (resourcePath.length === 0) {
|
434 |
|
435 | return {
|
436 | type: undefined,
|
437 | objectBody: undefined,
|
438 | };
|
439 | }
|
440 | if (resourcePath[resourcePath.length - 1] !== "/") {
|
441 | resourcePath = resourcePath + "/";
|
442 | }
|
443 | if (resourcePath[0] !== "/") {
|
444 | resourcePath = "/" + resourcePath;
|
445 | }
|
446 | |
447 |
|
448 |
|
449 |
|
450 |
|
451 |
|
452 |
|
453 |
|
454 |
|
455 |
|
456 |
|
457 | const pathParts = resourcePath.split("/");
|
458 | let id;
|
459 | let type;
|
460 | if (pathParts.length % 2 === 0) {
|
461 |
|
462 | id = pathParts[pathParts.length - 2];
|
463 | type = pathParts[pathParts.length - 3];
|
464 | }
|
465 | else {
|
466 |
|
467 | id = pathParts[pathParts.length - 3];
|
468 | type = pathParts[pathParts.length - 2];
|
469 | }
|
470 | const result = {
|
471 | type,
|
472 | objectBody: {
|
473 | id,
|
474 | self: resourcePath,
|
475 | },
|
476 | };
|
477 | return result;
|
478 | }
|
479 |
|
480 |
|
481 |
|
482 | function isReadRequest(operationType) {
|
483 | return operationType === exports.OperationType.Read || operationType === exports.OperationType.Query;
|
484 | }
|
485 |
|
486 |
|
487 |
|
488 | function sleep(time) {
|
489 | return new Promise((resolve) => {
|
490 | setTimeout(() => {
|
491 | resolve();
|
492 | }, time);
|
493 | });
|
494 | }
|
495 |
|
496 |
|
497 |
|
498 | function getContainerLink(link) {
|
499 | return link.split("/").slice(0, 4).join("/");
|
500 | }
|
501 |
|
502 |
|
503 |
|
504 | function trimSlashes(source) {
|
505 | return source.replace(trimLeftSlashes, "").replace(trimRightSlashes, "");
|
506 | }
|
507 |
|
508 |
|
509 |
|
510 | function parsePath(path) {
|
511 | const pathParts = [];
|
512 | let currentIndex = 0;
|
513 | const throwError = () => {
|
514 | throw new Error("Path " + path + " is invalid at index " + currentIndex);
|
515 | };
|
516 | const getEscapedToken = () => {
|
517 | const quote = path[currentIndex];
|
518 | let newIndex = ++currentIndex;
|
519 | for (;;) {
|
520 | newIndex = path.indexOf(quote, newIndex);
|
521 | if (newIndex === -1) {
|
522 | throwError();
|
523 | }
|
524 | if (path[newIndex - 1] !== "\\") {
|
525 | break;
|
526 | }
|
527 | ++newIndex;
|
528 | }
|
529 | const token = path.substr(currentIndex, newIndex - currentIndex);
|
530 | currentIndex = newIndex + 1;
|
531 | return token;
|
532 | };
|
533 | const getToken = () => {
|
534 | const newIndex = path.indexOf("/", currentIndex);
|
535 | let token = null;
|
536 | if (newIndex === -1) {
|
537 | token = path.substr(currentIndex);
|
538 | currentIndex = path.length;
|
539 | }
|
540 | else {
|
541 | token = path.substr(currentIndex, newIndex - currentIndex);
|
542 | currentIndex = newIndex;
|
543 | }
|
544 | token = token.trim();
|
545 | return token;
|
546 | };
|
547 | while (currentIndex < path.length) {
|
548 | if (path[currentIndex] !== "/") {
|
549 | throwError();
|
550 | }
|
551 | if (++currentIndex === path.length) {
|
552 | break;
|
553 | }
|
554 | if (path[currentIndex] === '"' || path[currentIndex] === "'") {
|
555 | pathParts.push(getEscapedToken());
|
556 | }
|
557 | else {
|
558 | pathParts.push(getToken());
|
559 | }
|
560 | }
|
561 | return pathParts;
|
562 | }
|
563 |
|
564 |
|
565 |
|
566 | function isResourceValid(resource, err) {
|
567 |
|
568 | if (resource.id) {
|
569 | if (typeof resource.id !== "string") {
|
570 | err.message = "Id must be a string.";
|
571 | return false;
|
572 | }
|
573 | if (resource.id.indexOf("/") !== -1 ||
|
574 | resource.id.indexOf("\\") !== -1 ||
|
575 | resource.id.indexOf("?") !== -1 ||
|
576 | resource.id.indexOf("#") !== -1) {
|
577 | err.message = "Id contains illegal chars.";
|
578 | return false;
|
579 | }
|
580 | if (resource.id[resource.id.length - 1] === " ") {
|
581 | err.message = "Id ends with a space.";
|
582 | return false;
|
583 | }
|
584 | }
|
585 | return true;
|
586 | }
|
587 |
|
588 |
|
589 |
|
590 | function isItemResourceValid(resource, err) {
|
591 |
|
592 | if (resource.id) {
|
593 | if (typeof resource.id !== "string") {
|
594 | err.message = "Id must be a string.";
|
595 | return false;
|
596 | }
|
597 | if (resource.id.indexOf("/") !== -1 ||
|
598 | resource.id.indexOf("\\") !== -1 ||
|
599 | resource.id.indexOf("#") !== -1) {
|
600 | err.message = "Id contains illegal chars.";
|
601 | return false;
|
602 | }
|
603 | }
|
604 | return true;
|
605 | }
|
606 |
|
607 | function getIdFromLink(resourceLink) {
|
608 | resourceLink = trimSlashes(resourceLink);
|
609 | return resourceLink;
|
610 | }
|
611 |
|
612 | function getPathFromLink(resourceLink, resourceType) {
|
613 | resourceLink = trimSlashes(resourceLink);
|
614 | if (resourceType) {
|
615 | return "/" + encodeURI(resourceLink) + "/" + resourceType;
|
616 | }
|
617 | else {
|
618 | return "/" + encodeURI(resourceLink);
|
619 | }
|
620 | }
|
621 |
|
622 |
|
623 |
|
624 | function isStringNullOrEmpty(inputString) {
|
625 |
|
626 | return !inputString || /^\s*$/.test(inputString);
|
627 | }
|
628 |
|
629 |
|
630 |
|
631 | function trimSlashFromLeftAndRight(inputString) {
|
632 | if (typeof inputString !== "string") {
|
633 | throw new Error("invalid input: input is not string");
|
634 | }
|
635 | return inputString.replace(trimLeftSlashes, "").replace(trimRightSlashes, "");
|
636 | }
|
637 |
|
638 |
|
639 |
|
640 | function validateResourceId(resourceId) {
|
641 |
|
642 | if (typeof resourceId !== "string" || isStringNullOrEmpty(resourceId)) {
|
643 | throw new Error("Resource ID must be a string and cannot be undefined, null or empty");
|
644 | }
|
645 |
|
646 | if (illegalResourceIdCharacters.test(resourceId)) {
|
647 | throw new Error("Illegal characters ['/', '\\', '#', '?'] cannot be used in Resource ID");
|
648 | }
|
649 | return true;
|
650 | }
|
651 |
|
652 |
|
653 |
|
654 | function validateItemResourceId(resourceId) {
|
655 |
|
656 | if (typeof resourceId !== "string" || isStringNullOrEmpty(resourceId)) {
|
657 | throw new Error("Resource ID must be a string and cannot be undefined, null or empty");
|
658 | }
|
659 |
|
660 | if (illegalItemResourceIdCharacters.test(resourceId)) {
|
661 | throw new Error("Illegal characters ['/', '\\', '#'] cannot be used in Resource ID");
|
662 | }
|
663 | return true;
|
664 | }
|
665 |
|
666 |
|
667 |
|
668 | function getResourceIdFromPath(resourcePath) {
|
669 | if (!resourcePath || typeof resourcePath !== "string") {
|
670 | return null;
|
671 | }
|
672 | const trimmedPath = trimSlashFromLeftAndRight(resourcePath);
|
673 | const pathSegments = trimmedPath.split("/");
|
674 |
|
675 | if (pathSegments.length % 2 !== 0) {
|
676 | return null;
|
677 | }
|
678 | return pathSegments[pathSegments.length - 1];
|
679 | }
|
680 |
|
681 |
|
682 |
|
683 | function parseConnectionString(connectionString) {
|
684 | const keyValueStrings = connectionString.split(";");
|
685 | const { AccountEndpoint, AccountKey } = keyValueStrings.reduce((connectionObject, keyValueString) => {
|
686 | const [key, ...value] = keyValueString.split("=");
|
687 | connectionObject[key] = value.join("=");
|
688 | return connectionObject;
|
689 | }, {});
|
690 | if (!AccountEndpoint || !AccountKey) {
|
691 | throw new Error("Could not parse the provided connection string");
|
692 | }
|
693 | return {
|
694 | endpoint: AccountEndpoint,
|
695 | key: AccountKey,
|
696 | };
|
697 | }
|
698 |
|
699 |
|
700 |
|
701 |
|
702 |
|
703 |
|
704 | const StatusCodes = {
|
705 |
|
706 | Ok: 200,
|
707 | Created: 201,
|
708 | Accepted: 202,
|
709 | NoContent: 204,
|
710 | NotModified: 304,
|
711 |
|
712 | BadRequest: 400,
|
713 | Unauthorized: 401,
|
714 | Forbidden: 403,
|
715 | NotFound: 404,
|
716 | MethodNotAllowed: 405,
|
717 | RequestTimeout: 408,
|
718 | Conflict: 409,
|
719 | Gone: 410,
|
720 | PreconditionFailed: 412,
|
721 | RequestEntityTooLarge: 413,
|
722 | TooManyRequests: 429,
|
723 | RetryWith: 449,
|
724 |
|
725 | InternalServerError: 500,
|
726 | ServiceUnavailable: 503,
|
727 |
|
728 | ENOTFOUND: "ENOTFOUND",
|
729 |
|
730 | OperationPaused: 1200,
|
731 | OperationCancelled: 1201,
|
732 | };
|
733 |
|
734 |
|
735 |
|
736 | const SubStatusCodes = {
|
737 | Unknown: 0,
|
738 |
|
739 | CrossPartitionQueryNotServable: 1004,
|
740 |
|
741 | PartitionKeyRangeGone: 1002,
|
742 |
|
743 | ReadSessionNotAvailable: 1002,
|
744 |
|
745 | WriteForbidden: 3,
|
746 | DatabaseAccountNotFound: 1008,
|
747 | };
|
748 |
|
749 |
|
750 |
|
751 |
|
752 |
|
753 |
|
754 |
|
755 |
|
756 |
|
757 |
|
758 |
|
759 | function createDatabaseUri(databaseId) {
|
760 | databaseId = trimSlashFromLeftAndRight(databaseId);
|
761 | validateResourceId(databaseId);
|
762 | return Constants.Path.DatabasesPathSegment + "/" + databaseId;
|
763 | }
|
764 |
|
765 |
|
766 |
|
767 |
|
768 |
|
769 |
|
770 |
|
771 |
|
772 |
|
773 |
|
774 |
|
775 | function createDocumentCollectionUri(databaseId, collectionId) {
|
776 | collectionId = trimSlashFromLeftAndRight(collectionId);
|
777 | validateResourceId(collectionId);
|
778 | return (createDatabaseUri(databaseId) + "/" + Constants.Path.CollectionsPathSegment + "/" + collectionId);
|
779 | }
|
780 |
|
781 |
|
782 |
|
783 |
|
784 |
|
785 |
|
786 |
|
787 |
|
788 |
|
789 |
|
790 | function createUserUri(databaseId, userId) {
|
791 | userId = trimSlashFromLeftAndRight(userId);
|
792 | validateResourceId(userId);
|
793 | return createDatabaseUri(databaseId) + "/" + Constants.Path.UsersPathSegment + "/" + userId;
|
794 | }
|
795 |
|
796 |
|
797 |
|
798 |
|
799 |
|
800 |
|
801 |
|
802 |
|
803 |
|
804 |
|
805 |
|
806 |
|
807 | function createDocumentUri(databaseId, collectionId, documentId) {
|
808 | documentId = trimSlashFromLeftAndRight(documentId);
|
809 | validateItemResourceId(documentId);
|
810 | return (createDocumentCollectionUri(databaseId, collectionId) +
|
811 | "/" +
|
812 | Constants.Path.DocumentsPathSegment +
|
813 | "/" +
|
814 | documentId);
|
815 | }
|
816 |
|
817 |
|
818 |
|
819 |
|
820 |
|
821 |
|
822 |
|
823 |
|
824 |
|
825 |
|
826 | function createPermissionUri(databaseId, userId, permissionId) {
|
827 | permissionId = trimSlashFromLeftAndRight(permissionId);
|
828 | validateResourceId(permissionId);
|
829 | return (createUserUri(databaseId, userId) +
|
830 | "/" +
|
831 | Constants.Path.PermissionsPathSegment +
|
832 | "/" +
|
833 | permissionId);
|
834 | }
|
835 |
|
836 |
|
837 |
|
838 |
|
839 |
|
840 |
|
841 |
|
842 |
|
843 |
|
844 |
|
845 |
|
846 |
|
847 | function createStoredProcedureUri(databaseId, collectionId, storedProcedureId) {
|
848 | storedProcedureId = trimSlashFromLeftAndRight(storedProcedureId);
|
849 | validateResourceId(storedProcedureId);
|
850 | return (createDocumentCollectionUri(databaseId, collectionId) +
|
851 | "/" +
|
852 | Constants.Path.StoredProceduresPathSegment +
|
853 | "/" +
|
854 | storedProcedureId);
|
855 | }
|
856 |
|
857 |
|
858 |
|
859 |
|
860 |
|
861 |
|
862 |
|
863 |
|
864 |
|
865 |
|
866 |
|
867 | function createTriggerUri(databaseId, collectionId, triggerId) {
|
868 | triggerId = trimSlashFromLeftAndRight(triggerId);
|
869 | validateResourceId(triggerId);
|
870 | return (createDocumentCollectionUri(databaseId, collectionId) +
|
871 | "/" +
|
872 | Constants.Path.TriggersPathSegment +
|
873 | "/" +
|
874 | triggerId);
|
875 | }
|
876 |
|
877 |
|
878 |
|
879 |
|
880 |
|
881 |
|
882 |
|
883 |
|
884 |
|
885 |
|
886 |
|
887 | function createUserDefinedFunctionUri(databaseId, collectionId, udfId) {
|
888 | udfId = trimSlashFromLeftAndRight(udfId);
|
889 | validateResourceId(udfId);
|
890 | return (createDocumentCollectionUri(databaseId, collectionId) +
|
891 | "/" +
|
892 | Constants.Path.UserDefinedFunctionsPathSegment +
|
893 | "/" +
|
894 | udfId);
|
895 | }
|
896 |
|
897 |
|
898 |
|
899 |
|
900 |
|
901 | function extractPartitionKey(document, partitionKeyDefinition) {
|
902 | if (partitionKeyDefinition &&
|
903 | partitionKeyDefinition.paths &&
|
904 | partitionKeyDefinition.paths.length > 0) {
|
905 | const partitionKey = [];
|
906 | partitionKeyDefinition.paths.forEach((path) => {
|
907 | const pathParts = parsePath(path);
|
908 | let obj = document;
|
909 | for (const part of pathParts) {
|
910 | if (typeof obj === "object" && part in obj) {
|
911 | obj = obj[part];
|
912 | }
|
913 | else {
|
914 | obj = undefined;
|
915 | break;
|
916 | }
|
917 | }
|
918 | partitionKey.push(obj);
|
919 | });
|
920 | if (partitionKey.length === 1 && partitionKey[0] === undefined) {
|
921 | return undefinedPartitionKey(partitionKeyDefinition);
|
922 | }
|
923 | return partitionKey;
|
924 | }
|
925 | }
|
926 |
|
927 |
|
928 |
|
929 | function undefinedPartitionKey(partitionKeyDefinition) {
|
930 | if (partitionKeyDefinition.systemKey === true) {
|
931 | return [];
|
932 | }
|
933 | else {
|
934 | return [{}];
|
935 | }
|
936 | }
|
937 |
|
938 |
|
939 | async function hmac(key, message) {
|
940 | return crypto.createHmac("sha256", Buffer.from(key, "base64")).update(message).digest("base64");
|
941 | }
|
942 |
|
943 |
|
944 | async function generateHeaders(masterKey, method, resourceType = exports.ResourceType.none, resourceId = "", date = new Date()) {
|
945 | if (masterKey.startsWith("type=sas&")) {
|
946 | return {
|
947 | [Constants.HttpHeaders.Authorization]: encodeURIComponent(masterKey),
|
948 | [Constants.HttpHeaders.XDate]: date.toUTCString(),
|
949 | };
|
950 | }
|
951 | const sig = await signature(masterKey, method, resourceType, resourceId, date);
|
952 | return {
|
953 | [Constants.HttpHeaders.Authorization]: sig,
|
954 | [Constants.HttpHeaders.XDate]: date.toUTCString(),
|
955 | };
|
956 | }
|
957 | async function signature(masterKey, method, resourceType, resourceId = "", date = new Date()) {
|
958 | const type = "master";
|
959 | const version = "1.0";
|
960 | const text = method.toLowerCase() +
|
961 | "\n" +
|
962 | resourceType.toLowerCase() +
|
963 | "\n" +
|
964 | resourceId +
|
965 | "\n" +
|
966 | date.toUTCString().toLowerCase() +
|
967 | "\n" +
|
968 | "" +
|
969 | "\n";
|
970 | const signed = await hmac(masterKey, text);
|
971 | return encodeURIComponent("type=" + type + "&ver=" + version + "&sig=" + signed);
|
972 | }
|
973 |
|
974 |
|
975 |
|
976 |
|
977 |
|
978 | async function setAuthorizationHeader(clientOptions, verb, path, resourceId, resourceType, headers) {
|
979 | if (clientOptions.permissionFeed) {
|
980 | clientOptions.resourceTokens = {};
|
981 | for (const permission of clientOptions.permissionFeed) {
|
982 | const id = getResourceIdFromPath(permission.resource);
|
983 | if (!id) {
|
984 | throw new Error(`authorization error: ${id} \
|
985 | is an invalid resourceId in permissionFeed`);
|
986 | }
|
987 | clientOptions.resourceTokens[id] = permission._token;
|
988 | }
|
989 | }
|
990 | if (clientOptions.key) {
|
991 | await setAuthorizationTokenHeaderUsingMasterKey(verb, resourceId, resourceType, headers, clientOptions.key);
|
992 | }
|
993 | else if (clientOptions.resourceTokens) {
|
994 | headers[Constants.HttpHeaders.Authorization] = encodeURIComponent(getAuthorizationTokenUsingResourceTokens(clientOptions.resourceTokens, path, resourceId));
|
995 | }
|
996 | else if (clientOptions.tokenProvider) {
|
997 | headers[Constants.HttpHeaders.Authorization] = encodeURIComponent(await clientOptions.tokenProvider({ verb, path, resourceId, resourceType, headers }));
|
998 | }
|
999 | }
|
1000 |
|
1001 |
|
1002 |
|
1003 |
|
1004 | async function setAuthorizationTokenHeaderUsingMasterKey(verb, resourceId, resourceType, headers, masterKey) {
|
1005 |
|
1006 | if (resourceType === exports.ResourceType.offer) {
|
1007 | resourceId = resourceId && resourceId.toLowerCase();
|
1008 | }
|
1009 | headers = Object.assign(headers, await generateHeaders(masterKey, verb, resourceType, resourceId));
|
1010 | }
|
1011 |
|
1012 |
|
1013 |
|
1014 |
|
1015 | function getAuthorizationTokenUsingResourceTokens(resourceTokens, path, resourceId) {
|
1016 | if (resourceTokens && Object.keys(resourceTokens).length > 0) {
|
1017 |
|
1018 |
|
1019 |
|
1020 | if (!path && !resourceId) {
|
1021 | return resourceTokens[Object.keys(resourceTokens)[0]];
|
1022 | }
|
1023 |
|
1024 | if (resourceId && resourceTokens[resourceId]) {
|
1025 | return resourceTokens[resourceId];
|
1026 | }
|
1027 |
|
1028 | if (!path || path.length < 4) {
|
1029 |
|
1030 | return null;
|
1031 | }
|
1032 | path = trimSlashFromLeftAndRight(path);
|
1033 | const pathSegments = (path && path.split("/")) || [];
|
1034 |
|
1035 | if (pathSegments.length === 6) {
|
1036 |
|
1037 | const containerPath = pathSegments.slice(0, 4).map(decodeURIComponent).join("/");
|
1038 | if (resourceTokens[containerPath]) {
|
1039 | return resourceTokens[containerPath];
|
1040 | }
|
1041 | }
|
1042 |
|
1043 |
|
1044 |
|
1045 |
|
1046 | let index = pathSegments.length % 2 === 0 ? pathSegments.length - 1 : pathSegments.length - 2;
|
1047 | for (; index > 0; index -= 2) {
|
1048 | const id = decodeURI(pathSegments[index]);
|
1049 | if (resourceTokens[id]) {
|
1050 | return resourceTokens[id];
|
1051 | }
|
1052 | }
|
1053 | }
|
1054 |
|
1055 | return null;
|
1056 | }
|
1057 |
|
1058 |
|
1059 |
|
1060 |
|
1061 |
|
1062 | const defaultLogger = logger$4.createClientLogger("cosmosdb");
|
1063 |
|
1064 |
|
1065 |
|
1066 |
|
1067 |
|
1068 |
|
1069 | function javaScriptFriendlyJSONStringify(s) {
|
1070 |
|
1071 |
|
1072 | return JSON.stringify(s)
|
1073 | .replace(/\u2028/g, "\\u2028")
|
1074 | .replace(/\u2029/g, "\\u2029");
|
1075 | }
|
1076 |
|
1077 | function bodyFromData(data) {
|
1078 | if (typeof data === "object") {
|
1079 | return javaScriptFriendlyJSONStringify(data);
|
1080 | }
|
1081 | return data;
|
1082 | }
|
1083 | const JsonContentType = "application/json";
|
1084 |
|
1085 |
|
1086 |
|
1087 | async function getHeaders({ clientOptions, defaultHeaders, verb, path, resourceId, resourceType, options = {}, partitionKeyRangeId, useMultipleWriteLocations, partitionKey, }) {
|
1088 | const headers = Object.assign({ [Constants.HttpHeaders.ResponseContinuationTokenLimitInKB]: 1, [Constants.HttpHeaders.EnableCrossPartitionQuery]: true }, defaultHeaders);
|
1089 | if (useMultipleWriteLocations) {
|
1090 | headers[Constants.HttpHeaders.ALLOW_MULTIPLE_WRITES] = true;
|
1091 | }
|
1092 | if (options.continuationTokenLimitInKB) {
|
1093 | headers[Constants.HttpHeaders.ResponseContinuationTokenLimitInKB] =
|
1094 | options.continuationTokenLimitInKB;
|
1095 | }
|
1096 | if (options.continuationToken) {
|
1097 | headers[Constants.HttpHeaders.Continuation] = options.continuationToken;
|
1098 | }
|
1099 | else if (options.continuation) {
|
1100 | headers[Constants.HttpHeaders.Continuation] = options.continuation;
|
1101 | }
|
1102 | if (options.preTriggerInclude) {
|
1103 | headers[Constants.HttpHeaders.PreTriggerInclude] =
|
1104 | options.preTriggerInclude.constructor === Array
|
1105 | ? options.preTriggerInclude.join(",")
|
1106 | : options.preTriggerInclude;
|
1107 | }
|
1108 | if (options.postTriggerInclude) {
|
1109 | headers[Constants.HttpHeaders.PostTriggerInclude] =
|
1110 | options.postTriggerInclude.constructor === Array
|
1111 | ? options.postTriggerInclude.join(",")
|
1112 | : options.postTriggerInclude;
|
1113 | }
|
1114 | if (options.offerType) {
|
1115 | headers[Constants.HttpHeaders.OfferType] = options.offerType;
|
1116 | }
|
1117 | if (options.offerThroughput) {
|
1118 | headers[Constants.HttpHeaders.OfferThroughput] = options.offerThroughput;
|
1119 | }
|
1120 | if (options.maxItemCount) {
|
1121 | headers[Constants.HttpHeaders.PageSize] = options.maxItemCount;
|
1122 | }
|
1123 | if (options.accessCondition) {
|
1124 | if (options.accessCondition.type === "IfMatch") {
|
1125 | headers[Constants.HttpHeaders.IfMatch] = options.accessCondition.condition;
|
1126 | }
|
1127 | else {
|
1128 | headers[Constants.HttpHeaders.IfNoneMatch] = options.accessCondition.condition;
|
1129 | }
|
1130 | }
|
1131 | if (options.useIncrementalFeed) {
|
1132 | headers[Constants.HttpHeaders.A_IM] = "Incremental Feed";
|
1133 | }
|
1134 | if (options.indexingDirective) {
|
1135 | headers[Constants.HttpHeaders.IndexingDirective] = options.indexingDirective;
|
1136 | }
|
1137 | if (options.consistencyLevel) {
|
1138 | headers[Constants.HttpHeaders.ConsistencyLevel] = options.consistencyLevel;
|
1139 | }
|
1140 | if (options.maxIntegratedCacheStalenessInMs && resourceType === exports.ResourceType.item) {
|
1141 | if (typeof options.maxIntegratedCacheStalenessInMs === "number") {
|
1142 | headers[Constants.HttpHeaders.DedicatedGatewayPerRequestCacheStaleness] =
|
1143 | options.maxIntegratedCacheStalenessInMs.toString();
|
1144 | }
|
1145 | else {
|
1146 | defaultLogger.error(`RangeError: maxIntegratedCacheStalenessInMs "${options.maxIntegratedCacheStalenessInMs}" is not a valid parameter.`);
|
1147 | headers[Constants.HttpHeaders.DedicatedGatewayPerRequestCacheStaleness] = "null";
|
1148 | }
|
1149 | }
|
1150 | if (options.resourceTokenExpirySeconds) {
|
1151 | headers[Constants.HttpHeaders.ResourceTokenExpiry] = options.resourceTokenExpirySeconds;
|
1152 | }
|
1153 | if (options.sessionToken) {
|
1154 | headers[Constants.HttpHeaders.SessionToken] = options.sessionToken;
|
1155 | }
|
1156 | if (options.enableScanInQuery) {
|
1157 | headers[Constants.HttpHeaders.EnableScanInQuery] = options.enableScanInQuery;
|
1158 | }
|
1159 | if (options.populateQuotaInfo) {
|
1160 | headers[Constants.HttpHeaders.PopulateQuotaInfo] = options.populateQuotaInfo;
|
1161 | }
|
1162 | if (options.populateQueryMetrics) {
|
1163 | headers[Constants.HttpHeaders.PopulateQueryMetrics] = options.populateQueryMetrics;
|
1164 | }
|
1165 | if (options.maxDegreeOfParallelism !== undefined) {
|
1166 | headers[Constants.HttpHeaders.ParallelizeCrossPartitionQuery] = true;
|
1167 | }
|
1168 | if (options.populateQuotaInfo) {
|
1169 | headers[Constants.HttpHeaders.PopulateQuotaInfo] = true;
|
1170 | }
|
1171 | if (partitionKey !== undefined && !headers[Constants.HttpHeaders.PartitionKey]) {
|
1172 | if (partitionKey === null || !Array.isArray(partitionKey)) {
|
1173 | partitionKey = [partitionKey];
|
1174 | }
|
1175 | headers[Constants.HttpHeaders.PartitionKey] = jsonStringifyAndEscapeNonASCII(partitionKey);
|
1176 | }
|
1177 | if (clientOptions.key || clientOptions.tokenProvider) {
|
1178 | headers[Constants.HttpHeaders.XDate] = new Date().toUTCString();
|
1179 | }
|
1180 | if (verb === exports.HTTPMethod.post || verb === exports.HTTPMethod.put) {
|
1181 | if (!headers[Constants.HttpHeaders.ContentType]) {
|
1182 | headers[Constants.HttpHeaders.ContentType] = JsonContentType;
|
1183 | }
|
1184 | }
|
1185 | if (!headers[Constants.HttpHeaders.Accept]) {
|
1186 | headers[Constants.HttpHeaders.Accept] = JsonContentType;
|
1187 | }
|
1188 | if (partitionKeyRangeId !== undefined) {
|
1189 | headers[Constants.HttpHeaders.PartitionKeyRangeID] = partitionKeyRangeId;
|
1190 | }
|
1191 | if (options.enableScriptLogging) {
|
1192 | headers[Constants.HttpHeaders.EnableScriptLogging] = options.enableScriptLogging;
|
1193 | }
|
1194 | if (options.disableRUPerMinuteUsage) {
|
1195 | headers[Constants.HttpHeaders.DisableRUPerMinuteUsage] = true;
|
1196 | }
|
1197 | if (clientOptions.key ||
|
1198 | clientOptions.resourceTokens ||
|
1199 | clientOptions.tokenProvider ||
|
1200 | clientOptions.permissionFeed) {
|
1201 | await setAuthorizationHeader(clientOptions, verb, path, resourceId, resourceType, headers);
|
1202 | }
|
1203 | return headers;
|
1204 | }
|
1205 |
|
1206 |
|
1207 | const uuid$2 = uuid$3.v4;
|
1208 | function isKeyInRange(min, max, key) {
|
1209 | const isAfterMinInclusive = key.localeCompare(min) >= 0;
|
1210 | const isBeforeMax = key.localeCompare(max) < 0;
|
1211 | return isAfterMinInclusive && isBeforeMax;
|
1212 | }
|
1213 | const BulkOperationType = {
|
1214 | Create: "Create",
|
1215 | Upsert: "Upsert",
|
1216 | Read: "Read",
|
1217 | Delete: "Delete",
|
1218 | Replace: "Replace",
|
1219 | Patch: "Patch",
|
1220 | };
|
1221 | function hasResource(operation) {
|
1222 | return (operation.operationType !== "Patch" &&
|
1223 | operation.resourceBody !== undefined);
|
1224 | }
|
1225 | function getPartitionKeyToHash(operation, partitionProperty) {
|
1226 | const toHashKey = hasResource(operation)
|
1227 | ? deepFind(operation.resourceBody, partitionProperty)
|
1228 | : (operation.partitionKey && operation.partitionKey.replace(/[[\]"']/g, "")) ||
|
1229 | operation.partitionKey;
|
1230 |
|
1231 |
|
1232 | if (toHashKey === "{}" && operation.partitionKey === "[{}]") {
|
1233 | return {};
|
1234 | }
|
1235 | if (toHashKey === "null" && operation.partitionKey === "[null]") {
|
1236 | return null;
|
1237 | }
|
1238 | if (toHashKey === "0" && operation.partitionKey === "[0]") {
|
1239 | return 0;
|
1240 | }
|
1241 | return toHashKey;
|
1242 | }
|
1243 | function decorateOperation(operation, definition, options = {}) {
|
1244 | if (operation.operationType === BulkOperationType.Create ||
|
1245 | operation.operationType === BulkOperationType.Upsert) {
|
1246 | if ((operation.resourceBody.id === undefined || operation.resourceBody.id === "") &&
|
1247 | !options.disableAutomaticIdGeneration) {
|
1248 | operation.resourceBody.id = uuid$2();
|
1249 | }
|
1250 | }
|
1251 | if ("partitionKey" in operation) {
|
1252 | const extracted = extractPartitionKey(operation, { paths: ["/partitionKey"] });
|
1253 | return Object.assign(Object.assign({}, operation), { partitionKey: JSON.stringify(extracted) });
|
1254 | }
|
1255 | else if (operation.operationType === BulkOperationType.Create ||
|
1256 | operation.operationType === BulkOperationType.Replace ||
|
1257 | operation.operationType === BulkOperationType.Upsert) {
|
1258 | const pk = extractPartitionKey(operation.resourceBody, definition);
|
1259 | return Object.assign(Object.assign({}, operation), { partitionKey: JSON.stringify(pk) });
|
1260 | }
|
1261 | else if (operation.operationType === BulkOperationType.Read ||
|
1262 | operation.operationType === BulkOperationType.Delete) {
|
1263 | return Object.assign(Object.assign({}, operation), { partitionKey: "[{}]" });
|
1264 | }
|
1265 | return operation;
|
1266 | }
|
1267 |
|
1268 |
|
1269 |
|
1270 |
|
1271 |
|
1272 |
|
1273 |
|
1274 |
|
1275 |
|
1276 | function splitBatchBasedOnBodySize(originalBatch) {
|
1277 | if ((originalBatch === null || originalBatch === void 0 ? void 0 : originalBatch.operations) === undefined || originalBatch.operations.length < 1)
|
1278 | return [];
|
1279 | let currentBatchSize = calculateObjectSizeInBytes(originalBatch.operations[0]);
|
1280 | let currentBatch = Object.assign(Object.assign({}, originalBatch), { operations: [originalBatch.operations[0]], indexes: [originalBatch.indexes[0]] });
|
1281 | const processedBatches = [];
|
1282 | processedBatches.push(currentBatch);
|
1283 | for (let index = 1; index < originalBatch.operations.length; index++) {
|
1284 | const operation = originalBatch.operations[index];
|
1285 | const currentOpSize = calculateObjectSizeInBytes(operation);
|
1286 | if (currentBatchSize + currentOpSize > Constants.DefaultMaxBulkRequestBodySizeInBytes) {
|
1287 | currentBatch = Object.assign(Object.assign({}, originalBatch), { operations: [], indexes: [] });
|
1288 | processedBatches.push(currentBatch);
|
1289 | currentBatchSize = 0;
|
1290 | }
|
1291 | currentBatch.operations.push(operation);
|
1292 | currentBatch.indexes.push(originalBatch.indexes[index]);
|
1293 | currentBatchSize += currentOpSize;
|
1294 | }
|
1295 | return processedBatches;
|
1296 | }
|
1297 |
|
1298 |
|
1299 |
|
1300 |
|
1301 | function calculateObjectSizeInBytes(obj) {
|
1302 | return new TextEncoder().encode(bodyFromData(obj)).length;
|
1303 | }
|
1304 | function decorateBatchOperation(operation, options = {}) {
|
1305 | if (operation.operationType === BulkOperationType.Create ||
|
1306 | operation.operationType === BulkOperationType.Upsert) {
|
1307 | if ((operation.resourceBody.id === undefined || operation.resourceBody.id === "") &&
|
1308 | !options.disableAutomaticIdGeneration) {
|
1309 | operation.resourceBody.id = uuid$2();
|
1310 | }
|
1311 | }
|
1312 | return operation;
|
1313 | }
|
1314 |
|
1315 |
|
1316 |
|
1317 |
|
1318 | function deepFind(document, path) {
|
1319 | const apath = path.split("/");
|
1320 | let h = document;
|
1321 | for (const p of apath) {
|
1322 | if (p in h)
|
1323 | h = h[p];
|
1324 | else {
|
1325 | if (p !== "_partitionKey") {
|
1326 | console.warn(`Partition key not found, using undefined: ${path} at ${p}`);
|
1327 | }
|
1328 | return "{}";
|
1329 | }
|
1330 | }
|
1331 | return h;
|
1332 | }
|
1333 |
|
1334 |
|
1335 |
|
1336 | const PatchOperationType = {
|
1337 | add: "add",
|
1338 | replace: "replace",
|
1339 | remove: "remove",
|
1340 | set: "set",
|
1341 | incr: "incr",
|
1342 | };
|
1343 |
|
1344 | // Copyright (c) Microsoft Corporation.
|
1345 | // Licensed under the MIT license.
|
1346 | /** Determines the connection behavior of the CosmosClient. Note, we currently only support Gateway Mode. */
|
1347 | exports.ConnectionMode = void 0;
|
1348 | (function (ConnectionMode) {
|
1349 |
|
1350 | ConnectionMode[ConnectionMode["Gateway"] = 0] = "Gateway";
|
1351 | })(exports.ConnectionMode || (exports.ConnectionMode = {}));
|
1352 |
|
1353 |
|
1354 |
|
1355 |
|
1356 | const defaultConnectionPolicy = Object.freeze({
|
1357 | connectionMode: exports.ConnectionMode.Gateway,
|
1358 | requestTimeout: 60000,
|
1359 | enableEndpointDiscovery: true,
|
1360 | preferredLocations: [],
|
1361 | retryOptions: {
|
1362 | maxRetryAttemptCount: 9,
|
1363 | fixedRetryIntervalInMilliseconds: 0,
|
1364 | maxWaitTimeInSeconds: 30,
|
1365 | },
|
1366 | useMultipleWriteLocations: true,
|
1367 | endpointRefreshRateInMs: 300000,
|
1368 | enableBackgroundEndpointRefreshing: true,
|
1369 | });
|
1370 |
|
1371 |
|
1372 |
|
1373 |
|
1374 |
|
1375 |
|
1376 |
|
1377 |
|
1378 |
|
1379 |
|
1380 |
|
1381 |
|
1382 | exports.ConsistencyLevel = void 0;
|
1383 | (function (ConsistencyLevel) {
|
1384 | |
1385 |
|
1386 |
|
1387 | ConsistencyLevel["Strong"] = "Strong";
|
1388 | |
1389 |
|
1390 |
|
1391 |
|
1392 | ConsistencyLevel["BoundedStaleness"] = "BoundedStaleness";
|
1393 | |
1394 |
|
1395 |
|
1396 |
|
1397 |
|
1398 | ConsistencyLevel["Session"] = "Session";
|
1399 | |
1400 |
|
1401 |
|
1402 |
|
1403 | ConsistencyLevel["Eventual"] = "Eventual";
|
1404 | |
1405 |
|
1406 |
|
1407 |
|
1408 | ConsistencyLevel["ConsistentPrefix"] = "ConsistentPrefix";
|
1409 | })(exports.ConsistencyLevel || (exports.ConsistencyLevel = {}));
|
1410 |
|
1411 |
|
1412 |
|
1413 |
|
1414 |
|
1415 | class DatabaseAccount {
|
1416 |
|
1417 | constructor(body, headers) {
|
1418 |
|
1419 | this.writableLocations = [];
|
1420 |
|
1421 | this.readableLocations = [];
|
1422 | this.databasesLink = "/dbs/";
|
1423 | this.mediaLink = "/media/";
|
1424 | this.maxMediaStorageUsageInMB = headers[Constants.HttpHeaders.MaxMediaStorageUsageInMB];
|
1425 | this.currentMediaStorageUsageInMB = headers[Constants.HttpHeaders.CurrentMediaStorageUsageInMB];
|
1426 | this.consistencyPolicy = body.userConsistencyPolicy
|
1427 | ? body.userConsistencyPolicy.defaultConsistencyLevel
|
1428 | : exports.ConsistencyLevel.Session;
|
1429 | if (body[Constants.WritableLocations] && body.id !== "localhost") {
|
1430 | this.writableLocations = body[Constants.WritableLocations];
|
1431 | }
|
1432 | if (body[Constants.ReadableLocations] && body.id !== "localhost") {
|
1433 | this.readableLocations = body[Constants.ReadableLocations];
|
1434 | }
|
1435 | if (body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS]) {
|
1436 | this.enableMultipleWritableLocations =
|
1437 | body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === true ||
|
1438 | body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === "true";
|
1439 | }
|
1440 | }
|
1441 | |
1442 |
|
1443 |
|
1444 |
|
1445 | get DatabasesLink() {
|
1446 | return this.databasesLink;
|
1447 | }
|
1448 | |
1449 |
|
1450 |
|
1451 |
|
1452 | get MediaLink() {
|
1453 | return this.mediaLink;
|
1454 | }
|
1455 | |
1456 |
|
1457 |
|
1458 |
|
1459 | get MaxMediaStorageUsageInMB() {
|
1460 | return this.maxMediaStorageUsageInMB;
|
1461 | }
|
1462 | |
1463 |
|
1464 |
|
1465 |
|
1466 |
|
1467 |
|
1468 |
|
1469 |
|
1470 | get CurrentMediaStorageUsageInMB() {
|
1471 | return this.currentMediaStorageUsageInMB;
|
1472 | }
|
1473 | |
1474 |
|
1475 |
|
1476 |
|
1477 | get ConsistencyPolicy() {
|
1478 | return this.consistencyPolicy;
|
1479 | }
|
1480 | }
|
1481 |
|
1482 |
|
1483 |
|
1484 |
|
1485 | exports.DataType = void 0;
|
1486 | (function (DataType) {
|
1487 |
|
1488 | DataType["Number"] = "Number";
|
1489 |
|
1490 | DataType["String"] = "String";
|
1491 |
|
1492 | DataType["Point"] = "Point";
|
1493 |
|
1494 | DataType["LineString"] = "LineString";
|
1495 |
|
1496 | DataType["Polygon"] = "Polygon";
|
1497 |
|
1498 | DataType["MultiPolygon"] = "MultiPolygon";
|
1499 | })(exports.DataType || (exports.DataType = {}));
|
1500 |
|
1501 |
|
1502 |
|
1503 |
|
1504 |
|
1505 |
|
1506 | exports.IndexingMode = void 0;
|
1507 | (function (IndexingMode) {
|
1508 | |
1509 |
|
1510 |
|
1511 |
|
1512 |
|
1513 |
|
1514 | IndexingMode["consistent"] = "consistent";
|
1515 | |
1516 |
|
1517 |
|
1518 |
|
1519 |
|
1520 | IndexingMode["lazy"] = "lazy";
|
1521 |
|
1522 | IndexingMode["none"] = "none";
|
1523 | })(exports.IndexingMode || (exports.IndexingMode = {}));
|
1524 |
|
1525 |
|
1526 | exports.SpatialType = void 0;
|
1527 | (function (SpatialType) {
|
1528 | SpatialType["LineString"] = "LineString";
|
1529 | SpatialType["MultiPolygon"] = "MultiPolygon";
|
1530 | SpatialType["Point"] = "Point";
|
1531 | SpatialType["Polygon"] = "Polygon";
|
1532 | })(exports.SpatialType || (exports.SpatialType = {}));
|
1533 |
|
1534 |
|
1535 |
|
1536 |
|
1537 |
|
1538 |
|
1539 | exports.IndexKind = void 0;
|
1540 | (function (IndexKind) {
|
1541 | |
1542 |
|
1543 |
|
1544 | IndexKind["Range"] = "Range";
|
1545 | |
1546 |
|
1547 |
|
1548 | IndexKind["Spatial"] = "Spatial";
|
1549 | })(exports.IndexKind || (exports.IndexKind = {}));
|
1550 |
|
1551 |
|
1552 |
|
1553 |
|
1554 |
|
1555 |
|
1556 | exports.PermissionMode = void 0;
|
1557 | (function (PermissionMode) {
|
1558 |
|
1559 | PermissionMode["None"] = "none";
|
1560 |
|
1561 | PermissionMode["Read"] = "read";
|
1562 |
|
1563 | PermissionMode["All"] = "all";
|
1564 | })(exports.PermissionMode || (exports.PermissionMode = {}));
|
1565 |
|
1566 |
|
1567 |
|
1568 |
|
1569 |
|
1570 |
|
1571 |
|
1572 | exports.TriggerOperation = void 0;
|
1573 | (function (TriggerOperation) {
|
1574 |
|
1575 | TriggerOperation["All"] = "all";
|
1576 |
|
1577 | TriggerOperation["Create"] = "create";
|
1578 |
|
1579 | TriggerOperation["Update"] = "update";
|
1580 |
|
1581 | TriggerOperation["Delete"] = "delete";
|
1582 |
|
1583 | TriggerOperation["Replace"] = "replace";
|
1584 | })(exports.TriggerOperation || (exports.TriggerOperation = {}));
|
1585 |
|
1586 |
|
1587 |
|
1588 |
|
1589 |
|
1590 |
|
1591 |
|
1592 | exports.TriggerType = void 0;
|
1593 | (function (TriggerType) {
|
1594 |
|
1595 | TriggerType["Pre"] = "pre";
|
1596 |
|
1597 | TriggerType["Post"] = "post";
|
1598 | })(exports.TriggerType || (exports.TriggerType = {}));
|
1599 |
|
1600 |
|
1601 |
|
1602 |
|
1603 |
|
1604 |
|
1605 |
|
1606 | exports.UserDefinedFunctionType = void 0;
|
1607 | (function (UserDefinedFunctionType) {
|
1608 |
|
1609 | UserDefinedFunctionType["Javascript"] = "Javascript";
|
1610 | })(exports.UserDefinedFunctionType || (exports.UserDefinedFunctionType = {}));
|
1611 |
|
1612 |
|
1613 |
|
1614 | exports.GeospatialType = void 0;
|
1615 | (function (GeospatialType) {
|
1616 |
|
1617 | GeospatialType["Geography"] = "Geography";
|
1618 |
|
1619 | GeospatialType["Geometry"] = "Geometry";
|
1620 | })(exports.GeospatialType || (exports.GeospatialType = {}));
|
1621 |
|
1622 | class ErrorResponse extends Error {
|
1623 | }
|
1624 |
|
1625 |
|
1626 | class ResourceResponse {
|
1627 | constructor(resource, headers, statusCode, substatus) {
|
1628 | this.resource = resource;
|
1629 | this.headers = headers;
|
1630 | this.statusCode = statusCode;
|
1631 | this.substatus = substatus;
|
1632 | }
|
1633 | get requestCharge() {
|
1634 | return Number(this.headers[Constants.HttpHeaders.RequestCharge]) || 0;
|
1635 | }
|
1636 | get activityId() {
|
1637 | return this.headers[Constants.HttpHeaders.ActivityId];
|
1638 | }
|
1639 | get etag() {
|
1640 | return this.headers[Constants.HttpHeaders.ETag];
|
1641 | }
|
1642 | }
|
1643 |
|
1644 |
|
1645 | class FeedResponse {
|
1646 | constructor(resources, headers, hasMoreResults) {
|
1647 | this.resources = resources;
|
1648 | this.headers = headers;
|
1649 | this.hasMoreResults = hasMoreResults;
|
1650 | }
|
1651 | get continuation() {
|
1652 | return this.continuationToken;
|
1653 | }
|
1654 | get continuationToken() {
|
1655 | return this.headers[Constants.HttpHeaders.Continuation];
|
1656 | }
|
1657 | get queryMetrics() {
|
1658 | return this.headers[Constants.HttpHeaders.QueryMetrics];
|
1659 | }
|
1660 | get requestCharge() {
|
1661 | return this.headers[Constants.HttpHeaders.RequestCharge];
|
1662 | }
|
1663 | get activityId() {
|
1664 | return this.headers[Constants.HttpHeaders.ActivityId];
|
1665 | }
|
1666 | }
|
1667 |
|
1668 |
|
1669 |
|
1670 |
|
1671 |
|
1672 |
|
1673 | const TimeoutErrorCode = "TimeoutError";
|
1674 | class TimeoutError extends Error {
|
1675 | constructor(message = "Timeout Error") {
|
1676 | super(message);
|
1677 | this.code = TimeoutErrorCode;
|
1678 | this.name = TimeoutErrorCode;
|
1679 | }
|
1680 | }
|
1681 |
|
1682 |
|
1683 |
|
1684 | class ClientSideMetrics {
|
1685 | constructor(requestCharge) {
|
1686 | this.requestCharge = requestCharge;
|
1687 | }
|
1688 | |
1689 |
|
1690 |
|
1691 | add(...clientSideMetricsArray) {
|
1692 | let requestCharge = this.requestCharge;
|
1693 | for (const clientSideMetrics of clientSideMetricsArray) {
|
1694 | if (clientSideMetrics == null) {
|
1695 | throw new Error("clientSideMetrics has null or undefined item(s)");
|
1696 | }
|
1697 | requestCharge += clientSideMetrics.requestCharge;
|
1698 | }
|
1699 | return new ClientSideMetrics(requestCharge);
|
1700 | }
|
1701 | static createFromArray(...clientSideMetricsArray) {
|
1702 | if (clientSideMetricsArray == null) {
|
1703 | throw new Error("clientSideMetricsArray is null or undefined item(s)");
|
1704 | }
|
1705 | return this.zero.add(...clientSideMetricsArray);
|
1706 | }
|
1707 | }
|
1708 | ClientSideMetrics.zero = new ClientSideMetrics(0);
|
1709 |
|
1710 |
|
1711 |
|
1712 | var QueryMetricsConstants = {
|
1713 |
|
1714 | RetrievedDocumentCount: "retrievedDocumentCount",
|
1715 | RetrievedDocumentSize: "retrievedDocumentSize",
|
1716 | OutputDocumentCount: "outputDocumentCount",
|
1717 | OutputDocumentSize: "outputDocumentSize",
|
1718 | IndexHitRatio: "indexUtilizationRatio",
|
1719 | IndexHitDocumentCount: "indexHitDocumentCount",
|
1720 | TotalQueryExecutionTimeInMs: "totalExecutionTimeInMs",
|
1721 |
|
1722 | QueryCompileTimeInMs: "queryCompileTimeInMs",
|
1723 | LogicalPlanBuildTimeInMs: "queryLogicalPlanBuildTimeInMs",
|
1724 | PhysicalPlanBuildTimeInMs: "queryPhysicalPlanBuildTimeInMs",
|
1725 | QueryOptimizationTimeInMs: "queryOptimizationTimeInMs",
|
1726 |
|
1727 | IndexLookupTimeInMs: "indexLookupTimeInMs",
|
1728 | DocumentLoadTimeInMs: "documentLoadTimeInMs",
|
1729 | VMExecutionTimeInMs: "VMExecutionTimeInMs",
|
1730 | DocumentWriteTimeInMs: "writeOutputTimeInMs",
|
1731 |
|
1732 | QueryEngineTimes: "queryEngineTimes",
|
1733 | SystemFunctionExecuteTimeInMs: "systemFunctionExecuteTimeInMs",
|
1734 | UserDefinedFunctionExecutionTimeInMs: "userFunctionExecuteTimeInMs",
|
1735 |
|
1736 | RetrievedDocumentCountText: "Retrieved Document Count",
|
1737 | RetrievedDocumentSizeText: "Retrieved Document Size",
|
1738 | OutputDocumentCountText: "Output Document Count",
|
1739 | OutputDocumentSizeText: "Output Document Size",
|
1740 | IndexUtilizationText: "Index Utilization",
|
1741 | TotalQueryExecutionTimeText: "Total Query Execution Time",
|
1742 |
|
1743 | QueryPreparationTimesText: "Query Preparation Times",
|
1744 | QueryCompileTimeText: "Query Compilation Time",
|
1745 | LogicalPlanBuildTimeText: "Logical Plan Build Time",
|
1746 | PhysicalPlanBuildTimeText: "Physical Plan Build Time",
|
1747 | QueryOptimizationTimeText: "Query Optimization Time",
|
1748 |
|
1749 | QueryEngineTimesText: "Query Engine Times",
|
1750 | IndexLookupTimeText: "Index Lookup Time",
|
1751 | DocumentLoadTimeText: "Document Load Time",
|
1752 | WriteOutputTimeText: "Document Write Time",
|
1753 |
|
1754 | RuntimeExecutionTimesText: "Runtime Execution Times",
|
1755 | TotalExecutionTimeText: "Query Engine Execution Time",
|
1756 | SystemFunctionExecuteTimeText: "System Function Execution Time",
|
1757 | UserDefinedFunctionExecutionTimeText: "User-defined Function Execution Time",
|
1758 |
|
1759 | ClientSideQueryMetricsText: "Client Side Metrics",
|
1760 | RetriesText: "Retry Count",
|
1761 | RequestChargeText: "Request Charge",
|
1762 | FetchExecutionRangesText: "Partition Execution Timeline",
|
1763 | SchedulingMetricsText: "Scheduling Metrics",
|
1764 | };
|
1765 |
|
1766 |
|
1767 |
|
1768 |
|
1769 |
|
1770 |
|
1771 |
|
1772 |
|
1773 | const ticksPerMillisecond = 10000;
|
1774 |
|
1775 | const millisecondsPerTick = 1.0 / ticksPerMillisecond;
|
1776 |
|
1777 | const ticksPerSecond = ticksPerMillisecond * 1000;
|
1778 |
|
1779 | const secondsPerTick = 1.0 / ticksPerSecond;
|
1780 |
|
1781 | const ticksPerMinute = ticksPerSecond * 60;
|
1782 |
|
1783 | const minutesPerTick = 1.0 / ticksPerMinute;
|
1784 |
|
1785 | const ticksPerHour = ticksPerMinute * 60;
|
1786 |
|
1787 | const hoursPerTick = 1.0 / ticksPerHour;
|
1788 |
|
1789 | const ticksPerDay = ticksPerHour * 24;
|
1790 |
|
1791 | const daysPerTick = 1.0 / ticksPerDay;
|
1792 |
|
1793 | const millisPerSecond = 1000;
|
1794 |
|
1795 | const millisPerMinute = millisPerSecond * 60;
|
1796 |
|
1797 | const millisPerHour = millisPerMinute * 60;
|
1798 |
|
1799 | const millisPerDay = millisPerHour * 24;
|
1800 |
|
1801 | const maxMilliSeconds = Number.MAX_SAFE_INTEGER / ticksPerMillisecond;
|
1802 |
|
1803 | const minMilliSeconds = Number.MIN_SAFE_INTEGER / ticksPerMillisecond;
|
1804 |
|
1805 |
|
1806 |
|
1807 |
|
1808 |
|
1809 |
|
1810 |
|
1811 |
|
1812 |
|
1813 |
|
1814 | class TimeSpan {
|
1815 | constructor(days, hours, minutes, seconds, milliseconds) {
|
1816 |
|
1817 | if (!Number.isInteger(days)) {
|
1818 | throw new Error("days is not an integer");
|
1819 | }
|
1820 | if (!Number.isInteger(hours)) {
|
1821 | throw new Error("hours is not an integer");
|
1822 | }
|
1823 | if (!Number.isInteger(minutes)) {
|
1824 | throw new Error("minutes is not an integer");
|
1825 | }
|
1826 | if (!Number.isInteger(seconds)) {
|
1827 | throw new Error("seconds is not an integer");
|
1828 | }
|
1829 | if (!Number.isInteger(milliseconds)) {
|
1830 | throw new Error("milliseconds is not an integer");
|
1831 | }
|
1832 | const totalMilliSeconds = (days * 3600 * 24 + hours * 3600 + minutes * 60 + seconds) * 1000 + milliseconds;
|
1833 | if (totalMilliSeconds > maxMilliSeconds || totalMilliSeconds < minMilliSeconds) {
|
1834 | throw new Error("Total number of milliseconds was either too large or too small");
|
1835 | }
|
1836 | this._ticks = totalMilliSeconds * ticksPerMillisecond;
|
1837 | }
|
1838 | |
1839 |
|
1840 |
|
1841 |
|
1842 | add(ts) {
|
1843 | if (TimeSpan.additionDoesOverflow(this._ticks, ts._ticks)) {
|
1844 | throw new Error("Adding the two timestamps causes an overflow.");
|
1845 | }
|
1846 | const results = this._ticks + ts._ticks;
|
1847 | return TimeSpan.fromTicks(results);
|
1848 | }
|
1849 | |
1850 |
|
1851 |
|
1852 |
|
1853 | subtract(ts) {
|
1854 | if (TimeSpan.subtractionDoesUnderflow(this._ticks, ts._ticks)) {
|
1855 | throw new Error("Subtracting the two timestamps causes an underflow.");
|
1856 | }
|
1857 | const results = this._ticks - ts._ticks;
|
1858 | return TimeSpan.fromTicks(results);
|
1859 | }
|
1860 | |
1861 |
|
1862 |
|
1863 |
|
1864 |
|
1865 | compareTo(value) {
|
1866 | if (value == null) {
|
1867 | return 1;
|
1868 | }
|
1869 | if (!TimeSpan.isTimeSpan(value)) {
|
1870 | throw new Error("Argument must be a TimeSpan object");
|
1871 | }
|
1872 | return TimeSpan.compare(this, value);
|
1873 | }
|
1874 | |
1875 |
|
1876 |
|
1877 | duration() {
|
1878 | return TimeSpan.fromTicks(this._ticks >= 0 ? this._ticks : -this._ticks);
|
1879 | }
|
1880 | |
1881 |
|
1882 |
|
1883 |
|
1884 | equals(value) {
|
1885 | if (TimeSpan.isTimeSpan(value)) {
|
1886 | return this._ticks === value._ticks;
|
1887 | }
|
1888 | return false;
|
1889 | }
|
1890 | |
1891 |
|
1892 |
|
1893 |
|
1894 | negate() {
|
1895 | return TimeSpan.fromTicks(-this._ticks);
|
1896 | }
|
1897 | days() {
|
1898 | return Math.floor(this._ticks / ticksPerDay);
|
1899 | }
|
1900 | hours() {
|
1901 | return Math.floor(this._ticks / ticksPerHour);
|
1902 | }
|
1903 | milliseconds() {
|
1904 | return Math.floor(this._ticks / ticksPerMillisecond);
|
1905 | }
|
1906 | seconds() {
|
1907 | return Math.floor(this._ticks / ticksPerSecond);
|
1908 | }
|
1909 | ticks() {
|
1910 | return this._ticks;
|
1911 | }
|
1912 | totalDays() {
|
1913 | return this._ticks * daysPerTick;
|
1914 | }
|
1915 | totalHours() {
|
1916 | return this._ticks * hoursPerTick;
|
1917 | }
|
1918 | totalMilliseconds() {
|
1919 | return this._ticks * millisecondsPerTick;
|
1920 | }
|
1921 | totalMinutes() {
|
1922 | return this._ticks * minutesPerTick;
|
1923 | }
|
1924 | totalSeconds() {
|
1925 | return this._ticks * secondsPerTick;
|
1926 | }
|
1927 | static fromTicks(value) {
|
1928 | const timeSpan = new TimeSpan(0, 0, 0, 0, 0);
|
1929 | timeSpan._ticks = value;
|
1930 | return timeSpan;
|
1931 | }
|
1932 | static isTimeSpan(timespan) {
|
1933 | return timespan._ticks;
|
1934 | }
|
1935 | static additionDoesOverflow(a, b) {
|
1936 | const c = a + b;
|
1937 | return a !== c - b || b !== c - a;
|
1938 | }
|
1939 | static subtractionDoesUnderflow(a, b) {
|
1940 | const c = a - b;
|
1941 | return a !== c + b || b !== a - c;
|
1942 | }
|
1943 | static compare(t1, t2) {
|
1944 | if (t1._ticks > t2._ticks) {
|
1945 | return 1;
|
1946 | }
|
1947 | if (t1._ticks < t2._ticks) {
|
1948 | return -1;
|
1949 | }
|
1950 | return 0;
|
1951 | }
|
1952 | static interval(value, scale) {
|
1953 | if (isNaN(value)) {
|
1954 | throw new Error("value must be a number");
|
1955 | }
|
1956 | const milliseconds = value * scale;
|
1957 | if (milliseconds > maxMilliSeconds || milliseconds < minMilliSeconds) {
|
1958 | throw new Error("timespan too long");
|
1959 | }
|
1960 | return TimeSpan.fromTicks(Math.floor(milliseconds * ticksPerMillisecond));
|
1961 | }
|
1962 | static fromMilliseconds(value) {
|
1963 | return TimeSpan.interval(value, 1);
|
1964 | }
|
1965 | static fromSeconds(value) {
|
1966 | return TimeSpan.interval(value, millisPerSecond);
|
1967 | }
|
1968 | static fromMinutes(value) {
|
1969 | return TimeSpan.interval(value, millisPerMinute);
|
1970 | }
|
1971 | static fromHours(value) {
|
1972 | return TimeSpan.interval(value, millisPerHour);
|
1973 | }
|
1974 | static fromDays(value) {
|
1975 | return TimeSpan.interval(value, millisPerDay);
|
1976 | }
|
1977 | }
|
1978 | TimeSpan.zero = new TimeSpan(0, 0, 0, 0, 0);
|
1979 | TimeSpan.maxValue = TimeSpan.fromTicks(Number.MAX_SAFE_INTEGER);
|
1980 | TimeSpan.minValue = TimeSpan.fromTicks(Number.MIN_SAFE_INTEGER);
|
1981 |
|
1982 |
|
1983 |
|
1984 |
|
1985 |
|
1986 | function parseDelimitedString(delimitedString) {
|
1987 | if (delimitedString == null) {
|
1988 | throw new Error("delimitedString is null or undefined");
|
1989 | }
|
1990 | const metrics = {};
|
1991 | const headerAttributes = delimitedString.split(";");
|
1992 | for (const attribute of headerAttributes) {
|
1993 | const attributeKeyValue = attribute.split("=");
|
1994 | if (attributeKeyValue.length !== 2) {
|
1995 | throw new Error("recieved a malformed delimited string");
|
1996 | }
|
1997 | const attributeKey = attributeKeyValue[0];
|
1998 | const attributeValue = parseFloat(attributeKeyValue[1]);
|
1999 | metrics[attributeKey] = attributeValue;
|
2000 | }
|
2001 | return metrics;
|
2002 | }
|
2003 |
|
2004 |
|
2005 |
|
2006 | function timeSpanFromMetrics(metrics /* TODO: any */, key) {
|
2007 | if (key in metrics) {
|
2008 | return TimeSpan.fromMilliseconds(metrics[key]);
|
2009 | }
|
2010 | return TimeSpan.zero;
|
2011 | }
|
2012 |
|
2013 |
|
2014 | class QueryPreparationTimes {
|
2015 | constructor(queryCompilationTime, logicalPlanBuildTime, physicalPlanBuildTime, queryOptimizationTime) {
|
2016 | this.queryCompilationTime = queryCompilationTime;
|
2017 | this.logicalPlanBuildTime = logicalPlanBuildTime;
|
2018 | this.physicalPlanBuildTime = physicalPlanBuildTime;
|
2019 | this.queryOptimizationTime = queryOptimizationTime;
|
2020 | }
|
2021 | |
2022 |
|
2023 |
|
2024 | add(...queryPreparationTimesArray) {
|
2025 | let queryCompilationTime = this.queryCompilationTime;
|
2026 | let logicalPlanBuildTime = this.logicalPlanBuildTime;
|
2027 | let physicalPlanBuildTime = this.physicalPlanBuildTime;
|
2028 | let queryOptimizationTime = this.queryOptimizationTime;
|
2029 | for (const queryPreparationTimes of queryPreparationTimesArray) {
|
2030 | if (queryPreparationTimes == null) {
|
2031 | throw new Error("queryPreparationTimesArray has null or undefined item(s)");
|
2032 | }
|
2033 | queryCompilationTime = queryCompilationTime.add(queryPreparationTimes.queryCompilationTime);
|
2034 | logicalPlanBuildTime = logicalPlanBuildTime.add(queryPreparationTimes.logicalPlanBuildTime);
|
2035 | physicalPlanBuildTime = physicalPlanBuildTime.add(queryPreparationTimes.physicalPlanBuildTime);
|
2036 | queryOptimizationTime = queryOptimizationTime.add(queryPreparationTimes.queryOptimizationTime);
|
2037 | }
|
2038 | return new QueryPreparationTimes(queryCompilationTime, logicalPlanBuildTime, physicalPlanBuildTime, queryOptimizationTime);
|
2039 | }
|
2040 | |
2041 |
|
2042 |
|
2043 | toDelimitedString() {
|
2044 | return (`${QueryMetricsConstants.QueryCompileTimeInMs}=${this.queryCompilationTime.totalMilliseconds()};` +
|
2045 | `${QueryMetricsConstants.LogicalPlanBuildTimeInMs}=${this.logicalPlanBuildTime.totalMilliseconds()};` +
|
2046 | `${QueryMetricsConstants.PhysicalPlanBuildTimeInMs}=${this.physicalPlanBuildTime.totalMilliseconds()};` +
|
2047 | `${QueryMetricsConstants.QueryOptimizationTimeInMs}=${this.queryOptimizationTime.totalMilliseconds()}`);
|
2048 | }
|
2049 | |
2050 |
|
2051 |
|
2052 |
|
2053 | static createFromArray(queryPreparationTimesArray) {
|
2054 | if (queryPreparationTimesArray == null) {
|
2055 | throw new Error("queryPreparationTimesArray is null or undefined item(s)");
|
2056 | }
|
2057 | return QueryPreparationTimes.zero.add(...queryPreparationTimesArray);
|
2058 | }
|
2059 | |
2060 |
|
2061 |
|
2062 | static createFromDelimitedString(delimitedString) {
|
2063 | const metrics = parseDelimitedString(delimitedString);
|
2064 | return new QueryPreparationTimes(timeSpanFromMetrics(metrics, QueryMetricsConstants.QueryCompileTimeInMs), timeSpanFromMetrics(metrics, QueryMetricsConstants.LogicalPlanBuildTimeInMs), timeSpanFromMetrics(metrics, QueryMetricsConstants.PhysicalPlanBuildTimeInMs), timeSpanFromMetrics(metrics, QueryMetricsConstants.QueryOptimizationTimeInMs));
|
2065 | }
|
2066 | }
|
2067 | QueryPreparationTimes.zero = new QueryPreparationTimes(TimeSpan.zero, TimeSpan.zero, TimeSpan.zero, TimeSpan.zero);
|
2068 |
|
2069 |
|
2070 | class RuntimeExecutionTimes {
|
2071 | constructor(queryEngineExecutionTime, systemFunctionExecutionTime, userDefinedFunctionExecutionTime) {
|
2072 | this.queryEngineExecutionTime = queryEngineExecutionTime;
|
2073 | this.systemFunctionExecutionTime = systemFunctionExecutionTime;
|
2074 | this.userDefinedFunctionExecutionTime = userDefinedFunctionExecutionTime;
|
2075 | }
|
2076 | |
2077 |
|
2078 |
|
2079 | add(...runtimeExecutionTimesArray) {
|
2080 | let queryEngineExecutionTime = this.queryEngineExecutionTime;
|
2081 | let systemFunctionExecutionTime = this.systemFunctionExecutionTime;
|
2082 | let userDefinedFunctionExecutionTime = this.userDefinedFunctionExecutionTime;
|
2083 | for (const runtimeExecutionTimes of runtimeExecutionTimesArray) {
|
2084 | if (runtimeExecutionTimes == null) {
|
2085 | throw new Error("runtimeExecutionTimes has null or undefined item(s)");
|
2086 | }
|
2087 | queryEngineExecutionTime = queryEngineExecutionTime.add(runtimeExecutionTimes.queryEngineExecutionTime);
|
2088 | systemFunctionExecutionTime = systemFunctionExecutionTime.add(runtimeExecutionTimes.systemFunctionExecutionTime);
|
2089 | userDefinedFunctionExecutionTime = userDefinedFunctionExecutionTime.add(runtimeExecutionTimes.userDefinedFunctionExecutionTime);
|
2090 | }
|
2091 | return new RuntimeExecutionTimes(queryEngineExecutionTime, systemFunctionExecutionTime, userDefinedFunctionExecutionTime);
|
2092 | }
|
2093 | |
2094 |
|
2095 |
|
2096 | toDelimitedString() {
|
2097 | return (`${QueryMetricsConstants.SystemFunctionExecuteTimeInMs}=${this.systemFunctionExecutionTime.totalMilliseconds()};` +
|
2098 | `${QueryMetricsConstants.UserDefinedFunctionExecutionTimeInMs}=${this.userDefinedFunctionExecutionTime.totalMilliseconds()}`);
|
2099 | }
|
2100 | |
2101 |
|
2102 |
|
2103 |
|
2104 | static createFromArray(runtimeExecutionTimesArray) {
|
2105 | if (runtimeExecutionTimesArray == null) {
|
2106 | throw new Error("runtimeExecutionTimesArray is null or undefined item(s)");
|
2107 | }
|
2108 | return RuntimeExecutionTimes.zero.add(...runtimeExecutionTimesArray);
|
2109 | }
|
2110 | |
2111 |
|
2112 |
|
2113 | static createFromDelimitedString(delimitedString) {
|
2114 | const metrics = parseDelimitedString(delimitedString);
|
2115 | const vmExecutionTime = timeSpanFromMetrics(metrics, QueryMetricsConstants.VMExecutionTimeInMs);
|
2116 | const indexLookupTime = timeSpanFromMetrics(metrics, QueryMetricsConstants.IndexLookupTimeInMs);
|
2117 | const documentLoadTime = timeSpanFromMetrics(metrics, QueryMetricsConstants.DocumentLoadTimeInMs);
|
2118 | const documentWriteTime = timeSpanFromMetrics(metrics, QueryMetricsConstants.DocumentWriteTimeInMs);
|
2119 | let queryEngineExecutionTime = TimeSpan.zero;
|
2120 | queryEngineExecutionTime = queryEngineExecutionTime.add(vmExecutionTime);
|
2121 | queryEngineExecutionTime = queryEngineExecutionTime.subtract(indexLookupTime);
|
2122 | queryEngineExecutionTime = queryEngineExecutionTime.subtract(documentLoadTime);
|
2123 | queryEngineExecutionTime = queryEngineExecutionTime.subtract(documentWriteTime);
|
2124 | return new RuntimeExecutionTimes(queryEngineExecutionTime, timeSpanFromMetrics(metrics, QueryMetricsConstants.SystemFunctionExecuteTimeInMs), timeSpanFromMetrics(metrics, QueryMetricsConstants.UserDefinedFunctionExecutionTimeInMs));
|
2125 | }
|
2126 | }
|
2127 | RuntimeExecutionTimes.zero = new RuntimeExecutionTimes(TimeSpan.zero, TimeSpan.zero, TimeSpan.zero);
|
2128 |
|
2129 |
|
2130 | class QueryMetrics {
|
2131 | constructor(retrievedDocumentCount, retrievedDocumentSize, outputDocumentCount, outputDocumentSize, indexHitDocumentCount, totalQueryExecutionTime, queryPreparationTimes, indexLookupTime, documentLoadTime, vmExecutionTime, runtimeExecutionTimes, documentWriteTime, clientSideMetrics) {
|
2132 | this.retrievedDocumentCount = retrievedDocumentCount;
|
2133 | this.retrievedDocumentSize = retrievedDocumentSize;
|
2134 | this.outputDocumentCount = outputDocumentCount;
|
2135 | this.outputDocumentSize = outputDocumentSize;
|
2136 | this.indexHitDocumentCount = indexHitDocumentCount;
|
2137 | this.totalQueryExecutionTime = totalQueryExecutionTime;
|
2138 | this.queryPreparationTimes = queryPreparationTimes;
|
2139 | this.indexLookupTime = indexLookupTime;
|
2140 | this.documentLoadTime = documentLoadTime;
|
2141 | this.vmExecutionTime = vmExecutionTime;
|
2142 | this.runtimeExecutionTimes = runtimeExecutionTimes;
|
2143 | this.documentWriteTime = documentWriteTime;
|
2144 | this.clientSideMetrics = clientSideMetrics;
|
2145 | }
|
2146 | |
2147 |
|
2148 |
|
2149 |
|
2150 | get indexHitRatio() {
|
2151 | return this.retrievedDocumentCount === 0
|
2152 | ? 1
|
2153 | : this.indexHitDocumentCount / this.retrievedDocumentCount;
|
2154 | }
|
2155 | |
2156 |
|
2157 |
|
2158 | add(queryMetricsArray) {
|
2159 | let retrievedDocumentCount = 0;
|
2160 | let retrievedDocumentSize = 0;
|
2161 | let outputDocumentCount = 0;
|
2162 | let outputDocumentSize = 0;
|
2163 | let indexHitDocumentCount = 0;
|
2164 | let totalQueryExecutionTime = TimeSpan.zero;
|
2165 | const queryPreparationTimesArray = [];
|
2166 | let indexLookupTime = TimeSpan.zero;
|
2167 | let documentLoadTime = TimeSpan.zero;
|
2168 | let vmExecutionTime = TimeSpan.zero;
|
2169 | const runtimeExecutionTimesArray = [];
|
2170 | let documentWriteTime = TimeSpan.zero;
|
2171 | const clientSideQueryMetricsArray = [];
|
2172 | queryMetricsArray.push(this);
|
2173 | for (const queryMetrics of queryMetricsArray) {
|
2174 | if (queryMetrics) {
|
2175 | retrievedDocumentCount += queryMetrics.retrievedDocumentCount;
|
2176 | retrievedDocumentSize += queryMetrics.retrievedDocumentSize;
|
2177 | outputDocumentCount += queryMetrics.outputDocumentCount;
|
2178 | outputDocumentSize += queryMetrics.outputDocumentSize;
|
2179 | indexHitDocumentCount += queryMetrics.indexHitDocumentCount;
|
2180 | totalQueryExecutionTime = totalQueryExecutionTime.add(queryMetrics.totalQueryExecutionTime);
|
2181 | queryPreparationTimesArray.push(queryMetrics.queryPreparationTimes);
|
2182 | indexLookupTime = indexLookupTime.add(queryMetrics.indexLookupTime);
|
2183 | documentLoadTime = documentLoadTime.add(queryMetrics.documentLoadTime);
|
2184 | vmExecutionTime = vmExecutionTime.add(queryMetrics.vmExecutionTime);
|
2185 | runtimeExecutionTimesArray.push(queryMetrics.runtimeExecutionTimes);
|
2186 | documentWriteTime = documentWriteTime.add(queryMetrics.documentWriteTime);
|
2187 | clientSideQueryMetricsArray.push(queryMetrics.clientSideMetrics);
|
2188 | }
|
2189 | }
|
2190 | return new QueryMetrics(retrievedDocumentCount, retrievedDocumentSize, outputDocumentCount, outputDocumentSize, indexHitDocumentCount, totalQueryExecutionTime, QueryPreparationTimes.createFromArray(queryPreparationTimesArray), indexLookupTime, documentLoadTime, vmExecutionTime, RuntimeExecutionTimes.createFromArray(runtimeExecutionTimesArray), documentWriteTime, ClientSideMetrics.createFromArray(...clientSideQueryMetricsArray));
|
2191 | }
|
2192 | |
2193 |
|
2194 |
|
2195 |
|
2196 | toDelimitedString() {
|
2197 | return (QueryMetricsConstants.RetrievedDocumentCount +
|
2198 | "=" +
|
2199 | this.retrievedDocumentCount +
|
2200 | ";" +
|
2201 | QueryMetricsConstants.RetrievedDocumentSize +
|
2202 | "=" +
|
2203 | this.retrievedDocumentSize +
|
2204 | ";" +
|
2205 | QueryMetricsConstants.OutputDocumentCount +
|
2206 | "=" +
|
2207 | this.outputDocumentCount +
|
2208 | ";" +
|
2209 | QueryMetricsConstants.OutputDocumentSize +
|
2210 | "=" +
|
2211 | this.outputDocumentSize +
|
2212 | ";" +
|
2213 | QueryMetricsConstants.IndexHitRatio +
|
2214 | "=" +
|
2215 | this.indexHitRatio +
|
2216 | ";" +
|
2217 | QueryMetricsConstants.TotalQueryExecutionTimeInMs +
|
2218 | "=" +
|
2219 | this.totalQueryExecutionTime.totalMilliseconds() +
|
2220 | ";" +
|
2221 | this.queryPreparationTimes.toDelimitedString() +
|
2222 | ";" +
|
2223 | QueryMetricsConstants.IndexLookupTimeInMs +
|
2224 | "=" +
|
2225 | this.indexLookupTime.totalMilliseconds() +
|
2226 | ";" +
|
2227 | QueryMetricsConstants.DocumentLoadTimeInMs +
|
2228 | "=" +
|
2229 | this.documentLoadTime.totalMilliseconds() +
|
2230 | ";" +
|
2231 | QueryMetricsConstants.VMExecutionTimeInMs +
|
2232 | "=" +
|
2233 | this.vmExecutionTime.totalMilliseconds() +
|
2234 | ";" +
|
2235 | this.runtimeExecutionTimes.toDelimitedString() +
|
2236 | ";" +
|
2237 | QueryMetricsConstants.DocumentWriteTimeInMs +
|
2238 | "=" +
|
2239 | this.documentWriteTime.totalMilliseconds());
|
2240 | }
|
2241 | |
2242 |
|
2243 |
|
2244 | static createFromArray(queryMetricsArray) {
|
2245 | if (!queryMetricsArray) {
|
2246 | throw new Error("queryMetricsArray is null or undefined item(s)");
|
2247 | }
|
2248 | return QueryMetrics.zero.add(queryMetricsArray);
|
2249 | }
|
2250 | |
2251 |
|
2252 |
|
2253 | static createFromDelimitedString(delimitedString, clientSideMetrics) {
|
2254 | const metrics = parseDelimitedString(delimitedString);
|
2255 | const indexHitRatio = metrics[QueryMetricsConstants.IndexHitRatio] || 0;
|
2256 | const retrievedDocumentCount = metrics[QueryMetricsConstants.RetrievedDocumentCount] || 0;
|
2257 | const indexHitCount = indexHitRatio * retrievedDocumentCount;
|
2258 | const outputDocumentCount = metrics[QueryMetricsConstants.OutputDocumentCount] || 0;
|
2259 | const outputDocumentSize = metrics[QueryMetricsConstants.OutputDocumentSize] || 0;
|
2260 | const retrievedDocumentSize = metrics[QueryMetricsConstants.RetrievedDocumentSize] || 0;
|
2261 | const totalQueryExecutionTime = timeSpanFromMetrics(metrics, QueryMetricsConstants.TotalQueryExecutionTimeInMs);
|
2262 | return new QueryMetrics(retrievedDocumentCount, retrievedDocumentSize, outputDocumentCount, outputDocumentSize, indexHitCount, totalQueryExecutionTime, QueryPreparationTimes.createFromDelimitedString(delimitedString), timeSpanFromMetrics(metrics, QueryMetricsConstants.IndexLookupTimeInMs), timeSpanFromMetrics(metrics, QueryMetricsConstants.DocumentLoadTimeInMs), timeSpanFromMetrics(metrics, QueryMetricsConstants.VMExecutionTimeInMs), RuntimeExecutionTimes.createFromDelimitedString(delimitedString), timeSpanFromMetrics(metrics, QueryMetricsConstants.DocumentWriteTimeInMs), clientSideMetrics || ClientSideMetrics.zero);
|
2263 | }
|
2264 | }
|
2265 | QueryMetrics.zero = new QueryMetrics(0, 0, 0, 0, 0, TimeSpan.zero, QueryPreparationTimes.zero, TimeSpan.zero, TimeSpan.zero, TimeSpan.zero, RuntimeExecutionTimes.zero, TimeSpan.zero, ClientSideMetrics.zero);
|
2266 |
|
2267 |
|
2268 |
|
2269 |
|
2270 | function getRequestChargeIfAny(headers) {
|
2271 | if (typeof headers === "number") {
|
2272 | return headers;
|
2273 | }
|
2274 | else if (typeof headers === "string") {
|
2275 | return parseFloat(headers);
|
2276 | }
|
2277 | if (headers) {
|
2278 | const rc = headers[Constants.HttpHeaders.RequestCharge];
|
2279 | if (rc) {
|
2280 | return parseFloat(rc);
|
2281 | }
|
2282 | else {
|
2283 | return 0;
|
2284 | }
|
2285 | }
|
2286 | else {
|
2287 | return 0;
|
2288 | }
|
2289 | }
|
2290 |
|
2291 |
|
2292 |
|
2293 | function getInitialHeader() {
|
2294 | const headers = {};
|
2295 | headers[Constants.HttpHeaders.RequestCharge] = 0;
|
2296 | headers[Constants.HttpHeaders.QueryMetrics] = {};
|
2297 | return headers;
|
2298 | }
|
2299 |
|
2300 |
|
2301 |
|
2302 |
|
2303 | function mergeHeaders(headers, toBeMergedHeaders) {
|
2304 | if (headers[Constants.HttpHeaders.RequestCharge] === undefined) {
|
2305 | headers[Constants.HttpHeaders.RequestCharge] = 0;
|
2306 | }
|
2307 | if (headers[Constants.HttpHeaders.QueryMetrics] === undefined) {
|
2308 | headers[Constants.HttpHeaders.QueryMetrics] = QueryMetrics.zero;
|
2309 | }
|
2310 | if (!toBeMergedHeaders) {
|
2311 | return;
|
2312 | }
|
2313 | headers[Constants.HttpHeaders.RequestCharge] += getRequestChargeIfAny(toBeMergedHeaders);
|
2314 | if (toBeMergedHeaders[Constants.HttpHeaders.IsRUPerMinuteUsed]) {
|
2315 | headers[Constants.HttpHeaders.IsRUPerMinuteUsed] =
|
2316 | toBeMergedHeaders[Constants.HttpHeaders.IsRUPerMinuteUsed];
|
2317 | }
|
2318 | if (Constants.HttpHeaders.QueryMetrics in toBeMergedHeaders) {
|
2319 | const headerQueryMetrics = headers[Constants.HttpHeaders.QueryMetrics];
|
2320 | const toBeMergedHeaderQueryMetrics = toBeMergedHeaders[Constants.HttpHeaders.QueryMetrics];
|
2321 | for (const partitionId in toBeMergedHeaderQueryMetrics) {
|
2322 | if (headerQueryMetrics[partitionId]) {
|
2323 | const combinedQueryMetrics = headerQueryMetrics[partitionId].add([
|
2324 | toBeMergedHeaderQueryMetrics[partitionId],
|
2325 | ]);
|
2326 | headerQueryMetrics[partitionId] = combinedQueryMetrics;
|
2327 | }
|
2328 | else {
|
2329 | headerQueryMetrics[partitionId] = toBeMergedHeaderQueryMetrics[partitionId];
|
2330 | }
|
2331 | }
|
2332 | }
|
2333 | }
|
2334 |
|
2335 |
|
2336 | const logger$3 = logger$4.createClientLogger("ClientContext");
|
2337 |
|
2338 | var STATES;
|
2339 | (function (STATES) {
|
2340 | STATES["start"] = "start";
|
2341 | STATES["inProgress"] = "inProgress";
|
2342 | STATES["ended"] = "ended";
|
2343 | })(STATES || (STATES = {}));
|
2344 |
|
2345 | class DefaultQueryExecutionContext {
|
2346 | |
2347 |
|
2348 |
|
2349 |
|
2350 |
|
2351 |
|
2352 |
|
2353 |
|
2354 |
|
2355 |
|
2356 |
|
2357 | constructor(options, fetchFunctions) {
|
2358 | this.resources = [];
|
2359 | this.currentIndex = 0;
|
2360 | this.currentPartitionIndex = 0;
|
2361 | this.fetchFunctions = Array.isArray(fetchFunctions) ? fetchFunctions : [fetchFunctions];
|
2362 | this.options = options || {};
|
2363 | this.continuationToken = this.options.continuationToken || this.options.continuation || null;
|
2364 | this.state = DefaultQueryExecutionContext.STATES.start;
|
2365 | }
|
2366 | get continuation() {
|
2367 | return this.continuationToken;
|
2368 | }
|
2369 | |
2370 |
|
2371 |
|
2372 | async nextItem() {
|
2373 | ++this.currentIndex;
|
2374 | const response = await this.current();
|
2375 | return response;
|
2376 | }
|
2377 | |
2378 |
|
2379 |
|
2380 | async current() {
|
2381 | if (this.currentIndex < this.resources.length) {
|
2382 | return {
|
2383 | result: this.resources[this.currentIndex],
|
2384 | headers: getInitialHeader(),
|
2385 | };
|
2386 | }
|
2387 | if (this._canFetchMore()) {
|
2388 | const { result: resources, headers } = await this.fetchMore();
|
2389 | this.resources = resources;
|
2390 | if (this.resources.length === 0) {
|
2391 | if (!this.continuationToken && this.currentPartitionIndex >= this.fetchFunctions.length) {
|
2392 | this.state = DefaultQueryExecutionContext.STATES.ended;
|
2393 | return { result: undefined, headers };
|
2394 | }
|
2395 | else {
|
2396 | return this.current();
|
2397 | }
|
2398 | }
|
2399 | return { result: this.resources[this.currentIndex], headers };
|
2400 | }
|
2401 | else {
|
2402 | this.state = DefaultQueryExecutionContext.STATES.ended;
|
2403 | return { result: undefined, headers: getInitialHeader() };
|
2404 | }
|
2405 | }
|
2406 | |
2407 |
|
2408 |
|
2409 |
|
2410 |
|
2411 |
|
2412 | hasMoreResults() {
|
2413 | return (this.state === DefaultQueryExecutionContext.STATES.start ||
|
2414 | this.continuationToken !== undefined ||
|
2415 | this.currentIndex < this.resources.length - 1 ||
|
2416 | this.currentPartitionIndex < this.fetchFunctions.length);
|
2417 | }
|
2418 | |
2419 |
|
2420 |
|
2421 | async fetchMore() {
|
2422 | if (this.currentPartitionIndex >= this.fetchFunctions.length) {
|
2423 | return { headers: getInitialHeader(), result: undefined };
|
2424 | }
|
2425 |
|
2426 | const originalContinuation = this.options.continuationToken || this.options.continuation;
|
2427 | this.options.continuationToken = this.continuationToken;
|
2428 |
|
2429 | if (this.currentPartitionIndex >= this.fetchFunctions.length) {
|
2430 | return { headers: getInitialHeader(), result: undefined };
|
2431 | }
|
2432 | let resources;
|
2433 | let responseHeaders;
|
2434 | try {
|
2435 | let p;
|
2436 | if (this.nextFetchFunction !== undefined) {
|
2437 | logger$3.verbose("using prefetch");
|
2438 | p = this.nextFetchFunction;
|
2439 | this.nextFetchFunction = undefined;
|
2440 | }
|
2441 | else {
|
2442 | logger$3.verbose("using fresh fetch");
|
2443 | p = this.fetchFunctions[this.currentPartitionIndex](this.options);
|
2444 | }
|
2445 | const response = await p;
|
2446 | resources = response.result;
|
2447 | responseHeaders = response.headers;
|
2448 | this.continuationToken = responseHeaders[Constants.HttpHeaders.Continuation];
|
2449 | if (!this.continuationToken) {
|
2450 | ++this.currentPartitionIndex;
|
2451 | }
|
2452 | if (this.options && this.options.bufferItems === true) {
|
2453 | const fetchFunction = this.fetchFunctions[this.currentPartitionIndex];
|
2454 | this.nextFetchFunction = fetchFunction
|
2455 | ? fetchFunction(Object.assign(Object.assign({}, this.options), { continuationToken: this.continuationToken }))
|
2456 | : undefined;
|
2457 | }
|
2458 | }
|
2459 | catch (err) {
|
2460 | this.state = DefaultQueryExecutionContext.STATES.ended;
|
2461 |
|
2462 |
|
2463 | throw err;
|
2464 | }
|
2465 | this.state = DefaultQueryExecutionContext.STATES.inProgress;
|
2466 | this.currentIndex = 0;
|
2467 | this.options.continuationToken = originalContinuation;
|
2468 | this.options.continuation = originalContinuation;
|
2469 |
|
2470 | if (Constants.HttpHeaders.QueryMetrics in responseHeaders) {
|
2471 | const delimitedString = responseHeaders[Constants.HttpHeaders.QueryMetrics];
|
2472 | let queryMetrics = QueryMetrics.createFromDelimitedString(delimitedString);
|
2473 |
|
2474 | if (Constants.HttpHeaders.RequestCharge in responseHeaders) {
|
2475 | const requestCharge = Number(responseHeaders[Constants.HttpHeaders.RequestCharge]) || 0;
|
2476 | queryMetrics = new QueryMetrics(queryMetrics.retrievedDocumentCount, queryMetrics.retrievedDocumentSize, queryMetrics.outputDocumentCount, queryMetrics.outputDocumentSize, queryMetrics.indexHitDocumentCount, queryMetrics.totalQueryExecutionTime, queryMetrics.queryPreparationTimes, queryMetrics.indexLookupTime, queryMetrics.documentLoadTime, queryMetrics.vmExecutionTime, queryMetrics.runtimeExecutionTimes, queryMetrics.documentWriteTime, new ClientSideMetrics(requestCharge));
|
2477 | }
|
2478 |
|
2479 |
|
2480 | responseHeaders[Constants.HttpHeaders.QueryMetrics] = {};
|
2481 | responseHeaders[Constants.HttpHeaders.QueryMetrics]["0"] = queryMetrics;
|
2482 | }
|
2483 | return { result: resources, headers: responseHeaders };
|
2484 | }
|
2485 | _canFetchMore() {
|
2486 | const res = this.state === DefaultQueryExecutionContext.STATES.start ||
|
2487 | (this.continuationToken && this.state === DefaultQueryExecutionContext.STATES.inProgress) ||
|
2488 | (this.currentPartitionIndex < this.fetchFunctions.length &&
|
2489 | this.state === DefaultQueryExecutionContext.STATES.inProgress);
|
2490 | return res;
|
2491 | }
|
2492 | }
|
2493 | DefaultQueryExecutionContext.STATES = STATES;
|
2494 |
|
2495 |
|
2496 | class AverageAggregator {
|
2497 | |
2498 |
|
2499 |
|
2500 | aggregate(other) {
|
2501 | if (other == null || other.sum == null) {
|
2502 | return;
|
2503 | }
|
2504 | if (this.sum == null) {
|
2505 | this.sum = 0.0;
|
2506 | this.count = 0;
|
2507 | }
|
2508 | this.sum += other.sum;
|
2509 | this.count += other.count;
|
2510 | }
|
2511 | |
2512 |
|
2513 |
|
2514 | getResult() {
|
2515 | if (this.sum == null || this.count <= 0) {
|
2516 | return undefined;
|
2517 | }
|
2518 | return this.sum / this.count;
|
2519 | }
|
2520 | }
|
2521 |
|
2522 |
|
2523 | class CountAggregator {
|
2524 | |
2525 |
|
2526 |
|
2527 |
|
2528 | constructor() {
|
2529 | this.value = 0;
|
2530 | }
|
2531 | |
2532 |
|
2533 |
|
2534 | aggregate(other) {
|
2535 | this.value += other;
|
2536 | }
|
2537 | |
2538 |
|
2539 |
|
2540 | getResult() {
|
2541 | return this.value;
|
2542 | }
|
2543 | }
|
2544 |
|
2545 |
|
2546 |
|
2547 | const TYPEORDCOMPARATOR = Object.freeze({
|
2548 | NoValue: {
|
2549 | ord: 0,
|
2550 | },
|
2551 | undefined: {
|
2552 | ord: 1,
|
2553 | },
|
2554 | boolean: {
|
2555 | ord: 2,
|
2556 | compFunc: (a, b) => {
|
2557 | return a === b ? 0 : a > b ? 1 : -1;
|
2558 | },
|
2559 | },
|
2560 | number: {
|
2561 | ord: 4,
|
2562 | compFunc: (a, b) => {
|
2563 | return a === b ? 0 : a > b ? 1 : -1;
|
2564 | },
|
2565 | },
|
2566 | string: {
|
2567 | ord: 5,
|
2568 | compFunc: (a, b) => {
|
2569 | return a === b ? 0 : a > b ? 1 : -1;
|
2570 | },
|
2571 | },
|
2572 | });
|
2573 |
|
2574 | class OrderByDocumentProducerComparator {
|
2575 | constructor(sortOrder) {
|
2576 | this.sortOrder = sortOrder;
|
2577 | }
|
2578 | targetPartitionKeyRangeDocProdComparator(docProd1, docProd2) {
|
2579 | const a = docProd1.getTargetParitionKeyRange()["minInclusive"];
|
2580 | const b = docProd2.getTargetParitionKeyRange()["minInclusive"];
|
2581 | return a === b ? 0 : a > b ? 1 : -1;
|
2582 | }
|
2583 | compare(docProd1, docProd2) {
|
2584 |
|
2585 | if (docProd1.gotSplit()) {
|
2586 | return -1;
|
2587 | }
|
2588 | if (docProd2.gotSplit()) {
|
2589 | return 1;
|
2590 | }
|
2591 | const orderByItemsRes1 = this.getOrderByItems(docProd1.peekBufferedItems()[0]);
|
2592 | const orderByItemsRes2 = this.getOrderByItems(docProd2.peekBufferedItems()[0]);
|
2593 |
|
2594 |
|
2595 | this.validateOrderByItems(orderByItemsRes1, orderByItemsRes2);
|
2596 |
|
2597 | for (let i = 0; i < orderByItemsRes1.length; i++) {
|
2598 |
|
2599 | const compRes = this.compareOrderByItem(orderByItemsRes1[i], orderByItemsRes2[i]);
|
2600 | if (compRes !== 0) {
|
2601 | if (this.sortOrder[i] === "Ascending") {
|
2602 | return compRes;
|
2603 | }
|
2604 | else if (this.sortOrder[i] === "Descending") {
|
2605 | return -compRes;
|
2606 | }
|
2607 | }
|
2608 | }
|
2609 | return this.targetPartitionKeyRangeDocProdComparator(docProd1, docProd2);
|
2610 | }
|
2611 |
|
2612 | compareValue(item1, type1, item2, type2) {
|
2613 | if (type1 === "object" || type2 === "object") {
|
2614 | throw new Error("Tried to compare an object type");
|
2615 | }
|
2616 | const type1Ord = TYPEORDCOMPARATOR[type1].ord;
|
2617 | const type2Ord = TYPEORDCOMPARATOR[type2].ord;
|
2618 | const typeCmp = type1Ord - type2Ord;
|
2619 | if (typeCmp !== 0) {
|
2620 |
|
2621 | return typeCmp;
|
2622 | }
|
2623 |
|
2624 | if (type1Ord === TYPEORDCOMPARATOR["undefined"].ord ||
|
2625 | type1Ord === TYPEORDCOMPARATOR["NoValue"].ord) {
|
2626 |
|
2627 | return 0;
|
2628 | }
|
2629 | const compFunc = TYPEORDCOMPARATOR[type1].compFunc;
|
2630 | if (typeof compFunc === "undefined") {
|
2631 | throw new Error("Cannot find the comparison function");
|
2632 | }
|
2633 |
|
2634 | return compFunc(item1, item2);
|
2635 | }
|
2636 | compareOrderByItem(orderByItem1, orderByItem2) {
|
2637 | const type1 = this.getType(orderByItem1);
|
2638 | const type2 = this.getType(orderByItem2);
|
2639 | return this.compareValue(orderByItem1["item"], type1, orderByItem2["item"], type2);
|
2640 | }
|
2641 | validateOrderByItems(res1, res2) {
|
2642 | if (res1.length !== res2.length) {
|
2643 | throw new Error(`Expected ${res1.length}, but got ${res2.length}.`);
|
2644 | }
|
2645 | if (res1.length !== this.sortOrder.length) {
|
2646 | throw new Error("orderByItems cannot have a different size than sort orders.");
|
2647 | }
|
2648 | for (let i = 0; i < this.sortOrder.length; i++) {
|
2649 | const type1 = this.getType(res1[i]);
|
2650 | const type2 = this.getType(res2[i]);
|
2651 | if (type1 !== type2) {
|
2652 | throw new Error(`Expected ${type1}, but got ${type2}. Cannot execute cross partition order-by queries on mixed types. Consider filtering your query using IS_STRING or IS_NUMBER to get around this exception.`);
|
2653 | }
|
2654 | }
|
2655 | }
|
2656 | getType(orderByItem) {
|
2657 |
|
2658 | if (orderByItem === undefined || orderByItem.item === undefined) {
|
2659 | return "NoValue";
|
2660 | }
|
2661 | const type = typeof orderByItem.item;
|
2662 | if (TYPEORDCOMPARATOR[type] === undefined) {
|
2663 | throw new Error(`unrecognizable type ${type}`);
|
2664 | }
|
2665 | return type;
|
2666 | }
|
2667 | getOrderByItems(res) {
|
2668 |
|
2669 | return res["orderByItems"];
|
2670 | }
|
2671 | }
|
2672 |
|
2673 |
|
2674 |
|
2675 | class MaxAggregator {
|
2676 | |
2677 |
|
2678 |
|
2679 |
|
2680 | constructor() {
|
2681 | this.value = undefined;
|
2682 | this.comparer = new OrderByDocumentProducerComparator(["Ascending"]);
|
2683 | }
|
2684 | |
2685 |
|
2686 |
|
2687 | aggregate(other) {
|
2688 | if (this.value === undefined) {
|
2689 | this.value = other.max;
|
2690 | }
|
2691 | else if (this.comparer.compareValue(other.max, typeof other.max, this.value, typeof this.value) > 0) {
|
2692 | this.value = other.max;
|
2693 | }
|
2694 | }
|
2695 | |
2696 |
|
2697 |
|
2698 | getResult() {
|
2699 | return this.value;
|
2700 | }
|
2701 | }
|
2702 |
|
2703 |
|
2704 |
|
2705 | class MinAggregator {
|
2706 | |
2707 |
|
2708 |
|
2709 |
|
2710 | constructor() {
|
2711 | this.value = undefined;
|
2712 | this.comparer = new OrderByDocumentProducerComparator(["Ascending"]);
|
2713 | }
|
2714 | |
2715 |
|
2716 |
|
2717 | aggregate(other) {
|
2718 | if (this.value === undefined) {
|
2719 |
|
2720 | this.value = other.min;
|
2721 | }
|
2722 | else {
|
2723 | const otherType = other.min === null ? "NoValue" : typeof other.min;
|
2724 | const thisType = this.value === null ? "NoValue" : typeof this.value;
|
2725 | if (this.comparer.compareValue(other.min, otherType, this.value, thisType) < 0) {
|
2726 | this.value = other.min;
|
2727 | }
|
2728 | }
|
2729 | }
|
2730 | |
2731 |
|
2732 |
|
2733 | getResult() {
|
2734 | return this.value;
|
2735 | }
|
2736 | }
|
2737 |
|
2738 |
|
2739 | class SumAggregator {
|
2740 | |
2741 |
|
2742 |
|
2743 | aggregate(other) {
|
2744 | if (other === undefined) {
|
2745 | return;
|
2746 | }
|
2747 | if (this.sum === undefined) {
|
2748 | this.sum = other;
|
2749 | }
|
2750 | else {
|
2751 | this.sum += other;
|
2752 | }
|
2753 | }
|
2754 | |
2755 |
|
2756 |
|
2757 | getResult() {
|
2758 | return this.sum;
|
2759 | }
|
2760 | }
|
2761 |
|
2762 |
|
2763 | class StaticValueAggregator {
|
2764 | aggregate(other) {
|
2765 | if (this.value === undefined) {
|
2766 | this.value = other;
|
2767 | }
|
2768 | }
|
2769 | getResult() {
|
2770 | return this.value;
|
2771 | }
|
2772 | }
|
2773 |
|
2774 |
|
2775 | function createAggregator(aggregateType) {
|
2776 | switch (aggregateType) {
|
2777 | case "Average":
|
2778 | return new AverageAggregator();
|
2779 | case "Count":
|
2780 | return new CountAggregator();
|
2781 | case "Max":
|
2782 | return new MaxAggregator();
|
2783 | case "Min":
|
2784 | return new MinAggregator();
|
2785 | case "Sum":
|
2786 | return new SumAggregator();
|
2787 | default:
|
2788 | return new StaticValueAggregator();
|
2789 | }
|
2790 | }
|
2791 |
|
2792 |
|
2793 |
|
2794 |
|
2795 | var FetchResultType;
|
2796 | (function (FetchResultType) {
|
2797 | FetchResultType[FetchResultType["Done"] = 0] = "Done";
|
2798 | FetchResultType[FetchResultType["Exception"] = 1] = "Exception";
|
2799 | FetchResultType[FetchResultType["Result"] = 2] = "Result";
|
2800 | })(FetchResultType || (FetchResultType = {}));
|
2801 |
|
2802 | class FetchResult {
|
2803 | |
2804 |
|
2805 |
|
2806 |
|
2807 |
|
2808 |
|
2809 |
|
2810 |
|
2811 | constructor(feedResponse, error) {
|
2812 |
|
2813 | if (feedResponse !== undefined) {
|
2814 | this.feedResponse = feedResponse;
|
2815 | this.fetchResultType = FetchResultType.Result;
|
2816 | }
|
2817 | else {
|
2818 | this.error = error;
|
2819 | this.fetchResultType = FetchResultType.Exception;
|
2820 | }
|
2821 | }
|
2822 | }
|
2823 |
|
2824 |
|
2825 | class DocumentProducer {
|
2826 | |
2827 |
|
2828 |
|
2829 |
|
2830 |
|
2831 |
|
2832 |
|
2833 |
|
2834 | constructor(clientContext, collectionLink, query, targetPartitionKeyRange, options) {
|
2835 | this.clientContext = clientContext;
|
2836 | this.generation = 0;
|
2837 | this.fetchFunction = async (options) => {
|
2838 | const path = getPathFromLink(this.collectionLink, exports.ResourceType.item);
|
2839 | const id = getIdFromLink(this.collectionLink);
|
2840 | return this.clientContext.queryFeed({
|
2841 | path,
|
2842 | resourceType: exports.ResourceType.item,
|
2843 | resourceId: id,
|
2844 | resultFn: (result) => result.Documents,
|
2845 | query: this.query,
|
2846 | options,
|
2847 | partitionKeyRangeId: this.targetPartitionKeyRange["id"],
|
2848 | });
|
2849 | };
|
2850 |
|
2851 | this.collectionLink = collectionLink;
|
2852 | this.query = query;
|
2853 | this.targetPartitionKeyRange = targetPartitionKeyRange;
|
2854 | this.fetchResults = [];
|
2855 | this.allFetched = false;
|
2856 | this.err = undefined;
|
2857 | this.previousContinuationToken = undefined;
|
2858 | this.continuationToken = undefined;
|
2859 | this.respHeaders = getInitialHeader();
|
2860 | this.internalExecutionContext = new DefaultQueryExecutionContext(options, this.fetchFunction);
|
2861 | }
|
2862 | |
2863 |
|
2864 |
|
2865 |
|
2866 |
|
2867 | peekBufferedItems() {
|
2868 | const bufferedResults = [];
|
2869 | for (let i = 0, done = false; i < this.fetchResults.length && !done; i++) {
|
2870 | const fetchResult = this.fetchResults[i];
|
2871 | switch (fetchResult.fetchResultType) {
|
2872 | case FetchResultType.Done:
|
2873 | done = true;
|
2874 | break;
|
2875 | case FetchResultType.Exception:
|
2876 | done = true;
|
2877 | break;
|
2878 | case FetchResultType.Result:
|
2879 | bufferedResults.push(fetchResult.feedResponse);
|
2880 | break;
|
2881 | }
|
2882 | }
|
2883 | return bufferedResults;
|
2884 | }
|
2885 | hasMoreResults() {
|
2886 | return this.internalExecutionContext.hasMoreResults() || this.fetchResults.length !== 0;
|
2887 | }
|
2888 | gotSplit() {
|
2889 | const fetchResult = this.fetchResults[0];
|
2890 | if (fetchResult.fetchResultType === FetchResultType.Exception) {
|
2891 | if (DocumentProducer._needPartitionKeyRangeCacheRefresh(fetchResult.error)) {
|
2892 | return true;
|
2893 | }
|
2894 | }
|
2895 | return false;
|
2896 | }
|
2897 | _getAndResetActiveResponseHeaders() {
|
2898 | const ret = this.respHeaders;
|
2899 | this.respHeaders = getInitialHeader();
|
2900 | return ret;
|
2901 | }
|
2902 | _updateStates(err, allFetched) {
|
2903 |
|
2904 | if (err) {
|
2905 | this.err = err;
|
2906 | return;
|
2907 | }
|
2908 | if (allFetched) {
|
2909 | this.allFetched = true;
|
2910 | }
|
2911 | if (this.internalExecutionContext.continuationToken === this.continuationToken) {
|
2912 |
|
2913 | return;
|
2914 | }
|
2915 | this.previousContinuationToken = this.continuationToken;
|
2916 | this.continuationToken = this.internalExecutionContext.continuationToken;
|
2917 | }
|
2918 | static _needPartitionKeyRangeCacheRefresh(error) {
|
2919 |
|
2920 | return (error.code === StatusCodes.Gone &&
|
2921 | "substatus" in error &&
|
2922 | error["substatus"] === SubStatusCodes.PartitionKeyRangeGone);
|
2923 | }
|
2924 | |
2925 |
|
2926 |
|
2927 | async bufferMore() {
|
2928 | if (this.err) {
|
2929 | throw this.err;
|
2930 | }
|
2931 | try {
|
2932 | const { result: resources, headers: headerResponse } = await this.internalExecutionContext.fetchMore();
|
2933 | ++this.generation;
|
2934 | this._updateStates(undefined, resources === undefined);
|
2935 | if (resources !== undefined) {
|
2936 |
|
2937 | resources.forEach((element) => {
|
2938 |
|
2939 | this.fetchResults.push(new FetchResult(element, undefined));
|
2940 | });
|
2941 | }
|
2942 |
|
2943 | if (headerResponse != null && Constants.HttpHeaders.QueryMetrics in headerResponse) {
|
2944 |
|
2945 | const queryMetrics = headerResponse[Constants.HttpHeaders.QueryMetrics]["0"];
|
2946 |
|
2947 | headerResponse[Constants.HttpHeaders.QueryMetrics] = {};
|
2948 | headerResponse[Constants.HttpHeaders.QueryMetrics][this.targetPartitionKeyRange.id] =
|
2949 | queryMetrics;
|
2950 | }
|
2951 | return { result: resources, headers: headerResponse };
|
2952 | }
|
2953 | catch (err) {
|
2954 |
|
2955 | if (DocumentProducer._needPartitionKeyRangeCacheRefresh(err)) {
|
2956 |
|
2957 |
|
2958 | const bufferedError = new FetchResult(undefined, err);
|
2959 | this.fetchResults.push(bufferedError);
|
2960 |
|
2961 | return { result: [bufferedError], headers: err.headers };
|
2962 | }
|
2963 | else {
|
2964 | this._updateStates(err, err.resources === undefined);
|
2965 | throw err;
|
2966 | }
|
2967 | }
|
2968 | }
|
2969 | |
2970 |
|
2971 |
|
2972 |
|
2973 |
|
2974 | getTargetParitionKeyRange() {
|
2975 | return this.targetPartitionKeyRange;
|
2976 | }
|
2977 | |
2978 |
|
2979 |
|
2980 | async nextItem() {
|
2981 | if (this.err) {
|
2982 | this._updateStates(this.err, undefined);
|
2983 | throw this.err;
|
2984 | }
|
2985 | try {
|
2986 | const { result, headers } = await this.current();
|
2987 | const fetchResult = this.fetchResults.shift();
|
2988 | this._updateStates(undefined, result === undefined);
|
2989 | if (fetchResult.feedResponse !== result) {
|
2990 | throw new Error(`Expected ${fetchResult.feedResponse} to equal ${result}`);
|
2991 | }
|
2992 | switch (fetchResult.fetchResultType) {
|
2993 | case FetchResultType.Done:
|
2994 | return { result: undefined, headers };
|
2995 | case FetchResultType.Exception:
|
2996 | fetchResult.error.headers = headers;
|
2997 | throw fetchResult.error;
|
2998 | case FetchResultType.Result:
|
2999 | return { result: fetchResult.feedResponse, headers };
|
3000 | }
|
3001 | }
|
3002 | catch (err) {
|
3003 | this._updateStates(err, err.item === undefined);
|
3004 | throw err;
|
3005 | }
|
3006 | }
|
3007 | |
3008 |
|
3009 |
|
3010 | async current() {
|
3011 |
|
3012 | if (this.fetchResults.length > 0) {
|
3013 | const fetchResult = this.fetchResults[0];
|
3014 |
|
3015 | switch (fetchResult.fetchResultType) {
|
3016 | case FetchResultType.Done:
|
3017 | return {
|
3018 | result: undefined,
|
3019 | headers: this._getAndResetActiveResponseHeaders(),
|
3020 | };
|
3021 | case FetchResultType.Exception:
|
3022 | fetchResult.error.headers = this._getAndResetActiveResponseHeaders();
|
3023 | throw fetchResult.error;
|
3024 | case FetchResultType.Result:
|
3025 | return {
|
3026 | result: fetchResult.feedResponse,
|
3027 | headers: this._getAndResetActiveResponseHeaders(),
|
3028 | };
|
3029 | }
|
3030 | }
|
3031 |
|
3032 | if (this.allFetched) {
|
3033 | return {
|
3034 | result: undefined,
|
3035 | headers: this._getAndResetActiveResponseHeaders(),
|
3036 | };
|
3037 | }
|
3038 |
|
3039 | const { result, headers } = await this.bufferMore();
|
3040 | mergeHeaders(this.respHeaders, headers);
|
3041 | if (result === undefined) {
|
3042 | return { result: undefined, headers: this.respHeaders };
|
3043 | }
|
3044 | return this.current();
|
3045 | }
|
3046 | }
|
3047 |
|
3048 |
|
3049 | class QueryRange {
|
3050 | |
3051 |
|
3052 |
|
3053 |
|
3054 |
|
3055 |
|
3056 |
|
3057 |
|
3058 |
|
3059 | constructor(rangeMin, rangeMax, isMinInclusive, isMaxInclusive) {
|
3060 | this.min = rangeMin;
|
3061 | this.max = rangeMax;
|
3062 | this.isMinInclusive = isMinInclusive;
|
3063 | this.isMaxInclusive = isMaxInclusive;
|
3064 | }
|
3065 | overlaps(other) {
|
3066 | const range1 = this;
|
3067 | const range2 = other;
|
3068 | if (range1 === undefined || range2 === undefined) {
|
3069 | return false;
|
3070 | }
|
3071 | if (range1.isEmpty() || range2.isEmpty()) {
|
3072 | return false;
|
3073 | }
|
3074 | if (range1.min <= range2.max || range2.min <= range1.max) {
|
3075 | if ((range1.min === range2.max && !(range1.isMinInclusive && range2.isMaxInclusive)) ||
|
3076 | (range2.min === range1.max && !(range2.isMinInclusive && range1.isMaxInclusive))) {
|
3077 | return false;
|
3078 | }
|
3079 | return true;
|
3080 | }
|
3081 | return false;
|
3082 | }
|
3083 | isFullRange() {
|
3084 | return (this.min === Constants.EffectivePartitionKeyConstants.MinimumInclusiveEffectivePartitionKey &&
|
3085 | this.max === Constants.EffectivePartitionKeyConstants.MaximumExclusiveEffectivePartitionKey &&
|
3086 | this.isMinInclusive === true &&
|
3087 | this.isMaxInclusive === false);
|
3088 | }
|
3089 | isEmpty() {
|
3090 | return !(this.isMinInclusive && this.isMaxInclusive) && this.min === this.max;
|
3091 | }
|
3092 | |
3093 |
|
3094 |
|
3095 |
|
3096 |
|
3097 | static parsePartitionKeyRange(partitionKeyRange) {
|
3098 | return new QueryRange(partitionKeyRange[Constants.PartitionKeyRange.MinInclusive], partitionKeyRange[Constants.PartitionKeyRange.MaxExclusive], true, false);
|
3099 | }
|
3100 | |
3101 |
|
3102 |
|
3103 |
|
3104 |
|
3105 | static parseFromDict(queryRangeDict) {
|
3106 | return new QueryRange(queryRangeDict.min, queryRangeDict.max, queryRangeDict.isMinInclusive, queryRangeDict.isMaxInclusive);
|
3107 | }
|
3108 | }
|
3109 |
|
3110 |
|
3111 | class InMemoryCollectionRoutingMap {
|
3112 | |
3113 |
|
3114 |
|
3115 |
|
3116 |
|
3117 | constructor(orderedPartitionKeyRanges, orderedPartitionInfo) {
|
3118 | this.orderedPartitionKeyRanges = orderedPartitionKeyRanges;
|
3119 | this.orderedRanges = orderedPartitionKeyRanges.map((pkr) => {
|
3120 | return new QueryRange(pkr[Constants.PartitionKeyRange.MinInclusive], pkr[Constants.PartitionKeyRange.MaxExclusive], true, false);
|
3121 | });
|
3122 | this.orderedPartitionInfo = orderedPartitionInfo;
|
3123 | }
|
3124 | getOrderedParitionKeyRanges() {
|
3125 | return this.orderedPartitionKeyRanges;
|
3126 | }
|
3127 | getOverlappingRanges(providedQueryRanges) {
|
3128 |
|
3129 |
|
3130 | const pqr = Array.isArray(providedQueryRanges)
|
3131 | ? providedQueryRanges
|
3132 | : [providedQueryRanges];
|
3133 | const minToPartitionRange = {};
|
3134 |
|
3135 | for (const queryRange of pqr) {
|
3136 | if (queryRange.isEmpty()) {
|
3137 | continue;
|
3138 | }
|
3139 | if (queryRange.isFullRange()) {
|
3140 | return this.orderedPartitionKeyRanges;
|
3141 | }
|
3142 | const minIndex = this.orderedRanges.findIndex((range) => {
|
3143 | if (queryRange.min > range.min && queryRange.min < range.max) {
|
3144 | return true;
|
3145 | }
|
3146 | if (queryRange.min === range.min) {
|
3147 | return true;
|
3148 | }
|
3149 | if (queryRange.min === range.max) {
|
3150 | return true;
|
3151 | }
|
3152 | });
|
3153 | if (minIndex < 0) {
|
3154 | throw new Error("error in collection routing map, queried value is less than the start range.");
|
3155 | }
|
3156 |
|
3157 | let maxIndex;
|
3158 | for (let i = this.orderedRanges.length - 1; i >= 0; i--) {
|
3159 | const range = this.orderedRanges[i];
|
3160 | if (queryRange.max > range.min && queryRange.max < range.max) {
|
3161 | maxIndex = i;
|
3162 | break;
|
3163 | }
|
3164 | if (queryRange.max === range.min) {
|
3165 | maxIndex = i;
|
3166 | break;
|
3167 | }
|
3168 | if (queryRange.max === range.max) {
|
3169 | maxIndex = i;
|
3170 | break;
|
3171 | }
|
3172 | }
|
3173 | if (maxIndex > this.orderedRanges.length) {
|
3174 | throw new Error("error in collection routing map, queried value is greater than the end range.");
|
3175 | }
|
3176 | for (let j = minIndex; j < maxIndex + 1; j++) {
|
3177 | if (queryRange.overlaps(this.orderedRanges[j])) {
|
3178 | minToPartitionRange[this.orderedPartitionKeyRanges[j][Constants.PartitionKeyRange.MinInclusive]] = this.orderedPartitionKeyRanges[j];
|
3179 | }
|
3180 | }
|
3181 | }
|
3182 | const overlappingPartitionKeyRanges = Object.keys(minToPartitionRange).map((k) => minToPartitionRange[k]);
|
3183 | return overlappingPartitionKeyRanges.sort((a, b) => {
|
3184 | return a[Constants.PartitionKeyRange.MinInclusive].localeCompare(b[Constants.PartitionKeyRange.MinInclusive]);
|
3185 | });
|
3186 | }
|
3187 | }
|
3188 |
|
3189 |
|
3190 |
|
3191 |
|
3192 |
|
3193 | function compareRanges(a, b) {
|
3194 | const aVal = a[0][Constants.PartitionKeyRange.MinInclusive];
|
3195 | const bVal = b[0][Constants.PartitionKeyRange.MinInclusive];
|
3196 | if (aVal > bVal) {
|
3197 | return 1;
|
3198 | }
|
3199 | if (aVal < bVal) {
|
3200 | return -1;
|
3201 | }
|
3202 | return 0;
|
3203 | }
|
3204 |
|
3205 | function createCompleteRoutingMap(partitionKeyRangeInfoTuppleList) {
|
3206 | const rangeById = {};
|
3207 | const rangeByInfo = {};
|
3208 | let sortedRanges = [];
|
3209 |
|
3210 | for (const r of partitionKeyRangeInfoTuppleList) {
|
3211 | rangeById[r[0][Constants.PartitionKeyRange.Id]] = r;
|
3212 | rangeByInfo[r[1]] = r[0];
|
3213 | sortedRanges.push(r);
|
3214 | }
|
3215 | sortedRanges = sortedRanges.sort(compareRanges);
|
3216 | const partitionKeyOrderedRange = sortedRanges.map((r) => r[0]);
|
3217 | const orderedPartitionInfo = sortedRanges.map((r) => r[1]);
|
3218 | if (!isCompleteSetOfRange(partitionKeyOrderedRange)) {
|
3219 | return undefined;
|
3220 | }
|
3221 | return new InMemoryCollectionRoutingMap(partitionKeyOrderedRange, orderedPartitionInfo);
|
3222 | }
|
3223 |
|
3224 |
|
3225 |
|
3226 | function isCompleteSetOfRange(partitionKeyOrderedRange) {
|
3227 |
|
3228 | let isComplete = false;
|
3229 | if (partitionKeyOrderedRange.length > 0) {
|
3230 | const firstRange = partitionKeyOrderedRange[0];
|
3231 | const lastRange = partitionKeyOrderedRange[partitionKeyOrderedRange.length - 1];
|
3232 | isComplete =
|
3233 | firstRange[Constants.PartitionKeyRange.MinInclusive] ===
|
3234 | Constants.EffectivePartitionKeyConstants.MinimumInclusiveEffectivePartitionKey;
|
3235 | isComplete =
|
3236 | isComplete &&
|
3237 | lastRange[Constants.PartitionKeyRange.MaxExclusive] ===
|
3238 | Constants.EffectivePartitionKeyConstants.MaximumExclusiveEffectivePartitionKey;
|
3239 | for (let i = 1; i < partitionKeyOrderedRange.length; i++) {
|
3240 | const previousRange = partitionKeyOrderedRange[i - 1];
|
3241 | const currentRange = partitionKeyOrderedRange[i];
|
3242 | isComplete =
|
3243 | isComplete &&
|
3244 | previousRange[Constants.PartitionKeyRange.MaxExclusive] ===
|
3245 | currentRange[Constants.PartitionKeyRange.MinInclusive];
|
3246 | if (!isComplete) {
|
3247 | if (previousRange[Constants.PartitionKeyRange.MaxExclusive] >
|
3248 | currentRange[Constants.PartitionKeyRange.MinInclusive]) {
|
3249 | throw Error("Ranges overlap");
|
3250 | }
|
3251 | break;
|
3252 | }
|
3253 | }
|
3254 | }
|
3255 | return isComplete;
|
3256 | }
|
3257 |
|
3258 |
|
3259 | class PartitionKeyRangeCache {
|
3260 | constructor(clientContext) {
|
3261 | this.clientContext = clientContext;
|
3262 | this.collectionRoutingMapByCollectionId = {};
|
3263 | }
|
3264 | |
3265 |
|
3266 |
|
3267 |
|
3268 |
|
3269 | async onCollectionRoutingMap(collectionLink) {
|
3270 | const collectionId = getIdFromLink(collectionLink);
|
3271 | if (this.collectionRoutingMapByCollectionId[collectionId] === undefined) {
|
3272 | this.collectionRoutingMapByCollectionId[collectionId] =
|
3273 | this.requestCollectionRoutingMap(collectionLink);
|
3274 | }
|
3275 | return this.collectionRoutingMapByCollectionId[collectionId];
|
3276 | }
|
3277 | |
3278 |
|
3279 |
|
3280 |
|
3281 | async getOverlappingRanges(collectionLink, queryRange) {
|
3282 | const crm = await this.onCollectionRoutingMap(collectionLink);
|
3283 | return crm.getOverlappingRanges(queryRange);
|
3284 | }
|
3285 | async requestCollectionRoutingMap(collectionLink) {
|
3286 | const { resources } = await this.clientContext
|
3287 | .queryPartitionKeyRanges(collectionLink)
|
3288 | .fetchAll();
|
3289 | return createCompleteRoutingMap(resources.map((r) => [r, true]));
|
3290 | }
|
3291 | }
|
3292 |
|
3293 |
|
3294 | const PARITIONKEYRANGE = Constants.PartitionKeyRange;
|
3295 |
|
3296 | class SmartRoutingMapProvider {
|
3297 | constructor(clientContext) {
|
3298 | this.partitionKeyRangeCache = new PartitionKeyRangeCache(clientContext);
|
3299 | }
|
3300 | static _secondRangeIsAfterFirstRange(range1, range2) {
|
3301 | if (typeof range1.max === "undefined") {
|
3302 | throw new Error("range1 must have max");
|
3303 | }
|
3304 | if (typeof range2.min === "undefined") {
|
3305 | throw new Error("range2 must have min");
|
3306 | }
|
3307 | if (range1.max > range2.min) {
|
3308 |
|
3309 | return false;
|
3310 | }
|
3311 | else {
|
3312 | if (range1.max === range2.min && range1.isMaxInclusive && range2.isMinInclusive) {
|
3313 |
|
3314 |
|
3315 | return false;
|
3316 | }
|
3317 | return true;
|
3318 | }
|
3319 | }
|
3320 | static _isSortedAndNonOverlapping(ranges) {
|
3321 | for (let idx = 1; idx < ranges.length; idx++) {
|
3322 | const previousR = ranges[idx - 1];
|
3323 | const r = ranges[idx];
|
3324 | if (!this._secondRangeIsAfterFirstRange(previousR, r)) {
|
3325 | return false;
|
3326 | }
|
3327 | }
|
3328 | return true;
|
3329 | }
|
3330 | static _stringMax(a, b) {
|
3331 | return a >= b ? a : b;
|
3332 | }
|
3333 | static _stringCompare(a, b) {
|
3334 | return a === b ? 0 : a > b ? 1 : -1;
|
3335 | }
|
3336 | static _subtractRange(r, partitionKeyRange) {
|
3337 | const left = this._stringMax(partitionKeyRange[PARITIONKEYRANGE.MaxExclusive], r.min);
|
3338 | const leftInclusive = this._stringCompare(left, r.min) === 0 ? r.isMinInclusive : false;
|
3339 | return new QueryRange(left, r.max, leftInclusive, r.isMaxInclusive);
|
3340 | }
|
3341 | |
3342 |
|
3343 |
|
3344 |
|
3345 |
|
3346 |
|
3347 | async getOverlappingRanges(collectionLink, sortedRanges) {
|
3348 |
|
3349 | if (!SmartRoutingMapProvider._isSortedAndNonOverlapping(sortedRanges)) {
|
3350 | throw new Error("the list of ranges is not a non-overlapping sorted ranges");
|
3351 | }
|
3352 | let partitionKeyRanges = [];
|
3353 | if (sortedRanges.length === 0) {
|
3354 | return partitionKeyRanges;
|
3355 | }
|
3356 | const collectionRoutingMap = await this.partitionKeyRangeCache.onCollectionRoutingMap(collectionLink);
|
3357 | let index = 0;
|
3358 | let currentProvidedRange = sortedRanges[index];
|
3359 | for (;;) {
|
3360 | if (currentProvidedRange.isEmpty()) {
|
3361 |
|
3362 | if (++index >= sortedRanges.length) {
|
3363 | return partitionKeyRanges;
|
3364 | }
|
3365 | currentProvidedRange = sortedRanges[index];
|
3366 | continue;
|
3367 | }
|
3368 | let queryRange;
|
3369 | if (partitionKeyRanges.length > 0) {
|
3370 | queryRange = SmartRoutingMapProvider._subtractRange(currentProvidedRange, partitionKeyRanges[partitionKeyRanges.length - 1]);
|
3371 | }
|
3372 | else {
|
3373 | queryRange = currentProvidedRange;
|
3374 | }
|
3375 | const overlappingRanges = collectionRoutingMap.getOverlappingRanges(queryRange);
|
3376 | if (overlappingRanges.length <= 0) {
|
3377 | throw new Error(`error: returned overlapping ranges for queryRange ${queryRange} is empty`);
|
3378 | }
|
3379 | partitionKeyRanges = partitionKeyRanges.concat(overlappingRanges);
|
3380 | const lastKnownTargetRange = QueryRange.parsePartitionKeyRange(partitionKeyRanges[partitionKeyRanges.length - 1]);
|
3381 | if (!lastKnownTargetRange) {
|
3382 | throw new Error("expected lastKnowTargetRange to be truthy");
|
3383 | }
|
3384 |
|
3385 | if (SmartRoutingMapProvider._stringCompare(currentProvidedRange.max, lastKnownTargetRange.max) >
|
3386 | 0) {
|
3387 | throw new Error(`error: returned overlapping ranges ${overlappingRanges} \
|
3388 | does not contain the requested range ${queryRange}`);
|
3389 | }
|
3390 |
|
3391 | if (++index >= sortedRanges.length) {
|
3392 | return partitionKeyRanges;
|
3393 | }
|
3394 | currentProvidedRange = sortedRanges[index];
|
3395 | while (SmartRoutingMapProvider._stringCompare(currentProvidedRange.max, lastKnownTargetRange.max) <= 0) {
|
3396 |
|
3397 | if (++index >= sortedRanges.length) {
|
3398 | return partitionKeyRanges;
|
3399 | }
|
3400 | currentProvidedRange = sortedRanges[index];
|
3401 | }
|
3402 | }
|
3403 | }
|
3404 | }
|
3405 |
|
3406 |
|
3407 |
|
3408 | const logger$2 = logger$4.createClientLogger("parallelQueryExecutionContextBase");
|
3409 |
|
3410 | var ParallelQueryExecutionContextBaseStates;
|
3411 | (function (ParallelQueryExecutionContextBaseStates) {
|
3412 | ParallelQueryExecutionContextBaseStates["started"] = "started";
|
3413 | ParallelQueryExecutionContextBaseStates["inProgress"] = "inProgress";
|
3414 | ParallelQueryExecutionContextBaseStates["ended"] = "ended";
|
3415 | })(ParallelQueryExecutionContextBaseStates || (ParallelQueryExecutionContextBaseStates = {}));
|
3416 |
|
3417 | class ParallelQueryExecutionContextBase {
|
3418 | |
3419 |
|
3420 |
|
3421 |
|
3422 |
|
3423 |
|
3424 |
|
3425 |
|
3426 |
|
3427 |
|
3428 |
|
3429 |
|
3430 |
|
3431 | constructor(clientContext, collectionLink, query, options, partitionedQueryExecutionInfo) {
|
3432 | this.clientContext = clientContext;
|
3433 | this.collectionLink = collectionLink;
|
3434 | this.query = query;
|
3435 | this.options = options;
|
3436 | this.partitionedQueryExecutionInfo = partitionedQueryExecutionInfo;
|
3437 | this.clientContext = clientContext;
|
3438 | this.collectionLink = collectionLink;
|
3439 | this.query = query;
|
3440 | this.options = options;
|
3441 | this.partitionedQueryExecutionInfo = partitionedQueryExecutionInfo;
|
3442 | this.err = undefined;
|
3443 | this.state = ParallelQueryExecutionContextBase.STATES.started;
|
3444 | this.routingProvider = new SmartRoutingMapProvider(this.clientContext);
|
3445 | this.sortOrders = this.partitionedQueryExecutionInfo.queryInfo.orderBy;
|
3446 | this.requestContinuation = options ? options.continuationToken || options.continuation : null;
|
3447 |
|
3448 | this.respHeaders = getInitialHeader();
|
3449 |
|
3450 |
|
3451 | this.orderByPQ = new PriorityQueue__default["default"]((a, b) => this.documentProducerComparator(b, a));
|
3452 |
|
3453 | this.sem = semaphore__default["default"](1);
|
3454 |
|
3455 |
|
3456 | const createDocumentProducersAndFillUpPriorityQueueFunc = async () => {
|
3457 |
|
3458 | try {
|
3459 | const targetPartitionRanges = await this._onTargetPartitionRanges();
|
3460 | this.waitingForInternalExecutionContexts = targetPartitionRanges.length;
|
3461 | const maxDegreeOfParallelism = options.maxDegreeOfParallelism === undefined || options.maxDegreeOfParallelism < 1
|
3462 | ? targetPartitionRanges.length
|
3463 | : Math.min(options.maxDegreeOfParallelism, targetPartitionRanges.length);
|
3464 | logger$2.info("Query starting against " +
|
3465 | targetPartitionRanges.length +
|
3466 | " ranges with parallelism of " +
|
3467 | maxDegreeOfParallelism);
|
3468 | const parallelismSem = semaphore__default["default"](maxDegreeOfParallelism);
|
3469 | let filteredPartitionKeyRanges = [];
|
3470 |
|
3471 | const targetPartitionQueryExecutionContextList = [];
|
3472 | if (this.requestContinuation) {
|
3473 | throw new Error("Continuation tokens are not yet supported for cross partition queries");
|
3474 | }
|
3475 | else {
|
3476 | filteredPartitionKeyRanges = targetPartitionRanges;
|
3477 | }
|
3478 |
|
3479 | filteredPartitionKeyRanges.forEach((partitionTargetRange) => {
|
3480 |
|
3481 |
|
3482 | targetPartitionQueryExecutionContextList.push(this._createTargetPartitionQueryExecutionContext(partitionTargetRange));
|
3483 | });
|
3484 |
|
3485 | targetPartitionQueryExecutionContextList.forEach((documentProducer) => {
|
3486 |
|
3487 | const throttledFunc = async () => {
|
3488 | try {
|
3489 | const { result: document, headers } = await documentProducer.current();
|
3490 | this._mergeWithActiveResponseHeaders(headers);
|
3491 | if (document === undefined) {
|
3492 |
|
3493 | return;
|
3494 | }
|
3495 |
|
3496 | try {
|
3497 | this.orderByPQ.enq(documentProducer);
|
3498 | }
|
3499 | catch (e) {
|
3500 | this.err = e;
|
3501 | }
|
3502 | }
|
3503 | catch (err) {
|
3504 | this._mergeWithActiveResponseHeaders(err.headers);
|
3505 | this.err = err;
|
3506 | }
|
3507 | finally {
|
3508 | parallelismSem.leave();
|
3509 | this._decrementInitiationLock();
|
3510 | }
|
3511 | };
|
3512 | parallelismSem.take(throttledFunc);
|
3513 | });
|
3514 | }
|
3515 | catch (err) {
|
3516 | this.err = err;
|
3517 |
|
3518 | this.sem.leave();
|
3519 | return;
|
3520 | }
|
3521 | };
|
3522 | this.sem.take(createDocumentProducersAndFillUpPriorityQueueFunc);
|
3523 | }
|
3524 | _decrementInitiationLock() {
|
3525 |
|
3526 |
|
3527 | this.waitingForInternalExecutionContexts = this.waitingForInternalExecutionContexts - 1;
|
3528 | if (this.waitingForInternalExecutionContexts === 0) {
|
3529 | this.sem.leave();
|
3530 | if (this.orderByPQ.size() === 0) {
|
3531 | this.state = ParallelQueryExecutionContextBase.STATES.inProgress;
|
3532 | }
|
3533 | }
|
3534 | }
|
3535 | _mergeWithActiveResponseHeaders(headers) {
|
3536 | mergeHeaders(this.respHeaders, headers);
|
3537 | }
|
3538 | _getAndResetActiveResponseHeaders() {
|
3539 | const ret = this.respHeaders;
|
3540 | this.respHeaders = getInitialHeader();
|
3541 | return ret;
|
3542 | }
|
3543 | async _onTargetPartitionRanges() {
|
3544 |
|
3545 | const parsedRanges = this.partitionedQueryExecutionInfo.queryRanges;
|
3546 | const queryRanges = parsedRanges.map((item) => QueryRange.parseFromDict(item));
|
3547 | return this.routingProvider.getOverlappingRanges(this.collectionLink, queryRanges);
|
3548 | }
|
3549 | |
3550 |
|
3551 |
|
3552 | async _getReplacementPartitionKeyRanges(documentProducer) {
|
3553 | const partitionKeyRange = documentProducer.targetPartitionKeyRange;
|
3554 |
|
3555 | this.routingProvider = new SmartRoutingMapProvider(this.clientContext);
|
3556 |
|
3557 | const queryRange = QueryRange.parsePartitionKeyRange(partitionKeyRange);
|
3558 | return this.routingProvider.getOverlappingRanges(this.collectionLink, [queryRange]);
|
3559 | }
|
3560 |
|
3561 | |
3562 |
|
3563 |
|
3564 |
|
3565 |
|
3566 | async _repairExecutionContext(originFunction) {
|
3567 |
|
3568 |
|
3569 |
|
3570 | const parentDocumentProducer = this.orderByPQ.deq();
|
3571 | try {
|
3572 | const replacementPartitionKeyRanges = await this._getReplacementPartitionKeyRanges(parentDocumentProducer);
|
3573 | const replacementDocumentProducers = [];
|
3574 |
|
3575 | replacementPartitionKeyRanges.forEach((partitionKeyRange) => {
|
3576 |
|
3577 | const replacementDocumentProducer = this._createTargetPartitionQueryExecutionContext(partitionKeyRange, parentDocumentProducer.continuationToken);
|
3578 | replacementDocumentProducers.push(replacementDocumentProducer);
|
3579 | });
|
3580 |
|
3581 | const checkAndEnqueueDocumentProducer = async (documentProducerToCheck, checkNextDocumentProducerCallback) => {
|
3582 | try {
|
3583 | const { result: afterItem } = await documentProducerToCheck.current();
|
3584 | if (afterItem === undefined) {
|
3585 |
|
3586 | }
|
3587 | else {
|
3588 |
|
3589 | this.orderByPQ.enq(documentProducerToCheck);
|
3590 | }
|
3591 | await checkNextDocumentProducerCallback();
|
3592 | }
|
3593 | catch (err) {
|
3594 | this.err = err;
|
3595 | return;
|
3596 | }
|
3597 | };
|
3598 | const checkAndEnqueueDocumentProducers = async (rdp) => {
|
3599 | if (rdp.length > 0) {
|
3600 |
|
3601 | const replacementDocumentProducer = rdp.shift();
|
3602 | await checkAndEnqueueDocumentProducer(replacementDocumentProducer, async () => {
|
3603 | await checkAndEnqueueDocumentProducers(rdp);
|
3604 | });
|
3605 | }
|
3606 | else {
|
3607 |
|
3608 | return originFunction();
|
3609 | }
|
3610 | };
|
3611 |
|
3612 | await checkAndEnqueueDocumentProducers(replacementDocumentProducers);
|
3613 | }
|
3614 | catch (err) {
|
3615 | this.err = err;
|
3616 | throw err;
|
3617 | }
|
3618 | }
|
3619 | static _needPartitionKeyRangeCacheRefresh(error) {
|
3620 |
|
3621 | return (error.code === StatusCodes.Gone &&
|
3622 | "substatus" in error &&
|
3623 | error["substatus"] === SubStatusCodes.PartitionKeyRangeGone);
|
3624 | }
|
3625 | |
3626 |
|
3627 |
|
3628 |
|
3629 |
|
3630 | async _repairExecutionContextIfNeeded(ifCallback, elseCallback) {
|
3631 | const documentProducer = this.orderByPQ.peek();
|
3632 |
|
3633 | try {
|
3634 | await documentProducer.current();
|
3635 | elseCallback();
|
3636 | }
|
3637 | catch (err) {
|
3638 | if (ParallelQueryExecutionContextBase._needPartitionKeyRangeCacheRefresh(err)) {
|
3639 |
|
3640 | return this._repairExecutionContext(ifCallback);
|
3641 | }
|
3642 | else {
|
3643 |
|
3644 | this.err = err;
|
3645 | throw err;
|
3646 | }
|
3647 | }
|
3648 | }
|
3649 | |
3650 |
|
3651 |
|
3652 | async nextItem() {
|
3653 | if (this.err) {
|
3654 |
|
3655 | throw this.err;
|
3656 | }
|
3657 | return new Promise((resolve, reject) => {
|
3658 | this.sem.take(() => {
|
3659 |
|
3660 | if (this.err) {
|
3661 |
|
3662 | this.sem.leave();
|
3663 |
|
3664 | this.err.headers = this._getAndResetActiveResponseHeaders();
|
3665 | reject(this.err);
|
3666 | return;
|
3667 | }
|
3668 | if (this.orderByPQ.size() === 0) {
|
3669 |
|
3670 | this.state = ParallelQueryExecutionContextBase.STATES.ended;
|
3671 |
|
3672 | this.sem.leave();
|
3673 | return resolve({
|
3674 | result: undefined,
|
3675 | headers: this._getAndResetActiveResponseHeaders(),
|
3676 | });
|
3677 | }
|
3678 | const ifCallback = () => {
|
3679 |
|
3680 | this.sem.leave();
|
3681 |
|
3682 | return resolve(this.nextItem());
|
3683 | };
|
3684 | const elseCallback = async () => {
|
3685 | let documentProducer;
|
3686 | try {
|
3687 | documentProducer = this.orderByPQ.deq();
|
3688 | }
|
3689 | catch (e) {
|
3690 |
|
3691 |
|
3692 | this.err = e;
|
3693 |
|
3694 | this.sem.leave();
|
3695 | this.err.headers = this._getAndResetActiveResponseHeaders();
|
3696 | reject(this.err);
|
3697 | return;
|
3698 | }
|
3699 | let item;
|
3700 | let headers;
|
3701 | try {
|
3702 | const response = await documentProducer.nextItem();
|
3703 | item = response.result;
|
3704 | headers = response.headers;
|
3705 | this._mergeWithActiveResponseHeaders(headers);
|
3706 | if (item === undefined) {
|
3707 |
|
3708 |
|
3709 |
|
3710 | this.err = new Error(`Extracted DocumentProducer from the priority queue \
|
3711 | doesn't have any buffered item!`);
|
3712 |
|
3713 | this.sem.leave();
|
3714 | return resolve({
|
3715 | result: undefined,
|
3716 | headers: this._getAndResetActiveResponseHeaders(),
|
3717 | });
|
3718 | }
|
3719 | }
|
3720 | catch (err) {
|
3721 | this.err = new Error(`Extracted DocumentProducer from the priority queue fails to get the \
|
3722 | buffered item. Due to ${JSON.stringify(err)}`);
|
3723 | this.err.headers = this._getAndResetActiveResponseHeaders();
|
3724 |
|
3725 | this.sem.leave();
|
3726 | reject(this.err);
|
3727 | return;
|
3728 | }
|
3729 |
|
3730 |
|
3731 | try {
|
3732 | const { result: afterItem, headers: otherHeaders } = await documentProducer.current();
|
3733 | this._mergeWithActiveResponseHeaders(otherHeaders);
|
3734 | if (afterItem === undefined) {
|
3735 |
|
3736 | }
|
3737 | else {
|
3738 | try {
|
3739 | const headItem = documentProducer.fetchResults[0];
|
3740 | if (typeof headItem === "undefined") {
|
3741 | throw new Error("Extracted DocumentProducer from PQ is invalid state with no result!");
|
3742 | }
|
3743 | this.orderByPQ.enq(documentProducer);
|
3744 | }
|
3745 | catch (e) {
|
3746 |
|
3747 |
|
3748 | this.err = e;
|
3749 | }
|
3750 | }
|
3751 | }
|
3752 | catch (err) {
|
3753 | if (ParallelQueryExecutionContextBase._needPartitionKeyRangeCacheRefresh(err)) {
|
3754 |
|
3755 |
|
3756 | this.orderByPQ.enq(documentProducer);
|
3757 | }
|
3758 | else {
|
3759 |
|
3760 | this.err = err;
|
3761 | reject(this.err);
|
3762 | }
|
3763 | }
|
3764 | finally {
|
3765 |
|
3766 | this.sem.leave();
|
3767 | }
|
3768 |
|
3769 | return resolve({
|
3770 | result: item,
|
3771 | headers: this._getAndResetActiveResponseHeaders(),
|
3772 | });
|
3773 | };
|
3774 | this._repairExecutionContextIfNeeded(ifCallback, elseCallback).catch(reject);
|
3775 | });
|
3776 | });
|
3777 | }
|
3778 | |
3779 |
|
3780 |
|
3781 |
|
3782 |
|
3783 | hasMoreResults() {
|
3784 | return !(this.state === ParallelQueryExecutionContextBase.STATES.ended || this.err !== undefined);
|
3785 | }
|
3786 | |
3787 |
|
3788 |
|
3789 | _createTargetPartitionQueryExecutionContext(partitionKeyTargetRange, continuationToken) {
|
3790 |
|
3791 |
|
3792 | let rewrittenQuery = this.partitionedQueryExecutionInfo.queryInfo.rewrittenQuery;
|
3793 | let sqlQuerySpec;
|
3794 | const query = this.query;
|
3795 | if (typeof query === "string") {
|
3796 | sqlQuerySpec = { query };
|
3797 | }
|
3798 | else {
|
3799 | sqlQuerySpec = query;
|
3800 | }
|
3801 | const formatPlaceHolder = "{documentdb-formattableorderbyquery-filter}";
|
3802 | if (rewrittenQuery) {
|
3803 | sqlQuerySpec = JSON.parse(JSON.stringify(sqlQuerySpec));
|
3804 |
|
3805 | rewrittenQuery = rewrittenQuery.replace(formatPlaceHolder, "true");
|
3806 | sqlQuerySpec["query"] = rewrittenQuery;
|
3807 | }
|
3808 | const options = Object.assign({}, this.options);
|
3809 | options.continuationToken = continuationToken;
|
3810 | return new DocumentProducer(this.clientContext, this.collectionLink, sqlQuerySpec, partitionKeyTargetRange, options);
|
3811 | }
|
3812 | }
|
3813 | ParallelQueryExecutionContextBase.STATES = ParallelQueryExecutionContextBaseStates;
|
3814 |
|
3815 |
|
3816 |
|
3817 |
|
3818 |
|
3819 |
|
3820 |
|
3821 | class ParallelQueryExecutionContext extends ParallelQueryExecutionContextBase {
|
3822 |
|
3823 |
|
3824 | |
3825 |
|
3826 |
|
3827 |
|
3828 |
|
3829 | documentProducerComparator(docProd1, docProd2) {
|
3830 | return docProd1.generation - docProd2.generation;
|
3831 | }
|
3832 | }
|
3833 |
|
3834 |
|
3835 | class OrderByQueryExecutionContext extends ParallelQueryExecutionContextBase {
|
3836 | |
3837 |
|
3838 |
|
3839 |
|
3840 |
|
3841 |
|
3842 |
|
3843 |
|
3844 |
|
3845 |
|
3846 |
|
3847 |
|
3848 |
|
3849 | constructor(clientContext, collectionLink, query, options, partitionedQueryExecutionInfo) {
|
3850 |
|
3851 | super(clientContext, collectionLink, query, options, partitionedQueryExecutionInfo);
|
3852 | this.orderByComparator = new OrderByDocumentProducerComparator(this.sortOrders);
|
3853 | }
|
3854 |
|
3855 |
|
3856 | |
3857 |
|
3858 |
|
3859 |
|
3860 |
|
3861 | documentProducerComparator(docProd1, docProd2) {
|
3862 | return this.orderByComparator.compare(docProd1, docProd2);
|
3863 | }
|
3864 | }
|
3865 |
|
3866 |
|
3867 | class OffsetLimitEndpointComponent {
|
3868 | constructor(executionContext, offset, limit) {
|
3869 | this.executionContext = executionContext;
|
3870 | this.offset = offset;
|
3871 | this.limit = limit;
|
3872 | }
|
3873 | async nextItem() {
|
3874 | const aggregateHeaders = getInitialHeader();
|
3875 | while (this.offset > 0) {
|
3876 |
|
3877 | const { headers } = await this.executionContext.nextItem();
|
3878 | this.offset--;
|
3879 | mergeHeaders(aggregateHeaders, headers);
|
3880 | }
|
3881 | if (this.limit > 0) {
|
3882 | const { result, headers } = await this.executionContext.nextItem();
|
3883 | this.limit--;
|
3884 | mergeHeaders(aggregateHeaders, headers);
|
3885 | return { result, headers: aggregateHeaders };
|
3886 | }
|
3887 |
|
3888 | return { result: undefined, headers: getInitialHeader() };
|
3889 | }
|
3890 | hasMoreResults() {
|
3891 | return (this.offset > 0 || this.limit > 0) && this.executionContext.hasMoreResults();
|
3892 | }
|
3893 | }
|
3894 |
|
3895 |
|
3896 | class OrderByEndpointComponent {
|
3897 | |
3898 |
|
3899 |
|
3900 |
|
3901 |
|
3902 |
|
3903 |
|
3904 | constructor(executionContext) {
|
3905 | this.executionContext = executionContext;
|
3906 | }
|
3907 | |
3908 |
|
3909 |
|
3910 | async nextItem() {
|
3911 | const { result: item, headers } = await this.executionContext.nextItem();
|
3912 | return {
|
3913 | result: item !== undefined ? item.payload : undefined,
|
3914 | headers,
|
3915 | };
|
3916 | }
|
3917 | |
3918 |
|
3919 |
|
3920 |
|
3921 | hasMoreResults() {
|
3922 | return this.executionContext.hasMoreResults();
|
3923 | }
|
3924 | }
|
3925 |
|
3926 |
|
3927 | async function digest(str) {
|
3928 | const hash = crypto.createHash("sha256");
|
3929 | hash.update(str, "utf8");
|
3930 | return hash.digest("hex");
|
3931 | }
|
3932 |
|
3933 |
|
3934 | async function hashObject(object) {
|
3935 | const stringifiedObject = stableStringify__default["default"](object);
|
3936 | return digest(stringifiedObject);
|
3937 | }
|
3938 |
|
3939 |
|
3940 | class OrderedDistinctEndpointComponent {
|
3941 | constructor(executionContext) {
|
3942 | this.executionContext = executionContext;
|
3943 | }
|
3944 | async nextItem() {
|
3945 | const { headers, result } = await this.executionContext.nextItem();
|
3946 | if (result) {
|
3947 | const hashedResult = await hashObject(result);
|
3948 | if (hashedResult === this.hashedLastResult) {
|
3949 | return { result: undefined, headers };
|
3950 | }
|
3951 | this.hashedLastResult = hashedResult;
|
3952 | }
|
3953 | return { result, headers };
|
3954 | }
|
3955 | hasMoreResults() {
|
3956 | return this.executionContext.hasMoreResults();
|
3957 | }
|
3958 | }
|
3959 |
|
3960 |
|
3961 | class UnorderedDistinctEndpointComponent {
|
3962 | constructor(executionContext) {
|
3963 | this.executionContext = executionContext;
|
3964 | this.hashedResults = new Set();
|
3965 | }
|
3966 | async nextItem() {
|
3967 | const { headers, result } = await this.executionContext.nextItem();
|
3968 | if (result) {
|
3969 | const hashedResult = await hashObject(result);
|
3970 | if (this.hashedResults.has(hashedResult)) {
|
3971 | return { result: undefined, headers };
|
3972 | }
|
3973 | this.hashedResults.add(hashedResult);
|
3974 | }
|
3975 | return { result, headers };
|
3976 | }
|
3977 | hasMoreResults() {
|
3978 | return this.executionContext.hasMoreResults();
|
3979 | }
|
3980 | }
|
3981 |
|
3982 |
|
3983 |
|
3984 |
|
3985 |
|
3986 | const emptyGroup = "__empty__";
|
3987 |
|
3988 |
|
3989 | const extractAggregateResult = (payload) => Object.keys(payload).length > 0 ? (payload.item2 ? payload.item2 : payload.item) : null;
|
3990 |
|
3991 |
|
3992 | class GroupByEndpointComponent {
|
3993 | constructor(executionContext, queryInfo) {
|
3994 | this.executionContext = executionContext;
|
3995 | this.queryInfo = queryInfo;
|
3996 | this.groupings = new Map();
|
3997 | this.aggregateResultArray = [];
|
3998 | this.completed = false;
|
3999 | }
|
4000 | async nextItem() {
|
4001 |
|
4002 | if (this.aggregateResultArray.length > 0) {
|
4003 | return { result: this.aggregateResultArray.pop(), headers: getInitialHeader() };
|
4004 | }
|
4005 | if (this.completed) {
|
4006 | return { result: undefined, headers: getInitialHeader() };
|
4007 | }
|
4008 | const aggregateHeaders = getInitialHeader();
|
4009 | while (this.executionContext.hasMoreResults()) {
|
4010 |
|
4011 | const { result, headers } = (await this.executionContext.nextItem());
|
4012 | mergeHeaders(aggregateHeaders, headers);
|
4013 |
|
4014 | if (result) {
|
4015 | const group = result.groupByItems ? await hashObject(result.groupByItems) : emptyGroup;
|
4016 | const aggregators = this.groupings.get(group);
|
4017 | const payload = result.payload;
|
4018 | if (aggregators) {
|
4019 |
|
4020 | Object.keys(payload).map((key) => {
|
4021 |
|
4022 | const effectiveGroupByValue = payload[key]
|
4023 | ? payload[key]
|
4024 | : new Map().set("item2", null);
|
4025 | const aggregateResult = extractAggregateResult(effectiveGroupByValue);
|
4026 | aggregators.get(key).aggregate(aggregateResult);
|
4027 | });
|
4028 | }
|
4029 | else {
|
4030 |
|
4031 | const grouping = new Map();
|
4032 | this.groupings.set(group, grouping);
|
4033 |
|
4034 | Object.keys(payload).map((key) => {
|
4035 | const aggregateType = this.queryInfo.groupByAliasToAggregateType[key];
|
4036 |
|
4037 | const aggregator = createAggregator(aggregateType);
|
4038 | grouping.set(key, aggregator);
|
4039 | if (aggregateType) {
|
4040 | const aggregateResult = extractAggregateResult(payload[key]);
|
4041 | aggregator.aggregate(aggregateResult);
|
4042 | }
|
4043 | else {
|
4044 | aggregator.aggregate(payload[key]);
|
4045 | }
|
4046 | });
|
4047 | }
|
4048 | }
|
4049 | }
|
4050 | for (const grouping of this.groupings.values()) {
|
4051 | const groupResult = {};
|
4052 | for (const [aggregateKey, aggregator] of grouping.entries()) {
|
4053 | groupResult[aggregateKey] = aggregator.getResult();
|
4054 | }
|
4055 | this.aggregateResultArray.push(groupResult);
|
4056 | }
|
4057 | this.completed = true;
|
4058 | return { result: this.aggregateResultArray.pop(), headers: aggregateHeaders };
|
4059 | }
|
4060 | hasMoreResults() {
|
4061 | return this.executionContext.hasMoreResults() || this.aggregateResultArray.length > 0;
|
4062 | }
|
4063 | }
|
4064 |
|
4065 |
|
4066 | class GroupByValueEndpointComponent {
|
4067 | constructor(executionContext, queryInfo) {
|
4068 | this.executionContext = executionContext;
|
4069 | this.queryInfo = queryInfo;
|
4070 | this.aggregators = new Map();
|
4071 | this.aggregateResultArray = [];
|
4072 | this.completed = false;
|
4073 |
|
4074 | this.aggregateType = this.queryInfo.aggregates[0];
|
4075 | }
|
4076 | async nextItem() {
|
4077 |
|
4078 | if (this.aggregateResultArray.length > 0) {
|
4079 | return { result: this.aggregateResultArray.pop(), headers: getInitialHeader() };
|
4080 | }
|
4081 | if (this.completed) {
|
4082 | return { result: undefined, headers: getInitialHeader() };
|
4083 | }
|
4084 | const aggregateHeaders = getInitialHeader();
|
4085 | while (this.executionContext.hasMoreResults()) {
|
4086 |
|
4087 | const { result, headers } = (await this.executionContext.nextItem());
|
4088 | mergeHeaders(aggregateHeaders, headers);
|
4089 |
|
4090 | if (result) {
|
4091 | let grouping = emptyGroup;
|
4092 | let payload = result;
|
4093 | if (result.groupByItems) {
|
4094 |
|
4095 | payload = result.payload;
|
4096 | grouping = await hashObject(result.groupByItems);
|
4097 | }
|
4098 | const aggregator = this.aggregators.get(grouping);
|
4099 | if (!aggregator) {
|
4100 |
|
4101 | this.aggregators.set(grouping, createAggregator(this.aggregateType));
|
4102 | }
|
4103 | if (this.aggregateType) {
|
4104 | const aggregateResult = extractAggregateResult(payload[0]);
|
4105 |
|
4106 | if (aggregateResult === null) {
|
4107 | this.completed = true;
|
4108 | }
|
4109 | this.aggregators.get(grouping).aggregate(aggregateResult);
|
4110 | }
|
4111 | else {
|
4112 |
|
4113 |
|
4114 | this.aggregators.get(grouping).aggregate(payload);
|
4115 | }
|
4116 | }
|
4117 | }
|
4118 |
|
4119 | if (this.completed) {
|
4120 | return { result: undefined, headers: aggregateHeaders };
|
4121 | }
|
4122 |
|
4123 | for (const aggregator of this.aggregators.values()) {
|
4124 | this.aggregateResultArray.push(aggregator.getResult());
|
4125 | }
|
4126 | this.completed = true;
|
4127 | return { result: this.aggregateResultArray.pop(), headers: aggregateHeaders };
|
4128 | }
|
4129 | hasMoreResults() {
|
4130 | return this.executionContext.hasMoreResults() || this.aggregateResultArray.length > 0;
|
4131 | }
|
4132 | }
|
4133 |
|
4134 |
|
4135 | class PipelinedQueryExecutionContext {
|
4136 | constructor(clientContext, collectionLink, query, options, partitionedQueryExecutionInfo) {
|
4137 | this.clientContext = clientContext;
|
4138 | this.collectionLink = collectionLink;
|
4139 | this.query = query;
|
4140 | this.options = options;
|
4141 | this.partitionedQueryExecutionInfo = partitionedQueryExecutionInfo;
|
4142 | this.endpoint = null;
|
4143 | this.pageSize = options["maxItemCount"];
|
4144 | if (this.pageSize === undefined) {
|
4145 | this.pageSize = PipelinedQueryExecutionContext.DEFAULT_PAGE_SIZE;
|
4146 | }
|
4147 |
|
4148 | const sortOrders = partitionedQueryExecutionInfo.queryInfo.orderBy;
|
4149 | if (Array.isArray(sortOrders) && sortOrders.length > 0) {
|
4150 |
|
4151 |
|
4152 | this.endpoint = new OrderByEndpointComponent(new OrderByQueryExecutionContext(this.clientContext, this.collectionLink, this.query, this.options, this.partitionedQueryExecutionInfo));
|
4153 | }
|
4154 | else {
|
4155 | this.endpoint = new ParallelQueryExecutionContext(this.clientContext, this.collectionLink, this.query, this.options, this.partitionedQueryExecutionInfo);
|
4156 | }
|
4157 | if (Object.keys(partitionedQueryExecutionInfo.queryInfo.groupByAliasToAggregateType).length > 0 ||
|
4158 | partitionedQueryExecutionInfo.queryInfo.aggregates.length > 0 ||
|
4159 | partitionedQueryExecutionInfo.queryInfo.groupByExpressions.length > 0) {
|
4160 | if (partitionedQueryExecutionInfo.queryInfo.hasSelectValue) {
|
4161 | this.endpoint = new GroupByValueEndpointComponent(this.endpoint, partitionedQueryExecutionInfo.queryInfo);
|
4162 | }
|
4163 | else {
|
4164 | this.endpoint = new GroupByEndpointComponent(this.endpoint, partitionedQueryExecutionInfo.queryInfo);
|
4165 | }
|
4166 | }
|
4167 |
|
4168 | const top = partitionedQueryExecutionInfo.queryInfo.top;
|
4169 | if (typeof top === "number") {
|
4170 | this.endpoint = new OffsetLimitEndpointComponent(this.endpoint, 0, top);
|
4171 | }
|
4172 |
|
4173 | const limit = partitionedQueryExecutionInfo.queryInfo.limit;
|
4174 | const offset = partitionedQueryExecutionInfo.queryInfo.offset;
|
4175 | if (typeof limit === "number" && typeof offset === "number") {
|
4176 | this.endpoint = new OffsetLimitEndpointComponent(this.endpoint, offset, limit);
|
4177 | }
|
4178 |
|
4179 | const distinctType = partitionedQueryExecutionInfo.queryInfo.distinctType;
|
4180 | if (distinctType === "Ordered") {
|
4181 | this.endpoint = new OrderedDistinctEndpointComponent(this.endpoint);
|
4182 | }
|
4183 | if (distinctType === "Unordered") {
|
4184 | this.endpoint = new UnorderedDistinctEndpointComponent(this.endpoint);
|
4185 | }
|
4186 | }
|
4187 | async nextItem() {
|
4188 | return this.endpoint.nextItem();
|
4189 | }
|
4190 |
|
4191 | hasMoreResults() {
|
4192 | return this.endpoint.hasMoreResults();
|
4193 | }
|
4194 | async fetchMore() {
|
4195 |
|
4196 |
|
4197 | if (typeof this.endpoint.fetchMore === "function") {
|
4198 | return this.endpoint.fetchMore();
|
4199 | }
|
4200 | else {
|
4201 | this.fetchBuffer = [];
|
4202 | this.fetchMoreRespHeaders = getInitialHeader();
|
4203 | return this._fetchMoreImplementation();
|
4204 | }
|
4205 | }
|
4206 | async _fetchMoreImplementation() {
|
4207 | try {
|
4208 | const { result: item, headers } = await this.endpoint.nextItem();
|
4209 | mergeHeaders(this.fetchMoreRespHeaders, headers);
|
4210 | if (item === undefined) {
|
4211 |
|
4212 | if (this.fetchBuffer.length === 0) {
|
4213 | return {
|
4214 | result: undefined,
|
4215 | headers: this.fetchMoreRespHeaders,
|
4216 | };
|
4217 | }
|
4218 | else {
|
4219 |
|
4220 | const temp = this.fetchBuffer;
|
4221 | this.fetchBuffer = [];
|
4222 | return { result: temp, headers: this.fetchMoreRespHeaders };
|
4223 | }
|
4224 | }
|
4225 | else {
|
4226 |
|
4227 | this.fetchBuffer.push(item);
|
4228 | if (this.fetchBuffer.length >= this.pageSize) {
|
4229 |
|
4230 | const temp = this.fetchBuffer.slice(0, this.pageSize);
|
4231 | this.fetchBuffer = this.fetchBuffer.splice(this.pageSize);
|
4232 | return { result: temp, headers: this.fetchMoreRespHeaders };
|
4233 | }
|
4234 | else {
|
4235 |
|
4236 |
|
4237 | return this._fetchMoreImplementation();
|
4238 | }
|
4239 | }
|
4240 | }
|
4241 | catch (err) {
|
4242 | mergeHeaders(this.fetchMoreRespHeaders, err.headers);
|
4243 | err.headers = this.fetchMoreRespHeaders;
|
4244 | if (err) {
|
4245 | throw err;
|
4246 | }
|
4247 | }
|
4248 | }
|
4249 | }
|
4250 | PipelinedQueryExecutionContext.DEFAULT_PAGE_SIZE = 10;
|
4251 |
|
4252 |
|
4253 |
|
4254 |
|
4255 |
|
4256 |
|
4257 |
|
4258 | class QueryIterator {
|
4259 | |
4260 |
|
4261 |
|
4262 | constructor(clientContext, query, options, fetchFunctions, resourceLink, resourceType) {
|
4263 | this.clientContext = clientContext;
|
4264 | this.query = query;
|
4265 | this.options = options;
|
4266 | this.fetchFunctions = fetchFunctions;
|
4267 | this.resourceLink = resourceLink;
|
4268 | this.resourceType = resourceType;
|
4269 | this.query = query;
|
4270 | this.fetchFunctions = fetchFunctions;
|
4271 | this.options = options || {};
|
4272 | this.resourceLink = resourceLink;
|
4273 | this.fetchAllLastResHeaders = getInitialHeader();
|
4274 | this.reset();
|
4275 | this.isInitialized = false;
|
4276 | }
|
4277 | |
4278 |
|
4279 |
|
4280 |
|
4281 |
|
4282 |
|
4283 |
|
4284 |
|
4285 |
|
4286 |
|
4287 |
|
4288 |
|
4289 |
|
4290 |
|
4291 |
|
4292 |
|
4293 |
|
4294 |
|
4295 |
|
4296 |
|
4297 |
|
4298 |
|
4299 | getAsyncIterator() {
|
4300 | return tslib.__asyncGenerator(this, arguments, function* getAsyncIterator_1() {
|
4301 | this.reset();
|
4302 | this.queryPlanPromise = this.fetchQueryPlan();
|
4303 | while (this.queryExecutionContext.hasMoreResults()) {
|
4304 | let response;
|
4305 | try {
|
4306 | response = yield tslib.__await(this.queryExecutionContext.fetchMore());
|
4307 | }
|
4308 | catch (error) {
|
4309 | if (this.needsQueryPlan(error)) {
|
4310 | yield tslib.__await(this.createPipelinedExecutionContext());
|
4311 | try {
|
4312 | response = yield tslib.__await(this.queryExecutionContext.fetchMore());
|
4313 | }
|
4314 | catch (queryError) {
|
4315 | this.handleSplitError(queryError);
|
4316 | }
|
4317 | }
|
4318 | else {
|
4319 | throw error;
|
4320 | }
|
4321 | }
|
4322 | const feedResponse = new FeedResponse(response.result, response.headers, this.queryExecutionContext.hasMoreResults());
|
4323 | if (response.result !== undefined) {
|
4324 | yield yield tslib.__await(feedResponse);
|
4325 | }
|
4326 | }
|
4327 | });
|
4328 | }
|
4329 | |
4330 |
|
4331 |
|
4332 |
|
4333 |
|
4334 | hasMoreResults() {
|
4335 | return this.queryExecutionContext.hasMoreResults();
|
4336 | }
|
4337 | |
4338 |
|
4339 |
|
4340 | async fetchAll() {
|
4341 | this.reset();
|
4342 | this.fetchAllTempResources = [];
|
4343 | let response;
|
4344 | try {
|
4345 | response = await this.toArrayImplementation();
|
4346 | }
|
4347 | catch (error) {
|
4348 | this.handleSplitError(error);
|
4349 | }
|
4350 | return response;
|
4351 | }
|
4352 | |
4353 |
|
4354 |
|
4355 |
|
4356 |
|
4357 |
|
4358 |
|
4359 | async fetchNext() {
|
4360 | this.queryPlanPromise = this.fetchQueryPlan();
|
4361 | if (!this.isInitialized) {
|
4362 | await this.init();
|
4363 | }
|
4364 | let response;
|
4365 | try {
|
4366 | response = await this.queryExecutionContext.fetchMore();
|
4367 | }
|
4368 | catch (error) {
|
4369 | if (this.needsQueryPlan(error)) {
|
4370 | await this.createPipelinedExecutionContext();
|
4371 | try {
|
4372 | response = await this.queryExecutionContext.fetchMore();
|
4373 | }
|
4374 | catch (queryError) {
|
4375 | this.handleSplitError(queryError);
|
4376 | }
|
4377 | }
|
4378 | else {
|
4379 | throw error;
|
4380 | }
|
4381 | }
|
4382 | return new FeedResponse(response.result, response.headers, this.queryExecutionContext.hasMoreResults());
|
4383 | }
|
4384 | |
4385 |
|
4386 |
|
4387 | reset() {
|
4388 | this.queryPlanPromise = undefined;
|
4389 | this.queryExecutionContext = new DefaultQueryExecutionContext(this.options, this.fetchFunctions);
|
4390 | }
|
4391 | async toArrayImplementation() {
|
4392 | this.queryPlanPromise = this.fetchQueryPlan();
|
4393 | if (!this.isInitialized) {
|
4394 | await this.init();
|
4395 | }
|
4396 | while (this.queryExecutionContext.hasMoreResults()) {
|
4397 | let response;
|
4398 | try {
|
4399 | response = await this.queryExecutionContext.nextItem();
|
4400 | }
|
4401 | catch (error) {
|
4402 | if (this.needsQueryPlan(error)) {
|
4403 | await this.createPipelinedExecutionContext();
|
4404 | response = await this.queryExecutionContext.nextItem();
|
4405 | }
|
4406 | else {
|
4407 | throw error;
|
4408 | }
|
4409 | }
|
4410 | const { result, headers } = response;
|
4411 |
|
4412 | mergeHeaders(this.fetchAllLastResHeaders, headers);
|
4413 | if (result !== undefined) {
|
4414 | this.fetchAllTempResources.push(result);
|
4415 | }
|
4416 | }
|
4417 | return new FeedResponse(this.fetchAllTempResources, this.fetchAllLastResHeaders, this.queryExecutionContext.hasMoreResults());
|
4418 | }
|
4419 | async createPipelinedExecutionContext() {
|
4420 | const queryPlanResponse = await this.queryPlanPromise;
|
4421 |
|
4422 | if (queryPlanResponse instanceof Error) {
|
4423 | throw queryPlanResponse;
|
4424 | }
|
4425 | const queryPlan = queryPlanResponse.result;
|
4426 | const queryInfo = queryPlan.queryInfo;
|
4427 | if (queryInfo.aggregates.length > 0 && queryInfo.hasSelectValue === false) {
|
4428 | throw new Error("Aggregate queries must use the VALUE keyword");
|
4429 | }
|
4430 | this.queryExecutionContext = new PipelinedQueryExecutionContext(this.clientContext, this.resourceLink, this.query, this.options, queryPlan);
|
4431 | }
|
4432 | async fetchQueryPlan() {
|
4433 | if (!this.queryPlanPromise && this.resourceType === exports.ResourceType.item) {
|
4434 | return this.clientContext
|
4435 | .getQueryPlan(getPathFromLink(this.resourceLink) + "/docs", exports.ResourceType.item, this.resourceLink, this.query, this.options)
|
4436 | .catch((error) => error);
|
4437 | }
|
4438 | return this.queryPlanPromise;
|
4439 | }
|
4440 | needsQueryPlan(error) {
|
4441 | var _a;
|
4442 | if (((_a = error.body) === null || _a === void 0 ? void 0 : _a.additionalErrorInfo) ||
|
4443 | error.message.includes("Cross partition query only supports")) {
|
4444 | return error.code === StatusCodes.BadRequest && this.resourceType === exports.ResourceType.item;
|
4445 | }
|
4446 | else {
|
4447 | throw error;
|
4448 | }
|
4449 | }
|
4450 | async init() {
|
4451 | if (this.isInitialized === true) {
|
4452 | return;
|
4453 | }
|
4454 | if (this.initPromise === undefined) {
|
4455 | this.initPromise = this._init();
|
4456 | }
|
4457 | return this.initPromise;
|
4458 | }
|
4459 | async _init() {
|
4460 | if (this.options.forceQueryPlan === true && this.resourceType === exports.ResourceType.item) {
|
4461 | await this.createPipelinedExecutionContext();
|
4462 | }
|
4463 | this.isInitialized = true;
|
4464 | }
|
4465 | handleSplitError(err) {
|
4466 | if (err.code === 410) {
|
4467 | const error = new Error("Encountered partition split and could not recover. This request is retryable");
|
4468 | error.code = 503;
|
4469 | error.originalError = err;
|
4470 | throw error;
|
4471 | }
|
4472 | else {
|
4473 | throw err;
|
4474 | }
|
4475 | }
|
4476 | }
|
4477 |
|
4478 | class ConflictResponse extends ResourceResponse {
|
4479 | constructor(resource, headers, statusCode, conflict) {
|
4480 | super(resource, headers, statusCode);
|
4481 | this.conflict = conflict;
|
4482 | }
|
4483 | }
|
4484 |
|
4485 |
|
4486 |
|
4487 |
|
4488 |
|
4489 |
|
4490 | class Conflict {
|
4491 | |
4492 |
|
4493 |
|
4494 |
|
4495 |
|
4496 | constructor(container, id, clientContext, partitionKey) {
|
4497 | this.container = container;
|
4498 | this.id = id;
|
4499 | this.clientContext = clientContext;
|
4500 | this.partitionKey = partitionKey;
|
4501 | this.partitionKey = partitionKey;
|
4502 | }
|
4503 | |
4504 |
|
4505 |
|
4506 | get url() {
|
4507 | return `/${this.container.url}/${Constants.Path.ConflictsPathSegment}/${this.id}`;
|
4508 | }
|
4509 | |
4510 |
|
4511 |
|
4512 | async read(options) {
|
4513 | const path = getPathFromLink(this.url, exports.ResourceType.conflicts);
|
4514 | const id = getIdFromLink(this.url);
|
4515 | const response = await this.clientContext.read({
|
4516 | path,
|
4517 | resourceType: exports.ResourceType.user,
|
4518 | resourceId: id,
|
4519 | options,
|
4520 | });
|
4521 | return new ConflictResponse(response.result, response.headers, response.code, this);
|
4522 | }
|
4523 | |
4524 |
|
4525 |
|
4526 | async delete(options) {
|
4527 | if (this.partitionKey === undefined) {
|
4528 | const { resource: partitionKeyDefinition } = await this.container.readPartitionKeyDefinition();
|
4529 | this.partitionKey = undefinedPartitionKey(partitionKeyDefinition);
|
4530 | }
|
4531 | const path = getPathFromLink(this.url);
|
4532 | const id = getIdFromLink(this.url);
|
4533 | const response = await this.clientContext.delete({
|
4534 | path,
|
4535 | resourceType: exports.ResourceType.conflicts,
|
4536 | resourceId: id,
|
4537 | options,
|
4538 | partitionKey: this.partitionKey,
|
4539 | });
|
4540 | return new ConflictResponse(response.result, response.headers, response.code, this);
|
4541 | }
|
4542 | }
|
4543 |
|
4544 |
|
4545 |
|
4546 |
|
4547 |
|
4548 |
|
4549 | class Conflicts {
|
4550 | constructor(container, clientContext) {
|
4551 | this.container = container;
|
4552 | this.clientContext = clientContext;
|
4553 | }
|
4554 | query(query, options) {
|
4555 | const path = getPathFromLink(this.container.url, exports.ResourceType.conflicts);
|
4556 | const id = getIdFromLink(this.container.url);
|
4557 | return new QueryIterator(this.clientContext, query, options, (innerOptions) => {
|
4558 | return this.clientContext.queryFeed({
|
4559 | path,
|
4560 | resourceType: exports.ResourceType.conflicts,
|
4561 | resourceId: id,
|
4562 | resultFn: (result) => result.Conflicts,
|
4563 | query,
|
4564 | options: innerOptions,
|
4565 | });
|
4566 | });
|
4567 | }
|
4568 | |
4569 |
|
4570 |
|
4571 |
|
4572 | readAll(options) {
|
4573 | return this.query(undefined, options);
|
4574 | }
|
4575 | }
|
4576 |
|
4577 |
|
4578 |
|
4579 | exports.ConflictResolutionMode = void 0;
|
4580 | (function (ConflictResolutionMode) {
|
4581 | ConflictResolutionMode["Custom"] = "Custom";
|
4582 | ConflictResolutionMode["LastWriterWins"] = "LastWriterWins";
|
4583 | })(exports.ConflictResolutionMode || (exports.ConflictResolutionMode = {}));
|
4584 |
|
4585 | class ItemResponse extends ResourceResponse {
|
4586 | constructor(resource, headers, statusCode, subsstatusCode, item) {
|
4587 | super(resource, headers, statusCode, subsstatusCode);
|
4588 | this.item = item;
|
4589 | }
|
4590 | }
|
4591 |
|
4592 |
|
4593 |
|
4594 |
|
4595 |
|
4596 |
|
4597 | class Item {
|
4598 | |
4599 |
|
4600 |
|
4601 |
|
4602 |
|
4603 |
|
4604 | constructor(container, id, partitionKey, clientContext) {
|
4605 | this.container = container;
|
4606 | this.id = id;
|
4607 | this.clientContext = clientContext;
|
4608 | this.partitionKey = partitionKey;
|
4609 | }
|
4610 | |
4611 |
|
4612 |
|
4613 | get url() {
|
4614 | return createDocumentUri(this.container.database.id, this.container.id, this.id);
|
4615 | }
|
4616 | |
4617 |
|
4618 |
|
4619 |
|
4620 |
|
4621 |
|
4622 |
|
4623 |
|
4624 |
|
4625 |
|
4626 |
|
4627 |
|
4628 |
|
4629 |
|
4630 |
|
4631 |
|
4632 |
|
4633 |
|
4634 |
|
4635 |
|
4636 |
|
4637 |
|
4638 |
|
4639 |
|
4640 | async read(options = {}) {
|
4641 | if (this.partitionKey === undefined) {
|
4642 | const { resource: partitionKeyDefinition } = await this.container.readPartitionKeyDefinition();
|
4643 | this.partitionKey = undefinedPartitionKey(partitionKeyDefinition);
|
4644 | }
|
4645 | const path = getPathFromLink(this.url);
|
4646 | const id = getIdFromLink(this.url);
|
4647 | let response;
|
4648 | try {
|
4649 | response = await this.clientContext.read({
|
4650 | path,
|
4651 | resourceType: exports.ResourceType.item,
|
4652 | resourceId: id,
|
4653 | options,
|
4654 | partitionKey: this.partitionKey,
|
4655 | });
|
4656 | }
|
4657 | catch (error) {
|
4658 | if (error.code !== StatusCodes.NotFound) {
|
4659 | throw error;
|
4660 | }
|
4661 | response = error;
|
4662 | }
|
4663 | return new ItemResponse(response.result, response.headers, response.code, response.substatus, this);
|
4664 | }
|
4665 | async replace(body, options = {}) {
|
4666 | if (this.partitionKey === undefined) {
|
4667 | const { resource: partitionKeyDefinition } = await this.container.readPartitionKeyDefinition();
|
4668 | this.partitionKey = extractPartitionKey(body, partitionKeyDefinition);
|
4669 | }
|
4670 | const err = {};
|
4671 | if (!isItemResourceValid(body, err)) {
|
4672 | throw err;
|
4673 | }
|
4674 | const path = getPathFromLink(this.url);
|
4675 | const id = getIdFromLink(this.url);
|
4676 | const response = await this.clientContext.replace({
|
4677 | body,
|
4678 | path,
|
4679 | resourceType: exports.ResourceType.item,
|
4680 | resourceId: id,
|
4681 | options,
|
4682 | partitionKey: this.partitionKey,
|
4683 | });
|
4684 | return new ItemResponse(response.result, response.headers, response.code, response.substatus, this);
|
4685 | }
|
4686 | |
4687 |
|
4688 |
|
4689 |
|
4690 |
|
4691 |
|
4692 |
|
4693 |
|
4694 | async delete(options = {}) {
|
4695 | if (this.partitionKey === undefined) {
|
4696 | const { resource: partitionKeyDefinition } = await this.container.readPartitionKeyDefinition();
|
4697 | this.partitionKey = undefinedPartitionKey(partitionKeyDefinition);
|
4698 | }
|
4699 | const path = getPathFromLink(this.url);
|
4700 | const id = getIdFromLink(this.url);
|
4701 | const response = await this.clientContext.delete({
|
4702 | path,
|
4703 | resourceType: exports.ResourceType.item,
|
4704 | resourceId: id,
|
4705 | options,
|
4706 | partitionKey: this.partitionKey,
|
4707 | });
|
4708 | return new ItemResponse(response.result, response.headers, response.code, response.substatus, this);
|
4709 | }
|
4710 | |
4711 |
|
4712 |
|
4713 |
|
4714 |
|
4715 |
|
4716 |
|
4717 |
|
4718 | async patch(body, options = {}) {
|
4719 | if (this.partitionKey === undefined) {
|
4720 | const { resource: partitionKeyDefinition } = await this.container.readPartitionKeyDefinition();
|
4721 | this.partitionKey = extractPartitionKey(body, partitionKeyDefinition);
|
4722 | }
|
4723 | const path = getPathFromLink(this.url);
|
4724 | const id = getIdFromLink(this.url);
|
4725 | const response = await this.clientContext.patch({
|
4726 | body,
|
4727 | path,
|
4728 | resourceType: exports.ResourceType.item,
|
4729 | resourceId: id,
|
4730 | options,
|
4731 | partitionKey: this.partitionKey,
|
4732 | });
|
4733 | return new ItemResponse(response.result, response.headers, response.code, response.substatus, this);
|
4734 | }
|
4735 | }
|
4736 |
|
4737 |
|
4738 |
|
4739 |
|
4740 |
|
4741 | class ChangeFeedResponse {
|
4742 | |
4743 |
|
4744 |
|
4745 | constructor(
|
4746 | /**
|
4747 | * Gets the items returned in the response from Azure Cosmos DB
|
4748 | */
|
4749 | result,
|
4750 | /**
|
4751 | * Gets the number of items returned in the response from Azure Cosmos DB
|
4752 | */
|
4753 | count,
|
4754 | /**
|
4755 | * Gets the status code of the response from Azure Cosmos DB
|
4756 | */
|
4757 | statusCode, headers) {
|
4758 | this.result = result;
|
4759 | this.count = count;
|
4760 | this.statusCode = statusCode;
|
4761 | this.headers = Object.freeze(headers);
|
4762 | }
|
4763 | |
4764 |
|
4765 |
|
4766 | get requestCharge() {
|
4767 | const rus = this.headers[Constants.HttpHeaders.RequestCharge];
|
4768 | return rus ? parseInt(rus, 10) : null;
|
4769 | }
|
4770 | |
4771 |
|
4772 |
|
4773 | get activityId() {
|
4774 | return this.headers[Constants.HttpHeaders.ActivityId];
|
4775 | }
|
4776 | |
4777 |
|
4778 |
|
4779 |
|
4780 |
|
4781 | get continuation() {
|
4782 | return this.etag;
|
4783 | }
|
4784 | |
4785 |
|
4786 |
|
4787 | get sessionToken() {
|
4788 | return this.headers[Constants.HttpHeaders.SessionToken];
|
4789 | }
|
4790 | |
4791 |
|
4792 |
|
4793 |
|
4794 |
|
4795 |
|
4796 |
|
4797 |
|
4798 |
|
4799 | get etag() {
|
4800 | return this.headers[Constants.HttpHeaders.ETag];
|
4801 | }
|
4802 | }
|
4803 |
|
4804 |
|
4805 |
|
4806 |
|
4807 |
|
4808 |
|
4809 | class ChangeFeedIterator {
|
4810 | |
4811 |
|
4812 |
|
4813 | constructor(clientContext, resourceId, resourceLink, partitionKey, changeFeedOptions) {
|
4814 | this.clientContext = clientContext;
|
4815 | this.resourceId = resourceId;
|
4816 | this.resourceLink = resourceLink;
|
4817 | this.partitionKey = partitionKey;
|
4818 | this.changeFeedOptions = changeFeedOptions;
|
4819 |
|
4820 | const partitionKeyValid = partitionKey !== undefined;
|
4821 | this.isPartitionSpecified = partitionKeyValid;
|
4822 | let canUseStartFromBeginning = true;
|
4823 | if (changeFeedOptions.continuation) {
|
4824 | this.nextIfNoneMatch = changeFeedOptions.continuation;
|
4825 | canUseStartFromBeginning = false;
|
4826 | }
|
4827 | if (changeFeedOptions.startTime) {
|
4828 |
|
4829 |
|
4830 |
|
4831 | this.ifModifiedSince = changeFeedOptions.startTime.toUTCString();
|
4832 | canUseStartFromBeginning = false;
|
4833 | }
|
4834 | if (canUseStartFromBeginning && !changeFeedOptions.startFromBeginning) {
|
4835 | this.nextIfNoneMatch = ChangeFeedIterator.IfNoneMatchAllHeaderValue;
|
4836 | }
|
4837 | }
|
4838 | |
4839 |
|
4840 |
|
4841 |
|
4842 |
|
4843 |
|
4844 |
|
4845 | get hasMoreResults() {
|
4846 | return this.lastStatusCode !== StatusCodes.NotModified;
|
4847 | }
|
4848 | |
4849 |
|
4850 |
|
4851 | getAsyncIterator() {
|
4852 | return tslib.__asyncGenerator(this, arguments, function* getAsyncIterator_1() {
|
4853 | do {
|
4854 | const result = yield tslib.__await(this.fetchNext());
|
4855 | if (result.count > 0) {
|
4856 | yield yield tslib.__await(result);
|
4857 | }
|
4858 | } while (this.hasMoreResults);
|
4859 | });
|
4860 | }
|
4861 | |
4862 |
|
4863 |
|
4864 | async fetchNext() {
|
4865 | const response = await this.getFeedResponse();
|
4866 | this.lastStatusCode = response.statusCode;
|
4867 | this.nextIfNoneMatch = response.headers[Constants.HttpHeaders.ETag];
|
4868 | return response;
|
4869 | }
|
4870 | async getFeedResponse() {
|
4871 | if (!this.isPartitionSpecified) {
|
4872 | throw new Error("Container is partitioned, but no partition key or partition key range id was specified.");
|
4873 | }
|
4874 | const feedOptions = { initialHeaders: {}, useIncrementalFeed: true };
|
4875 | if (typeof this.changeFeedOptions.maxItemCount === "number") {
|
4876 | feedOptions.maxItemCount = this.changeFeedOptions.maxItemCount;
|
4877 | }
|
4878 | if (this.changeFeedOptions.sessionToken) {
|
4879 | feedOptions.sessionToken = this.changeFeedOptions.sessionToken;
|
4880 | }
|
4881 | if (this.nextIfNoneMatch) {
|
4882 | feedOptions.accessCondition = {
|
4883 | type: Constants.HttpHeaders.IfNoneMatch,
|
4884 | condition: this.nextIfNoneMatch,
|
4885 | };
|
4886 | }
|
4887 | if (this.ifModifiedSince) {
|
4888 | feedOptions.initialHeaders[Constants.HttpHeaders.IfModifiedSince] = this.ifModifiedSince;
|
4889 | }
|
4890 | const response = await this.clientContext.queryFeed({
|
4891 | path: this.resourceLink,
|
4892 | resourceType: exports.ResourceType.item,
|
4893 | resourceId: this.resourceId,
|
4894 | resultFn: (result) => (result ? result.Documents : []),
|
4895 | query: undefined,
|
4896 | options: feedOptions,
|
4897 | partitionKey: this.partitionKey,
|
4898 | });
|
4899 | return new ChangeFeedResponse(response.result, response.result ? response.result.length : 0, response.code, response.headers);
|
4900 | }
|
4901 | }
|
4902 | ChangeFeedIterator.IfNoneMatchAllHeaderValue = "*";
|
4903 |
|
4904 |
|
4905 |
|
4906 | const BytePrefix = {
|
4907 | Undefined: "00",
|
4908 | Null: "01",
|
4909 | False: "02",
|
4910 | True: "03",
|
4911 | MinNumber: "04",
|
4912 | Number: "05",
|
4913 | MaxNumber: "06",
|
4914 | MinString: "07",
|
4915 | String: "08",
|
4916 | MaxString: "09",
|
4917 | Int64: "0a",
|
4918 | Int32: "0b",
|
4919 | Int16: "0c",
|
4920 | Int8: "0d",
|
4921 | Uint64: "0e",
|
4922 | Uint32: "0f",
|
4923 | Uint16: "10",
|
4924 | Uint8: "11",
|
4925 | Binary: "12",
|
4926 | Guid: "13",
|
4927 | Float: "14",
|
4928 | Infinity: "FF",
|
4929 | };
|
4930 |
|
4931 |
|
4932 | function writeNumberForBinaryEncodingJSBI(hash) {
|
4933 | let payload = encodeNumberAsUInt64JSBI(hash);
|
4934 | let outputStream = Buffer.from(BytePrefix.Number, "hex");
|
4935 | const firstChunk = JSBI__default["default"].asUintN(64, JSBI__default["default"].signedRightShift(payload, JSBI__default["default"].BigInt(56)));
|
4936 | outputStream = Buffer.concat([outputStream, Buffer.from(firstChunk.toString(16), "hex")]);
|
4937 | payload = JSBI__default["default"].asUintN(64, JSBI__default["default"].leftShift(JSBI__default["default"].BigInt(payload), JSBI__default["default"].BigInt(0x8)));
|
4938 | let byteToWrite = JSBI__default["default"].BigInt(0);
|
4939 | let shifted;
|
4940 | let padded;
|
4941 | do {
|
4942 | {
|
4943 |
|
4944 |
|
4945 |
|
4946 | padded = byteToWrite.toString(16).padStart(2, "0");
|
4947 | if (padded !== "00") {
|
4948 | outputStream = Buffer.concat([outputStream, Buffer.from(padded, "hex")]);
|
4949 | }
|
4950 | }
|
4951 | shifted = JSBI__default["default"].asUintN(64, JSBI__default["default"].signedRightShift(payload, JSBI__default["default"].BigInt(56)));
|
4952 | byteToWrite = JSBI__default["default"].asUintN(64, JSBI__default["default"].bitwiseOr(shifted, JSBI__default["default"].BigInt(0x01)));
|
4953 | payload = JSBI__default["default"].asUintN(64, JSBI__default["default"].leftShift(payload, JSBI__default["default"].BigInt(7)));
|
4954 | } while (JSBI__default["default"].notEqual(payload, JSBI__default["default"].BigInt(0)));
|
4955 | const lastChunk = JSBI__default["default"].asUintN(64, JSBI__default["default"].bitwiseAnd(byteToWrite, JSBI__default["default"].BigInt(0xfe)));
|
4956 |
|
4957 |
|
4958 |
|
4959 | padded = lastChunk.toString(16).padStart(2, "0");
|
4960 | if (padded !== "00") {
|
4961 | outputStream = Buffer.concat([outputStream, Buffer.from(padded, "hex")]);
|
4962 | }
|
4963 | return outputStream;
|
4964 | }
|
4965 | function encodeNumberAsUInt64JSBI(value) {
|
4966 | const rawValueBits = getRawBitsJSBI(value);
|
4967 | const mask = JSBI__default["default"].BigInt(0x8000000000000000);
|
4968 | const returned = rawValueBits < mask
|
4969 | ? JSBI__default["default"].bitwiseXor(rawValueBits, mask)
|
4970 | : JSBI__default["default"].add(JSBI__default["default"].bitwiseNot(rawValueBits), JSBI__default["default"].BigInt(1));
|
4971 | return returned;
|
4972 | }
|
4973 | function doubleToByteArrayJSBI(double) {
|
4974 | const output = Buffer.alloc(8);
|
4975 | const lng = getRawBitsJSBI(double);
|
4976 | for (let i = 0; i < 8; i++) {
|
4977 | output[i] = JSBI__default["default"].toNumber(JSBI__default["default"].bitwiseAnd(JSBI__default["default"].signedRightShift(lng, JSBI__default["default"].multiply(JSBI__default["default"].BigInt(i), JSBI__default["default"].BigInt(8))), JSBI__default["default"].BigInt(0xff)));
|
4978 | }
|
4979 | return output;
|
4980 | }
|
4981 | function getRawBitsJSBI(value) {
|
4982 | const view = new DataView(new ArrayBuffer(8));
|
4983 | view.setFloat64(0, value);
|
4984 | return JSBI__default["default"].BigInt(`0x${buf2hex(view.buffer)}`);
|
4985 | }
|
4986 | function buf2hex(buffer) {
|
4987 | return Array.prototype.map
|
4988 | .call(new Uint8Array(buffer), (x) => ("00" + x.toString(16)).slice(-2))
|
4989 | .join("");
|
4990 | }
|
4991 |
|
4992 |
|
4993 | function writeStringForBinaryEncoding(payload) {
|
4994 | let outputStream = Buffer.from(BytePrefix.String, "hex");
|
4995 | const MAX_STRING_BYTES_TO_APPEND = 100;
|
4996 | const byteArray = [...Buffer.from(payload)];
|
4997 | const isShortString = payload.length <= MAX_STRING_BYTES_TO_APPEND;
|
4998 | for (let index = 0; index < (isShortString ? byteArray.length : MAX_STRING_BYTES_TO_APPEND + 1); index++) {
|
4999 | let charByte = byteArray[index];
|
5000 | if (charByte < 0xff) {
|
5001 | charByte++;
|
5002 | }
|
5003 | outputStream = Buffer.concat([outputStream, Buffer.from(charByte.toString(16), "hex")]);
|
5004 | }
|
5005 | if (isShortString) {
|
5006 | outputStream = Buffer.concat([outputStream, Buffer.from(BytePrefix.Undefined, "hex")]);
|
5007 | }
|
5008 | return outputStream;
|
5009 | }
|
5010 |
|
5011 |
|
5012 |
|
5013 |
|
5014 |
|
5015 |
|
5016 |
|
5017 |
|
5018 |
|
5019 |
|
5020 |
|
5021 | function _x86Multiply(m, n) {
|
5022 |
|
5023 |
|
5024 |
|
5025 |
|
5026 | return (m & 0xffff) * n + ((((m >>> 16) * n) & 0xffff) << 16);
|
5027 | }
|
5028 | function _x86Rotl(m, n) {
|
5029 |
|
5030 |
|
5031 |
|
5032 |
|
5033 | return (m << n) | (m >>> (32 - n));
|
5034 | }
|
5035 | function _x86Fmix(h) {
|
5036 |
|
5037 |
|
5038 |
|
5039 | h ^= h >>> 16;
|
5040 | h = _x86Multiply(h, 0x85ebca6b);
|
5041 | h ^= h >>> 13;
|
5042 | h = _x86Multiply(h, 0xc2b2ae35);
|
5043 | h ^= h >>> 16;
|
5044 | return h;
|
5045 | }
|
5046 | function _x64Add(m, n) {
|
5047 |
|
5048 |
|
5049 |
|
5050 |
|
5051 | m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff];
|
5052 | n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff];
|
5053 | const o = [0, 0, 0, 0];
|
5054 | o[3] += m[3] + n[3];
|
5055 | o[2] += o[3] >>> 16;
|
5056 | o[3] &= 0xffff;
|
5057 | o[2] += m[2] + n[2];
|
5058 | o[1] += o[2] >>> 16;
|
5059 | o[2] &= 0xffff;
|
5060 | o[1] += m[1] + n[1];
|
5061 | o[0] += o[1] >>> 16;
|
5062 | o[1] &= 0xffff;
|
5063 | o[0] += m[0] + n[0];
|
5064 | o[0] &= 0xffff;
|
5065 | return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]];
|
5066 | }
|
5067 | function _x64Multiply(m, n) {
|
5068 |
|
5069 |
|
5070 |
|
5071 |
|
5072 | m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff];
|
5073 | n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff];
|
5074 | const o = [0, 0, 0, 0];
|
5075 | o[3] += m[3] * n[3];
|
5076 | o[2] += o[3] >>> 16;
|
5077 | o[3] &= 0xffff;
|
5078 | o[2] += m[2] * n[3];
|
5079 | o[1] += o[2] >>> 16;
|
5080 | o[2] &= 0xffff;
|
5081 | o[2] += m[3] * n[2];
|
5082 | o[1] += o[2] >>> 16;
|
5083 | o[2] &= 0xffff;
|
5084 | o[1] += m[1] * n[3];
|
5085 | o[0] += o[1] >>> 16;
|
5086 | o[1] &= 0xffff;
|
5087 | o[1] += m[2] * n[2];
|
5088 | o[0] += o[1] >>> 16;
|
5089 | o[1] &= 0xffff;
|
5090 | o[1] += m[3] * n[1];
|
5091 | o[0] += o[1] >>> 16;
|
5092 | o[1] &= 0xffff;
|
5093 | o[0] += m[0] * n[3] + m[1] * n[2] + m[2] * n[1] + m[3] * n[0];
|
5094 | o[0] &= 0xffff;
|
5095 | return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]];
|
5096 | }
|
5097 | function _x64Rotl(m, n) {
|
5098 |
|
5099 |
|
5100 |
|
5101 |
|
5102 |
|
5103 | n %= 64;
|
5104 | if (n === 32) {
|
5105 | return [m[1], m[0]];
|
5106 | }
|
5107 | else if (n < 32) {
|
5108 | return [(m[0] << n) | (m[1] >>> (32 - n)), (m[1] << n) | (m[0] >>> (32 - n))];
|
5109 | }
|
5110 | else {
|
5111 | n -= 32;
|
5112 | return [(m[1] << n) | (m[0] >>> (32 - n)), (m[0] << n) | (m[1] >>> (32 - n))];
|
5113 | }
|
5114 | }
|
5115 | function _x64LeftShift(m, n) {
|
5116 |
|
5117 |
|
5118 |
|
5119 |
|
5120 |
|
5121 | n %= 64;
|
5122 | if (n === 0) {
|
5123 | return m;
|
5124 | }
|
5125 | else if (n < 32) {
|
5126 | return [(m[0] << n) | (m[1] >>> (32 - n)), m[1] << n];
|
5127 | }
|
5128 | else {
|
5129 | return [m[1] << (n - 32), 0];
|
5130 | }
|
5131 | }
|
5132 | function _x64Xor(m, n) {
|
5133 |
|
5134 |
|
5135 |
|
5136 |
|
5137 | return [m[0] ^ n[0], m[1] ^ n[1]];
|
5138 | }
|
5139 | function _x64Fmix(h) {
|
5140 |
|
5141 |
|
5142 |
|
5143 |
|
5144 |
|
5145 | h = _x64Xor(h, [0, h[0] >>> 1]);
|
5146 | h = _x64Multiply(h, [0xff51afd7, 0xed558ccd]);
|
5147 | h = _x64Xor(h, [0, h[0] >>> 1]);
|
5148 | h = _x64Multiply(h, [0xc4ceb9fe, 0x1a85ec53]);
|
5149 | h = _x64Xor(h, [0, h[0] >>> 1]);
|
5150 | return h;
|
5151 | }
|
5152 |
|
5153 |
|
5154 | function x86Hash32(bytes, seed) {
|
5155 |
|
5156 |
|
5157 |
|
5158 |
|
5159 | seed = seed || 0;
|
5160 | const remainder = bytes.length % 4;
|
5161 | const blocks = bytes.length - remainder;
|
5162 | let h1 = seed;
|
5163 | let k1 = 0;
|
5164 | const c1 = 0xcc9e2d51;
|
5165 | const c2 = 0x1b873593;
|
5166 | let j = 0;
|
5167 | for (let i = 0; i < blocks; i = i + 4) {
|
5168 | k1 = bytes[i] | (bytes[i + 1] << 8) | (bytes[i + 2] << 16) | (bytes[i + 3] << 24);
|
5169 | k1 = _x86Multiply(k1, c1);
|
5170 | k1 = _x86Rotl(k1, 15);
|
5171 | k1 = _x86Multiply(k1, c2);
|
5172 | h1 ^= k1;
|
5173 | h1 = _x86Rotl(h1, 13);
|
5174 | h1 = _x86Multiply(h1, 5) + 0xe6546b64;
|
5175 | j = i + 4;
|
5176 | }
|
5177 | k1 = 0;
|
5178 | switch (remainder) {
|
5179 | case 3:
|
5180 | k1 ^= bytes[j + 2] << 16;
|
5181 | case 2:
|
5182 | k1 ^= bytes[j + 1] << 8;
|
5183 | case 1:
|
5184 | k1 ^= bytes[j];
|
5185 | k1 = _x86Multiply(k1, c1);
|
5186 | k1 = _x86Rotl(k1, 15);
|
5187 | k1 = _x86Multiply(k1, c2);
|
5188 | h1 ^= k1;
|
5189 | }
|
5190 | h1 ^= bytes.length;
|
5191 | h1 = _x86Fmix(h1);
|
5192 | return h1 >>> 0;
|
5193 | }
|
5194 | function x86Hash128(bytes, seed) {
|
5195 |
|
5196 |
|
5197 |
|
5198 |
|
5199 | seed = seed || 0;
|
5200 | const remainder = bytes.length % 16;
|
5201 | const blocks = bytes.length - remainder;
|
5202 | let h1 = seed;
|
5203 | let h2 = seed;
|
5204 | let h3 = seed;
|
5205 | let h4 = seed;
|
5206 | let k1 = 0;
|
5207 | let k2 = 0;
|
5208 | let k3 = 0;
|
5209 | let k4 = 0;
|
5210 | const c1 = 0x239b961b;
|
5211 | const c2 = 0xab0e9789;
|
5212 | const c3 = 0x38b34ae5;
|
5213 | const c4 = 0xa1e38b93;
|
5214 | let j = 0;
|
5215 | for (let i = 0; i < blocks; i = i + 16) {
|
5216 | k1 = bytes[i] | (bytes[i + 1] << 8) | (bytes[i + 2] << 16) | (bytes[i + 3] << 24);
|
5217 | k2 = bytes[i + 4] | (bytes[i + 5] << 8) | (bytes[i + 6] << 16) | (bytes[i + 7] << 24);
|
5218 | k3 = bytes[i + 8] | (bytes[i + 9] << 8) | (bytes[i + 10] << 16) | (bytes[i + 11] << 24);
|
5219 | k4 = bytes[i + 12] | (bytes[i + 13] << 8) | (bytes[i + 14] << 16) | (bytes[i + 15] << 24);
|
5220 | k1 = _x86Multiply(k1, c1);
|
5221 | k1 = _x86Rotl(k1, 15);
|
5222 | k1 = _x86Multiply(k1, c2);
|
5223 | h1 ^= k1;
|
5224 | h1 = _x86Rotl(h1, 19);
|
5225 | h1 += h2;
|
5226 | h1 = _x86Multiply(h1, 5) + 0x561ccd1b;
|
5227 | k2 = _x86Multiply(k2, c2);
|
5228 | k2 = _x86Rotl(k2, 16);
|
5229 | k2 = _x86Multiply(k2, c3);
|
5230 | h2 ^= k2;
|
5231 | h2 = _x86Rotl(h2, 17);
|
5232 | h2 += h3;
|
5233 | h2 = _x86Multiply(h2, 5) + 0x0bcaa747;
|
5234 | k3 = _x86Multiply(k3, c3);
|
5235 | k3 = _x86Rotl(k3, 17);
|
5236 | k3 = _x86Multiply(k3, c4);
|
5237 | h3 ^= k3;
|
5238 | h3 = _x86Rotl(h3, 15);
|
5239 | h3 += h4;
|
5240 | h3 = _x86Multiply(h3, 5) + 0x96cd1c35;
|
5241 | k4 = _x86Multiply(k4, c4);
|
5242 | k4 = _x86Rotl(k4, 18);
|
5243 | k4 = _x86Multiply(k4, c1);
|
5244 | h4 ^= k4;
|
5245 | h4 = _x86Rotl(h4, 13);
|
5246 | h4 += h1;
|
5247 | h4 = _x86Multiply(h4, 5) + 0x32ac3b17;
|
5248 | j = i + 16;
|
5249 | }
|
5250 | k1 = 0;
|
5251 | k2 = 0;
|
5252 | k3 = 0;
|
5253 | k4 = 0;
|
5254 | switch (remainder) {
|
5255 | case 15:
|
5256 | k4 ^= bytes[j + 14] << 16;
|
5257 | case 14:
|
5258 | k4 ^= bytes[j + 13] << 8;
|
5259 | case 13:
|
5260 | k4 ^= bytes[j + 12];
|
5261 | k4 = _x86Multiply(k4, c4);
|
5262 | k4 = _x86Rotl(k4, 18);
|
5263 | k4 = _x86Multiply(k4, c1);
|
5264 | h4 ^= k4;
|
5265 | case 12:
|
5266 | k3 ^= bytes[j + 11] << 24;
|
5267 | case 11:
|
5268 | k3 ^= bytes[j + 10] << 16;
|
5269 | case 10:
|
5270 | k3 ^= bytes[j + 9] << 8;
|
5271 | case 9:
|
5272 | k3 ^= bytes[j + 8];
|
5273 | k3 = _x86Multiply(k3, c3);
|
5274 | k3 = _x86Rotl(k3, 17);
|
5275 | k3 = _x86Multiply(k3, c4);
|
5276 | h3 ^= k3;
|
5277 | case 8:
|
5278 | k2 ^= bytes[j + 7] << 24;
|
5279 | case 7:
|
5280 | k2 ^= bytes[j + 6] << 16;
|
5281 | case 6:
|
5282 | k2 ^= bytes[j + 5] << 8;
|
5283 | case 5:
|
5284 | k2 ^= bytes[j + 4];
|
5285 | k2 = _x86Multiply(k2, c2);
|
5286 | k2 = _x86Rotl(k2, 16);
|
5287 | k2 = _x86Multiply(k2, c3);
|
5288 | h2 ^= k2;
|
5289 | case 4:
|
5290 | k1 ^= bytes[j + 3] << 24;
|
5291 | case 3:
|
5292 | k1 ^= bytes[j + 2] << 16;
|
5293 | case 2:
|
5294 | k1 ^= bytes[j + 1] << 8;
|
5295 | case 1:
|
5296 | k1 ^= bytes[j];
|
5297 | k1 = _x86Multiply(k1, c1);
|
5298 | k1 = _x86Rotl(k1, 15);
|
5299 | k1 = _x86Multiply(k1, c2);
|
5300 | h1 ^= k1;
|
5301 | }
|
5302 | h1 ^= bytes.length;
|
5303 | h2 ^= bytes.length;
|
5304 | h3 ^= bytes.length;
|
5305 | h4 ^= bytes.length;
|
5306 | h1 += h2;
|
5307 | h1 += h3;
|
5308 | h1 += h4;
|
5309 | h2 += h1;
|
5310 | h3 += h1;
|
5311 | h4 += h1;
|
5312 | h1 = _x86Fmix(h1);
|
5313 | h2 = _x86Fmix(h2);
|
5314 | h3 = _x86Fmix(h3);
|
5315 | h4 = _x86Fmix(h4);
|
5316 | h1 += h2;
|
5317 | h1 += h3;
|
5318 | h1 += h4;
|
5319 | h2 += h1;
|
5320 | h3 += h1;
|
5321 | h4 += h1;
|
5322 | return (("00000000" + (h1 >>> 0).toString(16)).slice(-8) +
|
5323 | ("00000000" + (h2 >>> 0).toString(16)).slice(-8) +
|
5324 | ("00000000" + (h3 >>> 0).toString(16)).slice(-8) +
|
5325 | ("00000000" + (h4 >>> 0).toString(16)).slice(-8));
|
5326 | }
|
5327 | function x64Hash128(bytes, seed) {
|
5328 |
|
5329 |
|
5330 |
|
5331 |
|
5332 | seed = seed || 0;
|
5333 | const remainder = bytes.length % 16;
|
5334 | const blocks = bytes.length - remainder;
|
5335 | let h1 = [0, seed];
|
5336 | let h2 = [0, seed];
|
5337 | let k1 = [0, 0];
|
5338 | let k2 = [0, 0];
|
5339 | const c1 = [0x87c37b91, 0x114253d5];
|
5340 | const c2 = [0x4cf5ad43, 0x2745937f];
|
5341 | let j = 0;
|
5342 | for (let i = 0; i < blocks; i = i + 16) {
|
5343 | k1 = [
|
5344 | bytes[i + 4] | (bytes[i + 5] << 8) | (bytes[i + 6] << 16) | (bytes[i + 7] << 24),
|
5345 | bytes[i] | (bytes[i + 1] << 8) | (bytes[i + 2] << 16) | (bytes[i + 3] << 24),
|
5346 | ];
|
5347 | k2 = [
|
5348 | bytes[i + 12] | (bytes[i + 13] << 8) | (bytes[i + 14] << 16) | (bytes[i + 15] << 24),
|
5349 | bytes[i + 8] | (bytes[i + 9] << 8) | (bytes[i + 10] << 16) | (bytes[i + 11] << 24),
|
5350 | ];
|
5351 | k1 = _x64Multiply(k1, c1);
|
5352 | k1 = _x64Rotl(k1, 31);
|
5353 | k1 = _x64Multiply(k1, c2);
|
5354 | h1 = _x64Xor(h1, k1);
|
5355 | h1 = _x64Rotl(h1, 27);
|
5356 | h1 = _x64Add(h1, h2);
|
5357 | h1 = _x64Add(_x64Multiply(h1, [0, 5]), [0, 0x52dce729]);
|
5358 | k2 = _x64Multiply(k2, c2);
|
5359 | k2 = _x64Rotl(k2, 33);
|
5360 | k2 = _x64Multiply(k2, c1);
|
5361 | h2 = _x64Xor(h2, k2);
|
5362 | h2 = _x64Rotl(h2, 31);
|
5363 | h2 = _x64Add(h2, h1);
|
5364 | h2 = _x64Add(_x64Multiply(h2, [0, 5]), [0, 0x38495ab5]);
|
5365 | j = i + 16;
|
5366 | }
|
5367 | k1 = [0, 0];
|
5368 | k2 = [0, 0];
|
5369 | switch (remainder) {
|
5370 | case 15:
|
5371 | k2 = _x64Xor(k2, _x64LeftShift([0, bytes[j + 14]], 48));
|
5372 | case 14:
|
5373 | k2 = _x64Xor(k2, _x64LeftShift([0, bytes[j + 13]], 40));
|
5374 | case 13:
|
5375 | k2 = _x64Xor(k2, _x64LeftShift([0, bytes[j + 12]], 32));
|
5376 | case 12:
|
5377 | k2 = _x64Xor(k2, _x64LeftShift([0, bytes[j + 11]], 24));
|
5378 | case 11:
|
5379 | k2 = _x64Xor(k2, _x64LeftShift([0, bytes[j + 10]], 16));
|
5380 | case 10:
|
5381 | k2 = _x64Xor(k2, _x64LeftShift([0, bytes[j + 9]], 8));
|
5382 | case 9:
|
5383 | k2 = _x64Xor(k2, [0, bytes[j + 8]]);
|
5384 | k2 = _x64Multiply(k2, c2);
|
5385 | k2 = _x64Rotl(k2, 33);
|
5386 | k2 = _x64Multiply(k2, c1);
|
5387 | h2 = _x64Xor(h2, k2);
|
5388 | case 8:
|
5389 | k1 = _x64Xor(k1, _x64LeftShift([0, bytes[j + 7]], 56));
|
5390 | case 7:
|
5391 | k1 = _x64Xor(k1, _x64LeftShift([0, bytes[j + 6]], 48));
|
5392 | case 6:
|
5393 | k1 = _x64Xor(k1, _x64LeftShift([0, bytes[j + 5]], 40));
|
5394 | case 5:
|
5395 | k1 = _x64Xor(k1, _x64LeftShift([0, bytes[j + 4]], 32));
|
5396 | case 4:
|
5397 | k1 = _x64Xor(k1, _x64LeftShift([0, bytes[j + 3]], 24));
|
5398 | case 3:
|
5399 | k1 = _x64Xor(k1, _x64LeftShift([0, bytes[j + 2]], 16));
|
5400 | case 2:
|
5401 | k1 = _x64Xor(k1, _x64LeftShift([0, bytes[j + 1]], 8));
|
5402 | case 1:
|
5403 | k1 = _x64Xor(k1, [0, bytes[j]]);
|
5404 | k1 = _x64Multiply(k1, c1);
|
5405 | k1 = _x64Rotl(k1, 31);
|
5406 | k1 = _x64Multiply(k1, c2);
|
5407 | h1 = _x64Xor(h1, k1);
|
5408 | }
|
5409 | h1 = _x64Xor(h1, [0, bytes.length]);
|
5410 | h2 = _x64Xor(h2, [0, bytes.length]);
|
5411 | h1 = _x64Add(h1, h2);
|
5412 | h2 = _x64Add(h2, h1);
|
5413 | h1 = _x64Fmix(h1);
|
5414 | h2 = _x64Fmix(h2);
|
5415 | h1 = _x64Add(h1, h2);
|
5416 | h2 = _x64Add(h2, h1);
|
5417 |
|
5418 |
|
5419 | const h1Buff = Buffer.from(("00000000" + (h1[0] >>> 0).toString(16)).slice(-8) +
|
5420 | ("00000000" + (h1[1] >>> 0).toString(16)).slice(-8), "hex");
|
5421 | const h1Reversed = reverse$1(h1Buff).toString("hex");
|
5422 | const h2Buff = Buffer.from(("00000000" + (h2[0] >>> 0).toString(16)).slice(-8) +
|
5423 | ("00000000" + (h2[1] >>> 0).toString(16)).slice(-8), "hex");
|
5424 | const h2Reversed = reverse$1(h2Buff).toString("hex");
|
5425 | return h1Reversed + h2Reversed;
|
5426 | }
|
5427 | function reverse$1(buff) {
|
5428 | const buffer = Buffer.allocUnsafe(buff.length);
|
5429 | for (let i = 0, j = buff.length - 1; i <= j; ++i, --j) {
|
5430 | buffer[i] = buff[j];
|
5431 | buffer[j] = buff[i];
|
5432 | }
|
5433 | return buffer;
|
5434 | }
|
5435 | var MurmurHash = {
|
5436 | version: "3.0.0",
|
5437 | x86: {
|
5438 | hash32: x86Hash32,
|
5439 | hash128: x86Hash128,
|
5440 | },
|
5441 | x64: {
|
5442 | hash128: x64Hash128,
|
5443 | },
|
5444 | inputValidation: true,
|
5445 | };
|
5446 |
|
5447 |
|
5448 | const MAX_STRING_CHARS = 100;
|
5449 | function hashV1PartitionKey(partitionKey) {
|
5450 | const toHash = prefixKeyByType$1(partitionKey);
|
5451 | const hash = MurmurHash.x86.hash32(toHash);
|
5452 | const encodedJSBI = writeNumberForBinaryEncodingJSBI(hash);
|
5453 | const encodedValue = encodeByType(partitionKey);
|
5454 | return Buffer.concat([encodedJSBI, encodedValue]).toString("hex").toUpperCase();
|
5455 | }
|
5456 | function prefixKeyByType$1(key) {
|
5457 | let bytes;
|
5458 | switch (typeof key) {
|
5459 | case "string": {
|
5460 | const truncated = key.substr(0, MAX_STRING_CHARS);
|
5461 | bytes = Buffer.concat([
|
5462 | Buffer.from(BytePrefix.String, "hex"),
|
5463 | Buffer.from(truncated),
|
5464 | Buffer.from(BytePrefix.Undefined, "hex"),
|
5465 | ]);
|
5466 | return bytes;
|
5467 | }
|
5468 | case "number": {
|
5469 | const numberBytes = doubleToByteArrayJSBI(key);
|
5470 | bytes = Buffer.concat([Buffer.from(BytePrefix.Number, "hex"), numberBytes]);
|
5471 | return bytes;
|
5472 | }
|
5473 | case "boolean": {
|
5474 | const prefix = key ? BytePrefix.True : BytePrefix.False;
|
5475 | return Buffer.from(prefix, "hex");
|
5476 | }
|
5477 | case "object": {
|
5478 | if (key === null) {
|
5479 | return Buffer.from(BytePrefix.Null, "hex");
|
5480 | }
|
5481 | return Buffer.from(BytePrefix.Undefined, "hex");
|
5482 | }
|
5483 | case "undefined": {
|
5484 | return Buffer.from(BytePrefix.Undefined, "hex");
|
5485 | }
|
5486 | default:
|
5487 | throw new Error(`Unexpected type: ${typeof key}`);
|
5488 | }
|
5489 | }
|
5490 | function encodeByType(key) {
|
5491 | switch (typeof key) {
|
5492 | case "string": {
|
5493 | const truncated = key.substr(0, MAX_STRING_CHARS);
|
5494 | return writeStringForBinaryEncoding(truncated);
|
5495 | }
|
5496 | case "number": {
|
5497 | const encodedJSBI = writeNumberForBinaryEncodingJSBI(key);
|
5498 | return encodedJSBI;
|
5499 | }
|
5500 | case "boolean": {
|
5501 | const prefix = key ? BytePrefix.True : BytePrefix.False;
|
5502 | return Buffer.from(prefix, "hex");
|
5503 | }
|
5504 | case "object":
|
5505 | if (key === null) {
|
5506 | return Buffer.from(BytePrefix.Null, "hex");
|
5507 | }
|
5508 | return Buffer.from(BytePrefix.Undefined, "hex");
|
5509 | case "undefined":
|
5510 | return Buffer.from(BytePrefix.Undefined, "hex");
|
5511 | default:
|
5512 | throw new Error(`Unexpected type: ${typeof key}`);
|
5513 | }
|
5514 | }
|
5515 |
|
5516 |
|
5517 | function hashV2PartitionKey(partitionKey) {
|
5518 | const toHash = prefixKeyByType(partitionKey);
|
5519 | const hash = MurmurHash.x64.hash128(toHash);
|
5520 | const reverseBuff = reverse(Buffer.from(hash, "hex"));
|
5521 | reverseBuff[0] &= 0x3f;
|
5522 | return reverseBuff.toString("hex").toUpperCase();
|
5523 | }
|
5524 | function prefixKeyByType(key) {
|
5525 | let bytes;
|
5526 | switch (typeof key) {
|
5527 | case "string": {
|
5528 | bytes = Buffer.concat([
|
5529 | Buffer.from(BytePrefix.String, "hex"),
|
5530 | Buffer.from(key),
|
5531 | Buffer.from(BytePrefix.Infinity, "hex"),
|
5532 | ]);
|
5533 | return bytes;
|
5534 | }
|
5535 | case "number": {
|
5536 | const numberBytes = doubleToByteArrayJSBI(key);
|
5537 | bytes = Buffer.concat([Buffer.from(BytePrefix.Number, "hex"), numberBytes]);
|
5538 | return bytes;
|
5539 | }
|
5540 | case "boolean": {
|
5541 | const prefix = key ? BytePrefix.True : BytePrefix.False;
|
5542 | return Buffer.from(prefix, "hex");
|
5543 | }
|
5544 | case "object": {
|
5545 | if (key === null) {
|
5546 | return Buffer.from(BytePrefix.Null, "hex");
|
5547 | }
|
5548 | return Buffer.from(BytePrefix.Undefined, "hex");
|
5549 | }
|
5550 | case "undefined": {
|
5551 | return Buffer.from(BytePrefix.Undefined, "hex");
|
5552 | }
|
5553 | default:
|
5554 | throw new Error(`Unexpected type: ${typeof key}`);
|
5555 | }
|
5556 | }
|
5557 | function reverse(buff) {
|
5558 | const buffer = Buffer.allocUnsafe(buff.length);
|
5559 | for (let i = 0, j = buff.length - 1; i <= j; ++i, --j) {
|
5560 | buffer[i] = buff[j];
|
5561 | buffer[j] = buff[i];
|
5562 | }
|
5563 | return buffer;
|
5564 | }
|
5565 |
|
5566 |
|
5567 | const uuid$1 = uuid$3.v4;
|
5568 |
|
5569 |
|
5570 |
|
5571 | function isChangeFeedOptions(options) {
|
5572 | const optionsType = typeof options;
|
5573 | return (options && !(optionsType === "string" || optionsType === "boolean" || optionsType === "number"));
|
5574 | }
|
5575 |
|
5576 |
|
5577 |
|
5578 |
|
5579 |
|
5580 | class Items {
|
5581 | |
5582 |
|
5583 |
|
5584 |
|
5585 |
|
5586 | constructor(container, clientContext) {
|
5587 | this.container = container;
|
5588 | this.clientContext = clientContext;
|
5589 | }
|
5590 | query(query, options = {}) {
|
5591 | const path = getPathFromLink(this.container.url, exports.ResourceType.item);
|
5592 | const id = getIdFromLink(this.container.url);
|
5593 | const fetchFunction = (innerOptions) => {
|
5594 | return this.clientContext.queryFeed({
|
5595 | path,
|
5596 | resourceType: exports.ResourceType.item,
|
5597 | resourceId: id,
|
5598 | resultFn: (result) => (result ? result.Documents : []),
|
5599 | query,
|
5600 | options: innerOptions,
|
5601 | partitionKey: options.partitionKey,
|
5602 | });
|
5603 | };
|
5604 | return new QueryIterator(this.clientContext, query, options, fetchFunction, this.container.url, exports.ResourceType.item);
|
5605 | }
|
5606 | readChangeFeed(partitionKeyOrChangeFeedOptions, changeFeedOptions) {
|
5607 | if (isChangeFeedOptions(partitionKeyOrChangeFeedOptions)) {
|
5608 | return this.changeFeed(partitionKeyOrChangeFeedOptions);
|
5609 | }
|
5610 | else {
|
5611 | return this.changeFeed(partitionKeyOrChangeFeedOptions, changeFeedOptions);
|
5612 | }
|
5613 | }
|
5614 | changeFeed(partitionKeyOrChangeFeedOptions, changeFeedOptions) {
|
5615 | let partitionKey;
|
5616 | if (!changeFeedOptions && isChangeFeedOptions(partitionKeyOrChangeFeedOptions)) {
|
5617 | partitionKey = undefined;
|
5618 | changeFeedOptions = partitionKeyOrChangeFeedOptions;
|
5619 | }
|
5620 | else if (partitionKeyOrChangeFeedOptions !== undefined &&
|
5621 | !isChangeFeedOptions(partitionKeyOrChangeFeedOptions)) {
|
5622 | partitionKey = partitionKeyOrChangeFeedOptions;
|
5623 | }
|
5624 | if (!changeFeedOptions) {
|
5625 | changeFeedOptions = {};
|
5626 | }
|
5627 | const path = getPathFromLink(this.container.url, exports.ResourceType.item);
|
5628 | const id = getIdFromLink(this.container.url);
|
5629 | return new ChangeFeedIterator(this.clientContext, id, path, partitionKey, changeFeedOptions);
|
5630 | }
|
5631 | readAll(options) {
|
5632 | return this.query("SELECT * from c", options);
|
5633 | }
|
5634 | |
5635 |
|
5636 |
|
5637 |
|
5638 |
|
5639 |
|
5640 |
|
5641 |
|
5642 |
|
5643 |
|
5644 |
|
5645 | async create(body, options = {}) {
|
5646 |
|
5647 |
|
5648 | if ((body.id === undefined || body.id === "") && !options.disableAutomaticIdGeneration) {
|
5649 | body.id = uuid$1();
|
5650 | }
|
5651 | const { resource: partitionKeyDefinition } = await this.container.readPartitionKeyDefinition();
|
5652 | const partitionKey = extractPartitionKey(body, partitionKeyDefinition);
|
5653 | const err = {};
|
5654 | if (!isItemResourceValid(body, err)) {
|
5655 | throw err;
|
5656 | }
|
5657 | const path = getPathFromLink(this.container.url, exports.ResourceType.item);
|
5658 | const id = getIdFromLink(this.container.url);
|
5659 | const response = await this.clientContext.create({
|
5660 | body,
|
5661 | path,
|
5662 | resourceType: exports.ResourceType.item,
|
5663 | resourceId: id,
|
5664 | options,
|
5665 | partitionKey,
|
5666 | });
|
5667 | const ref = new Item(this.container, response.result.id, partitionKey, this.clientContext);
|
5668 | return new ItemResponse(response.result, response.headers, response.code, response.substatus, ref);
|
5669 | }
|
5670 | async upsert(body, options = {}) {
|
5671 | const { resource: partitionKeyDefinition } = await this.container.readPartitionKeyDefinition();
|
5672 | const partitionKey = extractPartitionKey(body, partitionKeyDefinition);
|
5673 |
|
5674 |
|
5675 | if ((body.id === undefined || body.id === "") && !options.disableAutomaticIdGeneration) {
|
5676 | body.id = uuid$1();
|
5677 | }
|
5678 | const err = {};
|
5679 | if (!isItemResourceValid(body, err)) {
|
5680 | throw err;
|
5681 | }
|
5682 | const path = getPathFromLink(this.container.url, exports.ResourceType.item);
|
5683 | const id = getIdFromLink(this.container.url);
|
5684 | const response = await this.clientContext.upsert({
|
5685 | body,
|
5686 | path,
|
5687 | resourceType: exports.ResourceType.item,
|
5688 | resourceId: id,
|
5689 | options,
|
5690 | partitionKey,
|
5691 | });
|
5692 | const ref = new Item(this.container, response.result.id, partitionKey, this.clientContext);
|
5693 | return new ItemResponse(response.result, response.headers, response.code, response.substatus, ref);
|
5694 | }
|
5695 | |
5696 |
|
5697 |
|
5698 |
|
5699 |
|
5700 |
|
5701 |
|
5702 |
|
5703 |
|
5704 |
|
5705 |
|
5706 |
|
5707 |
|
5708 |
|
5709 |
|
5710 |
|
5711 |
|
5712 |
|
5713 |
|
5714 |
|
5715 |
|
5716 |
|
5717 |
|
5718 |
|
5719 |
|
5720 |
|
5721 |
|
5722 |
|
5723 | async bulk(operations, bulkOptions, options) {
|
5724 | const { resources: partitionKeyRanges } = await this.container
|
5725 | .readPartitionKeyRanges()
|
5726 | .fetchAll();
|
5727 | const { resource: definition } = await this.container.getPartitionKeyDefinition();
|
5728 | const batches = partitionKeyRanges.map((keyRange) => {
|
5729 | return {
|
5730 | min: keyRange.minInclusive,
|
5731 | max: keyRange.maxExclusive,
|
5732 | rangeId: keyRange.id,
|
5733 | indexes: [],
|
5734 | operations: [],
|
5735 | };
|
5736 | });
|
5737 | operations
|
5738 | .map((operation) => decorateOperation(operation, definition, options))
|
5739 | .forEach((operation, index) => {
|
5740 | const partitionProp = definition.paths[0].replace("/", "");
|
5741 | const isV2 = definition.version && definition.version === 2;
|
5742 | const toHashKey = getPartitionKeyToHash(operation, partitionProp);
|
5743 | const hashed = isV2 ? hashV2PartitionKey(toHashKey) : hashV1PartitionKey(toHashKey);
|
5744 | const batchForKey = batches.find((batch) => {
|
5745 | return isKeyInRange(batch.min, batch.max, hashed);
|
5746 | });
|
5747 | batchForKey.operations.push(operation);
|
5748 | batchForKey.indexes.push(index);
|
5749 | });
|
5750 | const path = getPathFromLink(this.container.url, exports.ResourceType.item);
|
5751 | const orderedResponses = [];
|
5752 | await Promise.all(batches
|
5753 | .filter((batch) => batch.operations.length)
|
5754 | .flatMap((batch) => splitBatchBasedOnBodySize(batch))
|
5755 | .map(async (batch) => {
|
5756 | if (batch.operations.length > 100) {
|
5757 | throw new Error("Cannot run bulk request with more than 100 operations per partition");
|
5758 | }
|
5759 | try {
|
5760 | const response = await this.clientContext.bulk({
|
5761 | body: batch.operations,
|
5762 | partitionKeyRangeId: batch.rangeId,
|
5763 | path,
|
5764 | resourceId: this.container.url,
|
5765 | bulkOptions,
|
5766 | options,
|
5767 | });
|
5768 | response.result.forEach((operationResponse, index) => {
|
5769 | orderedResponses[batch.indexes[index]] = operationResponse;
|
5770 | });
|
5771 | }
|
5772 | catch (err) {
|
5773 |
|
5774 |
|
5775 |
|
5776 | if (err.code === 410) {
|
5777 | throw new Error("Partition key error. Either the partitions have split or an operation has an unsupported partitionKey type");
|
5778 | }
|
5779 | throw new Error(`Bulk request errored with: ${err.message}`);
|
5780 | }
|
5781 | }));
|
5782 | return orderedResponses;
|
5783 | }
|
5784 | |
5785 |
|
5786 |
|
5787 |
|
5788 |
|
5789 |
|
5790 |
|
5791 |
|
5792 |
|
5793 |
|
5794 |
|
5795 |
|
5796 |
|
5797 |
|
5798 |
|
5799 |
|
5800 |
|
5801 |
|
5802 |
|
5803 |
|
5804 |
|
5805 |
|
5806 |
|
5807 |
|
5808 |
|
5809 |
|
5810 |
|
5811 | async batch(operations, partitionKey = "[{}]", options) {
|
5812 | operations.map((operation) => decorateBatchOperation(operation, options));
|
5813 | const path = getPathFromLink(this.container.url, exports.ResourceType.item);
|
5814 | if (operations.length > 100) {
|
5815 | throw new Error("Cannot run batch request with more than 100 operations per partition");
|
5816 | }
|
5817 | try {
|
5818 | const response = await this.clientContext.batch({
|
5819 | body: operations,
|
5820 | partitionKey,
|
5821 | path,
|
5822 | resourceId: this.container.url,
|
5823 | options,
|
5824 | });
|
5825 | return response;
|
5826 | }
|
5827 | catch (err) {
|
5828 | throw new Error(`Batch request error: ${err.message}`);
|
5829 | }
|
5830 | }
|
5831 | }
|
5832 |
|
5833 | class StoredProcedureResponse extends ResourceResponse {
|
5834 | constructor(resource, headers, statusCode, storedProcedure) {
|
5835 | super(resource, headers, statusCode);
|
5836 | this.storedProcedure = storedProcedure;
|
5837 | }
|
5838 | |
5839 |
|
5840 |
|
5841 |
|
5842 |
|
5843 | get sproc() {
|
5844 | return this.storedProcedure;
|
5845 | }
|
5846 | }
|
5847 |
|
5848 |
|
5849 |
|
5850 |
|
5851 |
|
5852 |
|
5853 | class StoredProcedure {
|
5854 | |
5855 |
|
5856 |
|
5857 |
|
5858 |
|
5859 |
|
5860 | constructor(container, id, clientContext) {
|
5861 | this.container = container;
|
5862 | this.id = id;
|
5863 | this.clientContext = clientContext;
|
5864 | }
|
5865 | |
5866 |
|
5867 |
|
5868 | get url() {
|
5869 | return createStoredProcedureUri(this.container.database.id, this.container.id, this.id);
|
5870 | }
|
5871 | |
5872 |
|
5873 |
|
5874 | async read(options) {
|
5875 | const path = getPathFromLink(this.url);
|
5876 | const id = getIdFromLink(this.url);
|
5877 | const response = await this.clientContext.read({
|
5878 | path,
|
5879 | resourceType: exports.ResourceType.sproc,
|
5880 | resourceId: id,
|
5881 | options,
|
5882 | });
|
5883 | return new StoredProcedureResponse(response.result, response.headers, response.code, this);
|
5884 | }
|
5885 | |
5886 |
|
5887 |
|
5888 |
|
5889 | async replace(body, options) {
|
5890 | if (body.body) {
|
5891 | body.body = body.body.toString();
|
5892 | }
|
5893 | const err = {};
|
5894 | if (!isResourceValid(body, err)) {
|
5895 | throw err;
|
5896 | }
|
5897 | const path = getPathFromLink(this.url);
|
5898 | const id = getIdFromLink(this.url);
|
5899 | const response = await this.clientContext.replace({
|
5900 | body,
|
5901 | path,
|
5902 | resourceType: exports.ResourceType.sproc,
|
5903 | resourceId: id,
|
5904 | options,
|
5905 | });
|
5906 | return new StoredProcedureResponse(response.result, response.headers, response.code, this);
|
5907 | }
|
5908 | |
5909 |
|
5910 |
|
5911 | async delete(options) {
|
5912 | const path = getPathFromLink(this.url);
|
5913 | const id = getIdFromLink(this.url);
|
5914 | const response = await this.clientContext.delete({
|
5915 | path,
|
5916 | resourceType: exports.ResourceType.sproc,
|
5917 | resourceId: id,
|
5918 | options,
|
5919 | });
|
5920 | return new StoredProcedureResponse(response.result, response.headers, response.code, this);
|
5921 | }
|
5922 | |
5923 |
|
5924 |
|
5925 |
|
5926 |
|
5927 |
|
5928 |
|
5929 |
|
5930 |
|
5931 |
|
5932 | async execute(partitionKey, params, options) {
|
5933 | if (partitionKey === undefined) {
|
5934 | const { resource: partitionKeyDefinition } = await this.container.readPartitionKeyDefinition();
|
5935 | partitionKey = undefinedPartitionKey(partitionKeyDefinition);
|
5936 | }
|
5937 | const response = await this.clientContext.execute({
|
5938 | sprocLink: this.url,
|
5939 | params,
|
5940 | options,
|
5941 | partitionKey,
|
5942 | });
|
5943 | return new ResourceResponse(response.result, response.headers, response.code);
|
5944 | }
|
5945 | }
|
5946 |
|
5947 |
|
5948 |
|
5949 |
|
5950 |
|
5951 |
|
5952 | class StoredProcedures {
|
5953 | |
5954 |
|
5955 |
|
5956 |
|
5957 | constructor(container, clientContext) {
|
5958 | this.container = container;
|
5959 | this.clientContext = clientContext;
|
5960 | }
|
5961 | query(query, options) {
|
5962 | const path = getPathFromLink(this.container.url, exports.ResourceType.sproc);
|
5963 | const id = getIdFromLink(this.container.url);
|
5964 | return new QueryIterator(this.clientContext, query, options, (innerOptions) => {
|
5965 | return this.clientContext.queryFeed({
|
5966 | path,
|
5967 | resourceType: exports.ResourceType.sproc,
|
5968 | resourceId: id,
|
5969 | resultFn: (result) => result.StoredProcedures,
|
5970 | query,
|
5971 | options: innerOptions,
|
5972 | });
|
5973 | });
|
5974 | }
|
5975 | |
5976 |
|
5977 |
|
5978 |
|
5979 |
|
5980 |
|
5981 |
|
5982 | readAll(options) {
|
5983 | return this.query(undefined, options);
|
5984 | }
|
5985 | |
5986 |
|
5987 |
|
5988 |
|
5989 |
|
5990 |
|
5991 |
|
5992 |
|
5993 |
|
5994 | async create(body, options) {
|
5995 | if (body.body) {
|
5996 | body.body = body.body.toString();
|
5997 | }
|
5998 | const err = {};
|
5999 | if (!isResourceValid(body, err)) {
|
6000 | throw err;
|
6001 | }
|
6002 | const path = getPathFromLink(this.container.url, exports.ResourceType.sproc);
|
6003 | const id = getIdFromLink(this.container.url);
|
6004 | const response = await this.clientContext.create({
|
6005 | body,
|
6006 | path,
|
6007 | resourceType: exports.ResourceType.sproc,
|
6008 | resourceId: id,
|
6009 | options,
|
6010 | });
|
6011 | const ref = new StoredProcedure(this.container, response.result.id, this.clientContext);
|
6012 | return new StoredProcedureResponse(response.result, response.headers, response.code, ref);
|
6013 | }
|
6014 | }
|
6015 |
|
6016 | class TriggerResponse extends ResourceResponse {
|
6017 | constructor(resource, headers, statusCode, trigger) {
|
6018 | super(resource, headers, statusCode);
|
6019 | this.trigger = trigger;
|
6020 | }
|
6021 | }
|
6022 |
|
6023 |
|
6024 |
|
6025 |
|
6026 |
|
6027 |
|
6028 | class Trigger {
|
6029 | |
6030 |
|
6031 |
|
6032 |
|
6033 |
|
6034 | constructor(container, id, clientContext) {
|
6035 | this.container = container;
|
6036 | this.id = id;
|
6037 | this.clientContext = clientContext;
|
6038 | }
|
6039 | |
6040 |
|
6041 |
|
6042 | get url() {
|
6043 | return createTriggerUri(this.container.database.id, this.container.id, this.id);
|
6044 | }
|
6045 | |
6046 |
|
6047 |
|
6048 | async read(options) {
|
6049 | const path = getPathFromLink(this.url);
|
6050 | const id = getIdFromLink(this.url);
|
6051 | const response = await this.clientContext.read({
|
6052 | path,
|
6053 | resourceType: exports.ResourceType.trigger,
|
6054 | resourceId: id,
|
6055 | options,
|
6056 | });
|
6057 | return new TriggerResponse(response.result, response.headers, response.code, this);
|
6058 | }
|
6059 | |
6060 |
|
6061 |
|
6062 |
|
6063 | async replace(body, options) {
|
6064 | if (body.body) {
|
6065 | body.body = body.body.toString();
|
6066 | }
|
6067 | const err = {};
|
6068 | if (!isResourceValid(body, err)) {
|
6069 | throw err;
|
6070 | }
|
6071 | const path = getPathFromLink(this.url);
|
6072 | const id = getIdFromLink(this.url);
|
6073 | const response = await this.clientContext.replace({
|
6074 | body,
|
6075 | path,
|
6076 | resourceType: exports.ResourceType.trigger,
|
6077 | resourceId: id,
|
6078 | options,
|
6079 | });
|
6080 | return new TriggerResponse(response.result, response.headers, response.code, this);
|
6081 | }
|
6082 | |
6083 |
|
6084 |
|
6085 | async delete(options) {
|
6086 | const path = getPathFromLink(this.url);
|
6087 | const id = getIdFromLink(this.url);
|
6088 | const response = await this.clientContext.delete({
|
6089 | path,
|
6090 | resourceType: exports.ResourceType.trigger,
|
6091 | resourceId: id,
|
6092 | options,
|
6093 | });
|
6094 | return new TriggerResponse(response.result, response.headers, response.code, this);
|
6095 | }
|
6096 | }
|
6097 |
|
6098 |
|
6099 |
|
6100 |
|
6101 |
|
6102 |
|
6103 | class Triggers {
|
6104 | |
6105 |
|
6106 |
|
6107 |
|
6108 | constructor(container, clientContext) {
|
6109 | this.container = container;
|
6110 | this.clientContext = clientContext;
|
6111 | }
|
6112 | query(query, options) {
|
6113 | const path = getPathFromLink(this.container.url, exports.ResourceType.trigger);
|
6114 | const id = getIdFromLink(this.container.url);
|
6115 | return new QueryIterator(this.clientContext, query, options, (innerOptions) => {
|
6116 | return this.clientContext.queryFeed({
|
6117 | path,
|
6118 | resourceType: exports.ResourceType.trigger,
|
6119 | resourceId: id,
|
6120 | resultFn: (result) => result.Triggers,
|
6121 | query,
|
6122 | options: innerOptions,
|
6123 | });
|
6124 | });
|
6125 | }
|
6126 | |
6127 |
|
6128 |
|
6129 |
|
6130 |
|
6131 |
|
6132 |
|
6133 | readAll(options) {
|
6134 | return this.query(undefined, options);
|
6135 | }
|
6136 | |
6137 |
|
6138 |
|
6139 |
|
6140 |
|
6141 |
|
6142 |
|
6143 |
|
6144 | async create(body, options) {
|
6145 | if (body.body) {
|
6146 | body.body = body.body.toString();
|
6147 | }
|
6148 | const err = {};
|
6149 | if (!isResourceValid(body, err)) {
|
6150 | throw err;
|
6151 | }
|
6152 | const path = getPathFromLink(this.container.url, exports.ResourceType.trigger);
|
6153 | const id = getIdFromLink(this.container.url);
|
6154 | const response = await this.clientContext.create({
|
6155 | body,
|
6156 | path,
|
6157 | resourceType: exports.ResourceType.trigger,
|
6158 | resourceId: id,
|
6159 | options,
|
6160 | });
|
6161 | const ref = new Trigger(this.container, response.result.id, this.clientContext);
|
6162 | return new TriggerResponse(response.result, response.headers, response.code, ref);
|
6163 | }
|
6164 | }
|
6165 |
|
6166 | class UserDefinedFunctionResponse extends ResourceResponse {
|
6167 | constructor(resource, headers, statusCode, udf) {
|
6168 | super(resource, headers, statusCode);
|
6169 | this.userDefinedFunction = udf;
|
6170 | }
|
6171 | |
6172 |
|
6173 |
|
6174 |
|
6175 |
|
6176 | get udf() {
|
6177 | return this.userDefinedFunction;
|
6178 | }
|
6179 | }
|
6180 |
|
6181 |
|
6182 |
|
6183 |
|
6184 |
|
6185 |
|
6186 | class UserDefinedFunction {
|
6187 | |
6188 |
|
6189 |
|
6190 |
|
6191 |
|
6192 | constructor(container, id, clientContext) {
|
6193 | this.container = container;
|
6194 | this.id = id;
|
6195 | this.clientContext = clientContext;
|
6196 | }
|
6197 | |
6198 |
|
6199 |
|
6200 | get url() {
|
6201 | return createUserDefinedFunctionUri(this.container.database.id, this.container.id, this.id);
|
6202 | }
|
6203 | |
6204 |
|
6205 |
|
6206 | async read(options) {
|
6207 | const path = getPathFromLink(this.url);
|
6208 | const id = getIdFromLink(this.url);
|
6209 | const response = await this.clientContext.read({
|
6210 | path,
|
6211 | resourceType: exports.ResourceType.udf,
|
6212 | resourceId: id,
|
6213 | options,
|
6214 | });
|
6215 | return new UserDefinedFunctionResponse(response.result, response.headers, response.code, this);
|
6216 | }
|
6217 | |
6218 |
|
6219 |
|
6220 |
|
6221 | async replace(body, options) {
|
6222 | if (body.body) {
|
6223 | body.body = body.body.toString();
|
6224 | }
|
6225 | const err = {};
|
6226 | if (!isResourceValid(body, err)) {
|
6227 | throw err;
|
6228 | }
|
6229 | const path = getPathFromLink(this.url);
|
6230 | const id = getIdFromLink(this.url);
|
6231 | const response = await this.clientContext.replace({
|
6232 | body,
|
6233 | path,
|
6234 | resourceType: exports.ResourceType.udf,
|
6235 | resourceId: id,
|
6236 | options,
|
6237 | });
|
6238 | return new UserDefinedFunctionResponse(response.result, response.headers, response.code, this);
|
6239 | }
|
6240 | |
6241 |
|
6242 |
|
6243 | async delete(options) {
|
6244 | const path = getPathFromLink(this.url);
|
6245 | const id = getIdFromLink(this.url);
|
6246 | const response = await this.clientContext.delete({
|
6247 | path,
|
6248 | resourceType: exports.ResourceType.udf,
|
6249 | resourceId: id,
|
6250 | options,
|
6251 | });
|
6252 | return new UserDefinedFunctionResponse(response.result, response.headers, response.code, this);
|
6253 | }
|
6254 | }
|
6255 |
|
6256 |
|
6257 |
|
6258 |
|
6259 |
|
6260 |
|
6261 | class UserDefinedFunctions {
|
6262 | |
6263 |
|
6264 |
|
6265 |
|
6266 | constructor(container, clientContext) {
|
6267 | this.container = container;
|
6268 | this.clientContext = clientContext;
|
6269 | }
|
6270 | query(query, options) {
|
6271 | const path = getPathFromLink(this.container.url, exports.ResourceType.udf);
|
6272 | const id = getIdFromLink(this.container.url);
|
6273 | return new QueryIterator(this.clientContext, query, options, (innerOptions) => {
|
6274 | return this.clientContext.queryFeed({
|
6275 | path,
|
6276 | resourceType: exports.ResourceType.udf,
|
6277 | resourceId: id,
|
6278 | resultFn: (result) => result.UserDefinedFunctions,
|
6279 | query,
|
6280 | options: innerOptions,
|
6281 | });
|
6282 | });
|
6283 | }
|
6284 | |
6285 |
|
6286 |
|
6287 |
|
6288 |
|
6289 |
|
6290 |
|
6291 | readAll(options) {
|
6292 | return this.query(undefined, options);
|
6293 | }
|
6294 | |
6295 |
|
6296 |
|
6297 |
|
6298 |
|
6299 |
|
6300 |
|
6301 |
|
6302 | async create(body, options) {
|
6303 | if (body.body) {
|
6304 | body.body = body.body.toString();
|
6305 | }
|
6306 | const err = {};
|
6307 | if (!isResourceValid(body, err)) {
|
6308 | throw err;
|
6309 | }
|
6310 | const path = getPathFromLink(this.container.url, exports.ResourceType.udf);
|
6311 | const id = getIdFromLink(this.container.url);
|
6312 | const response = await this.clientContext.create({
|
6313 | body,
|
6314 | path,
|
6315 | resourceType: exports.ResourceType.udf,
|
6316 | resourceId: id,
|
6317 | options,
|
6318 | });
|
6319 | const ref = new UserDefinedFunction(this.container, response.result.id, this.clientContext);
|
6320 | return new UserDefinedFunctionResponse(response.result, response.headers, response.code, ref);
|
6321 | }
|
6322 | }
|
6323 |
|
6324 |
|
6325 | class Scripts {
|
6326 | |
6327 |
|
6328 |
|
6329 |
|
6330 | constructor(container, clientContext) {
|
6331 | this.container = container;
|
6332 | this.clientContext = clientContext;
|
6333 | }
|
6334 | |
6335 |
|
6336 |
|
6337 |
|
6338 |
|
6339 |
|
6340 | storedProcedure(id) {
|
6341 | return new StoredProcedure(this.container, id, this.clientContext);
|
6342 | }
|
6343 | |
6344 |
|
6345 |
|
6346 |
|
6347 |
|
6348 |
|
6349 | trigger(id) {
|
6350 | return new Trigger(this.container, id, this.clientContext);
|
6351 | }
|
6352 | |
6353 |
|
6354 |
|
6355 |
|
6356 |
|
6357 |
|
6358 | userDefinedFunction(id) {
|
6359 | return new UserDefinedFunction(this.container, id, this.clientContext);
|
6360 | }
|
6361 | |
6362 |
|
6363 |
|
6364 |
|
6365 |
|
6366 | get storedProcedures() {
|
6367 | if (!this.$sprocs) {
|
6368 | this.$sprocs = new StoredProcedures(this.container, this.clientContext);
|
6369 | }
|
6370 | return this.$sprocs;
|
6371 | }
|
6372 | |
6373 |
|
6374 |
|
6375 |
|
6376 |
|
6377 | get triggers() {
|
6378 | if (!this.$triggers) {
|
6379 | this.$triggers = new Triggers(this.container, this.clientContext);
|
6380 | }
|
6381 | return this.$triggers;
|
6382 | }
|
6383 | |
6384 |
|
6385 |
|
6386 |
|
6387 |
|
6388 | get userDefinedFunctions() {
|
6389 | if (!this.$udfs) {
|
6390 | this.$udfs = new UserDefinedFunctions(this.container, this.clientContext);
|
6391 | }
|
6392 | return this.$udfs;
|
6393 | }
|
6394 | }
|
6395 |
|
6396 |
|
6397 | class ContainerResponse extends ResourceResponse {
|
6398 | constructor(resource, headers, statusCode, container) {
|
6399 | super(resource, headers, statusCode);
|
6400 | this.container = container;
|
6401 | }
|
6402 | }
|
6403 |
|
6404 | class OfferResponse extends ResourceResponse {
|
6405 | constructor(resource, headers, statusCode, offer) {
|
6406 | super(resource, headers, statusCode);
|
6407 | this.offer = offer;
|
6408 | }
|
6409 | }
|
6410 |
|
6411 |
|
6412 |
|
6413 |
|
6414 |
|
6415 |
|
6416 | class Offer {
|
6417 | |
6418 |
|
6419 |
|
6420 |
|
6421 |
|
6422 | constructor(client, id, clientContext) {
|
6423 | this.client = client;
|
6424 | this.id = id;
|
6425 | this.clientContext = clientContext;
|
6426 | }
|
6427 | |
6428 |
|
6429 |
|
6430 | get url() {
|
6431 | return `/${Constants.Path.OffersPathSegment}/${this.id}`;
|
6432 | }
|
6433 | |
6434 |
|
6435 |
|
6436 | async read(options) {
|
6437 | const response = await this.clientContext.read({
|
6438 | path: this.url,
|
6439 | resourceType: exports.ResourceType.offer,
|
6440 | resourceId: this.id,
|
6441 | options,
|
6442 | });
|
6443 | return new OfferResponse(response.result, response.headers, response.code, this);
|
6444 | }
|
6445 | |
6446 |
|
6447 |
|
6448 |
|
6449 | async replace(body, options) {
|
6450 | const err = {};
|
6451 | if (!isResourceValid(body, err)) {
|
6452 | throw err;
|
6453 | }
|
6454 | const response = await this.clientContext.replace({
|
6455 | body,
|
6456 | path: this.url,
|
6457 | resourceType: exports.ResourceType.offer,
|
6458 | resourceId: this.id,
|
6459 | options,
|
6460 | });
|
6461 | return new OfferResponse(response.result, response.headers, response.code, this);
|
6462 | }
|
6463 | }
|
6464 |
|
6465 |
|
6466 |
|
6467 |
|
6468 |
|
6469 |
|
6470 | class Offers {
|
6471 | |
6472 |
|
6473 |
|
6474 |
|
6475 | constructor(client, clientContext) {
|
6476 | this.client = client;
|
6477 | this.clientContext = clientContext;
|
6478 | }
|
6479 | query(query, options) {
|
6480 | return new QueryIterator(this.clientContext, query, options, (innerOptions) => {
|
6481 | return this.clientContext.queryFeed({
|
6482 | path: "/offers",
|
6483 | resourceType: exports.ResourceType.offer,
|
6484 | resourceId: "",
|
6485 | resultFn: (result) => result.Offers,
|
6486 | query,
|
6487 | options: innerOptions,
|
6488 | });
|
6489 | });
|
6490 | }
|
6491 | |
6492 |
|
6493 |
|
6494 |
|
6495 |
|
6496 |
|
6497 |
|
6498 | readAll(options) {
|
6499 | return this.query(undefined, options);
|
6500 | }
|
6501 | }
|
6502 |
|
6503 |
|
6504 |
|
6505 |
|
6506 |
|
6507 |
|
6508 |
|
6509 |
|
6510 |
|
6511 |
|
6512 |
|
6513 | class Container {
|
6514 | |
6515 |
|
6516 |
|
6517 |
|
6518 |
|
6519 |
|
6520 | constructor(database, id, clientContext) {
|
6521 | this.database = database;
|
6522 | this.id = id;
|
6523 | this.clientContext = clientContext;
|
6524 | }
|
6525 | |
6526 |
|
6527 |
|
6528 |
|
6529 |
|
6530 |
|
6531 |
|
6532 |
|
6533 |
|
6534 |
|
6535 | get items() {
|
6536 | if (!this.$items) {
|
6537 | this.$items = new Items(this, this.clientContext);
|
6538 | }
|
6539 | return this.$items;
|
6540 | }
|
6541 | |
6542 |
|
6543 |
|
6544 | get scripts() {
|
6545 | if (!this.$scripts) {
|
6546 | this.$scripts = new Scripts(this, this.clientContext);
|
6547 | }
|
6548 | return this.$scripts;
|
6549 | }
|
6550 | |
6551 |
|
6552 |
|
6553 |
|
6554 |
|
6555 | get conflicts() {
|
6556 | if (!this.$conflicts) {
|
6557 | this.$conflicts = new Conflicts(this, this.clientContext);
|
6558 | }
|
6559 | return this.$conflicts;
|
6560 | }
|
6561 | |
6562 |
|
6563 |
|
6564 | get url() {
|
6565 | return createDocumentCollectionUri(this.database.id, this.id);
|
6566 | }
|
6567 | |
6568 |
|
6569 |
|
6570 |
|
6571 |
|
6572 |
|
6573 |
|
6574 |
|
6575 |
|
6576 |
|
6577 | item(id, partitionKeyValue) {
|
6578 | return new Item(this, id, partitionKeyValue, this.clientContext);
|
6579 | }
|
6580 | |
6581 |
|
6582 |
|
6583 |
|
6584 |
|
6585 |
|
6586 | conflict(id, partitionKey) {
|
6587 | return new Conflict(this, id, this.clientContext, partitionKey);
|
6588 | }
|
6589 |
|
6590 | async read(options) {
|
6591 | const path = getPathFromLink(this.url);
|
6592 | const id = getIdFromLink(this.url);
|
6593 | const response = await this.clientContext.read({
|
6594 | path,
|
6595 | resourceType: exports.ResourceType.container,
|
6596 | resourceId: id,
|
6597 | options,
|
6598 | });
|
6599 | this.clientContext.partitionKeyDefinitionCache[this.url] = response.result.partitionKey;
|
6600 | return new ContainerResponse(response.result, response.headers, response.code, this);
|
6601 | }
|
6602 |
|
6603 | async replace(body, options) {
|
6604 | const err = {};
|
6605 | if (!isResourceValid(body, err)) {
|
6606 | throw err;
|
6607 | }
|
6608 | const path = getPathFromLink(this.url);
|
6609 | const id = getIdFromLink(this.url);
|
6610 | const response = await this.clientContext.replace({
|
6611 | body,
|
6612 | path,
|
6613 | resourceType: exports.ResourceType.container,
|
6614 | resourceId: id,
|
6615 | options,
|
6616 | });
|
6617 | return new ContainerResponse(response.result, response.headers, response.code, this);
|
6618 | }
|
6619 |
|
6620 | async delete(options) {
|
6621 | const path = getPathFromLink(this.url);
|
6622 | const id = getIdFromLink(this.url);
|
6623 | const response = await this.clientContext.delete({
|
6624 | path,
|
6625 | resourceType: exports.ResourceType.container,
|
6626 | resourceId: id,
|
6627 | options,
|
6628 | });
|
6629 | return new ContainerResponse(response.result, response.headers, response.code, this);
|
6630 | }
|
6631 | |
6632 |
|
6633 |
|
6634 |
|
6635 | async getPartitionKeyDefinition() {
|
6636 | return this.readPartitionKeyDefinition();
|
6637 | }
|
6638 | |
6639 |
|
6640 |
|
6641 |
|
6642 | async readPartitionKeyDefinition() {
|
6643 |
|
6644 |
|
6645 | if (this.url in this.clientContext.partitionKeyDefinitionCache) {
|
6646 | return new ResourceResponse(this.clientContext.partitionKeyDefinitionCache[this.url], {}, 0);
|
6647 | }
|
6648 | const { headers, statusCode } = await this.read();
|
6649 | return new ResourceResponse(this.clientContext.partitionKeyDefinitionCache[this.url], headers, statusCode);
|
6650 | }
|
6651 | |
6652 |
|
6653 |
|
6654 | async readOffer(options = {}) {
|
6655 | const { resource: container } = await this.read();
|
6656 | const path = "/offers";
|
6657 | const url = container._self;
|
6658 | const response = await this.clientContext.queryFeed({
|
6659 | path,
|
6660 | resourceId: "",
|
6661 | resourceType: exports.ResourceType.offer,
|
6662 | query: `SELECT * from root where root.resource = "${url}"`,
|
6663 | resultFn: (result) => result.Offers,
|
6664 | options,
|
6665 | });
|
6666 | const offer = response.result[0]
|
6667 | ? new Offer(this.database.client, response.result[0].id, this.clientContext)
|
6668 | : undefined;
|
6669 | return new OfferResponse(response.result[0], response.headers, response.code, offer);
|
6670 | }
|
6671 | async getQueryPlan(query) {
|
6672 | const path = getPathFromLink(this.url);
|
6673 | return this.clientContext.getQueryPlan(path + "/docs", exports.ResourceType.item, getIdFromLink(this.url), query);
|
6674 | }
|
6675 | readPartitionKeyRanges(feedOptions) {
|
6676 | feedOptions = feedOptions || {};
|
6677 | return this.clientContext.queryPartitionKeyRanges(this.url, undefined, feedOptions);
|
6678 | }
|
6679 | |
6680 |
|
6681 |
|
6682 |
|
6683 | async deleteAllItemsForPartitionKey(partitionKey, options) {
|
6684 | let path = getPathFromLink(this.url);
|
6685 | const id = getIdFromLink(this.url);
|
6686 | path = path + "/operations/partitionkeydelete";
|
6687 | const response = await this.clientContext.delete({
|
6688 | path,
|
6689 | resourceType: exports.ResourceType.container,
|
6690 | resourceId: id,
|
6691 | options,
|
6692 | partitionKey: partitionKey,
|
6693 | method: exports.HTTPMethod.post,
|
6694 | });
|
6695 | return new ContainerResponse(response.result, response.headers, response.code, this);
|
6696 | }
|
6697 | }
|
6698 |
|
6699 |
|
6700 |
|
6701 | function validateOffer(body) {
|
6702 | if (body.throughput) {
|
6703 | if (body.maxThroughput) {
|
6704 | console.log("should be erroring");
|
6705 | throw new Error("Cannot specify `throughput` with `maxThroughput`");
|
6706 | }
|
6707 | if (body.autoUpgradePolicy) {
|
6708 | throw new Error("Cannot specify autoUpgradePolicy with throughput. Use `maxThroughput` instead");
|
6709 | }
|
6710 | }
|
6711 | }
|
6712 |
|
6713 |
|
6714 |
|
6715 |
|
6716 |
|
6717 |
|
6718 |
|
6719 |
|
6720 |
|
6721 |
|
6722 |
|
6723 | class Containers {
|
6724 | constructor(database, clientContext) {
|
6725 | this.database = database;
|
6726 | this.clientContext = clientContext;
|
6727 | }
|
6728 | query(query, options) {
|
6729 | const path = getPathFromLink(this.database.url, exports.ResourceType.container);
|
6730 | const id = getIdFromLink(this.database.url);
|
6731 | return new QueryIterator(this.clientContext, query, options, (innerOptions) => {
|
6732 | return this.clientContext.queryFeed({
|
6733 | path,
|
6734 | resourceType: exports.ResourceType.container,
|
6735 | resourceId: id,
|
6736 | resultFn: (result) => result.DocumentCollections,
|
6737 | query,
|
6738 | options: innerOptions,
|
6739 | });
|
6740 | });
|
6741 | }
|
6742 | |
6743 |
|
6744 |
|
6745 |
|
6746 |
|
6747 |
|
6748 |
|
6749 |
|
6750 |
|
6751 |
|
6752 |
|
6753 |
|
6754 |
|
6755 |
|
6756 |
|
6757 |
|
6758 |
|
6759 | async create(body, options = {}) {
|
6760 | const err = {};
|
6761 | if (!isResourceValid(body, err)) {
|
6762 | throw err;
|
6763 | }
|
6764 | const path = getPathFromLink(this.database.url, exports.ResourceType.container);
|
6765 | const id = getIdFromLink(this.database.url);
|
6766 | validateOffer(body);
|
6767 | if (body.maxThroughput) {
|
6768 | const autoscaleParams = {
|
6769 | maxThroughput: body.maxThroughput,
|
6770 | };
|
6771 | if (body.autoUpgradePolicy) {
|
6772 | autoscaleParams.autoUpgradePolicy = body.autoUpgradePolicy;
|
6773 | }
|
6774 | const autoscaleHeader = JSON.stringify(autoscaleParams);
|
6775 | options.initialHeaders = Object.assign({}, options.initialHeaders, {
|
6776 | [Constants.HttpHeaders.AutoscaleSettings]: autoscaleHeader,
|
6777 | });
|
6778 | delete body.maxThroughput;
|
6779 | delete body.autoUpgradePolicy;
|
6780 | }
|
6781 | if (body.throughput) {
|
6782 | options.initialHeaders = Object.assign({}, options.initialHeaders, {
|
6783 | [Constants.HttpHeaders.OfferThroughput]: body.throughput,
|
6784 | });
|
6785 | delete body.throughput;
|
6786 | }
|
6787 | if (typeof body.partitionKey === "string") {
|
6788 | if (!body.partitionKey.startsWith("/")) {
|
6789 | throw new Error("Partition key must start with '/'");
|
6790 | }
|
6791 | body.partitionKey = {
|
6792 | paths: [body.partitionKey],
|
6793 | };
|
6794 | }
|
6795 |
|
6796 | if (!body.partitionKey || !body.partitionKey.paths) {
|
6797 | body.partitionKey = {
|
6798 | paths: [DEFAULT_PARTITION_KEY_PATH],
|
6799 | };
|
6800 | }
|
6801 | const response = await this.clientContext.create({
|
6802 | body,
|
6803 | path,
|
6804 | resourceType: exports.ResourceType.container,
|
6805 | resourceId: id,
|
6806 | options,
|
6807 | });
|
6808 | const ref = new Container(this.database, response.result.id, this.clientContext);
|
6809 | return new ContainerResponse(response.result, response.headers, response.code, ref);
|
6810 | }
|
6811 | |
6812 |
|
6813 |
|
6814 |
|
6815 |
|
6816 |
|
6817 |
|
6818 |
|
6819 |
|
6820 |
|
6821 |
|
6822 |
|
6823 |
|
6824 |
|
6825 |
|
6826 |
|
6827 |
|
6828 |
|
6829 |
|
6830 | async createIfNotExists(body, options) {
|
6831 | if (!body || body.id === null || body.id === undefined) {
|
6832 | throw new Error("body parameter must be an object with an id property");
|
6833 | }
|
6834 | |
6835 |
|
6836 |
|
6837 |
|
6838 | try {
|
6839 | const readResponse = await this.database.container(body.id).read(options);
|
6840 | return readResponse;
|
6841 | }
|
6842 | catch (err) {
|
6843 | if (err.code === StatusCodes.NotFound) {
|
6844 | const createResponse = await this.create(body, options);
|
6845 |
|
6846 | mergeHeaders(createResponse.headers, err.headers);
|
6847 | return createResponse;
|
6848 | }
|
6849 | else {
|
6850 | throw err;
|
6851 | }
|
6852 | }
|
6853 | }
|
6854 | |
6855 |
|
6856 |
|
6857 |
|
6858 |
|
6859 |
|
6860 |
|
6861 |
|
6862 |
|
6863 | readAll(options) {
|
6864 | return this.query(undefined, options);
|
6865 | }
|
6866 | }
|
6867 |
|
6868 | class PermissionResponse extends ResourceResponse {
|
6869 | constructor(resource, headers, statusCode, permission) {
|
6870 | super(resource, headers, statusCode);
|
6871 | this.permission = permission;
|
6872 | }
|
6873 | }
|
6874 |
|
6875 |
|
6876 |
|
6877 |
|
6878 |
|
6879 |
|
6880 | class Permission {
|
6881 | |
6882 |
|
6883 |
|
6884 |
|
6885 |
|
6886 | constructor(user, id, clientContext) {
|
6887 | this.user = user;
|
6888 | this.id = id;
|
6889 | this.clientContext = clientContext;
|
6890 | }
|
6891 | |
6892 |
|
6893 |
|
6894 | get url() {
|
6895 | return createPermissionUri(this.user.database.id, this.user.id, this.id);
|
6896 | }
|
6897 | |
6898 |
|
6899 |
|
6900 | async read(options) {
|
6901 | const path = getPathFromLink(this.url);
|
6902 | const id = getIdFromLink(this.url);
|
6903 | const response = await this.clientContext.read({
|
6904 | path,
|
6905 | resourceType: exports.ResourceType.permission,
|
6906 | resourceId: id,
|
6907 | options,
|
6908 | });
|
6909 | return new PermissionResponse(response.result, response.headers, response.code, this);
|
6910 | }
|
6911 | |
6912 |
|
6913 |
|
6914 |
|
6915 | async replace(body, options) {
|
6916 | const err = {};
|
6917 | if (!isResourceValid(body, err)) {
|
6918 | throw err;
|
6919 | }
|
6920 | const path = getPathFromLink(this.url);
|
6921 | const id = getIdFromLink(this.url);
|
6922 | const response = await this.clientContext.replace({
|
6923 | body,
|
6924 | path,
|
6925 | resourceType: exports.ResourceType.permission,
|
6926 | resourceId: id,
|
6927 | options,
|
6928 | });
|
6929 | return new PermissionResponse(response.result, response.headers, response.code, this);
|
6930 | }
|
6931 | |
6932 |
|
6933 |
|
6934 | async delete(options) {
|
6935 | const path = getPathFromLink(this.url);
|
6936 | const id = getIdFromLink(this.url);
|
6937 | const response = await this.clientContext.delete({
|
6938 | path,
|
6939 | resourceType: exports.ResourceType.permission,
|
6940 | resourceId: id,
|
6941 | options,
|
6942 | });
|
6943 | return new PermissionResponse(response.result, response.headers, response.code, this);
|
6944 | }
|
6945 | }
|
6946 |
|
6947 |
|
6948 |
|
6949 |
|
6950 |
|
6951 |
|
6952 | class Permissions {
|
6953 | |
6954 |
|
6955 |
|
6956 |
|
6957 | constructor(user, clientContext) {
|
6958 | this.user = user;
|
6959 | this.clientContext = clientContext;
|
6960 | }
|
6961 | query(query, options) {
|
6962 | const path = getPathFromLink(this.user.url, exports.ResourceType.permission);
|
6963 | const id = getIdFromLink(this.user.url);
|
6964 | return new QueryIterator(this.clientContext, query, options, (innerOptions) => {
|
6965 | return this.clientContext.queryFeed({
|
6966 | path,
|
6967 | resourceType: exports.ResourceType.permission,
|
6968 | resourceId: id,
|
6969 | resultFn: (result) => result.Permissions,
|
6970 | query,
|
6971 | options: innerOptions,
|
6972 | });
|
6973 | });
|
6974 | }
|
6975 | |
6976 |
|
6977 |
|
6978 |
|
6979 |
|
6980 |
|
6981 |
|
6982 | readAll(options) {
|
6983 | return this.query(undefined, options);
|
6984 | }
|
6985 | |
6986 |
|
6987 |
|
6988 |
|
6989 |
|
6990 |
|
6991 |
|
6992 | async create(body, options) {
|
6993 | const err = {};
|
6994 | if (!isResourceValid(body, err)) {
|
6995 | throw err;
|
6996 | }
|
6997 | const path = getPathFromLink(this.user.url, exports.ResourceType.permission);
|
6998 | const id = getIdFromLink(this.user.url);
|
6999 | const response = await this.clientContext.create({
|
7000 | body,
|
7001 | path,
|
7002 | resourceType: exports.ResourceType.permission,
|
7003 | resourceId: id,
|
7004 | options,
|
7005 | });
|
7006 | const ref = new Permission(this.user, response.result.id, this.clientContext);
|
7007 | return new PermissionResponse(response.result, response.headers, response.code, ref);
|
7008 | }
|
7009 | |
7010 |
|
7011 |
|
7012 |
|
7013 |
|
7014 |
|
7015 | async upsert(body, options) {
|
7016 | const err = {};
|
7017 | if (!isResourceValid(body, err)) {
|
7018 | throw err;
|
7019 | }
|
7020 | const path = getPathFromLink(this.user.url, exports.ResourceType.permission);
|
7021 | const id = getIdFromLink(this.user.url);
|
7022 | const response = await this.clientContext.upsert({
|
7023 | body,
|
7024 | path,
|
7025 | resourceType: exports.ResourceType.permission,
|
7026 | resourceId: id,
|
7027 | options,
|
7028 | });
|
7029 | const ref = new Permission(this.user, response.result.id, this.clientContext);
|
7030 | return new PermissionResponse(response.result, response.headers, response.code, ref);
|
7031 | }
|
7032 | }
|
7033 |
|
7034 | class UserResponse extends ResourceResponse {
|
7035 | constructor(resource, headers, statusCode, user) {
|
7036 | super(resource, headers, statusCode);
|
7037 | this.user = user;
|
7038 | }
|
7039 | }
|
7040 |
|
7041 |
|
7042 |
|
7043 |
|
7044 |
|
7045 |
|
7046 |
|
7047 |
|
7048 | class User {
|
7049 | |
7050 |
|
7051 |
|
7052 |
|
7053 | constructor(database, id, clientContext) {
|
7054 | this.database = database;
|
7055 | this.id = id;
|
7056 | this.clientContext = clientContext;
|
7057 | this.permissions = new Permissions(this, this.clientContext);
|
7058 | }
|
7059 | |
7060 |
|
7061 |
|
7062 | get url() {
|
7063 | return createUserUri(this.database.id, this.id);
|
7064 | }
|
7065 | |
7066 |
|
7067 |
|
7068 |
|
7069 |
|
7070 | permission(id) {
|
7071 | return new Permission(this, id, this.clientContext);
|
7072 | }
|
7073 | |
7074 |
|
7075 |
|
7076 | async read(options) {
|
7077 | const path = getPathFromLink(this.url);
|
7078 | const id = getIdFromLink(this.url);
|
7079 | const response = await this.clientContext.read({
|
7080 | path,
|
7081 | resourceType: exports.ResourceType.user,
|
7082 | resourceId: id,
|
7083 | options,
|
7084 | });
|
7085 | return new UserResponse(response.result, response.headers, response.code, this);
|
7086 | }
|
7087 | |
7088 |
|
7089 |
|
7090 |
|
7091 | async replace(body, options) {
|
7092 | const err = {};
|
7093 | if (!isResourceValid(body, err)) {
|
7094 | throw err;
|
7095 | }
|
7096 | const path = getPathFromLink(this.url);
|
7097 | const id = getIdFromLink(this.url);
|
7098 | const response = await this.clientContext.replace({
|
7099 | body,
|
7100 | path,
|
7101 | resourceType: exports.ResourceType.user,
|
7102 | resourceId: id,
|
7103 | options,
|
7104 | });
|
7105 | return new UserResponse(response.result, response.headers, response.code, this);
|
7106 | }
|
7107 | |
7108 |
|
7109 |
|
7110 | async delete(options) {
|
7111 | const path = getPathFromLink(this.url);
|
7112 | const id = getIdFromLink(this.url);
|
7113 | const response = await this.clientContext.delete({
|
7114 | path,
|
7115 | resourceType: exports.ResourceType.user,
|
7116 | resourceId: id,
|
7117 | options,
|
7118 | });
|
7119 | return new UserResponse(response.result, response.headers, response.code, this);
|
7120 | }
|
7121 | }
|
7122 |
|
7123 |
|
7124 |
|
7125 |
|
7126 |
|
7127 |
|
7128 | class Users {
|
7129 | |
7130 |
|
7131 |
|
7132 |
|
7133 | constructor(database, clientContext) {
|
7134 | this.database = database;
|
7135 | this.clientContext = clientContext;
|
7136 | }
|
7137 | query(query, options) {
|
7138 | const path = getPathFromLink(this.database.url, exports.ResourceType.user);
|
7139 | const id = getIdFromLink(this.database.url);
|
7140 | return new QueryIterator(this.clientContext, query, options, (innerOptions) => {
|
7141 | return this.clientContext.queryFeed({
|
7142 | path,
|
7143 | resourceType: exports.ResourceType.user,
|
7144 | resourceId: id,
|
7145 | resultFn: (result) => result.Users,
|
7146 | query,
|
7147 | options: innerOptions,
|
7148 | });
|
7149 | });
|
7150 | }
|
7151 | |
7152 |
|
7153 |
|
7154 |
|
7155 |
|
7156 |
|
7157 |
|
7158 | readAll(options) {
|
7159 | return this.query(undefined, options);
|
7160 | }
|
7161 | |
7162 |
|
7163 |
|
7164 |
|
7165 | async create(body, options) {
|
7166 | const err = {};
|
7167 | if (!isResourceValid(body, err)) {
|
7168 | throw err;
|
7169 | }
|
7170 | const path = getPathFromLink(this.database.url, exports.ResourceType.user);
|
7171 | const id = getIdFromLink(this.database.url);
|
7172 | const response = await this.clientContext.create({
|
7173 | body,
|
7174 | path,
|
7175 | resourceType: exports.ResourceType.user,
|
7176 | resourceId: id,
|
7177 | options,
|
7178 | });
|
7179 | const ref = new User(this.database, response.result.id, this.clientContext);
|
7180 | return new UserResponse(response.result, response.headers, response.code, ref);
|
7181 | }
|
7182 | |
7183 |
|
7184 |
|
7185 |
|
7186 | async upsert(body, options) {
|
7187 | const err = {};
|
7188 | if (!isResourceValid(body, err)) {
|
7189 | throw err;
|
7190 | }
|
7191 | const path = getPathFromLink(this.database.url, exports.ResourceType.user);
|
7192 | const id = getIdFromLink(this.database.url);
|
7193 | const response = await this.clientContext.upsert({
|
7194 | body,
|
7195 | path,
|
7196 | resourceType: exports.ResourceType.user,
|
7197 | resourceId: id,
|
7198 | options,
|
7199 | });
|
7200 | const ref = new User(this.database, response.result.id, this.clientContext);
|
7201 | return new UserResponse(response.result, response.headers, response.code, ref);
|
7202 | }
|
7203 | }
|
7204 |
|
7205 |
|
7206 | class DatabaseResponse extends ResourceResponse {
|
7207 | constructor(resource, headers, statusCode, database) {
|
7208 | super(resource, headers, statusCode);
|
7209 | this.database = database;
|
7210 | }
|
7211 | }
|
7212 |
|
7213 |
|
7214 |
|
7215 |
|
7216 |
|
7217 |
|
7218 |
|
7219 |
|
7220 |
|
7221 |
|
7222 |
|
7223 | class Database {
|
7224 | |
7225 |
|
7226 |
|
7227 |
|
7228 | constructor(client, id, clientContext) {
|
7229 | this.client = client;
|
7230 | this.id = id;
|
7231 | this.clientContext = clientContext;
|
7232 | this.containers = new Containers(this, this.clientContext);
|
7233 | this.users = new Users(this, this.clientContext);
|
7234 | }
|
7235 | |
7236 |
|
7237 |
|
7238 | get url() {
|
7239 | return createDatabaseUri(this.id);
|
7240 | }
|
7241 | |
7242 |
|
7243 |
|
7244 |
|
7245 |
|
7246 |
|
7247 |
|
7248 |
|
7249 |
|
7250 |
|
7251 | container(id) {
|
7252 | return new Container(this, id, this.clientContext);
|
7253 | }
|
7254 | |
7255 |
|
7256 |
|
7257 |
|
7258 |
|
7259 | user(id) {
|
7260 | return new User(this, id, this.clientContext);
|
7261 | }
|
7262 |
|
7263 | async read(options) {
|
7264 | const path = getPathFromLink(this.url);
|
7265 | const id = getIdFromLink(this.url);
|
7266 | const response = await this.clientContext.read({
|
7267 | path,
|
7268 | resourceType: exports.ResourceType.database,
|
7269 | resourceId: id,
|
7270 | options,
|
7271 | });
|
7272 | return new DatabaseResponse(response.result, response.headers, response.code, this);
|
7273 | }
|
7274 |
|
7275 | async delete(options) {
|
7276 | const path = getPathFromLink(this.url);
|
7277 | const id = getIdFromLink(this.url);
|
7278 | const response = await this.clientContext.delete({
|
7279 | path,
|
7280 | resourceType: exports.ResourceType.database,
|
7281 | resourceId: id,
|
7282 | options,
|
7283 | });
|
7284 | return new DatabaseResponse(response.result, response.headers, response.code, this);
|
7285 | }
|
7286 | |
7287 |
|
7288 |
|
7289 | async readOffer(options = {}) {
|
7290 | const { resource: record } = await this.read();
|
7291 | const path = "/offers";
|
7292 | const url = record._self;
|
7293 | const response = await this.clientContext.queryFeed({
|
7294 | path,
|
7295 | resourceId: "",
|
7296 | resourceType: exports.ResourceType.offer,
|
7297 | query: `SELECT * from root where root.resource = "${url}"`,
|
7298 | resultFn: (result) => result.Offers,
|
7299 | options,
|
7300 | });
|
7301 | const offer = response.result[0]
|
7302 | ? new Offer(this.client, response.result[0].id, this.clientContext)
|
7303 | : undefined;
|
7304 | return new OfferResponse(response.result[0], response.headers, response.code, offer);
|
7305 | }
|
7306 | }
|
7307 |
|
7308 |
|
7309 |
|
7310 |
|
7311 |
|
7312 |
|
7313 |
|
7314 |
|
7315 |
|
7316 |
|
7317 |
|
7318 | class Databases {
|
7319 | |
7320 |
|
7321 |
|
7322 |
|
7323 | constructor(client, clientContext) {
|
7324 | this.client = client;
|
7325 | this.clientContext = clientContext;
|
7326 | }
|
7327 | query(query, options) {
|
7328 | const cb = (innerOptions) => {
|
7329 | return this.clientContext.queryFeed({
|
7330 | path: "/dbs",
|
7331 | resourceType: exports.ResourceType.database,
|
7332 | resourceId: "",
|
7333 | resultFn: (result) => result.Databases,
|
7334 | query,
|
7335 | options: innerOptions,
|
7336 | });
|
7337 | };
|
7338 | return new QueryIterator(this.clientContext, query, options, cb);
|
7339 | }
|
7340 | |
7341 |
|
7342 |
|
7343 |
|
7344 |
|
7345 |
|
7346 |
|
7347 |
|
7348 |
|
7349 |
|
7350 |
|
7351 |
|
7352 |
|
7353 |
|
7354 | async create(body, options = {}) {
|
7355 | const err = {};
|
7356 | if (!isResourceValid(body, err)) {
|
7357 | throw err;
|
7358 | }
|
7359 | validateOffer(body);
|
7360 | if (body.maxThroughput) {
|
7361 | const autoscaleParams = {
|
7362 | maxThroughput: body.maxThroughput,
|
7363 | };
|
7364 | if (body.autoUpgradePolicy) {
|
7365 | autoscaleParams.autoUpgradePolicy = body.autoUpgradePolicy;
|
7366 | }
|
7367 | const autoscaleHeaders = JSON.stringify(autoscaleParams);
|
7368 | options.initialHeaders = Object.assign({}, options.initialHeaders, {
|
7369 | [Constants.HttpHeaders.AutoscaleSettings]: autoscaleHeaders,
|
7370 | });
|
7371 | delete body.maxThroughput;
|
7372 | delete body.autoUpgradePolicy;
|
7373 | }
|
7374 | if (body.throughput) {
|
7375 | options.initialHeaders = Object.assign({}, options.initialHeaders, {
|
7376 | [Constants.HttpHeaders.OfferThroughput]: body.throughput,
|
7377 | });
|
7378 | delete body.throughput;
|
7379 | }
|
7380 | const path = "/dbs";
|
7381 | const response = await this.clientContext.create({
|
7382 | body,
|
7383 | path,
|
7384 | resourceType: exports.ResourceType.database,
|
7385 | resourceId: undefined,
|
7386 | options,
|
7387 | });
|
7388 | const ref = new Database(this.client, body.id, this.clientContext);
|
7389 | return new DatabaseResponse(response.result, response.headers, response.code, ref);
|
7390 | }
|
7391 | |
7392 |
|
7393 |
|
7394 |
|
7395 |
|
7396 |
|
7397 |
|
7398 |
|
7399 |
|
7400 |
|
7401 |
|
7402 |
|
7403 |
|
7404 |
|
7405 |
|
7406 | async createIfNotExists(body, options) {
|
7407 | if (!body || body.id === null || body.id === undefined) {
|
7408 | throw new Error("body parameter must be an object with an id property");
|
7409 | }
|
7410 | |
7411 |
|
7412 |
|
7413 |
|
7414 | try {
|
7415 | const readResponse = await this.client.database(body.id).read(options);
|
7416 | return readResponse;
|
7417 | }
|
7418 | catch (err) {
|
7419 | if (err.code === StatusCodes.NotFound) {
|
7420 | const createResponse = await this.create(body, options);
|
7421 |
|
7422 | mergeHeaders(createResponse.headers, err.headers);
|
7423 | return createResponse;
|
7424 | }
|
7425 | else {
|
7426 | throw err;
|
7427 | }
|
7428 | }
|
7429 | }
|
7430 |
|
7431 | |
7432 |
|
7433 |
|
7434 |
|
7435 |
|
7436 |
|
7437 |
|
7438 |
|
7439 |
|
7440 | readAll(options) {
|
7441 | return this.query(undefined, options);
|
7442 | }
|
7443 | }
|
7444 |
|
7445 |
|
7446 |
|
7447 |
|
7448 |
|
7449 |
|
7450 | exports.PluginOn = void 0;
|
7451 | (function (PluginOn) {
|
7452 | |
7453 |
|
7454 |
|
7455 | PluginOn["request"] = "request";
|
7456 | |
7457 |
|
7458 |
|
7459 | PluginOn["operation"] = "operation";
|
7460 | })(exports.PluginOn || (exports.PluginOn = {}));
|
7461 |
|
7462 |
|
7463 |
|
7464 | async function executePlugins(requestContext, next, on) {
|
7465 | if (!requestContext.plugins) {
|
7466 | return next(requestContext, undefined);
|
7467 | }
|
7468 | let level = 0;
|
7469 | const _ = (inner) => {
|
7470 | if (++level >= inner.plugins.length) {
|
7471 | return next(requestContext, undefined);
|
7472 | }
|
7473 | else if (inner.plugins[level].on !== on) {
|
7474 | return _(requestContext);
|
7475 | }
|
7476 | else {
|
7477 | return inner.plugins[level].plugin(inner, _);
|
7478 | }
|
7479 | };
|
7480 | if (requestContext.plugins[level].on !== on) {
|
7481 | return _(requestContext);
|
7482 | }
|
7483 | else {
|
7484 | return requestContext.plugins[level].plugin(requestContext, _);
|
7485 | }
|
7486 | }
|
7487 |
|
7488 |
|
7489 |
|
7490 |
|
7491 |
|
7492 |
|
7493 | const WindowsInterruptedFunctionCall = 10004;
|
7494 |
|
7495 |
|
7496 |
|
7497 | const WindowsFileHandleNotValid = 10009;
|
7498 |
|
7499 |
|
7500 |
|
7501 | const WindowsPermissionDenied = 10013;
|
7502 |
|
7503 |
|
7504 |
|
7505 | const WindowsBadAddress = 10014;
|
7506 |
|
7507 |
|
7508 |
|
7509 | const WindowsInvalidArgumnet = 10022;
|
7510 |
|
7511 |
|
7512 |
|
7513 | const WindowsResourceTemporarilyUnavailable = 10035;
|
7514 |
|
7515 |
|
7516 |
|
7517 | const WindowsOperationNowInProgress = 10036;
|
7518 |
|
7519 |
|
7520 |
|
7521 | const WindowsAddressAlreadyInUse = 10048;
|
7522 |
|
7523 |
|
7524 |
|
7525 | const WindowsConnectionResetByPeer = 10054;
|
7526 |
|
7527 |
|
7528 |
|
7529 | const WindowsCannotSendAfterSocketShutdown = 10058;
|
7530 |
|
7531 |
|
7532 |
|
7533 | const WindowsConnectionTimedOut = 10060;
|
7534 |
|
7535 |
|
7536 |
|
7537 | const WindowsConnectionRefused = 10061;
|
7538 |
|
7539 |
|
7540 |
|
7541 | const WindowsNameTooLong = 10063;
|
7542 |
|
7543 |
|
7544 |
|
7545 | const WindowsHostIsDown = 10064;
|
7546 |
|
7547 |
|
7548 |
|
7549 | const WindowsNoRouteTohost = 10065;
|
7550 |
|
7551 |
|
7552 |
|
7553 |
|
7554 |
|
7555 |
|
7556 |
|
7557 | const LinuxConnectionReset = "ECONNRESET";
|
7558 |
|
7559 |
|
7560 |
|
7561 |
|
7562 | const BrokenPipe = "EPIPE";
|
7563 |
|
7564 |
|
7565 |
|
7566 | const CONNECTION_ERROR_CODES = [
|
7567 | WindowsInterruptedFunctionCall,
|
7568 | WindowsFileHandleNotValid,
|
7569 | WindowsPermissionDenied,
|
7570 | WindowsBadAddress,
|
7571 | WindowsInvalidArgumnet,
|
7572 | WindowsResourceTemporarilyUnavailable,
|
7573 | WindowsOperationNowInProgress,
|
7574 | WindowsAddressAlreadyInUse,
|
7575 | WindowsConnectionResetByPeer,
|
7576 | WindowsCannotSendAfterSocketShutdown,
|
7577 | WindowsConnectionTimedOut,
|
7578 | WindowsConnectionRefused,
|
7579 | WindowsNameTooLong,
|
7580 | WindowsHostIsDown,
|
7581 | WindowsNoRouteTohost,
|
7582 | LinuxConnectionReset,
|
7583 | TimeoutErrorCode,
|
7584 | BrokenPipe,
|
7585 | ];
|
7586 |
|
7587 |
|
7588 |
|
7589 | function needsRetry(operationType, code) {
|
7590 | if ((operationType === exports.OperationType.Read || operationType === exports.OperationType.Query) &&
|
7591 | CONNECTION_ERROR_CODES.indexOf(code) !== -1) {
|
7592 | return true;
|
7593 | }
|
7594 | else {
|
7595 | return false;
|
7596 | }
|
7597 | }
|
7598 |
|
7599 |
|
7600 |
|
7601 |
|
7602 | class DefaultRetryPolicy {
|
7603 | constructor(operationType) {
|
7604 | this.operationType = operationType;
|
7605 | this.maxTries = 10;
|
7606 | this.currentRetryAttemptCount = 0;
|
7607 | this.retryAfterInMs = 1000;
|
7608 | }
|
7609 | |
7610 |
|
7611 |
|
7612 |
|
7613 | async shouldRetry(err) {
|
7614 | if (err) {
|
7615 | if (this.currentRetryAttemptCount < this.maxTries &&
|
7616 | needsRetry(this.operationType, err.code)) {
|
7617 | this.currentRetryAttemptCount++;
|
7618 | return true;
|
7619 | }
|
7620 | }
|
7621 | return false;
|
7622 | }
|
7623 | }
|
7624 |
|
7625 |
|
7626 |
|
7627 |
|
7628 |
|
7629 | class EndpointDiscoveryRetryPolicy {
|
7630 | |
7631 |
|
7632 |
|
7633 | constructor(globalEndpointManager, operationType) {
|
7634 | this.globalEndpointManager = globalEndpointManager;
|
7635 | this.operationType = operationType;
|
7636 | this.maxTries = EndpointDiscoveryRetryPolicy.maxTries;
|
7637 | this.currentRetryAttemptCount = 0;
|
7638 | this.retryAfterInMs = EndpointDiscoveryRetryPolicy.retryAfterInMs;
|
7639 | }
|
7640 | |
7641 |
|
7642 |
|
7643 |
|
7644 | async shouldRetry(err, retryContext, locationEndpoint) {
|
7645 | if (!err) {
|
7646 | return false;
|
7647 | }
|
7648 | if (!retryContext || !locationEndpoint) {
|
7649 | return false;
|
7650 | }
|
7651 | if (!this.globalEndpointManager.enableEndpointDiscovery) {
|
7652 | return false;
|
7653 | }
|
7654 | if (this.currentRetryAttemptCount >= this.maxTries) {
|
7655 | return false;
|
7656 | }
|
7657 | this.currentRetryAttemptCount++;
|
7658 | if (isReadRequest(this.operationType)) {
|
7659 | await this.globalEndpointManager.markCurrentLocationUnavailableForRead(locationEndpoint);
|
7660 | }
|
7661 | else {
|
7662 | await this.globalEndpointManager.markCurrentLocationUnavailableForWrite(locationEndpoint);
|
7663 | }
|
7664 | retryContext.retryCount = this.currentRetryAttemptCount;
|
7665 | retryContext.clearSessionTokenNotAvailable = false;
|
7666 | retryContext.retryRequestOnPreferredLocations = false;
|
7667 | return true;
|
7668 | }
|
7669 | }
|
7670 | EndpointDiscoveryRetryPolicy.maxTries = 120;
|
7671 | EndpointDiscoveryRetryPolicy.retryAfterInMs = 1000;
|
7672 |
|
7673 |
|
7674 |
|
7675 |
|
7676 |
|
7677 | class ResourceThrottleRetryPolicy {
|
7678 | |
7679 |
|
7680 |
|
7681 |
|
7682 |
|
7683 |
|
7684 |
|
7685 | constructor(maxTries = 9, fixedRetryIntervalInMs = 0, timeoutInSeconds = 30) {
|
7686 | this.maxTries = maxTries;
|
7687 | this.fixedRetryIntervalInMs = fixedRetryIntervalInMs;
|
7688 |
|
7689 | this.currentRetryAttemptCount = 0;
|
7690 |
|
7691 | this.cummulativeWaitTimeinMs = 0;
|
7692 |
|
7693 | this.retryAfterInMs = 0;
|
7694 | this.timeoutInMs = timeoutInSeconds * 1000;
|
7695 | this.currentRetryAttemptCount = 0;
|
7696 | this.cummulativeWaitTimeinMs = 0;
|
7697 | }
|
7698 | |
7699 |
|
7700 |
|
7701 |
|
7702 | async shouldRetry(err) {
|
7703 |
|
7704 | if (err) {
|
7705 | if (this.currentRetryAttemptCount < this.maxTries) {
|
7706 | this.currentRetryAttemptCount++;
|
7707 | this.retryAfterInMs = 0;
|
7708 | if (this.fixedRetryIntervalInMs) {
|
7709 | this.retryAfterInMs = this.fixedRetryIntervalInMs;
|
7710 | }
|
7711 | else if (err.retryAfterInMs) {
|
7712 | this.retryAfterInMs = err.retryAfterInMs;
|
7713 | }
|
7714 | if (this.cummulativeWaitTimeinMs < this.timeoutInMs) {
|
7715 | this.cummulativeWaitTimeinMs += this.retryAfterInMs;
|
7716 | return true;
|
7717 | }
|
7718 | }
|
7719 | }
|
7720 | return false;
|
7721 | }
|
7722 | }
|
7723 |
|
7724 |
|
7725 |
|
7726 |
|
7727 |
|
7728 |
|
7729 | class SessionRetryPolicy {
|
7730 | |
7731 |
|
7732 |
|
7733 | constructor(globalEndpointManager, resourceType, operationType, connectionPolicy) {
|
7734 | this.globalEndpointManager = globalEndpointManager;
|
7735 | this.resourceType = resourceType;
|
7736 | this.operationType = operationType;
|
7737 | this.connectionPolicy = connectionPolicy;
|
7738 |
|
7739 | this.currentRetryAttemptCount = 0;
|
7740 |
|
7741 | this.retryAfterInMs = 0;
|
7742 | }
|
7743 | |
7744 |
|
7745 |
|
7746 |
|
7747 |
|
7748 |
|
7749 | async shouldRetry(err, retryContext) {
|
7750 | if (!err) {
|
7751 | return false;
|
7752 | }
|
7753 | if (!retryContext) {
|
7754 | return false;
|
7755 | }
|
7756 | if (!this.connectionPolicy.enableEndpointDiscovery) {
|
7757 | return false;
|
7758 | }
|
7759 | if (this.globalEndpointManager.canUseMultipleWriteLocations(this.resourceType, this.operationType)) {
|
7760 |
|
7761 | const endpoints = isReadRequest(this.operationType)
|
7762 | ? await this.globalEndpointManager.getReadEndpoints()
|
7763 | : await this.globalEndpointManager.getWriteEndpoints();
|
7764 | if (this.currentRetryAttemptCount > endpoints.length) {
|
7765 | return false;
|
7766 | }
|
7767 | else {
|
7768 | this.currentRetryAttemptCount++;
|
7769 | retryContext.retryCount++;
|
7770 | retryContext.retryRequestOnPreferredLocations = this.currentRetryAttemptCount > 1;
|
7771 | retryContext.clearSessionTokenNotAvailable =
|
7772 | this.currentRetryAttemptCount === endpoints.length;
|
7773 | return true;
|
7774 | }
|
7775 | }
|
7776 | else {
|
7777 | if (this.currentRetryAttemptCount > 1) {
|
7778 | return false;
|
7779 | }
|
7780 | else {
|
7781 | this.currentRetryAttemptCount++;
|
7782 | retryContext.retryCount++;
|
7783 | retryContext.retryRequestOnPreferredLocations = false;
|
7784 | retryContext.clearSessionTokenNotAvailable = true;
|
7785 | return true;
|
7786 | }
|
7787 | }
|
7788 | }
|
7789 | }
|
7790 |
|
7791 |
|
7792 |
|
7793 |
|
7794 |
|
7795 | async function execute({ retryContext = { retryCount: 0 }, retryPolicies, requestContext, executeRequest, }) {
|
7796 |
|
7797 | if (!retryPolicies) {
|
7798 | retryPolicies = {
|
7799 | endpointDiscoveryRetryPolicy: new EndpointDiscoveryRetryPolicy(requestContext.globalEndpointManager, requestContext.operationType),
|
7800 | resourceThrottleRetryPolicy: new ResourceThrottleRetryPolicy(requestContext.connectionPolicy.retryOptions.maxRetryAttemptCount, requestContext.connectionPolicy.retryOptions.fixedRetryIntervalInMilliseconds, requestContext.connectionPolicy.retryOptions.maxWaitTimeInSeconds),
|
7801 | sessionReadRetryPolicy: new SessionRetryPolicy(requestContext.globalEndpointManager, requestContext.resourceType, requestContext.operationType, requestContext.connectionPolicy),
|
7802 | defaultRetryPolicy: new DefaultRetryPolicy(requestContext.operationType),
|
7803 | };
|
7804 | }
|
7805 | if (retryContext && retryContext.clearSessionTokenNotAvailable) {
|
7806 | requestContext.client.clearSessionToken(requestContext.path);
|
7807 | delete requestContext.headers["x-ms-session-token"];
|
7808 | }
|
7809 | requestContext.endpoint = await requestContext.globalEndpointManager.resolveServiceEndpoint(requestContext.resourceType, requestContext.operationType);
|
7810 | try {
|
7811 | const response = await executeRequest(requestContext);
|
7812 | response.headers[Constants.ThrottleRetryCount] =
|
7813 | retryPolicies.resourceThrottleRetryPolicy.currentRetryAttemptCount;
|
7814 | response.headers[Constants.ThrottleRetryWaitTimeInMs] =
|
7815 | retryPolicies.resourceThrottleRetryPolicy.cummulativeWaitTimeinMs;
|
7816 | return response;
|
7817 | }
|
7818 | catch (err) {
|
7819 |
|
7820 | let retryPolicy = null;
|
7821 | const headers = err.headers || {};
|
7822 | if (err.code === StatusCodes.ENOTFOUND ||
|
7823 | err.code === "REQUEST_SEND_ERROR" ||
|
7824 | (err.code === StatusCodes.Forbidden &&
|
7825 | (err.substatus === SubStatusCodes.DatabaseAccountNotFound ||
|
7826 | err.substatus === SubStatusCodes.WriteForbidden))) {
|
7827 | retryPolicy = retryPolicies.endpointDiscoveryRetryPolicy;
|
7828 | }
|
7829 | else if (err.code === StatusCodes.TooManyRequests) {
|
7830 | retryPolicy = retryPolicies.resourceThrottleRetryPolicy;
|
7831 | }
|
7832 | else if (err.code === StatusCodes.NotFound &&
|
7833 | err.substatus === SubStatusCodes.ReadSessionNotAvailable) {
|
7834 | retryPolicy = retryPolicies.sessionReadRetryPolicy;
|
7835 | }
|
7836 | else {
|
7837 | retryPolicy = retryPolicies.defaultRetryPolicy;
|
7838 | }
|
7839 | const results = await retryPolicy.shouldRetry(err, retryContext, requestContext.endpoint);
|
7840 | if (!results) {
|
7841 | headers[Constants.ThrottleRetryCount] =
|
7842 | retryPolicies.resourceThrottleRetryPolicy.currentRetryAttemptCount;
|
7843 | headers[Constants.ThrottleRetryWaitTimeInMs] =
|
7844 | retryPolicies.resourceThrottleRetryPolicy.cummulativeWaitTimeinMs;
|
7845 | err.headers = Object.assign(Object.assign({}, err.headers), headers);
|
7846 | throw err;
|
7847 | }
|
7848 | else {
|
7849 | requestContext.retryCount++;
|
7850 | const newUrl = results[1];
|
7851 | if (newUrl !== undefined) {
|
7852 | requestContext.endpoint = newUrl;
|
7853 | }
|
7854 | await sleep(retryPolicy.retryAfterInMs);
|
7855 | return execute({
|
7856 | executeRequest,
|
7857 | requestContext,
|
7858 | retryContext,
|
7859 | retryPolicies,
|
7860 | });
|
7861 | }
|
7862 | }
|
7863 | }
|
7864 |
|
7865 |
|
7866 |
|
7867 |
|
7868 | let defaultHttpsAgent;
|
7869 | const https = require("https");
|
7870 | const tls = require("tls");
|
7871 |
|
7872 | if (tls.DEFAULT_MIN_VERSION) {
|
7873 | defaultHttpsAgent = new https.Agent({
|
7874 | keepAlive: true,
|
7875 | minVersion: "TLSv1.2",
|
7876 | });
|
7877 | }
|
7878 | else {
|
7879 |
|
7880 | defaultHttpsAgent = new https.Agent({
|
7881 | keepAlive: true,
|
7882 | secureProtocol: "TLSv1_2_method",
|
7883 | });
|
7884 | }
|
7885 | const http = require("http");
|
7886 |
|
7887 |
|
7888 |
|
7889 | const defaultHttpAgent = new http.Agent({
|
7890 | keepAlive: true,
|
7891 | });
|
7892 |
|
7893 |
|
7894 | let cachedHttpClient;
|
7895 | function getCachedDefaultHttpClient() {
|
7896 | if (!cachedHttpClient) {
|
7897 | cachedHttpClient = coreRestPipeline.createDefaultHttpClient();
|
7898 | }
|
7899 | return cachedHttpClient;
|
7900 | }
|
7901 |
|
7902 |
|
7903 | const logger$1 = logger$4.createClientLogger("RequestHandler");
|
7904 | async function executeRequest(requestContext) {
|
7905 | return executePlugins(requestContext, httpRequest, exports.PluginOn.request);
|
7906 | }
|
7907 |
|
7908 |
|
7909 |
|
7910 | async function httpRequest(requestContext) {
|
7911 | const controller = new nodeAbortController.AbortController();
|
7912 | const signal = controller.signal;
|
7913 |
|
7914 | const userSignal = requestContext.options && requestContext.options.abortSignal;
|
7915 | if (userSignal) {
|
7916 | if (userSignal.aborted) {
|
7917 | controller.abort();
|
7918 | }
|
7919 | else {
|
7920 | userSignal.addEventListener("abort", () => {
|
7921 | controller.abort();
|
7922 | });
|
7923 | }
|
7924 | }
|
7925 | const timeout = setTimeout(() => {
|
7926 | controller.abort();
|
7927 | }, requestContext.connectionPolicy.requestTimeout);
|
7928 | let response;
|
7929 | if (requestContext.body) {
|
7930 | requestContext.body = bodyFromData(requestContext.body);
|
7931 | }
|
7932 | const httpsClient = getCachedDefaultHttpClient();
|
7933 | const url = trimSlashes(requestContext.endpoint) + requestContext.path;
|
7934 | const reqHeaders = coreRestPipeline.createHttpHeaders(requestContext.headers);
|
7935 | const pipelineRequest = coreRestPipeline.createPipelineRequest({
|
7936 | url,
|
7937 | headers: reqHeaders,
|
7938 | method: requestContext.method,
|
7939 | abortSignal: signal,
|
7940 | body: requestContext.body,
|
7941 | });
|
7942 | if (requestContext.requestAgent) {
|
7943 | pipelineRequest.agent = requestContext.requestAgent;
|
7944 | }
|
7945 | else {
|
7946 | const parsedUrl = new URL(url);
|
7947 | pipelineRequest.agent = parsedUrl.protocol === "http" ? defaultHttpAgent : defaultHttpsAgent;
|
7948 | }
|
7949 | try {
|
7950 | if (requestContext.pipeline) {
|
7951 | response = await requestContext.pipeline.sendRequest(httpsClient, pipelineRequest);
|
7952 | }
|
7953 | else {
|
7954 | response = await httpsClient.sendRequest(pipelineRequest);
|
7955 | }
|
7956 | }
|
7957 | catch (error) {
|
7958 | if (error.name === "AbortError") {
|
7959 |
|
7960 | if (userSignal && userSignal.aborted === true) {
|
7961 | clearTimeout(timeout);
|
7962 | throw error;
|
7963 | }
|
7964 |
|
7965 | throw new TimeoutError(`Timeout Error! Request took more than ${requestContext.connectionPolicy.requestTimeout} ms`);
|
7966 | }
|
7967 | throw error;
|
7968 | }
|
7969 | clearTimeout(timeout);
|
7970 | const result = response.status === 204 || response.status === 304 || response.bodyAsText === ""
|
7971 | ? null
|
7972 | : JSON.parse(response.bodyAsText);
|
7973 | const headers = response.headers.toJSON();
|
7974 | const substatus = headers[Constants.HttpHeaders.SubStatus]
|
7975 | ? parseInt(headers[Constants.HttpHeaders.SubStatus], 10)
|
7976 | : undefined;
|
7977 | if (response.status >= 400) {
|
7978 | const errorResponse = new ErrorResponse(result.message);
|
7979 | logger$1.warning(response.status +
|
7980 | " " +
|
7981 | requestContext.endpoint +
|
7982 | " " +
|
7983 | requestContext.path +
|
7984 | " " +
|
7985 | result.message);
|
7986 | errorResponse.code = response.status;
|
7987 | errorResponse.body = result;
|
7988 | errorResponse.headers = headers;
|
7989 | if (Constants.HttpHeaders.ActivityId in headers) {
|
7990 | errorResponse.activityId = headers[Constants.HttpHeaders.ActivityId];
|
7991 | }
|
7992 | if (Constants.HttpHeaders.SubStatus in headers) {
|
7993 | errorResponse.substatus = substatus;
|
7994 | }
|
7995 | if (Constants.HttpHeaders.RetryAfterInMs in headers) {
|
7996 | errorResponse.retryAfterInMs = parseInt(headers[Constants.HttpHeaders.RetryAfterInMs], 10);
|
7997 | Object.defineProperty(errorResponse, "retryAfterInMilliseconds", {
|
7998 | get: () => {
|
7999 | return errorResponse.retryAfterInMs;
|
8000 | },
|
8001 | });
|
8002 | }
|
8003 | throw errorResponse;
|
8004 | }
|
8005 | return {
|
8006 | headers,
|
8007 | result,
|
8008 | code: response.status,
|
8009 | substatus,
|
8010 | };
|
8011 | }
|
8012 |
|
8013 |
|
8014 |
|
8015 | async function request(requestContext) {
|
8016 | if (requestContext.body) {
|
8017 | requestContext.body = bodyFromData(requestContext.body);
|
8018 | if (!requestContext.body) {
|
8019 | throw new Error("parameter data must be a javascript object, string, or Buffer");
|
8020 | }
|
8021 | }
|
8022 | return execute({
|
8023 | requestContext,
|
8024 | executeRequest,
|
8025 | });
|
8026 | }
|
8027 | const RequestHandler = {
|
8028 | request,
|
8029 | };
|
8030 |
|
8031 |
|
8032 |
|
8033 | function atob(str) {
|
8034 | return Buffer.from(str, "base64").toString("binary");
|
8035 | }
|
8036 |
|
8037 |
|
8038 |
|
8039 |
|
8040 |
|
8041 |
|
8042 |
|
8043 |
|
8044 |
|
8045 |
|
8046 |
|
8047 |
|
8048 |
|
8049 |
|
8050 | class VectorSessionToken {
|
8051 | constructor(version, globalLsn, localLsnByregion, sessionToken) {
|
8052 | this.version = version;
|
8053 | this.globalLsn = globalLsn;
|
8054 | this.localLsnByregion = localLsnByregion;
|
8055 | this.sessionToken = sessionToken;
|
8056 | if (!this.sessionToken) {
|
8057 | const regionAndLocalLsn = [];
|
8058 | for (const [key, value] of this.localLsnByregion.entries()) {
|
8059 | regionAndLocalLsn.push(`${key}${VectorSessionToken.REGION_PROGRESS_SEPARATOR}${value}`);
|
8060 | }
|
8061 | const regionProgress = regionAndLocalLsn.join(VectorSessionToken.SEGMENT_SEPARATOR);
|
8062 | if (regionProgress === "") {
|
8063 | this.sessionToken = `${this.version}${VectorSessionToken.SEGMENT_SEPARATOR}${this.globalLsn}`;
|
8064 | }
|
8065 | else {
|
8066 | this.sessionToken = `${this.version}${VectorSessionToken.SEGMENT_SEPARATOR}${this.globalLsn}${VectorSessionToken.SEGMENT_SEPARATOR}${regionProgress}`;
|
8067 | }
|
8068 | }
|
8069 | }
|
8070 | static create(sessionToken) {
|
8071 | const [versionStr, globalLsnStr, ...regionSegments] = sessionToken.split(VectorSessionToken.SEGMENT_SEPARATOR);
|
8072 | const version = parseInt(versionStr, 10);
|
8073 | const globalLsn = parseFloat(globalLsnStr);
|
8074 | if (typeof version !== "number" || typeof globalLsn !== "number") {
|
8075 | return null;
|
8076 | }
|
8077 | const lsnByRegion = new Map();
|
8078 | for (const regionSegment of regionSegments) {
|
8079 | const [regionIdStr, localLsnStr] = regionSegment.split(VectorSessionToken.REGION_PROGRESS_SEPARATOR);
|
8080 | if (!regionIdStr || !localLsnStr) {
|
8081 | return null;
|
8082 | }
|
8083 | const regionId = parseInt(regionIdStr, 10);
|
8084 | let localLsn;
|
8085 | try {
|
8086 | localLsn = localLsnStr;
|
8087 | }
|
8088 | catch (err) {
|
8089 |
|
8090 | return null;
|
8091 | }
|
8092 | if (typeof regionId !== "number") {
|
8093 | return null;
|
8094 | }
|
8095 | lsnByRegion.set(regionId, localLsn);
|
8096 | }
|
8097 | return new VectorSessionToken(version, globalLsn, lsnByRegion, sessionToken);
|
8098 | }
|
8099 | equals(other) {
|
8100 | return !other
|
8101 | ? false
|
8102 | : this.version === other.version &&
|
8103 | this.globalLsn === other.globalLsn &&
|
8104 | this.areRegionProgressEqual(other.localLsnByregion);
|
8105 | }
|
8106 | merge(other) {
|
8107 | if (other == null) {
|
8108 | throw new Error("other (Vector Session Token) must not be null");
|
8109 | }
|
8110 | if (this.version === other.version &&
|
8111 | this.localLsnByregion.size !== other.localLsnByregion.size) {
|
8112 | throw new Error(`Compared session tokens ${this.sessionToken} and ${other.sessionToken} have unexpected regions`);
|
8113 | }
|
8114 | const [higherVersionSessionToken, lowerVersionSessionToken] = this.version < other.version ? [other, this] : [this, other];
|
8115 | const highestLocalLsnByRegion = new Map();
|
8116 | for (const [regionId, highLocalLsn] of higherVersionSessionToken.localLsnByregion.entries()) {
|
8117 | const lowLocalLsn = lowerVersionSessionToken.localLsnByregion.get(regionId);
|
8118 | if (lowLocalLsn) {
|
8119 | highestLocalLsnByRegion.set(regionId, max(highLocalLsn, lowLocalLsn));
|
8120 | }
|
8121 | else if (this.version === other.version) {
|
8122 | throw new Error(`Compared session tokens have unexpected regions. Session 1: ${this.sessionToken} - Session 2: ${this.sessionToken}`);
|
8123 | }
|
8124 | else {
|
8125 | highestLocalLsnByRegion.set(regionId, highLocalLsn);
|
8126 | }
|
8127 | }
|
8128 | return new VectorSessionToken(Math.max(this.version, other.version), Math.max(this.globalLsn, other.globalLsn), highestLocalLsnByRegion);
|
8129 | }
|
8130 | toString() {
|
8131 | return this.sessionToken;
|
8132 | }
|
8133 | areRegionProgressEqual(other) {
|
8134 | if (this.localLsnByregion.size !== other.size) {
|
8135 | return false;
|
8136 | }
|
8137 | for (const [regionId, localLsn] of this.localLsnByregion.entries()) {
|
8138 | const otherLocalLsn = other.get(regionId);
|
8139 | if (localLsn !== otherLocalLsn) {
|
8140 | return false;
|
8141 | }
|
8142 | }
|
8143 | return true;
|
8144 | }
|
8145 | }
|
8146 | VectorSessionToken.SEGMENT_SEPARATOR = "#";
|
8147 | VectorSessionToken.REGION_PROGRESS_SEPARATOR = "=";
|
8148 |
|
8149 |
|
8150 |
|
8151 | function max(int1, int2) {
|
8152 |
|
8153 | if (int1.length === int2.length) {
|
8154 | return int1 > int2 ? int1 : int2;
|
8155 | }
|
8156 | else if (int1.length > int2.length) {
|
8157 | return int1;
|
8158 | }
|
8159 | else {
|
8160 | return int2;
|
8161 | }
|
8162 | }
|
8163 |
|
8164 |
|
8165 |
|
8166 | class SessionContainer {
|
8167 | constructor(collectionNameToCollectionResourceId = new Map(), collectionResourceIdToSessionTokens = new Map()) {
|
8168 | this.collectionNameToCollectionResourceId = collectionNameToCollectionResourceId;
|
8169 | this.collectionResourceIdToSessionTokens = collectionResourceIdToSessionTokens;
|
8170 | }
|
8171 | get(request) {
|
8172 | if (!request) {
|
8173 | throw new Error("request cannot be null");
|
8174 | }
|
8175 | const collectionName = getContainerLink(trimSlashes(request.resourceAddress));
|
8176 | const rangeIdToTokenMap = this.getPartitionKeyRangeIdToTokenMap(collectionName);
|
8177 | return SessionContainer.getCombinedSessionTokenString(rangeIdToTokenMap);
|
8178 | }
|
8179 | remove(request) {
|
8180 | let collectionResourceId;
|
8181 | const resourceAddress = trimSlashes(request.resourceAddress);
|
8182 | const collectionName = getContainerLink(resourceAddress);
|
8183 | if (collectionName) {
|
8184 | collectionResourceId = this.collectionNameToCollectionResourceId.get(collectionName);
|
8185 | this.collectionNameToCollectionResourceId.delete(collectionName);
|
8186 | }
|
8187 | if (collectionResourceId !== undefined) {
|
8188 | this.collectionResourceIdToSessionTokens.delete(collectionResourceId);
|
8189 | }
|
8190 | }
|
8191 | set(request, resHeaders) {
|
8192 |
|
8193 | if (!resHeaders ||
|
8194 | SessionContainer.isReadingFromMaster(request.resourceType, request.operationType)) {
|
8195 | return;
|
8196 | }
|
8197 | const sessionTokenString = resHeaders[Constants.HttpHeaders.SessionToken];
|
8198 | if (!sessionTokenString) {
|
8199 | return;
|
8200 | }
|
8201 | const containerName = this.getContainerName(request, resHeaders);
|
8202 | const ownerId = !request.isNameBased
|
8203 | ? request.resourceId
|
8204 | : resHeaders[Constants.HttpHeaders.OwnerId] || request.resourceId;
|
8205 | if (!ownerId) {
|
8206 | return;
|
8207 | }
|
8208 | if (containerName && this.validateOwnerID(ownerId)) {
|
8209 | if (!this.collectionResourceIdToSessionTokens.has(ownerId)) {
|
8210 | this.collectionResourceIdToSessionTokens.set(ownerId, new Map());
|
8211 | }
|
8212 | if (!this.collectionNameToCollectionResourceId.has(containerName)) {
|
8213 | this.collectionNameToCollectionResourceId.set(containerName, ownerId);
|
8214 | }
|
8215 | const containerSessionContainer = this.collectionResourceIdToSessionTokens.get(ownerId);
|
8216 | SessionContainer.compareAndSetToken(sessionTokenString, containerSessionContainer);
|
8217 | }
|
8218 | }
|
8219 | validateOwnerID(ownerId) {
|
8220 |
|
8221 |
|
8222 |
|
8223 |
|
8224 | return atob(ownerId.replace(/-/g, "/")).length === 8;
|
8225 | }
|
8226 | getPartitionKeyRangeIdToTokenMap(collectionName) {
|
8227 | let rangeIdToTokenMap = null;
|
8228 | if (collectionName && this.collectionNameToCollectionResourceId.has(collectionName)) {
|
8229 | rangeIdToTokenMap = this.collectionResourceIdToSessionTokens.get(this.collectionNameToCollectionResourceId.get(collectionName));
|
8230 | }
|
8231 | return rangeIdToTokenMap;
|
8232 | }
|
8233 | static getCombinedSessionTokenString(tokens) {
|
8234 | if (!tokens || tokens.size === 0) {
|
8235 | return SessionContainer.EMPTY_SESSION_TOKEN;
|
8236 | }
|
8237 | let result = "";
|
8238 | for (const [range, token] of tokens.entries()) {
|
8239 | result +=
|
8240 | range +
|
8241 | SessionContainer.SESSION_TOKEN_PARTITION_SPLITTER +
|
8242 | token.toString() +
|
8243 | SessionContainer.SESSION_TOKEN_SEPARATOR;
|
8244 | }
|
8245 | return result.slice(0, -1);
|
8246 | }
|
8247 | static compareAndSetToken(newTokenString, containerSessionTokens) {
|
8248 | if (!newTokenString) {
|
8249 | return;
|
8250 | }
|
8251 | const partitionsParts = newTokenString.split(SessionContainer.SESSION_TOKEN_SEPARATOR);
|
8252 | for (const partitionPart of partitionsParts) {
|
8253 | const newTokenParts = partitionPart.split(SessionContainer.SESSION_TOKEN_PARTITION_SPLITTER);
|
8254 | if (newTokenParts.length !== 2) {
|
8255 | return;
|
8256 | }
|
8257 | const range = newTokenParts[0];
|
8258 | const newToken = VectorSessionToken.create(newTokenParts[1]);
|
8259 | const tokenForRange = !containerSessionTokens.get(range)
|
8260 | ? newToken
|
8261 | : containerSessionTokens.get(range).merge(newToken);
|
8262 | containerSessionTokens.set(range, tokenForRange);
|
8263 | }
|
8264 | }
|
8265 |
|
8266 | static isReadingFromMaster(resourceType, operationType) {
|
8267 | if (resourceType === Constants.Path.OffersPathSegment ||
|
8268 | resourceType === Constants.Path.DatabasesPathSegment ||
|
8269 | resourceType === Constants.Path.UsersPathSegment ||
|
8270 | resourceType === Constants.Path.PermissionsPathSegment ||
|
8271 | resourceType === Constants.Path.TopologyPathSegment ||
|
8272 | resourceType === Constants.Path.DatabaseAccountPathSegment ||
|
8273 | resourceType === Constants.Path.PartitionKeyRangesPathSegment ||
|
8274 | (resourceType === Constants.Path.CollectionsPathSegment &&
|
8275 | operationType === exports.OperationType.Query)) {
|
8276 | return true;
|
8277 | }
|
8278 | return false;
|
8279 | }
|
8280 | getContainerName(request, headers) {
|
8281 | let ownerFullName = headers[Constants.HttpHeaders.OwnerFullName];
|
8282 | if (!ownerFullName) {
|
8283 | ownerFullName = trimSlashes(request.resourceAddress);
|
8284 | }
|
8285 | return getContainerLink(ownerFullName);
|
8286 | }
|
8287 | }
|
8288 | SessionContainer.EMPTY_SESSION_TOKEN = "";
|
8289 | SessionContainer.SESSION_TOKEN_SEPARATOR = ",";
|
8290 | SessionContainer.SESSION_TOKEN_PARTITION_SPLITTER = ":";
|
8291 |
|
8292 |
|
8293 |
|
8294 | function checkURL(testString) {
|
8295 | return new URL(testString);
|
8296 | }
|
8297 | function sanitizeEndpoint(url) {
|
8298 | return new URL(url).href.replace(/\/$/, "");
|
8299 | }
|
8300 |
|
8301 |
|
8302 | const uuid = uuid$3.v4;
|
8303 | const logger = logger$4.createClientLogger("ClientContext");
|
8304 | const QueryJsonContentType = "application/query+json";
|
8305 |
|
8306 |
|
8307 |
|
8308 |
|
8309 | class ClientContext {
|
8310 | constructor(cosmosClientOptions, globalEndpointManager) {
|
8311 | this.cosmosClientOptions = cosmosClientOptions;
|
8312 | this.globalEndpointManager = globalEndpointManager;
|
8313 | this.connectionPolicy = cosmosClientOptions.connectionPolicy;
|
8314 | this.sessionContainer = new SessionContainer();
|
8315 | this.partitionKeyDefinitionCache = {};
|
8316 | this.pipeline = null;
|
8317 | if (cosmosClientOptions.aadCredentials) {
|
8318 | this.pipeline = coreRestPipeline.createEmptyPipeline();
|
8319 | const hrefEndpoint = sanitizeEndpoint(cosmosClientOptions.endpoint);
|
8320 | const scope = `${hrefEndpoint}/.default`;
|
8321 | this.pipeline.addPolicy(coreRestPipeline.bearerTokenAuthenticationPolicy({
|
8322 | credential: cosmosClientOptions.aadCredentials,
|
8323 | scopes: scope,
|
8324 | challengeCallbacks: {
|
8325 | async authorizeRequest({ request, getAccessToken }) {
|
8326 | const tokenResponse = await getAccessToken([scope], {});
|
8327 | const AUTH_PREFIX = `type=aad&ver=1.0&sig=`;
|
8328 | const authorizationToken = `${AUTH_PREFIX}${tokenResponse.token}`;
|
8329 | request.headers.set("Authorization", authorizationToken);
|
8330 | },
|
8331 | },
|
8332 | }));
|
8333 | }
|
8334 | }
|
8335 |
|
8336 | async read({ path, resourceType, resourceId, options = {}, partitionKey, }) {
|
8337 | try {
|
8338 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.get, path, operationType: exports.OperationType.Read, resourceId,
|
8339 | options,
|
8340 | resourceType,
|
8341 | partitionKey });
|
8342 | request.headers = await this.buildHeaders(request);
|
8343 | this.applySessionToken(request);
|
8344 |
|
8345 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8346 | const response = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8347 | this.captureSessionToken(undefined, path, exports.OperationType.Read, response.headers);
|
8348 | return response;
|
8349 | }
|
8350 | catch (err) {
|
8351 | this.captureSessionToken(err, path, exports.OperationType.Upsert, err.headers);
|
8352 | throw err;
|
8353 | }
|
8354 | }
|
8355 | async queryFeed({ path, resourceType, resourceId, resultFn, query, options, partitionKeyRangeId, partitionKey, }) {
|
8356 |
|
8357 |
|
8358 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.get, path, operationType: exports.OperationType.Query, partitionKeyRangeId,
|
8359 | resourceId,
|
8360 | resourceType,
|
8361 | options, body: query, partitionKey });
|
8362 | const requestId = uuid();
|
8363 | if (query !== undefined) {
|
8364 | request.method = exports.HTTPMethod.post;
|
8365 | }
|
8366 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8367 | request.headers = await this.buildHeaders(request);
|
8368 | if (query !== undefined) {
|
8369 | request.headers[Constants.HttpHeaders.IsQuery] = "true";
|
8370 | request.headers[Constants.HttpHeaders.ContentType] = QueryJsonContentType;
|
8371 | if (typeof query === "string") {
|
8372 | request.body = { query };
|
8373 | }
|
8374 | }
|
8375 | this.applySessionToken(request);
|
8376 | logger.info("query " +
|
8377 | requestId +
|
8378 | " started" +
|
8379 | (request.partitionKeyRangeId ? " pkrid: " + request.partitionKeyRangeId : ""));
|
8380 | logger.verbose(request);
|
8381 | const start = Date.now();
|
8382 | const response = await RequestHandler.request(request);
|
8383 | logger.info("query " + requestId + " finished - " + (Date.now() - start) + "ms");
|
8384 | this.captureSessionToken(undefined, path, exports.OperationType.Query, response.headers);
|
8385 | return this.processQueryFeedResponse(response, !!query, resultFn);
|
8386 | }
|
8387 | async getQueryPlan(path, resourceType, resourceId, query, options = {}) {
|
8388 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.post, path, operationType: exports.OperationType.Read, resourceId,
|
8389 | resourceType,
|
8390 | options, body: query });
|
8391 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8392 | request.headers = await this.buildHeaders(request);
|
8393 | request.headers[Constants.HttpHeaders.IsQueryPlan] = "True";
|
8394 | request.headers[Constants.HttpHeaders.QueryVersion] = "1.4";
|
8395 | request.headers[Constants.HttpHeaders.SupportedQueryFeatures] =
|
8396 | "NonValueAggregate, Aggregate, Distinct, MultipleOrderBy, OffsetAndLimit, OrderBy, Top, CompositeAggregate, GroupBy, MultipleAggregates";
|
8397 | request.headers[Constants.HttpHeaders.ContentType] = QueryJsonContentType;
|
8398 | if (typeof query === "string") {
|
8399 | request.body = { query };
|
8400 | }
|
8401 | this.applySessionToken(request);
|
8402 | const response = await RequestHandler.request(request);
|
8403 | this.captureSessionToken(undefined, path, exports.OperationType.Query, response.headers);
|
8404 | return response;
|
8405 | }
|
8406 | queryPartitionKeyRanges(collectionLink, query, options) {
|
8407 | const path = getPathFromLink(collectionLink, exports.ResourceType.pkranges);
|
8408 | const id = getIdFromLink(collectionLink);
|
8409 | const cb = (innerOptions) => {
|
8410 | return this.queryFeed({
|
8411 | path,
|
8412 | resourceType: exports.ResourceType.pkranges,
|
8413 | resourceId: id,
|
8414 | resultFn: (result) => result.PartitionKeyRanges,
|
8415 | query,
|
8416 | options: innerOptions,
|
8417 | });
|
8418 | };
|
8419 | return new QueryIterator(this, query, options, cb);
|
8420 | }
|
8421 | async delete({ path, resourceType, resourceId, options = {}, partitionKey, method = exports.HTTPMethod.delete, }) {
|
8422 | try {
|
8423 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: method, operationType: exports.OperationType.Delete, path,
|
8424 | resourceType,
|
8425 | options,
|
8426 | resourceId,
|
8427 | partitionKey });
|
8428 | request.headers = await this.buildHeaders(request);
|
8429 | this.applySessionToken(request);
|
8430 |
|
8431 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8432 | const response = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8433 | if (parseLink(path).type !== "colls") {
|
8434 | this.captureSessionToken(undefined, path, exports.OperationType.Delete, response.headers);
|
8435 | }
|
8436 | else {
|
8437 | this.clearSessionToken(path);
|
8438 | }
|
8439 | return response;
|
8440 | }
|
8441 | catch (err) {
|
8442 | this.captureSessionToken(err, path, exports.OperationType.Upsert, err.headers);
|
8443 | throw err;
|
8444 | }
|
8445 | }
|
8446 | async patch({ body, path, resourceType, resourceId, options = {}, partitionKey, }) {
|
8447 | try {
|
8448 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.patch, operationType: exports.OperationType.Patch, path,
|
8449 | resourceType,
|
8450 | body,
|
8451 | resourceId,
|
8452 | options,
|
8453 | partitionKey });
|
8454 | request.headers = await this.buildHeaders(request);
|
8455 | this.applySessionToken(request);
|
8456 |
|
8457 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8458 | const response = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8459 | this.captureSessionToken(undefined, path, exports.OperationType.Patch, response.headers);
|
8460 | return response;
|
8461 | }
|
8462 | catch (err) {
|
8463 | this.captureSessionToken(err, path, exports.OperationType.Upsert, err.headers);
|
8464 | throw err;
|
8465 | }
|
8466 | }
|
8467 | async create({ body, path, resourceType, resourceId, options = {}, partitionKey, }) {
|
8468 | try {
|
8469 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.post, operationType: exports.OperationType.Create, path,
|
8470 | resourceType,
|
8471 | resourceId,
|
8472 | body,
|
8473 | options,
|
8474 | partitionKey });
|
8475 | request.headers = await this.buildHeaders(request);
|
8476 |
|
8477 | this.applySessionToken(request);
|
8478 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8479 | const response = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8480 | this.captureSessionToken(undefined, path, exports.OperationType.Create, response.headers);
|
8481 | return response;
|
8482 | }
|
8483 | catch (err) {
|
8484 | this.captureSessionToken(err, path, exports.OperationType.Upsert, err.headers);
|
8485 | throw err;
|
8486 | }
|
8487 | }
|
8488 | processQueryFeedResponse(res, isQuery, resultFn) {
|
8489 | if (isQuery) {
|
8490 | return { result: resultFn(res.result), headers: res.headers, code: res.code };
|
8491 | }
|
8492 | else {
|
8493 | const newResult = resultFn(res.result).map((body) => body);
|
8494 | return { result: newResult, headers: res.headers, code: res.code };
|
8495 | }
|
8496 | }
|
8497 | applySessionToken(requestContext) {
|
8498 | const request = this.getSessionParams(requestContext.path);
|
8499 | if (requestContext.headers && requestContext.headers[Constants.HttpHeaders.SessionToken]) {
|
8500 | return;
|
8501 | }
|
8502 | const sessionConsistency = requestContext.headers[Constants.HttpHeaders.ConsistencyLevel];
|
8503 | if (!sessionConsistency) {
|
8504 | return;
|
8505 | }
|
8506 | if (sessionConsistency !== exports.ConsistencyLevel.Session) {
|
8507 | return;
|
8508 | }
|
8509 | if (request.resourceAddress) {
|
8510 | const sessionToken = this.sessionContainer.get(request);
|
8511 | if (sessionToken) {
|
8512 | requestContext.headers[Constants.HttpHeaders.SessionToken] = sessionToken;
|
8513 | }
|
8514 | }
|
8515 | }
|
8516 | async replace({ body, path, resourceType, resourceId, options = {}, partitionKey, }) {
|
8517 | try {
|
8518 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.put, operationType: exports.OperationType.Replace, path,
|
8519 | resourceType,
|
8520 | body,
|
8521 | resourceId,
|
8522 | options,
|
8523 | partitionKey });
|
8524 | request.headers = await this.buildHeaders(request);
|
8525 | this.applySessionToken(request);
|
8526 |
|
8527 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8528 | const response = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8529 | this.captureSessionToken(undefined, path, exports.OperationType.Replace, response.headers);
|
8530 | return response;
|
8531 | }
|
8532 | catch (err) {
|
8533 | this.captureSessionToken(err, path, exports.OperationType.Upsert, err.headers);
|
8534 | throw err;
|
8535 | }
|
8536 | }
|
8537 | async upsert({ body, path, resourceType, resourceId, options = {}, partitionKey, }) {
|
8538 | try {
|
8539 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.post, operationType: exports.OperationType.Upsert, path,
|
8540 | resourceType,
|
8541 | body,
|
8542 | resourceId,
|
8543 | options,
|
8544 | partitionKey });
|
8545 | request.headers = await this.buildHeaders(request);
|
8546 | request.headers[Constants.HttpHeaders.IsUpsert] = true;
|
8547 | this.applySessionToken(request);
|
8548 |
|
8549 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8550 | const response = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8551 | this.captureSessionToken(undefined, path, exports.OperationType.Upsert, response.headers);
|
8552 | return response;
|
8553 | }
|
8554 | catch (err) {
|
8555 | this.captureSessionToken(err, path, exports.OperationType.Upsert, err.headers);
|
8556 | throw err;
|
8557 | }
|
8558 | }
|
8559 | async execute({ sprocLink, params, options = {}, partitionKey, }) {
|
8560 |
|
8561 |
|
8562 | if (params !== null && params !== undefined && !Array.isArray(params)) {
|
8563 | params = [params];
|
8564 | }
|
8565 | const path = getPathFromLink(sprocLink);
|
8566 | const id = getIdFromLink(sprocLink);
|
8567 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.post, operationType: exports.OperationType.Execute, path, resourceType: exports.ResourceType.sproc, options, resourceId: id, body: params, partitionKey });
|
8568 | request.headers = await this.buildHeaders(request);
|
8569 |
|
8570 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8571 | return executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8572 | }
|
8573 | |
8574 |
|
8575 |
|
8576 |
|
8577 |
|
8578 | async getDatabaseAccount(options = {}) {
|
8579 | const endpoint = options.urlConnection || this.cosmosClientOptions.endpoint;
|
8580 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { endpoint, method: exports.HTTPMethod.get, operationType: exports.OperationType.Read, path: "", resourceType: exports.ResourceType.none, options });
|
8581 | request.headers = await this.buildHeaders(request);
|
8582 |
|
8583 | const { result, headers } = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8584 | const databaseAccount = new DatabaseAccount(result, headers);
|
8585 | return { result: databaseAccount, headers };
|
8586 | }
|
8587 | getWriteEndpoint() {
|
8588 | return this.globalEndpointManager.getWriteEndpoint();
|
8589 | }
|
8590 | getReadEndpoint() {
|
8591 | return this.globalEndpointManager.getReadEndpoint();
|
8592 | }
|
8593 | getWriteEndpoints() {
|
8594 | return this.globalEndpointManager.getWriteEndpoints();
|
8595 | }
|
8596 | getReadEndpoints() {
|
8597 | return this.globalEndpointManager.getReadEndpoints();
|
8598 | }
|
8599 | async batch({ body, path, partitionKey, resourceId, options = {}, }) {
|
8600 | try {
|
8601 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.post, operationType: exports.OperationType.Batch, path,
|
8602 | body, resourceType: exports.ResourceType.item, resourceId,
|
8603 | options,
|
8604 | partitionKey });
|
8605 | request.headers = await this.buildHeaders(request);
|
8606 | request.headers[Constants.HttpHeaders.IsBatchRequest] = true;
|
8607 | request.headers[Constants.HttpHeaders.IsBatchAtomic] = true;
|
8608 | this.applySessionToken(request);
|
8609 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8610 | const response = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8611 | this.captureSessionToken(undefined, path, exports.OperationType.Batch, response.headers);
|
8612 | return response;
|
8613 | }
|
8614 | catch (err) {
|
8615 | this.captureSessionToken(err, path, exports.OperationType.Upsert, err.headers);
|
8616 | throw err;
|
8617 | }
|
8618 | }
|
8619 | async bulk({ body, path, partitionKeyRangeId, resourceId, bulkOptions = {}, options = {}, }) {
|
8620 | try {
|
8621 | const request = Object.assign(Object.assign({}, this.getContextDerivedPropsForRequestCreation()), { method: exports.HTTPMethod.post, operationType: exports.OperationType.Batch, path,
|
8622 | body, resourceType: exports.ResourceType.item, resourceId,
|
8623 | options });
|
8624 | request.headers = await this.buildHeaders(request);
|
8625 | request.headers[Constants.HttpHeaders.IsBatchRequest] = true;
|
8626 | request.headers[Constants.HttpHeaders.PartitionKeyRangeID] = partitionKeyRangeId;
|
8627 | request.headers[Constants.HttpHeaders.IsBatchAtomic] = false;
|
8628 | request.headers[Constants.HttpHeaders.BatchContinueOnError] =
|
8629 | bulkOptions.continueOnError || false;
|
8630 | this.applySessionToken(request);
|
8631 | request.endpoint = await this.globalEndpointManager.resolveServiceEndpoint(request.resourceType, request.operationType);
|
8632 | const response = await executePlugins(request, RequestHandler.request, exports.PluginOn.operation);
|
8633 | this.captureSessionToken(undefined, path, exports.OperationType.Batch, response.headers);
|
8634 | return response;
|
8635 | }
|
8636 | catch (err) {
|
8637 | this.captureSessionToken(err, path, exports.OperationType.Upsert, err.headers);
|
8638 | throw err;
|
8639 | }
|
8640 | }
|
8641 | captureSessionToken(err, path, operationType, resHeaders) {
|
8642 | const request = this.getSessionParams(path);
|
8643 | request.operationType = operationType;
|
8644 | if (!err ||
|
8645 | (!this.isMasterResource(request.resourceType) &&
|
8646 | (err.code === StatusCodes.PreconditionFailed ||
|
8647 | err.code === StatusCodes.Conflict ||
|
8648 | (err.code === StatusCodes.NotFound &&
|
8649 | err.substatus !== SubStatusCodes.ReadSessionNotAvailable)))) {
|
8650 | this.sessionContainer.set(request, resHeaders);
|
8651 | }
|
8652 | }
|
8653 | clearSessionToken(path) {
|
8654 | const request = this.getSessionParams(path);
|
8655 | this.sessionContainer.remove(request);
|
8656 | }
|
8657 | getSessionParams(resourceLink) {
|
8658 | const resourceId = null;
|
8659 | let resourceAddress = null;
|
8660 | const parserOutput = parseLink(resourceLink);
|
8661 | resourceAddress = parserOutput.objectBody.self;
|
8662 | const resourceType = parserOutput.type;
|
8663 | return {
|
8664 | resourceId,
|
8665 | resourceAddress,
|
8666 | resourceType,
|
8667 | isNameBased: true,
|
8668 | };
|
8669 | }
|
8670 | isMasterResource(resourceType) {
|
8671 | if (resourceType === Constants.Path.OffersPathSegment ||
|
8672 | resourceType === Constants.Path.DatabasesPathSegment ||
|
8673 | resourceType === Constants.Path.UsersPathSegment ||
|
8674 | resourceType === Constants.Path.PermissionsPathSegment ||
|
8675 | resourceType === Constants.Path.TopologyPathSegment ||
|
8676 | resourceType === Constants.Path.DatabaseAccountPathSegment ||
|
8677 | resourceType === Constants.Path.PartitionKeyRangesPathSegment ||
|
8678 | resourceType === Constants.Path.CollectionsPathSegment) {
|
8679 | return true;
|
8680 | }
|
8681 | return false;
|
8682 | }
|
8683 | buildHeaders(requestContext) {
|
8684 | return getHeaders({
|
8685 | clientOptions: this.cosmosClientOptions,
|
8686 | defaultHeaders: Object.assign(Object.assign({}, this.cosmosClientOptions.defaultHeaders), requestContext.options.initialHeaders),
|
8687 | verb: requestContext.method,
|
8688 | path: requestContext.path,
|
8689 | resourceId: requestContext.resourceId,
|
8690 | resourceType: requestContext.resourceType,
|
8691 | options: requestContext.options,
|
8692 | partitionKeyRangeId: requestContext.partitionKeyRangeId,
|
8693 | useMultipleWriteLocations: this.connectionPolicy.useMultipleWriteLocations,
|
8694 | partitionKey: requestContext.partitionKey,
|
8695 | });
|
8696 | }
|
8697 | |
8698 |
|
8699 |
|
8700 |
|
8701 | getContextDerivedPropsForRequestCreation() {
|
8702 | return {
|
8703 | globalEndpointManager: this.globalEndpointManager,
|
8704 | requestAgent: this.cosmosClientOptions.agent,
|
8705 | connectionPolicy: this.connectionPolicy,
|
8706 | client: this,
|
8707 | plugins: this.cosmosClientOptions.plugins,
|
8708 | pipeline: this.pipeline,
|
8709 | };
|
8710 | }
|
8711 | }
|
8712 |
|
8713 |
|
8714 |
|
8715 |
|
8716 |
|
8717 | function getUserAgent(suffix) {
|
8718 | const ua = `${universalUserAgent.getUserAgent()} ${Constants.SDKName}/${Constants.SDKVersion}`;
|
8719 | if (suffix) {
|
8720 | return ua + " " + suffix;
|
8721 | }
|
8722 | return ua;
|
8723 | }
|
8724 |
|
8725 |
|
8726 |
|
8727 |
|
8728 |
|
8729 |
|
8730 | class GlobalEndpointManager {
|
8731 | |
8732 |
|
8733 |
|
8734 | constructor(options, readDatabaseAccount) {
|
8735 | this.readDatabaseAccount = readDatabaseAccount;
|
8736 | this.writeableLocations = [];
|
8737 | this.readableLocations = [];
|
8738 | this.unavailableReadableLocations = [];
|
8739 | this.unavailableWriteableLocations = [];
|
8740 | this.options = options;
|
8741 | this.defaultEndpoint = options.endpoint;
|
8742 | this.enableEndpointDiscovery = options.connectionPolicy.enableEndpointDiscovery;
|
8743 | this.isRefreshing = false;
|
8744 | this.preferredLocations = this.options.connectionPolicy.preferredLocations;
|
8745 | }
|
8746 | |
8747 |
|
8748 |
|
8749 | async getReadEndpoint() {
|
8750 | return this.resolveServiceEndpoint(exports.ResourceType.item, exports.OperationType.Read);
|
8751 | }
|
8752 | |
8753 |
|
8754 |
|
8755 | async getWriteEndpoint() {
|
8756 | return this.resolveServiceEndpoint(exports.ResourceType.item, exports.OperationType.Replace);
|
8757 | }
|
8758 | async getReadEndpoints() {
|
8759 | return this.readableLocations.map((loc) => loc.databaseAccountEndpoint);
|
8760 | }
|
8761 | async getWriteEndpoints() {
|
8762 | return this.writeableLocations.map((loc) => loc.databaseAccountEndpoint);
|
8763 | }
|
8764 | async markCurrentLocationUnavailableForRead(endpoint) {
|
8765 | await this.refreshEndpointList();
|
8766 | const location = this.readableLocations.find((loc) => loc.databaseAccountEndpoint === endpoint);
|
8767 | if (location) {
|
8768 | location.unavailable = true;
|
8769 | location.lastUnavailabilityTimestampInMs = Date.now();
|
8770 | this.unavailableReadableLocations.push(location);
|
8771 | }
|
8772 | }
|
8773 | async markCurrentLocationUnavailableForWrite(endpoint) {
|
8774 | await this.refreshEndpointList();
|
8775 | const location = this.writeableLocations.find((loc) => loc.databaseAccountEndpoint === endpoint);
|
8776 | if (location) {
|
8777 | location.unavailable = true;
|
8778 | location.lastUnavailabilityTimestampInMs = Date.now();
|
8779 | this.unavailableWriteableLocations.push(location);
|
8780 | }
|
8781 | }
|
8782 | canUseMultipleWriteLocations(resourceType, operationType) {
|
8783 | let canUse = this.options.connectionPolicy.useMultipleWriteLocations;
|
8784 | if (resourceType) {
|
8785 | canUse =
|
8786 | canUse &&
|
8787 | (resourceType === exports.ResourceType.item ||
|
8788 | (resourceType === exports.ResourceType.sproc && operationType === exports.OperationType.Execute));
|
8789 | }
|
8790 | return canUse;
|
8791 | }
|
8792 | async resolveServiceEndpoint(resourceType, operationType) {
|
8793 |
|
8794 | if (!this.options.connectionPolicy.enableEndpointDiscovery) {
|
8795 | return this.defaultEndpoint;
|
8796 | }
|
8797 |
|
8798 | if (resourceType === exports.ResourceType.none) {
|
8799 | return this.defaultEndpoint;
|
8800 | }
|
8801 | if (this.readableLocations.length === 0 || this.writeableLocations.length === 0) {
|
8802 | const { resource: databaseAccount } = await this.readDatabaseAccount({
|
8803 | urlConnection: this.defaultEndpoint,
|
8804 | });
|
8805 | this.writeableLocations = databaseAccount.writableLocations;
|
8806 | this.readableLocations = databaseAccount.readableLocations;
|
8807 | }
|
8808 | const locations = isReadRequest(operationType)
|
8809 | ? this.readableLocations
|
8810 | : this.writeableLocations;
|
8811 | let location;
|
8812 |
|
8813 | if (this.preferredLocations && this.preferredLocations.length > 0) {
|
8814 | for (const preferredLocation of this.preferredLocations) {
|
8815 | location = locations.find((loc) => loc.unavailable !== true &&
|
8816 | normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation));
|
8817 | if (location) {
|
8818 | break;
|
8819 | }
|
8820 | }
|
8821 | }
|
8822 |
|
8823 | if (!location) {
|
8824 | location = locations.find((loc) => {
|
8825 | return loc.unavailable !== true;
|
8826 | });
|
8827 | }
|
8828 | return location ? location.databaseAccountEndpoint : this.defaultEndpoint;
|
8829 | }
|
8830 | |
8831 |
|
8832 |
|
8833 |
|
8834 |
|
8835 |
|
8836 | async refreshEndpointList() {
|
8837 | if (!this.isRefreshing && this.enableEndpointDiscovery) {
|
8838 | this.isRefreshing = true;
|
8839 | const databaseAccount = await this.getDatabaseAccountFromAnyEndpoint();
|
8840 | if (databaseAccount) {
|
8841 | this.refreshStaleUnavailableLocations();
|
8842 | this.refreshEndpoints(databaseAccount);
|
8843 | }
|
8844 | this.isRefreshing = false;
|
8845 | }
|
8846 | }
|
8847 | refreshEndpoints(databaseAccount) {
|
8848 | for (const location of databaseAccount.writableLocations) {
|
8849 | const existingLocation = this.writeableLocations.find((loc) => loc.name === location.name);
|
8850 | if (!existingLocation) {
|
8851 | this.writeableLocations.push(location);
|
8852 | }
|
8853 | }
|
8854 | for (const location of databaseAccount.readableLocations) {
|
8855 | const existingLocation = this.readableLocations.find((loc) => loc.name === location.name);
|
8856 | if (!existingLocation) {
|
8857 | this.readableLocations.push(location);
|
8858 | }
|
8859 | }
|
8860 | }
|
8861 | refreshStaleUnavailableLocations() {
|
8862 | const now = Date.now();
|
8863 | this.updateLocation(now, this.unavailableReadableLocations, this.readableLocations);
|
8864 | this.unavailableReadableLocations = this.cleanUnavailableLocationList(now, this.unavailableReadableLocations);
|
8865 | this.updateLocation(now, this.unavailableWriteableLocations, this.writeableLocations);
|
8866 | this.unavailableWriteableLocations = this.cleanUnavailableLocationList(now, this.unavailableWriteableLocations);
|
8867 | }
|
8868 | |
8869 |
|
8870 |
|
8871 |
|
8872 |
|
8873 |
|
8874 | updateLocation(now, unavailableLocations, allLocations) {
|
8875 | for (const location of unavailableLocations) {
|
8876 | const unavaialableLocation = allLocations.find((loc) => loc.name === location.name);
|
8877 | if (unavaialableLocation &&
|
8878 | now - unavaialableLocation.lastUnavailabilityTimestampInMs >
|
8879 | Constants.LocationUnavailableExpirationTimeInMs) {
|
8880 | unavaialableLocation.unavailable = false;
|
8881 | }
|
8882 | }
|
8883 | }
|
8884 | cleanUnavailableLocationList(now, unavailableLocations) {
|
8885 | return unavailableLocations.filter((loc) => {
|
8886 | if (loc &&
|
8887 | now - loc.lastUnavailabilityTimestampInMs >= Constants.LocationUnavailableExpirationTimeInMs) {
|
8888 | return false;
|
8889 | }
|
8890 | return true;
|
8891 | });
|
8892 | }
|
8893 | |
8894 |
|
8895 |
|
8896 |
|
8897 |
|
8898 | async getDatabaseAccountFromAnyEndpoint() {
|
8899 | try {
|
8900 | const options = { urlConnection: this.defaultEndpoint };
|
8901 | const { resource: databaseAccount } = await this.readDatabaseAccount(options);
|
8902 | return databaseAccount;
|
8903 |
|
8904 |
|
8905 |
|
8906 |
|
8907 |
|
8908 |
|
8909 | }
|
8910 | catch (err) {
|
8911 |
|
8912 | }
|
8913 | if (this.preferredLocations) {
|
8914 | for (const location of this.preferredLocations) {
|
8915 | try {
|
8916 | const locationalEndpoint = GlobalEndpointManager.getLocationalEndpoint(this.defaultEndpoint, location);
|
8917 | const options = { urlConnection: locationalEndpoint };
|
8918 | const { resource: databaseAccount } = await this.readDatabaseAccount(options);
|
8919 | if (databaseAccount) {
|
8920 | return databaseAccount;
|
8921 | }
|
8922 | }
|
8923 | catch (err) {
|
8924 |
|
8925 | }
|
8926 | }
|
8927 | }
|
8928 | }
|
8929 | |
8930 |
|
8931 |
|
8932 |
|
8933 |
|
8934 |
|
8935 | static getLocationalEndpoint(defaultEndpoint, locationName) {
|
8936 |
|
8937 |
|
8938 |
|
8939 | const endpointUrl = new URL(defaultEndpoint);
|
8940 |
|
8941 | if (endpointUrl.hostname) {
|
8942 | const hostnameParts = endpointUrl.hostname.toString().toLowerCase().split(".");
|
8943 | if (hostnameParts) {
|
8944 |
|
8945 | const globalDatabaseAccountName = hostnameParts[0];
|
8946 |
|
8947 | const locationalDatabaseAccountName = globalDatabaseAccountName + "-" + locationName.replace(" ", "");
|
8948 |
|
8949 |
|
8950 | const locationalEndpoint = defaultEndpoint
|
8951 | .toLowerCase()
|
8952 | .replace(globalDatabaseAccountName, locationalDatabaseAccountName);
|
8953 | return locationalEndpoint;
|
8954 | }
|
8955 | }
|
8956 | return null;
|
8957 | }
|
8958 | }
|
8959 | function normalizeEndpoint(endpoint) {
|
8960 | return endpoint.split(" ").join("").toLowerCase();
|
8961 | }
|
8962 |
|
8963 |
|
8964 |
|
8965 |
|
8966 |
|
8967 |
|
8968 |
|
8969 |
|
8970 |
|
8971 |
|
8972 |
|
8973 |
|
8974 |
|
8975 |
|
8976 |
|
8977 |
|
8978 |
|
8979 |
|
8980 |
|
8981 |
|
8982 |
|
8983 | class CosmosClient {
|
8984 | constructor(optionsOrConnectionString) {
|
8985 | var _a, _b;
|
8986 | if (typeof optionsOrConnectionString === "string") {
|
8987 | optionsOrConnectionString = parseConnectionString(optionsOrConnectionString);
|
8988 | }
|
8989 | const endpoint = checkURL(optionsOrConnectionString.endpoint);
|
8990 | if (!endpoint) {
|
8991 | throw new Error("Invalid endpoint specified");
|
8992 | }
|
8993 | optionsOrConnectionString.connectionPolicy = Object.assign({}, defaultConnectionPolicy, optionsOrConnectionString.connectionPolicy);
|
8994 | optionsOrConnectionString.defaultHeaders = optionsOrConnectionString.defaultHeaders || {};
|
8995 | optionsOrConnectionString.defaultHeaders[Constants.HttpHeaders.CacheControl] = "no-cache";
|
8996 | optionsOrConnectionString.defaultHeaders[Constants.HttpHeaders.Version] =
|
8997 | Constants.CurrentVersion;
|
8998 | if (optionsOrConnectionString.consistencyLevel !== undefined) {
|
8999 | optionsOrConnectionString.defaultHeaders[Constants.HttpHeaders.ConsistencyLevel] =
|
9000 | optionsOrConnectionString.consistencyLevel;
|
9001 | }
|
9002 | optionsOrConnectionString.defaultHeaders[Constants.HttpHeaders.UserAgent] = getUserAgent(optionsOrConnectionString.userAgentSuffix);
|
9003 | const globalEndpointManager = new GlobalEndpointManager(optionsOrConnectionString, async (opts) => this.getDatabaseAccount(opts));
|
9004 | this.clientContext = new ClientContext(optionsOrConnectionString, globalEndpointManager);
|
9005 | if (((_a = optionsOrConnectionString.connectionPolicy) === null || _a === void 0 ? void 0 : _a.enableEndpointDiscovery) &&
|
9006 | ((_b = optionsOrConnectionString.connectionPolicy) === null || _b === void 0 ? void 0 : _b.enableBackgroundEndpointRefreshing)) {
|
9007 | this.backgroundRefreshEndpointList(globalEndpointManager, optionsOrConnectionString.connectionPolicy.endpointRefreshRateInMs ||
|
9008 | defaultConnectionPolicy.endpointRefreshRateInMs);
|
9009 | }
|
9010 | this.databases = new Databases(this, this.clientContext);
|
9011 | this.offers = new Offers(this, this.clientContext);
|
9012 | }
|
9013 | |
9014 |
|
9015 |
|
9016 | async getDatabaseAccount(options) {
|
9017 | const response = await this.clientContext.getDatabaseAccount(options);
|
9018 | return new ResourceResponse(response.result, response.headers, response.code);
|
9019 | }
|
9020 | |
9021 |
|
9022 |
|
9023 |
|
9024 |
|
9025 | getWriteEndpoint() {
|
9026 | return this.clientContext.getWriteEndpoint();
|
9027 | }
|
9028 | |
9029 |
|
9030 |
|
9031 |
|
9032 |
|
9033 | getReadEndpoint() {
|
9034 | return this.clientContext.getReadEndpoint();
|
9035 | }
|
9036 | |
9037 |
|
9038 |
|
9039 |
|
9040 |
|
9041 | getWriteEndpoints() {
|
9042 | return this.clientContext.getWriteEndpoints();
|
9043 | }
|
9044 | |
9045 |
|
9046 |
|
9047 |
|
9048 |
|
9049 | getReadEndpoints() {
|
9050 | return this.clientContext.getReadEndpoints();
|
9051 | }
|
9052 | |
9053 |
|
9054 |
|
9055 |
|
9056 |
|
9057 |
|
9058 |
|
9059 |
|
9060 |
|
9061 |
|
9062 |
|
9063 |
|
9064 |
|
9065 |
|
9066 |
|
9067 |
|
9068 | database(id) {
|
9069 | return new Database(this, id, this.clientContext);
|
9070 | }
|
9071 | |
9072 |
|
9073 |
|
9074 |
|
9075 | offer(id) {
|
9076 | return new Offer(this, id, this.clientContext);
|
9077 | }
|
9078 | |
9079 |
|
9080 |
|
9081 | dispose() {
|
9082 | clearTimeout(this.endpointRefresher);
|
9083 | }
|
9084 | async backgroundRefreshEndpointList(globalEndpointManager, refreshRate) {
|
9085 | this.endpointRefresher = setInterval(() => {
|
9086 | try {
|
9087 | globalEndpointManager.refreshEndpointList();
|
9088 | }
|
9089 | catch (e) {
|
9090 | console.warn("Failed to refresh endpoints", e);
|
9091 | }
|
9092 | }, refreshRate);
|
9093 | if (this.endpointRefresher.unref && typeof this.endpointRefresher.unref === "function") {
|
9094 | this.endpointRefresher.unref();
|
9095 | }
|
9096 | }
|
9097 | }
|
9098 |
|
9099 |
|
9100 |
|
9101 | class SasTokenProperties {
|
9102 | }
|
9103 |
|
9104 |
|
9105 |
|
9106 |
|
9107 | function encodeUTF8(str) {
|
9108 | const bytes = new Uint8Array(str.length);
|
9109 | for (let i = 0; i < str.length; i++) {
|
9110 | bytes[i] = str.charCodeAt(i);
|
9111 | }
|
9112 | return bytes;
|
9113 | }
|
9114 |
|
9115 |
|
9116 |
|
9117 |
|
9118 |
|
9119 |
|
9120 | async function createAuthorizationSasToken(masterKey, sasTokenProperties) {
|
9121 | let resourcePrefixPath = "";
|
9122 | if (typeof sasTokenProperties.databaseName === "string" &&
|
9123 | sasTokenProperties.databaseName !== "") {
|
9124 | resourcePrefixPath += `/${Constants.Path.DatabasesPathSegment}/${sasTokenProperties.databaseName}`;
|
9125 | }
|
9126 | if (typeof sasTokenProperties.containerName === "string" &&
|
9127 | sasTokenProperties.containerName !== "") {
|
9128 | if (sasTokenProperties.databaseName === "") {
|
9129 | throw new Error(`illegalArgumentException : ${sasTokenProperties.databaseName} \
|
9130 | is an invalid database name`);
|
9131 | }
|
9132 | resourcePrefixPath += `/${Constants.Path.CollectionsPathSegment}/${sasTokenProperties.containerName}`;
|
9133 | }
|
9134 | if (typeof sasTokenProperties.resourceName === "string" &&
|
9135 | sasTokenProperties.resourceName !== "") {
|
9136 | if (sasTokenProperties.containerName === "") {
|
9137 | throw new Error(`illegalArgumentException : ${sasTokenProperties.containerName} \
|
9138 | is an invalid container name`);
|
9139 | }
|
9140 | switch (sasTokenProperties.resourceKind) {
|
9141 | case "ITEM":
|
9142 | resourcePrefixPath += `${Constants.Path.Root}${Constants.Path.DocumentsPathSegment}`;
|
9143 | break;
|
9144 | case "STORED_PROCEDURE":
|
9145 | resourcePrefixPath += `${Constants.Path.Root}${Constants.Path.StoredProceduresPathSegment}`;
|
9146 | break;
|
9147 | case "USER_DEFINED_FUNCTION":
|
9148 | resourcePrefixPath += `${Constants.Path.Root}${Constants.Path.UserDefinedFunctionsPathSegment}`;
|
9149 | break;
|
9150 | case "TRIGGER":
|
9151 | resourcePrefixPath += `${Constants.Path.Root}${Constants.Path.TriggersPathSegment}`;
|
9152 | break;
|
9153 | default:
|
9154 | throw new Error(`illegalArgumentException : ${sasTokenProperties.resourceKind} \
|
9155 | is an invalid resource kind`);
|
9156 | }
|
9157 | resourcePrefixPath += `${Constants.Path.Root}${sasTokenProperties.resourceName}${Constants.Path.Root}`;
|
9158 | }
|
9159 | sasTokenProperties.resourcePath = resourcePrefixPath.toString();
|
9160 | let partitionRanges = "";
|
9161 | if (sasTokenProperties.partitionKeyValueRanges !== undefined &&
|
9162 | sasTokenProperties.partitionKeyValueRanges.length > 0) {
|
9163 | if (typeof sasTokenProperties.resourceKind !== "string" &&
|
9164 | sasTokenProperties.resourceKind !== "ITEM") {
|
9165 | throw new Error(`illegalArgumentException : ${sasTokenProperties.resourceKind} \
|
9166 | is an invalid partition key value range`);
|
9167 | }
|
9168 | sasTokenProperties.partitionKeyValueRanges.forEach((range) => {
|
9169 | partitionRanges += `${encodeUTF8(range)},`;
|
9170 | });
|
9171 | }
|
9172 | if (sasTokenProperties.controlPlaneReaderScope === 0) {
|
9173 | sasTokenProperties.controlPlaneReaderScope += exports.SasTokenPermissionKind.ContainerReadAny;
|
9174 | sasTokenProperties.controlPlaneWriterScope += exports.SasTokenPermissionKind.ContainerReadAny;
|
9175 | }
|
9176 | if (sasTokenProperties.dataPlaneReaderScope === 0 &&
|
9177 | sasTokenProperties.dataPlaneWriterScope === 0) {
|
9178 | sasTokenProperties.dataPlaneReaderScope = exports.SasTokenPermissionKind.ContainerFullAccess;
|
9179 | sasTokenProperties.dataPlaneWriterScope = exports.SasTokenPermissionKind.ContainerFullAccess;
|
9180 | }
|
9181 | if (typeof sasTokenProperties.keyType !== "number" ||
|
9182 | typeof sasTokenProperties.keyType === undefined) {
|
9183 | switch (sasTokenProperties.keyType) {
|
9184 | case CosmosKeyType.PrimaryMaster:
|
9185 | sasTokenProperties.keyType = 1;
|
9186 | break;
|
9187 | case CosmosKeyType.SecondaryMaster:
|
9188 | sasTokenProperties.keyType = 2;
|
9189 | break;
|
9190 | case CosmosKeyType.PrimaryReadOnly:
|
9191 | sasTokenProperties.keyType = 3;
|
9192 | break;
|
9193 | case CosmosKeyType.SecondaryReadOnly:
|
9194 | sasTokenProperties.keyType = 4;
|
9195 | break;
|
9196 | default:
|
9197 | throw new Error(`illegalArgumentException : ${sasTokenProperties.keyType} \
|
9198 | is an invalid key type`);
|
9199 | }
|
9200 | }
|
9201 | const payload = sasTokenProperties.user +
|
9202 | "\n" +
|
9203 | sasTokenProperties.userTag +
|
9204 | "\n" +
|
9205 | sasTokenProperties.resourcePath +
|
9206 | "\n" +
|
9207 | partitionRanges +
|
9208 | "\n" +
|
9209 | utcsecondsSinceEpoch(sasTokenProperties.startTime).toString(16) +
|
9210 | "\n" +
|
9211 | utcsecondsSinceEpoch(sasTokenProperties.expiryTime).toString(16) +
|
9212 | "\n" +
|
9213 | sasTokenProperties.keyType +
|
9214 | "\n" +
|
9215 | sasTokenProperties.controlPlaneReaderScope.toString(16) +
|
9216 | "\n" +
|
9217 | sasTokenProperties.controlPlaneWriterScope.toString(16) +
|
9218 | "\n" +
|
9219 | sasTokenProperties.dataPlaneReaderScope.toString(16) +
|
9220 | "\n" +
|
9221 | sasTokenProperties.dataPlaneWriterScope.toString(16) +
|
9222 | "\n";
|
9223 | const signedPayload = await hmac(masterKey, Buffer.from(payload).toString("base64"));
|
9224 | return "type=sas&ver=1.0&sig=" + signedPayload + ";" + Buffer.from(payload).toString("base64");
|
9225 | }
|
9226 |
|
9227 |
|
9228 |
|
9229 |
|
9230 | function utcsecondsSinceEpoch(date) {
|
9231 | return Math.round(date.getTime() / 1000);
|
9232 | }
|
9233 |
|
9234 | Object.defineProperty(exports, 'RestError', {
|
9235 | enumerable: true,
|
9236 | get: function () { return coreRestPipeline.RestError; }
|
9237 | });
|
9238 | Object.defineProperty(exports, 'AbortError', {
|
9239 | enumerable: true,
|
9240 | get: function () { return abortController.AbortError; }
|
9241 | });
|
9242 | exports.BulkOperationType = BulkOperationType;
|
9243 | exports.ChangeFeedIterator = ChangeFeedIterator;
|
9244 | exports.ChangeFeedResponse = ChangeFeedResponse;
|
9245 | exports.ClientContext = ClientContext;
|
9246 | exports.ClientSideMetrics = ClientSideMetrics;
|
9247 | exports.Conflict = Conflict;
|
9248 | exports.ConflictResponse = ConflictResponse;
|
9249 | exports.Conflicts = Conflicts;
|
9250 | exports.Constants = Constants;
|
9251 | exports.Container = Container;
|
9252 | exports.ContainerResponse = ContainerResponse;
|
9253 | exports.Containers = Containers;
|
9254 | exports.CosmosClient = CosmosClient;
|
9255 | exports.DEFAULT_PARTITION_KEY_PATH = DEFAULT_PARTITION_KEY_PATH;
|
9256 | exports.Database = Database;
|
9257 | exports.DatabaseAccount = DatabaseAccount;
|
9258 | exports.DatabaseResponse = DatabaseResponse;
|
9259 | exports.Databases = Databases;
|
9260 | exports.ErrorResponse = ErrorResponse;
|
9261 | exports.FeedResponse = FeedResponse;
|
9262 | exports.GlobalEndpointManager = GlobalEndpointManager;
|
9263 | exports.Item = Item;
|
9264 | exports.ItemResponse = ItemResponse;
|
9265 | exports.Items = Items;
|
9266 | exports.Offer = Offer;
|
9267 | exports.OfferResponse = OfferResponse;
|
9268 | exports.Offers = Offers;
|
9269 | exports.PatchOperationType = PatchOperationType;
|
9270 | exports.Permission = Permission;
|
9271 | exports.PermissionResponse = PermissionResponse;
|
9272 | exports.Permissions = Permissions;
|
9273 | exports.QueryIterator = QueryIterator;
|
9274 | exports.QueryMetrics = QueryMetrics;
|
9275 | exports.QueryMetricsConstants = QueryMetricsConstants;
|
9276 | exports.QueryPreparationTimes = QueryPreparationTimes;
|
9277 | exports.ResourceResponse = ResourceResponse;
|
9278 | exports.RuntimeExecutionTimes = RuntimeExecutionTimes;
|
9279 | exports.SasTokenProperties = SasTokenProperties;
|
9280 | exports.Scripts = Scripts;
|
9281 | exports.StatusCodes = StatusCodes;
|
9282 | exports.StoredProcedure = StoredProcedure;
|
9283 | exports.StoredProcedureResponse = StoredProcedureResponse;
|
9284 | exports.StoredProcedures = StoredProcedures;
|
9285 | exports.TimeSpan = TimeSpan;
|
9286 | exports.TimeoutError = TimeoutError;
|
9287 | exports.Trigger = Trigger;
|
9288 | exports.TriggerResponse = TriggerResponse;
|
9289 | exports.Triggers = Triggers;
|
9290 | exports.User = User;
|
9291 | exports.UserDefinedFunction = UserDefinedFunction;
|
9292 | exports.UserDefinedFunctionResponse = UserDefinedFunctionResponse;
|
9293 | exports.UserDefinedFunctions = UserDefinedFunctions;
|
9294 | exports.UserResponse = UserResponse;
|
9295 | exports.Users = Users;
|
9296 | exports.createAuthorizationSasToken = createAuthorizationSasToken;
|
9297 | exports.extractPartitionKey = extractPartitionKey;
|
9298 | exports.setAuthorizationTokenHeaderUsingMasterKey = setAuthorizationTokenHeaderUsingMasterKey;
|
9299 |
|