azure-mock 2.36.0 → 2.37.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +15 -7
- package/dist/index.d.ts +56 -46
- package/dist/index.js +112 -134
- package/package.json +7 -7
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RestError, createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
|
|
2
2
|
import { toHttpHeadersLike } from "@azure/core-http-compat";
|
|
3
|
-
import { ID_SEPARATOR, InvalidOperationError, Operation, exhaustiveGuard, getOrCreate, getResult, html, noop, streamToText, takeOne } from "@esposter/shared";
|
|
3
|
+
import { ID_SEPARATOR, InvalidOperationError, Operation, chunk, exhaustiveGuard, getDecodedUriComponent, getOrCreate, getResult, html, noop, streamToText, takeOne } from "@esposter/shared";
|
|
4
4
|
import { AnonymousCredential } from "@azure/storage-blob";
|
|
5
5
|
import { Readable } from "node:stream";
|
|
6
6
|
import { MAX_QUEUE_VISIBILITY_TIMEOUT_MS, deserializeClause, deserializeKey, getTableNullClause, serializeClauses } from "@esposter/db";
|
|
@@ -26,6 +26,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
value: mod,
|
|
27
27
|
enumerable: true
|
|
28
28
|
}) : target, mod));
|
|
29
|
+
const BLOB_NOT_FOUND_ERROR_CODE = "BlobNotFound";
|
|
30
|
+
const BLOB_NOT_FOUND_MESSAGE = "The specified blob does not exist.";
|
|
29
31
|
const MOCK_BLOB_BASE_URL = "https://mockaccount.blob.core.windows.net";
|
|
30
32
|
const MOCK_QUEUE_BASE_URL = "https://mockaccount.queue.core.windows.net";
|
|
31
33
|
const MOCK_SEARCH_BASE_URL = "https://mockaccount.search.windows.net";
|
|
@@ -94,7 +96,7 @@ const getAzureErrorXml = (errorCode, errorMessage) => html`<?xml version="1.0" e
|
|
|
94
96
|
<code>${errorCode}</code>
|
|
95
97
|
<Message>${errorMessage}</Message>
|
|
96
98
|
</Error>`;
|
|
97
|
-
const decodeSegment = (segment) =>
|
|
99
|
+
const decodeSegment = (segment) => getDecodedUriComponent(segment, segment);
|
|
98
100
|
const getBlobUrlParts = (url) => {
|
|
99
101
|
const parsedUrl = getResult(() => new URL(url)).unwrapOr(void 0);
|
|
100
102
|
if (!parsedUrl) return void 0;
|
|
@@ -105,6 +107,7 @@ const getBlobUrlParts = (url) => {
|
|
|
105
107
|
containerName: decodeSegment(takeOne(pathSegments))
|
|
106
108
|
};
|
|
107
109
|
};
|
|
110
|
+
const getMockContainer = (containerName) => getOrCreate(MockContainerDatabase, containerName, () => /* @__PURE__ */ new Map());
|
|
108
111
|
var MockBlobBatchClient = class {
|
|
109
112
|
url;
|
|
110
113
|
constructor(url) {
|
|
@@ -123,19 +126,7 @@ var MockBlobBatchClient = class {
|
|
|
123
126
|
for (const url of urls) {
|
|
124
127
|
const urlParts = getBlobUrlParts(url);
|
|
125
128
|
if (!urlParts) {
|
|
126
|
-
|
|
127
|
-
const statusMessage = "Invalid blob URL format.";
|
|
128
|
-
subResponses.push({
|
|
129
|
-
_request: {
|
|
130
|
-
credential,
|
|
131
|
-
url: this.url
|
|
132
|
-
},
|
|
133
|
-
bodyAsText: getAzureErrorXml(errorCode, statusMessage),
|
|
134
|
-
errorCode,
|
|
135
|
-
headers: toHttpHeadersLike(createHttpHeaders()),
|
|
136
|
-
status: 400,
|
|
137
|
-
statusMessage
|
|
138
|
-
});
|
|
129
|
+
subResponses.push(this.#createFailedSubResponse(credential, 400, "InvalidUri", "Invalid blob URL format."));
|
|
139
130
|
subResponsesFailedCount++;
|
|
140
131
|
continue;
|
|
141
132
|
}
|
|
@@ -155,19 +146,7 @@ var MockBlobBatchClient = class {
|
|
|
155
146
|
});
|
|
156
147
|
subResponsesSucceededCount++;
|
|
157
148
|
} else {
|
|
158
|
-
|
|
159
|
-
const statusMessage = "The specified blob does not exist.";
|
|
160
|
-
subResponses.push({
|
|
161
|
-
_request: {
|
|
162
|
-
credential,
|
|
163
|
-
url: this.url
|
|
164
|
-
},
|
|
165
|
-
bodyAsText: getAzureErrorXml(errorCode, statusMessage),
|
|
166
|
-
errorCode,
|
|
167
|
-
headers: toHttpHeadersLike(createHttpHeaders()),
|
|
168
|
-
status: 404,
|
|
169
|
-
statusMessage
|
|
170
|
-
});
|
|
149
|
+
subResponses.push(this.#createFailedSubResponse(credential, 404, BLOB_NOT_FOUND_ERROR_CODE, BLOB_NOT_FOUND_MESSAGE));
|
|
171
150
|
subResponsesFailedCount++;
|
|
172
151
|
}
|
|
173
152
|
}
|
|
@@ -185,7 +164,20 @@ var MockBlobBatchClient = class {
|
|
|
185
164
|
});
|
|
186
165
|
}
|
|
187
166
|
getContainer(containerName) {
|
|
188
|
-
return
|
|
167
|
+
return getMockContainer(containerName);
|
|
168
|
+
}
|
|
169
|
+
#createFailedSubResponse(credential, status, errorCode, statusMessage) {
|
|
170
|
+
return {
|
|
171
|
+
_request: {
|
|
172
|
+
credential,
|
|
173
|
+
url: this.url
|
|
174
|
+
},
|
|
175
|
+
bodyAsText: getAzureErrorXml(errorCode, statusMessage),
|
|
176
|
+
errorCode,
|
|
177
|
+
headers: toHttpHeadersLike(createHttpHeaders()),
|
|
178
|
+
status,
|
|
179
|
+
statusMessage
|
|
180
|
+
};
|
|
189
181
|
}
|
|
190
182
|
};
|
|
191
183
|
const getBlobUrl = (containerName, blobName) => `${MOCK_BLOB_BASE_URL}/${containerName}/${blobName.split("/").map((segment) => encodeURIComponent(segment)).join("/")}`;
|
|
@@ -196,7 +188,7 @@ var MockBlobClient = class {
|
|
|
196
188
|
name;
|
|
197
189
|
url;
|
|
198
190
|
get container() {
|
|
199
|
-
return
|
|
191
|
+
return getMockContainer(this.containerName);
|
|
200
192
|
}
|
|
201
193
|
constructor(connectionString, containerName, blobName) {
|
|
202
194
|
this.connectionString = connectionString;
|
|
@@ -237,7 +229,7 @@ var MockBlobClient = class {
|
|
|
237
229
|
throw new Error("Method not implemented.");
|
|
238
230
|
}
|
|
239
231
|
delete() {
|
|
240
|
-
if (!this.container.has(this.name)) throw new MockRestError(
|
|
232
|
+
if (!this.container.has(this.name)) throw new MockRestError(BLOB_NOT_FOUND_MESSAGE, 404);
|
|
241
233
|
this.container.delete(this.name);
|
|
242
234
|
MockContainerCreatedOnDatabase.delete(getMockContainerCreatedOnKey(this.containerName, this.name));
|
|
243
235
|
return Promise.resolve({ _response: createMockResponse(200) });
|
|
@@ -265,7 +257,7 @@ var MockBlobClient = class {
|
|
|
265
257
|
}
|
|
266
258
|
downloadToBuffer() {
|
|
267
259
|
const data = this.container.get(this.name);
|
|
268
|
-
if (!data) throw new MockRestError(
|
|
260
|
+
if (!data) throw new MockRestError(BLOB_NOT_FOUND_MESSAGE, 404);
|
|
269
261
|
return Promise.resolve(Buffer.from(data));
|
|
270
262
|
}
|
|
271
263
|
downloadToFile() {
|
|
@@ -429,6 +421,23 @@ const getListBlobsXml = (containerName, blobsXml) => html`<?xml version="1.0" en
|
|
|
429
421
|
<Blobs>${blobsXml}</Blobs>
|
|
430
422
|
<NextMarker />
|
|
431
423
|
</EnumerationResults>`;
|
|
424
|
+
const getListBlobsSegmentResponse = (containerName, prefix, segment, blobsXml) => {
|
|
425
|
+
const segmentResponse = {
|
|
426
|
+
containerName,
|
|
427
|
+
marker: "",
|
|
428
|
+
prefix,
|
|
429
|
+
segment,
|
|
430
|
+
serviceEndpoint: ""
|
|
431
|
+
};
|
|
432
|
+
return {
|
|
433
|
+
_response: {
|
|
434
|
+
...createMockResponse(200),
|
|
435
|
+
bodyAsText: getListBlobsXml(containerName, blobsXml),
|
|
436
|
+
parsedBody: segmentResponse
|
|
437
|
+
},
|
|
438
|
+
...segmentResponse
|
|
439
|
+
};
|
|
440
|
+
};
|
|
432
441
|
/**
|
|
433
442
|
* An in-memory mock of the Azure ContainerClient.
|
|
434
443
|
* It uses a Map to simulate blob storage.
|
|
@@ -445,7 +454,7 @@ var MockContainerClient = class {
|
|
|
445
454
|
credential = new AnonymousCredential();
|
|
446
455
|
url;
|
|
447
456
|
get container() {
|
|
448
|
-
return
|
|
457
|
+
return getMockContainer(this.containerName);
|
|
449
458
|
}
|
|
450
459
|
constructor(connectionString, containerName) {
|
|
451
460
|
this.connectionString = connectionString;
|
|
@@ -462,7 +471,7 @@ var MockContainerClient = class {
|
|
|
462
471
|
throw new Error("Method not implemented.");
|
|
463
472
|
}
|
|
464
473
|
deleteBlob(blobName) {
|
|
465
|
-
if (!this.container.has(blobName)) throw new MockRestError(
|
|
474
|
+
if (!this.container.has(blobName)) throw new MockRestError(BLOB_NOT_FOUND_MESSAGE, 404);
|
|
466
475
|
this.container.delete(blobName);
|
|
467
476
|
MockContainerCreatedOnDatabase.delete(getMockContainerCreatedOnKey(this.containerName, blobName));
|
|
468
477
|
return Promise.resolve({ _response: createMockResponse(200, getBlobUrl(this.containerName, blobName)) });
|
|
@@ -530,24 +539,10 @@ var MockContainerClient = class {
|
|
|
530
539
|
allBlobPrefixes.push({ name: blobHierarchyItem.name });
|
|
531
540
|
allBlobPrefixXml.push(getBlobPrefixXml(blobHierarchyItem.name));
|
|
532
541
|
}
|
|
533
|
-
if (allBlobItems.length > 0 || allBlobPrefixes.length > 0) yield await Promise.resolve({
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
parsedBody: {
|
|
538
|
-
containerName: this.containerName,
|
|
539
|
-
marker: "",
|
|
540
|
-
prefix: options?.prefix ?? "",
|
|
541
|
-
segment: { blobItems: allBlobItems },
|
|
542
|
-
serviceEndpoint: ""
|
|
543
|
-
}
|
|
544
|
-
},
|
|
545
|
-
containerName: this.containerName,
|
|
546
|
-
marker: "",
|
|
547
|
-
prefix: options?.prefix ?? "",
|
|
548
|
-
segment: { blobItems: allBlobItems },
|
|
549
|
-
serviceEndpoint: ""
|
|
550
|
-
});
|
|
542
|
+
if (allBlobItems.length > 0 || allBlobPrefixes.length > 0) yield await Promise.resolve(getListBlobsSegmentResponse(this.containerName, options?.prefix ?? "", {
|
|
543
|
+
blobItems: allBlobItems,
|
|
544
|
+
blobPrefixes: allBlobPrefixes
|
|
545
|
+
}, `${allBlobItemXml.join("")}${allBlobPrefixXml.join("")}`));
|
|
551
546
|
}.bind(this)(),
|
|
552
547
|
next: blobHierarchyItemIterator.next.bind(blobHierarchyItemIterator),
|
|
553
548
|
[Symbol.asyncIterator]() {
|
|
@@ -565,24 +560,7 @@ var MockContainerClient = class {
|
|
|
565
560
|
allBlobItems.push(blobItem);
|
|
566
561
|
allBlobItemXml.push(getBlobItemXml(blobItem));
|
|
567
562
|
}
|
|
568
|
-
if (allBlobItems.length > 0) yield await Promise.resolve({
|
|
569
|
-
_response: {
|
|
570
|
-
...createMockResponse(200),
|
|
571
|
-
bodyAsText: getListBlobsXml(this.containerName, allBlobItemXml.join("")),
|
|
572
|
-
parsedBody: {
|
|
573
|
-
containerName: this.containerName,
|
|
574
|
-
marker: "",
|
|
575
|
-
prefix: options?.prefix ?? "",
|
|
576
|
-
segment: { blobItems: allBlobItems },
|
|
577
|
-
serviceEndpoint: ""
|
|
578
|
-
}
|
|
579
|
-
},
|
|
580
|
-
containerName: this.containerName,
|
|
581
|
-
marker: "",
|
|
582
|
-
prefix: options?.prefix ?? "",
|
|
583
|
-
segment: { blobItems: allBlobItems },
|
|
584
|
-
serviceEndpoint: ""
|
|
585
|
-
});
|
|
563
|
+
if (allBlobItems.length > 0) yield await Promise.resolve(getListBlobsSegmentResponse(this.containerName, options?.prefix ?? "", { blobItems: allBlobItems }, allBlobItemXml.join("")));
|
|
586
564
|
}.bind(this)(),
|
|
587
565
|
next: blobItemIterator.next.bind(blobItemIterator),
|
|
588
566
|
[Symbol.asyncIterator]() {
|
|
@@ -611,21 +589,7 @@ var MockContainerClient = class {
|
|
|
611
589
|
if (!name.startsWith(prefix)) continue;
|
|
612
590
|
const nameAfterPrefix = name.slice(prefix.length);
|
|
613
591
|
const delimiterIndex = nameAfterPrefix.indexOf(delimiter);
|
|
614
|
-
if (delimiterIndex === -1) blobsInCurrentLevel.push(
|
|
615
|
-
deleted: false,
|
|
616
|
-
name,
|
|
617
|
-
properties: {
|
|
618
|
-
blobType: "BlockBlob",
|
|
619
|
-
contentLength: buffer.length,
|
|
620
|
-
contentType: "application/octet-stream",
|
|
621
|
-
createdOn: MockContainerCreatedOnDatabase.get(getMockContainerCreatedOnKey(this.containerName, name)) ?? MOCK_BLOB_SEEDED_CREATED_ON,
|
|
622
|
-
etag: `"${crypto.randomUUID()}"`,
|
|
623
|
-
lastModified: /* @__PURE__ */ new Date(),
|
|
624
|
-
leaseState: "available",
|
|
625
|
-
leaseStatus: "unlocked"
|
|
626
|
-
},
|
|
627
|
-
snapshot: ""
|
|
628
|
-
});
|
|
592
|
+
if (delimiterIndex === -1) blobsInCurrentLevel.push(this.#getBlobItem(name, buffer));
|
|
629
593
|
else {
|
|
630
594
|
const subprefix = `${prefix}${nameAfterPrefix.slice(0, delimiterIndex + delimiter.length)}`;
|
|
631
595
|
uniqueSubprefixes.add(subprefix);
|
|
@@ -640,25 +604,28 @@ var MockContainerClient = class {
|
|
|
640
604
|
...blobItem
|
|
641
605
|
});
|
|
642
606
|
}
|
|
607
|
+
#getBlobItem(name, buffer) {
|
|
608
|
+
return {
|
|
609
|
+
deleted: false,
|
|
610
|
+
name,
|
|
611
|
+
properties: {
|
|
612
|
+
blobType: "BlockBlob",
|
|
613
|
+
contentLength: buffer.length,
|
|
614
|
+
contentType: "application/octet-stream",
|
|
615
|
+
createdOn: MockContainerCreatedOnDatabase.get(getMockContainerCreatedOnKey(this.containerName, name)) ?? MOCK_BLOB_SEEDED_CREATED_ON,
|
|
616
|
+
etag: `"${crypto.randomUUID()}"`,
|
|
617
|
+
lastModified: /* @__PURE__ */ new Date(),
|
|
618
|
+
leaseState: "available",
|
|
619
|
+
leaseStatus: "unlocked"
|
|
620
|
+
},
|
|
621
|
+
snapshot: ""
|
|
622
|
+
};
|
|
623
|
+
}
|
|
643
624
|
async *#getBlobItemIterator(options) {
|
|
644
625
|
const prefix = options?.prefix ?? "";
|
|
645
626
|
for (const [name, buffer] of this.container.entries()) {
|
|
646
627
|
if (!name.startsWith(prefix)) continue;
|
|
647
|
-
yield await Promise.resolve(
|
|
648
|
-
deleted: false,
|
|
649
|
-
name,
|
|
650
|
-
properties: {
|
|
651
|
-
blobType: "BlockBlob",
|
|
652
|
-
contentLength: buffer.length,
|
|
653
|
-
contentType: "application/octet-stream",
|
|
654
|
-
createdOn: MockContainerCreatedOnDatabase.get(getMockContainerCreatedOnKey(this.containerName, name)) ?? MOCK_BLOB_SEEDED_CREATED_ON,
|
|
655
|
-
etag: `"${crypto.randomUUID()}"`,
|
|
656
|
-
lastModified: /* @__PURE__ */ new Date(),
|
|
657
|
-
leaseState: "available",
|
|
658
|
-
leaseStatus: "unlocked"
|
|
659
|
-
},
|
|
660
|
-
snapshot: ""
|
|
661
|
-
});
|
|
628
|
+
yield await Promise.resolve(this.#getBlobItem(name, buffer));
|
|
662
629
|
}
|
|
663
630
|
}
|
|
664
631
|
};
|
|
@@ -681,6 +648,15 @@ var MockEventGridPublisherClient = class {
|
|
|
681
648
|
return Promise.resolve();
|
|
682
649
|
}
|
|
683
650
|
};
|
|
651
|
+
const getMockQueueMessageItem = (messageText) => {
|
|
652
|
+
const insertedOn = /* @__PURE__ */ new Date();
|
|
653
|
+
return {
|
|
654
|
+
expiresOn: new Date(insertedOn.getTime() + MAX_QUEUE_VISIBILITY_TIMEOUT_MS),
|
|
655
|
+
insertedOn,
|
|
656
|
+
messageId: crypto.randomUUID(),
|
|
657
|
+
messageText
|
|
658
|
+
};
|
|
659
|
+
};
|
|
684
660
|
/**
|
|
685
661
|
* An in-memory mock of the Azure QueueClient.
|
|
686
662
|
* It uses a Map to simulate queue storage and correctly implements the QueueClient interface.
|
|
@@ -751,10 +727,7 @@ var MockQueueClient = class {
|
|
|
751
727
|
peekMessages(_options) {
|
|
752
728
|
const peekedMessageItems = this.queue.map((text) => ({
|
|
753
729
|
dequeueCount: 0,
|
|
754
|
-
|
|
755
|
-
insertedOn: /* @__PURE__ */ new Date(),
|
|
756
|
-
messageId: crypto.randomUUID(),
|
|
757
|
-
messageText: text
|
|
730
|
+
...getMockQueueMessageItem(text)
|
|
758
731
|
}));
|
|
759
732
|
return Promise.resolve({
|
|
760
733
|
_response: {
|
|
@@ -766,12 +739,8 @@ var MockQueueClient = class {
|
|
|
766
739
|
});
|
|
767
740
|
}
|
|
768
741
|
receiveMessages(_options) {
|
|
769
|
-
const receivedMessageItems = this.queue.splice(0).map((text) => ({
|
|
742
|
+
const receivedMessageItems = this.queue.splice(0).map((text) => Object.assign(getMockQueueMessageItem(text), {
|
|
770
743
|
dequeueCount: 1,
|
|
771
|
-
expiresOn: new Date(Date.now() + MAX_QUEUE_VISIBILITY_TIMEOUT_MS),
|
|
772
|
-
insertedOn: /* @__PURE__ */ new Date(),
|
|
773
|
-
messageId: crypto.randomUUID(),
|
|
774
|
-
messageText: text,
|
|
775
744
|
nextVisibleOn: /* @__PURE__ */ new Date(),
|
|
776
745
|
popReceipt: crypto.randomUUID()
|
|
777
746
|
}));
|
|
@@ -786,11 +755,8 @@ var MockQueueClient = class {
|
|
|
786
755
|
}
|
|
787
756
|
sendMessage(messageText, _options) {
|
|
788
757
|
this.queue.push(messageText);
|
|
789
|
-
const
|
|
790
|
-
const
|
|
791
|
-
const insertedOn = now;
|
|
792
|
-
const messageId = crypto.randomUUID();
|
|
793
|
-
const nextVisibleOn = now;
|
|
758
|
+
const { expiresOn, insertedOn, messageId } = getMockQueueMessageItem(messageText);
|
|
759
|
+
const nextVisibleOn = insertedOn;
|
|
794
760
|
const popReceipt = crypto.randomUUID();
|
|
795
761
|
const enqueuedMessages = [{
|
|
796
762
|
expiresOn,
|
|
@@ -874,15 +840,20 @@ const isNullClause = (clause) => {
|
|
|
874
840
|
return (0, import_fast_deep_equal.default)(clause, tableNullClause);
|
|
875
841
|
};
|
|
876
842
|
const createFilterPredicate = (filter) => {
|
|
877
|
-
const orGroups = filter.replaceAll(String.raw`(`, " ").replaceAll(String.raw`)`, "").split(/\s+and\s+/iu).filter(Boolean).map((group) => group.split(/\s+or\s+/iu).filter(Boolean))
|
|
843
|
+
const orGroups = filter.replaceAll(String.raw`(`, " ").replaceAll(String.raw`)`, "").split(/\s+and\s+/iu).filter(Boolean).map((group) => group.split(/\s+or\s+/iu).filter(Boolean).map((clauseString) => {
|
|
844
|
+
const clause = deserializeClause(clauseString);
|
|
845
|
+
return {
|
|
846
|
+
clause,
|
|
847
|
+
isNull: isNullClause(clause)
|
|
848
|
+
};
|
|
849
|
+
}));
|
|
878
850
|
return (document) => {
|
|
879
851
|
for (const orGroup of orGroups) {
|
|
880
852
|
let isGroupMatched = false;
|
|
881
|
-
for (const
|
|
882
|
-
const clause = deserializeClause(group);
|
|
853
|
+
for (const { clause, isNull } of orGroup) {
|
|
883
854
|
const value = takeOne(document, clause.key);
|
|
884
855
|
let isMatched;
|
|
885
|
-
if (
|
|
856
|
+
if (isNull) isMatched = compare(BinaryOperator.eq, value, null);
|
|
886
857
|
else {
|
|
887
858
|
const comparisonResult = compare(clause.operator, value, clause.value);
|
|
888
859
|
isMatched = clause.not ? !comparisonResult : comparisonResult;
|
|
@@ -908,15 +879,22 @@ const compareValues = (leftHandSide, rightHandSide) => {
|
|
|
908
879
|
if (typeof left === "number" && typeof right === "number") return left - right;
|
|
909
880
|
return String(left).localeCompare(String(right));
|
|
910
881
|
};
|
|
911
|
-
const sortDocuments = (documents, orderBy) =>
|
|
912
|
-
|
|
882
|
+
const sortDocuments = (documents, orderBy) => {
|
|
883
|
+
const parsedOrderBy = orderBy.map((clause) => {
|
|
913
884
|
const [field = "", direction = "asc"] = clause.split(/\s+/u);
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
885
|
+
return {
|
|
886
|
+
direction,
|
|
887
|
+
key: deserializeKey(field)
|
|
888
|
+
};
|
|
889
|
+
});
|
|
890
|
+
return documents.toSorted((leftHandSide, rightHandSide) => {
|
|
891
|
+
for (const { direction, key } of parsedOrderBy) {
|
|
892
|
+
const comparison = compareValues(leftHandSide[key], rightHandSide[key]);
|
|
893
|
+
if (comparison !== 0) return direction === "desc" ? -comparison : comparison;
|
|
894
|
+
}
|
|
895
|
+
return 0;
|
|
896
|
+
});
|
|
897
|
+
};
|
|
920
898
|
const getSearchFieldValues = (value, pathSegments) => {
|
|
921
899
|
if (pathSegments.length === 0) return [value];
|
|
922
900
|
if (Array.isArray(value)) return value.flatMap((item) => getSearchFieldValues(item, pathSegments));
|
|
@@ -927,7 +905,8 @@ const getSearchFieldValues = (value, pathSegments) => {
|
|
|
927
905
|
const searchDocuments = (documents, searchText, searchFields) => {
|
|
928
906
|
if (!searchText || searchText === "*") return documents;
|
|
929
907
|
const normalizedSearchText = searchText.toLocaleLowerCase();
|
|
930
|
-
|
|
908
|
+
const searchFieldPaths = searchFields?.map((searchField) => searchField.split("/"));
|
|
909
|
+
return documents.filter((document) => (searchFieldPaths ?? Object.keys(document).map((field) => field.split("/"))).some((pathSegments) => getSearchFieldValues(document, pathSegments).some((value) => typeof value === "string" && value.toLocaleLowerCase().includes(normalizedSearchText))));
|
|
931
910
|
};
|
|
932
911
|
/**
|
|
933
912
|
* An in-memory mock of the Azure SearchClient.
|
|
@@ -1094,9 +1073,9 @@ var MockTableClient = class {
|
|
|
1094
1073
|
listEntities(options) {
|
|
1095
1074
|
const withMetadata = this.#withMetadata.bind(this);
|
|
1096
1075
|
const filter = options?.queryOptions?.filter;
|
|
1097
|
-
const tableEntities = [...this.table.values()]
|
|
1076
|
+
const tableEntities = [...this.table.values()];
|
|
1098
1077
|
const predicate = filter ? createFilterPredicate(filter) : void 0;
|
|
1099
|
-
const resultTableEntities = predicate ? tableEntities.filter((e) => predicate(e)) : tableEntities;
|
|
1078
|
+
const resultTableEntities = (predicate ? tableEntities.filter((e) => predicate(e)) : tableEntities).toSorted(compareByCompositeKey);
|
|
1100
1079
|
const entityIterator = (async function* (entities) {
|
|
1101
1080
|
for (const entity of entities) yield await Promise.resolve(withMetadata(entity));
|
|
1102
1081
|
})(resultTableEntities);
|
|
@@ -1104,13 +1083,12 @@ var MockTableClient = class {
|
|
|
1104
1083
|
byPage: ({ maxPageSize } = {}) => (async function* (entities) {
|
|
1105
1084
|
if (maxPageSize !== void 0 && maxPageSize <= 0) throw new RangeError("maxPageSize must be greater than 0.");
|
|
1106
1085
|
else if (maxPageSize !== void 0 && maxPageSize > AZURE_MAX_PAGE_SIZE) throw new MockRestError("One of the request inputs is not valid.", 400);
|
|
1107
|
-
|
|
1108
|
-
if (allEntitiesWithMetadata.length === 0) return;
|
|
1086
|
+
if (entities.length === 0) return;
|
|
1109
1087
|
else if (!maxPageSize) {
|
|
1110
|
-
yield await Promise.resolve(
|
|
1088
|
+
yield await Promise.resolve(entities.map((e) => withMetadata(e)));
|
|
1111
1089
|
return;
|
|
1112
1090
|
}
|
|
1113
|
-
for (
|
|
1091
|
+
for (const page of chunk(entities, maxPageSize)) yield await Promise.resolve(page.map((e) => withMetadata(e)));
|
|
1114
1092
|
})(resultTableEntities),
|
|
1115
1093
|
next: () => entityIterator.next(),
|
|
1116
1094
|
[Symbol.asyncIterator]() {
|
|
@@ -1235,4 +1213,4 @@ const applyFilter = (documents, clauses) => {
|
|
|
1235
1213
|
const predicate = createFilterPredicate(serializeClauses(clauses));
|
|
1236
1214
|
return documents.filter((document) => predicate(document));
|
|
1237
1215
|
};
|
|
1238
|
-
export { MOCK_BLOB_BASE_URL, MOCK_BLOB_SEEDED_CREATED_ON, MOCK_QUEUE_BASE_URL, MOCK_SEARCH_BASE_URL, MOCK_TABLE_BASE_URL, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerCreatedOnDatabase, MockContainerDatabase, MockEventGridDatabase, MockEventGridPublisherClient, MockQueueClient, MockQueueDatabase, MockRestError, MockSearchClient, MockSearchDatabase, MockServiceBusDatabase, MockServiceBusSender, MockTableClient, MockTableDatabase, MockWebPubSubServiceClient, applyFilter, bodyToBuffer, compare, compareByCompositeKey, createFilterPredicate, createMockResponse, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getBlobUrl, getBlobUrlParts, getListBlobsXml, getMockContainerCreatedOnKey, getMockSasUrl, isNullClause, isReadableStream, toWebResourceLike };
|
|
1216
|
+
export { BLOB_NOT_FOUND_ERROR_CODE, BLOB_NOT_FOUND_MESSAGE, MOCK_BLOB_BASE_URL, MOCK_BLOB_SEEDED_CREATED_ON, MOCK_QUEUE_BASE_URL, MOCK_SEARCH_BASE_URL, MOCK_TABLE_BASE_URL, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerCreatedOnDatabase, MockContainerDatabase, MockEventGridDatabase, MockEventGridPublisherClient, MockQueueClient, MockQueueDatabase, MockRestError, MockSearchClient, MockSearchDatabase, MockServiceBusDatabase, MockServiceBusSender, MockTableClient, MockTableDatabase, MockWebPubSubServiceClient, applyFilter, bodyToBuffer, compare, compareByCompositeKey, createFilterPredicate, createMockResponse, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getBlobUrl, getBlobUrlParts, getListBlobsSegmentResponse, getListBlobsXml, getMockContainer, getMockContainerCreatedOnKey, getMockQueueMessageItem, getMockSasUrl, isNullClause, isReadableStream, toWebResourceLike };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "azure-mock",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.37.2",
|
|
4
4
|
"description": "A library that contains azure mock classes.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"azure",
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"typecheck": "tsgo"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@esposter/db": "2.
|
|
51
|
-
"@esposter/db-schema": "2.
|
|
52
|
-
"@esposter/shared": "2.
|
|
50
|
+
"@esposter/db": "2.37.2",
|
|
51
|
+
"@esposter/db-schema": "2.37.2",
|
|
52
|
+
"@esposter/shared": "2.37.2",
|
|
53
53
|
"fast-deep-equal": "^3.1.3"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@esposter/configuration": "2.
|
|
56
|
+
"@esposter/configuration": "2.37.2",
|
|
57
57
|
"ctix": "^2.8.2",
|
|
58
|
-
"rolldown": "^1.2.
|
|
58
|
+
"rolldown": "^1.2.4",
|
|
59
59
|
"type-fest": "^5.8.0",
|
|
60
60
|
"typedoc": "^0.28.20",
|
|
61
61
|
"vitest": "^4.1.10"
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"@azure/storage-blob": "^12.33.0",
|
|
71
71
|
"@azure/storage-queue": "^12.31.0"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "4d775dbd8289e6caaee48f08038b65fddb4babbc"
|
|
74
74
|
}
|